Passed
Branch merging-leagues-tournaments (1b2f12)
by Benedikt
06:40
created

RankingSystemServiceTest   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 1277
Duplicated Lines 0 %

Importance

Changes 4
Bugs 1 Features 3
Metric Value
wmc 34
eloc 563
c 4
b 1
f 3
dl 0
loc 1277
rs 9.68

32 Methods

Rating   Name   Duplication   Size   Complexity  
A prepareUpdateRankingFrom() 0 38 3
A testUpdateRankingForTournamentTournamentIsEarlier() 0 23 1
A testUpdateRankingFromNoReusable() 0 11 1
A testGetEntityManager() 0 8 1
A createEntities() 0 6 1
A createEmptyChange() 0 5 1
A prepareCreateChange() 0 10 1
A testGetEntities() 0 25 1
A testUpdateRankingForTournamentOldEarliestIsEarlier() 0 24 1
A testUpdateRankingForTournamentOldEarliestIsNullAndTournamentNotRanked() 0 15 1
A testConstruct() 0 18 1
A testGetAverage() 0 11 1
A testGetOrCreateChangeCreateNewOne() 0 17 1
A testDontUseDeletedChange() 0 13 1
A testUpdateRankingCreateMonthlyLists() 0 60 1
A testGetEarliestInfluenceGameLevel() 0 50 1
A testGetOrCreateChangeCreateTwice() 0 9 1
A testGetEarliestInfluenceTournamentLevel() 0 21 1
A testUpdateRankingForTournamentOldEarliestIsNull() 0 23 1
A testGetEmptyAverage() 0 6 1
A testUpdateRankingFromNoEntities() 0 25 1
A testUpdateRankingFromCalledTwice() 0 14 1
A testUpdateRankingForTournamentOldEarliestIsNotNullAndTournamentNotRanked() 0 16 1
A testUpdateRankingFromNoCurrent() 0 50 1
A testGetOrCreateRankingSystemListEntryNewEntry() 0 28 1
A testDoubleOldChange() 0 16 1
A createEmptyEntry() 0 5 1
B testUpdateRankingFrom() 0 115 1
A testGetOrCreateGetDeletedChange() 0 18 1
A testGetEntriesOfPlayers() 0 19 1
A testGetOrCreateRankingSystemListEntryExistingEntry() 0 13 1
B testGetEarliestInfluenceGameLevelWithDifferentImpactLevels() 0 102 1
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Created by PhpStorm.
5
 * User: benedikt
6
 * Date: 1/3/18
7
 * Time: 3:54 PM
8
 */
9
10
namespace Tfboe\FmLib\Tests\Unit\Service\RankingSystem;
11
12
use DateTime;
13
use Doctrine\Common\Collections\ArrayCollection;
14
use Doctrine\Common\Collections\Collection;
15
use Doctrine\ORM\AbstractQuery;
16
use Doctrine\ORM\EntityManager;
17
use Doctrine\ORM\EntityManagerInterface;
18
use Doctrine\ORM\QueryBuilder;
19
use PHPUnit\Framework\MockObject\MockObject;
20
use ReflectionException;
21
use Tfboe\FmLib\Entity\Helpers\AutomaticInstanceGeneration;
22
use Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity;
23
use Tfboe\FmLib\Entity\Helpers\TournamentHierarchyInterface;
24
use Tfboe\FmLib\Entity\RankingSystemChangeInterface;
25
use Tfboe\FmLib\Entity\RankingSystemInterface;
26
use Tfboe\FmLib\Entity\RankingSystemListEntryInterface;
27
use Tfboe\FmLib\Entity\RankingSystemListInterface;
28
use Tfboe\FmLib\Exceptions\PreconditionFailedException;
29
use Tfboe\FmLib\Helpers\Level;
30
use Tfboe\FmLib\Service\ObjectCreatorServiceInterface;
31
use Tfboe\FmLib\Service\RankingSystem\EntityComparerInterface;
32
use Tfboe\FmLib\Service\RankingSystem\RankingSystemService;
33
use Tfboe\FmLib\Service\RankingSystem\TimeServiceInterface;
34
use Tfboe\FmLib\Tests\Entity\Competition;
35
use Tfboe\FmLib\Tests\Entity\Game;
36
use Tfboe\FmLib\Tests\Entity\Match;
37
use Tfboe\FmLib\Tests\Entity\Phase;
38
use Tfboe\FmLib\Tests\Entity\Player;
39
use Tfboe\FmLib\Tests\Entity\RankingSystem;
40
use Tfboe\FmLib\Tests\Entity\RankingSystemChange;
41
use Tfboe\FmLib\Tests\Entity\RankingSystemList;
42
use Tfboe\FmLib\Tests\Entity\RankingSystemListEntry;
43
use Tfboe\FmLib\Tests\Entity\Tournament;
44
use Tfboe\FmLib\Tests\Helpers\UnitTestCase;
45
46
47
/**
48
 * Class RankingSystemServiceTest
49
 * @packageTfboe\FmLib\Tests\Unit\Service\RankingSystemService
50
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
51
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
52
 * @SuppressWarnings(PHPMD.TooManyMethods)
53
 * @SuppressWarnings(PHPMD.ExcessiveClassLength)
54
 */
55
class RankingSystemServiceTest extends UnitTestCase
56
{
57
//<editor-fold desc="Public Methods">
58
59
  /**
60
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
61
   * @throws ReflectionException
62
   */
63
  public function testConstruct()
64
  {
65
    $entityManager = $this->createMock(EntityManagerInterface::class);
66
    $timeService = $this->createMock(TimeServiceInterface::class);
67
    $entityComparer = $this->createMock(EntityComparerInterface::class);
68
    $objectCreator = $this->createMock(ObjectCreatorServiceInterface::class);
69
    $system = $this->getMockForAbstractClass(RankingSystemService::class,
70
      [$entityManager, $timeService, $entityComparer, $objectCreator]);
71
    self::assertInstanceOf(RankingSystemService::class, $system);
72
    /** @noinspection PhpUnhandledExceptionInspection */
73
    self::assertEquals($entityManager, self::getProperty(get_class($system), 'entityManager')->getValue($system));
74
    /** @noinspection PhpUnhandledExceptionInspection */
75
    self::assertEquals($timeService, self::getProperty(get_class($system), 'timeService')->getValue($system));
76
    /** @noinspection PhpUnhandledExceptionInspection */
77
    self::assertEquals($entityComparer, self::getProperty(get_class($system), 'entityComparer')->getValue($system));
78
    /** @noinspection PhpUnhandledExceptionInspection */
79
    self::assertEquals($objectCreator, self::getProperty(get_class($system), 'objectCreatorService')
80
      ->getValue($system));
81
  }
82
83
  /**
84
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
85
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
86
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
87
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
88
   * @throws ReflectionException
89
   * @throws ReflectionException
90
   * @throws PreconditionFailedException
91
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
92
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
93
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange::init
94
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
95
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
96
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
97
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
98
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
99
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
100
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
101
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
102
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
103
   */
104
  public function testDontUseDeletedChange()
105
  {
106
    [$entity, $ranking, $player] = $this->createEntities();
107
    $change = $this->createStub(RankingSystemChange::class,
108
      ['getRankingSystem' => $ranking, 'getPlayer' => $player, 'getHierarchyEntity' => $entity, 'getId' => "c1"]);
109
110
    $entityManager = $this->getEntityManagerMockForQuery([$change], null, ['persist', 'flush', 'detach', 'remove',
111
      'getRepository']);
112
    $entityManager->expects(self::once())->method('flush');
113
    $entityManager->expects(self::once())->method('remove')->with($change);
114
    $service = $this->prepareUpdateRankingFrom($ranking, $entityManager, null, 1, [], [$entity]);
115
    /** @noinspection PhpUnhandledExceptionInspection */
116
    $service->updateRankingFrom($ranking, new DateTime('2017-02-28'));
117
  }
118
119
  /**
120
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
121
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
122
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
123
   * @throws ReflectionException
124
   * @throws ReflectionException
125
   * @throws PreconditionFailedException
126
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
127
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange::init
128
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
129
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
130
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
131
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
132
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
133
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
134
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
135
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
136
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
137
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
138
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
139
   */
140
  public function testDoubleOldChange()
141
  {
142
    [$entity, $ranking, $player] = $this->createEntities();
143
    $change1 = $this->createStub(RankingSystemChange::class,
144
      ['getRankingSystem' => $ranking, 'getPlayer' => $player, 'getHierarchyEntity' => $entity, 'getId' => "c1"]);
145
    $change2 = $this->createStub(RankingSystemChange::class,
146
      ['getRankingSystem' => $ranking, 'getPlayer' => $player, 'getHierarchyEntity' => $entity, 'getId' => "c2"]);
147
    self::assertNotEquals($change1->getId(), $change2->getId());
148
149
    $entityManager = $this->getEntityManagerMockForQuery([$change1, $change2], null, ['persist', 'flush', 'remove',
150
      'getRepository']);
151
    $entityManager->expects(self::once())->method('flush');
152
    $entityManager->expects(self::exactly(2))->method('remove')->withConsecutive([$change2], [$change1]);
153
    $service = $this->prepareUpdateRankingFrom($ranking, $entityManager, null, 1, ['deleteOldChanges']);
154
    /** @noinspection PhpUnhandledExceptionInspection */
155
    $service->updateRankingFrom($ranking, new DateTime('2017-02-28'));
156
  }
157
158
  /**
159
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getAverage
160
   * @throws ReflectionException
161
   */
162
  public function testGetAverage()
163
  {
164
    /** @var RankingSystemService $service */
165
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
166
167
    $entry1 = $this->createMock(RankingSystemListEntry::class);
168
    $entry1->method('getPoints')->willReturn(1.0);
169
    $entry2 = $this->createMock(RankingSystemListEntry::class);
170
    $entry2->method('getPoints')->willReturn(2.0);
171
172
    self::assertEquals(1.5, static::callProtectedMethod($service, 'getAverage', [[$entry1, $entry2]]));
173
  }
174
175
  /**
176
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
177
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
178
   * @throws ReflectionException
179
   * @uses   \Tfboe\FmLib\Entity\Traits\Competition
180
   * @uses   \Tfboe\FmLib\Entity\Traits\Competition
181
   * @uses   \Tfboe\FmLib\Entity\Traits\Game
182
   * @uses   \Tfboe\FmLib\Entity\Traits\Game
183
   * @uses   \Tfboe\FmLib\Entity\Helpers\NameEntity
184
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
185
   * @uses   \Tfboe\FmLib\Entity\Traits\Match
186
   * @uses   \Tfboe\FmLib\Entity\Traits\Match
187
   * @uses   \Tfboe\FmLib\Entity\Traits\Phase
188
   * @uses   \Tfboe\FmLib\Entity\Traits\Phase
189
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
190
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
191
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
192
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
193
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
194
   */
195
  public function testGetEarliestInfluenceGameLevel()
196
  {
197
    $ranking = $this->createStubWithId(RankingSystem::class);
198
    $timeService = $this->createMock(TimeServiceInterface::class);
199
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
200
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
201
      return $entity->getEndTime();
202
    })->after('clearTimes');
203
    /** @var RankingSystemInterface $ranking */
204
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
205
      [$this->createMock(EntityManagerInterface::class),
206
        $timeService,
207
        $this->createMock(EntityComparerInterface::class),
208
        $this->createMock(ObjectCreatorServiceInterface::class)]);
209
    $service->method("getLevel")->willReturn(Level::GAME);
210
    /** @var RankingSystemService $service */
211
    $tournament = new Tournament();
212
    $competition = new Competition();
213
    $competition->setName("TestCompetition")->setTournament($tournament);
214
    $phase = new Phase();
215
    $phase->setPhaseNumber(1);
216
    $phase->setCompetition($competition);
217
    $match = new Match();
218
    $match->setMatchNumber(1);
219
    $match->setPhase($phase);
220
    self::assertNull($service->getEarliestInfluence($ranking, $tournament));
221
222
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
223
    self::assertNull($service->getEarliestInfluence($ranking, $tournament));
224
225
    $game = new Game();
226
    $game->setGameNumber(1);
227
    $game->setMatch($match);
228
    $gameEndTime = new DateTime("2017-06-01 00:00:00");
229
    $game->setEndTime($gameEndTime);
230
    self::assertEquals($gameEndTime, $service->getEarliestInfluence($ranking, $tournament));
231
232
    $game2 = new Game();
233
    $game2->setGameNumber(2);
234
    $game2->setMatch($match);
235
    $game2EndTime = new DateTime("2017-05-01 00:00:00");
236
    $game2->setEndTime($game2EndTime);
237
    self::assertEquals($game2EndTime, $service->getEarliestInfluence($ranking, $tournament));
238
239
    $game3 = new Game();
240
    $game3->setGameNumber(3);
241
    $game3->setMatch($match);
242
    $game3EndTime = new DateTime("2017-07-01 00:00:00");
243
    $game3->setEndTime($game3EndTime);
244
    self::assertEquals($game2EndTime, $service->getEarliestInfluence($ranking, $tournament));
245
  }
246
247
  /**
248
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
249
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
250
   * @throws ReflectionException
251
   * @uses   \Tfboe\FmLib\Entity\Traits\Competition
252
   * @uses   \Tfboe\FmLib\Entity\Traits\Competition
253
   * @uses   \Tfboe\FmLib\Entity\Traits\Game
254
   * @uses   \Tfboe\FmLib\Entity\Traits\Game
255
   * @uses   \Tfboe\FmLib\Entity\Helpers\NameEntity
256
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
257
   * @uses   \Tfboe\FmLib\Entity\Traits\Match
258
   * @uses   \Tfboe\FmLib\Entity\Traits\Match
259
   * @uses   \Tfboe\FmLib\Entity\Traits\Phase
260
   * @uses   \Tfboe\FmLib\Entity\Traits\Phase
261
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
262
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
263
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
264
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
265
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
266
   * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
267
   */
268
  public function testGetEarliestInfluenceGameLevelWithDifferentImpactLevels()
269
  {
270
    $ranking = $this->createStubWithId(RankingSystem::class);
271
    $timeService = $this->createMock(TimeServiceInterface::class);
272
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
273
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
274
      return $entity->getEndTime();
275
    })->after('clearTimes');
276
    /** @var RankingSystemInterface $ranking */
277
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
278
      [$this->createMock(EntityManagerInterface::class),
279
        $timeService,
280
        $this->createMock(EntityComparerInterface::class),
281
        $this->createMock(ObjectCreatorServiceInterface::class)]);
282
    $service->method("getLevel")->willReturn(Level::GAME);
283
    /** @var RankingSystemService $service */
284
    $tournament = new Tournament();
285
    $competition = new Competition();
286
    $competition->setName("TestCompetition")->setTournament($tournament);
287
    $phase = new Phase();
288
    $phase->setPhaseNumber(1);
289
    $phase->setCompetition($competition);
290
    $match = new Match();
291
    $match->setMatchNumber(1);
292
    $match->setPhase($phase);
293
    $game = new Game();
294
    $game->setGameNumber(1);
295
    $game->setMatch($match);
296
    $endTime1 = new DateTime("2017-12-01 00:00:00");
297
    $game->setEndTime($endTime1);
298
    $game->getRankingSystems()->set($ranking->getId(), $ranking);
299
    self::assertEquals($endTime1, $service->getEarliestInfluence($ranking, $tournament));
300
301
    $game2 = new Game();
302
    $game2->setGameNumber(2);
303
    $game2->setMatch($match);
304
    $endTime2 = new DateTime("2017-11-01 00:00:00");
305
    $game2->setEndTime($endTime2);
306
    self::assertEquals($endTime1, $service->getEarliestInfluence($ranking, $tournament));
307
308
    $match->getRankingSystems()->set($ranking->getId(), $ranking);
309
    self::assertEquals($endTime2, $service->getEarliestInfluence($ranking, $tournament));
310
311
    $match2 = new Match();
312
    $match2->setMatchNumber(2);
313
    $match2->setPhase($phase);
314
    $game3 = new Game();
315
    $game3->setGameNumber(1);
316
    $game3->setMatch($match2);
317
    $endTime3 = new DateTime("2017-10-01 00:00:00");
318
    $game3->setEndTime($endTime3);
319
    self::assertEquals($endTime2, $service->getEarliestInfluence($ranking, $tournament));
320
321
    $phase->getRankingSystems()->set($ranking->getId(), $ranking);
322
    self::assertEquals($endTime3, $service->getEarliestInfluence($ranking, $tournament));
323
324
    $phase2 = new Phase();
325
    $phase2->setPhaseNumber(2);
326
    $phase2->setCompetition($competition);
327
    $match3 = new Match();
328
    $match3->setMatchNumber(1);
329
    $match3->setPhase($phase2);
330
    $game4 = new Game();
331
    $game4->setGameNumber(1);
332
    $game4->setMatch($match3);
333
    $endTime4 = new DateTime("2017-09-01 00:00:00");
334
    $game4->setEndTime($endTime4);
335
    self::assertEquals($endTime3, $service->getEarliestInfluence($ranking, $tournament));
336
337
    $competition->getRankingSystems()->set($ranking->getId(), $ranking);
338
    self::assertEquals($endTime4, $service->getEarliestInfluence($ranking, $tournament));
339
340
    $competition2 = new Competition();
341
    $competition2->setName("TestCompetition2")->setTournament($tournament);
342
    $phase3 = new Phase();
343
    $phase3->setPhaseNumber(1);
344
    $phase3->setCompetition($competition2);
345
    $match4 = new Match();
346
    $match4->setMatchNumber(1);
347
    $match4->setPhase($phase3);
348
    $game5 = new Game();
349
    $game5->setGameNumber(1);
350
    $game5->setMatch($match4);
351
    $endTime5 = new DateTime("2017-01-01 00:00:00");
352
    $game5->setEndTime($endTime5);
353
    self::assertEquals($endTime4, $service->getEarliestInfluence($ranking, $tournament));
354
355
    $game6 = new Game();
356
    $game6->setGameNumber(2);
357
    $game6->setMatch($match4);
358
    $endTime6 = new DateTime("2017-10-01 00:00:00");
359
    $game6->setEndTime($endTime6);
360
    $game6->getRankingSystems()->set($ranking->getId(), $ranking);
361
    self::assertEquals($endTime4, $service->getEarliestInfluence($ranking, $tournament));
362
363
    $game7 = new Game();
364
    $game7->setGameNumber(3);
365
    $game7->setMatch($match4);
366
    $endTime7 = new DateTime("2017-08-01 00:00:00");
367
    $game7->setEndTime($endTime7);
368
    $game7->getRankingSystems()->set($ranking->getId(), $ranking);
369
    self::assertEquals($endTime7, $service->getEarliestInfluence($ranking, $tournament));
370
  }
371
372
  /**
373
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
374
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
375
   * @throws ReflectionException
376
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
377
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
378
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
379
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
380
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
381
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
382
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
383
   */
384
  public function testGetEarliestInfluenceTournamentLevel()
385
  {
386
    $ranking = $this->createStubWithId(RankingSystem::class);
387
    $timeService = $this->createMock(TimeServiceInterface::class);
388
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
389
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
390
      return $entity->getEndTime();
391
    })->after('clearTimes');
392
    /** @var RankingSystemInterface $ranking */
393
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
394
      [$this->createMock(EntityManagerInterface::class),
395
        $timeService,
396
        $this->createMock(EntityComparerInterface::class),
397
        $this->createMock(ObjectCreatorServiceInterface::class)]);
398
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
399
    /** @var RankingSystemService $service */
400
    $tournament = new Tournament();
401
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
402
    $endTime = new DateTime("2017-03-01 00:00:00");
403
    $tournament->setEndTime($endTime);
404
    self::assertEquals($endTime, $service->getEarliestInfluence($ranking, $tournament));
405
  }
406
407
  /**
408
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getAverage
409
   * @throws ReflectionException
410
   */
411
  public function testGetEmptyAverage()
412
  {
413
    /** @var RankingSystemService $service */
414
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
415
416
    self::assertEquals(0.0, static::callProtectedMethod($service, 'getAverage', [[]]));
417
  }
418
419
  /**
420
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
421
   * @throws ReflectionException
422
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
423
   */
424
  public function testGetEntities()
425
  {
426
    //create mock for input
427
    $ranking = $this->createMock(RankingSystem::class);
428
429
    //create service mock
430
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
431
      [$this->createMock(EntityManagerInterface::class), $this->createMock(TimeServiceInterface::class),
432
        $this->createMock(EntityComparerInterface::class),
433
        $this->createMock(ObjectCreatorServiceInterface::class)]);
434
435
    //create mock for queryBuilder
436
    $entityList = ['e1', 'e2'];
437
    $query = $this->createMock(AbstractQuery::class);
438
    $query->expects(static::once())->method('getResult')->willReturn($entityList);
439
    //create query builder mock for getEntities
440
    $queryBuilder = $this->createMock(QueryBuilder::class);
441
    $queryBuilder->expects(static::once())->method('getQuery')->willReturn($query);
442
    $service->expects(static::once())->method('getEntitiesQueryBuilder')
443
      ->with($ranking, new DateTime("2017-01-01"))->willReturn($queryBuilder);
444
445
    /** @var RankingSystemService $service */
446
    /** @noinspection PhpUnhandledExceptionInspection */
447
    self::assertEquals($entityList, static::getMethod(get_class($service), 'getEntities')
448
      ->invokeArgs($service, [$ranking, new DateTime("2017-01-01"), new DateTime("2018-01-01")]));
449
  }
450
451
  /**
452
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntityManager
453
   * @throws ReflectionException
454
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
455
   */
456
  public function testGetEntityManager()
457
  {
458
    $entityManager = $this->createMock(EntityManagerInterface::class);
459
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [$entityManager,
460
      $this->createMock(TimeServiceInterface::class), $this->createMock(EntityComparerInterface::class),
461
      $this->createMock(ObjectCreatorServiceInterface::class)]);
462
    $em = static::callProtectedMethod($service, 'getEntityManager');
463
    self::assertEquals($entityManager, $em);
464
  }
465
466
  /**
467
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntriesOfPlayers
468
   * @throws ReflectionException
469
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
470
   */
471
  public function testGetEntriesOfPlayers()
472
  {
473
474
    /** @var RankingSystemService $service */
475
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
476
477
    $entry1 = $this->createMock(RankingSystemListEntry::class);
478
    $entry2 = $this->createMock(RankingSystemListEntry::class);
479
    $entry3 = $this->createMock(RankingSystemListEntry::class);
480
481
    $entries = new ArrayCollection([1 => $entry1, 2 => $entry2, 3 => $entry3]);
482
    $list = $this->createStub(RankingSystemList::class, ['getEntries' => $entries]);
483
484
    $player1 = $this->createStub(Player::class, ['getId' => 1]);
485
    $player3 = $this->createStub(Player::class, ['getId' => 3]);
486
487
    $returnedEntries = static::callProtectedMethod($service, 'getEntriesOfPlayers',
488
      [new ArrayCollection([$player1, $player3]), $list]);
489
    self::assertEquals([$entry1, $entry3], $returnedEntries);
490
  }
491
492
  /**
493
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
494
   * @throws ReflectionException
495
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
496
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
497
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::setProperty
498
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getAdditionalChangeFields()
499
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
500
   */
501
  public function testGetOrCreateChangeCreateNewOne()
502
  {
503
    $persisted = null;
504
505
    [$entity, $ranking, $player] = $this->createEntities();
506
    [$service, $entityManager] = $this->prepareCreateChange();
507
    $entityManager->expects(self::once())->method('persist')->willReturnCallback(
508
      function (RankingSystemChangeInterface $change) use (&$persisted, $entity, $ranking, $player) {
509
        $persisted = $change;
510
        self::assertInstanceOf(RankingSystemChange::class, $change);
511
        self::assertEquals($entity, $change->getHierarchyEntity());
512
        self::assertEquals($ranking, $change->getRankingSystem());
513
        self::assertEquals($player, $change->getPlayer());
514
      });
515
516
    $change = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
517
    self::assertEquals($persisted, $change);
518
  }
519
520
  /**
521
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
522
   * @throws ReflectionException
523
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
524
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
525
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getAdditionalChangeFields()
526
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
527
   */
528
  public function testGetOrCreateChangeCreateTwice()
529
  {
530
    [$entity, $ranking, $player] = $this->createEntities();
531
    [$service, $entityManager] = $this->prepareCreateChange();
532
    $entityManager->expects(self::once())->method('persist');
533
534
    $change = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
535
    $change2 = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
536
    self::assertEquals($change, $change2);
537
  }
538
539
  /**
540
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
541
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
542
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
543
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
544
   * @throws ReflectionException
545
   * @throws ReflectionException
546
   * @throws PreconditionFailedException
547
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
548
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
549
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange::init
550
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
551
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
552
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
553
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
554
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
555
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
556
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
557
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
558
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
559
   */
560
  public function testGetOrCreateGetDeletedChange()
561
  {
562
    [$entity, $ranking, $player] = $this->createEntities();
563
    $change = $this->createStub(RankingSystemChange::class,
564
      ['getRankingSystem' => $ranking, 'getPlayer' => $player, 'getHierarchyEntity' => $entity, 'getId' => "c1"]);
565
566
    $entityManager = $this->getEntityManagerMockForQuery([$change], null, ['persist', 'flush', 'detach', 'remove',
567
      'getRepository']);
568
    $entityManager->expects(self::once())->method('flush');
569
    $service = $this->prepareUpdateRankingFrom($ranking, $entityManager, null, 1, ['getChanges'], [$entity]);
570
    $service->expects(self::once())->method('getChanges')->willReturnCallback(
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Tfboe\FmLib\Service\Rank...em\RankingSystemService. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

570
    $service->/** @scrutinizer ignore-call */ 
571
              expects(self::once())->method('getChanges')->willReturnCallback(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
571
      function ($e) use ($service, $ranking, $player, $change) {
572
        $foundChange = static::callProtectedMethod($service, 'getOrCreateChange', [$e, $ranking, $player]);
573
        self::assertEquals($foundChange->getId(), $change->getId());
574
        return [];
575
      });
576
    /** @noinspection PhpUnhandledExceptionInspection */
577
    $service->updateRankingFrom($ranking, new DateTime('2017-02-28'));
578
  }
579
580
  /**
581
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
582
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::startPoints
583
   * @throws ReflectionException
584
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemListEntry
585
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
586
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
587
   */
588
  public function testGetOrCreateRankingSystemListEntryExistingEntry()
589
  {
590
    $player = $this->createStubWithId(Player::class, 1, 'getId');
591
    $entries = new ArrayCollection([]);
592
    $list = $this->createStub(RankingSystemList::class, ['getEntries' => $entries]);
593
    $entry = $this->createStub(RankingSystemListEntry::class,
594
      ['getPlayer' => $player, 'getRankingSystemList' => $list]);
595
    $entries->set(1, $entry);
596
597
    /** @var RankingSystemService $service */
598
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
599
    $foundEntry = static::callProtectedMethod($service, 'getOrCreateRankingSystemListEntry', [$list, $player]);
600
    self::assertEquals($entry, $foundEntry);
601
  }
602
603
  /**
604
   * @covers   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
605
   * @covers   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::startPoints
606
   * @covers   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::resetListEntry
607
   * @throws ReflectionException
608
   * @uses     \Tfboe\FmLib\Entity\Traits\RankingSystemListEntry
609
   * @uses     \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
610
   * @uses     \Tfboe\FmLib\Entity\Helpers\SubClassData::setProperty
611
   * @uses     \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
612
   */
613
  public function testGetOrCreateRankingSystemListEntryNewEntry()
614
  {
615
    $player = $this->createStubWithId(Player::class, 1, 'getId');
616
    $entries = new ArrayCollection([]);
617
    $list = $this->createStub(RankingSystemList::class, ['getEntries' => $entries]);
618
619
    /** @var RankingSystemListEntryInterface $createdEntry */
620
    $createdEntry = null;
621
    $entityManager = $this->createMock(EntityManager::class);
622
    $entityManager->expects(self::once())->method('persist')->willReturnCallback(
623
      function (RankingSystemListEntryInterface $entry) use (&$createdEntry, $player, $list) {
0 ignored issues
show
Unused Code introduced by
The import $player is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
Unused Code introduced by
The import $list is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
624
        $createdEntry = $entry;
625
      });
626
627
628
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [$entityManager,
629
      $this->createMock(TimeServiceInterface::class), $this->createMock(EntityComparerInterface::class),
630
      $this->getObjectCreator()]);
631
    $service->method('getAdditionalFields')->willReturn(['additional' => 0.0]);
632
    /** @var RankingSystemService $service */
633
634
    $entry = static::callProtectedMethod($service, 'getOrCreateRankingSystemListEntry', [$list, $player]);
635
    self::assertEquals($createdEntry, $entry);
636
    self::assertInstanceOf(RankingSystemListEntry::class, $entry);
637
    self::assertEquals($player, $entry->getPlayer());
638
    self::assertEquals($list, $entry->getRankingSystemList());
639
    self::assertEquals(1, $entries->count());
640
    self::assertEquals($entry, $entries[1]);
641
  }
642
643
  /**
644
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
645
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
646
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
647
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
648
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
649
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
650
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
651
   * @throws ReflectionException
652
   * @throws ReflectionException
653
   * @throws PreconditionFailedException
654
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
655
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
656
   * @uses   \Tfboe\FmLib\Entity\Helpers\UUIDEntity::getId
657
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
658
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
659
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
660
   * @uses   \Tfboe\FmLib\Helpers\DateTime::eq
661
   */
662
  public function testUpdateRankingCreateMonthlyLists()
663
  {
664
    //create mock for input
665
    $ranking = $this->createStubWithId(RankingSystem::class, 'r1');
666
    $ranking->method('getGenerationInterval')->willReturn(AutomaticInstanceGeneration::MONTHLY);
667
668
    //create mocks for ranking lists
669
    $list = $this->createMock(RankingSystemList::class);
670
    $list->method('isCurrent')->willReturn(true);
671
    $list->method('getLastEntryTime')->willReturn(new DateTime("2017-12-01"));
672
    $list->method('getEntries')->willReturn(new ArrayCollection());
673
    $list->method('getRankingSystem')->willReturn($ranking);
674
675
    $lists = $this->createMock(Collection::class);
676
    $lists->expects(static::once())->method('toArray')->willReturn([$list]);
677
    $lists->expects(static::once())->method('set')->with('new')->willReturnSelf();
678
679
    //create entities mocks
680
    $entity1 = $this->createStubWithId(TournamentHierarchyEntity::class, "e1");
681
    $entity1->method('getEndTime')->willReturn(new DateTime("2018-03-01"));
682
683
    $entity2 = $this->createStubWithId(TournamentHierarchyEntity::class, "e2");
684
    $entity2->method('getEndTime')->willReturn(new DateTime("2018-04-01 00:00:01"));
685
686
    //finish mock for input
687
    $ranking->expects(static::exactly(2))->method('getLists')->willReturn($lists);
688
689
    //create service mock
690
    $entityManager = $this->getEntityManagerMockForQuery([],
691
      'SELECT c FROM Tfboe\FmLib\Entity\RankingSystemChangeInterface c WHERE c.rankingSystem = :ranking' .
692
      ' AND c.hierarchyEntity IN(:entities)', ['persist', 'flush', 'detach']);
693
    $entityManager->expects(static::once())->method('persist')->willReturnCallback(
694
      function (RankingSystemListInterface $entity) {
695
        self::assertInstanceOf(RankingSystemList::class, $entity);
696
        static::getProperty(get_class($entity), 'id')->setValue($entity, 'new');
697
      });
698
    $timeService = $this->createMock(TimeServiceInterface::class);
699
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
700
      return $entity->getEndTime();
701
    });
702
    $service = $this->getMockWithMockedArguments(RankingSystemService::class, [$entityManager,
703
      $timeService, $this->createMock(EntityComparerInterface::class),
704
      $this->getObjectCreator()]);
705
706
    //create query mock for getEntities
707
    $query = $this->createMock(AbstractQuery::class);
708
    $query->expects(static::once())->method('getResult')->willReturn([$entity1, $entity2]);
709
    //create query builder mock for getEntities
710
    $queryBuilder = $this->createMock(QueryBuilder::class);
711
    $queryBuilder->expects(static::once())->method('getQuery')->willReturn($query);
712
    $service->expects(static::once())->method('getEntitiesQueryBuilder')
713
      ->with($ranking, new DateTime("2017-12-01"))->willReturn($queryBuilder);
714
715
    /** @var RankingSystemService $service */
716
    /** @var RankingSystemInterface $ranking */
717
    /** @noinspection PhpUnhandledExceptionInspection */
718
    /** @noinspection PhpUnhandledExceptionInspection */
719
    /** @noinspection PhpUnhandledExceptionInspection */
720
    /** @noinspection PhpUnhandledExceptionInspection */
721
    $service->updateRankingFrom($ranking, new DateTime('2018-02-28'));
722
  }
723
724
  /**
725
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
726
   * @throws PreconditionFailedException
727
   * @throws ReflectionException
728
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
729
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
730
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
731
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
732
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
733
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
734
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
735
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
736
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
737
   * @uses   \Tfboe\FmLib\Helpers\DateTime::eq
738
   */
739
  public function testUpdateRankingForTournamentOldEarliestIsEarlier()
740
  {
741
    $ranking = $this->createStubWithId(RankingSystem::class);
742
    $timeService = $this->createMock(TimeServiceInterface::class);
743
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
744
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
745
      return $entity->getEndTime();
746
    })->after('clearTimes');
747
    $service = $this->getMockWithMockedArguments(RankingSystemService::class,
748
      [$this->createMock(EntityManagerInterface::class),
749
        $timeService], ['updateRankingFrom']);
750
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
751
    /** @var RankingSystemInterface $ranking */
752
    $tournament = new Tournament();
753
    $endedAt = new DateTime("2017-02-01 00:00:00");
754
    $tournament->setUpdatedAt($endedAt);
755
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
756
    $oldInfluence = new DateTime("2017-01-01 00:00:00");
757
    $service->expects(static::once())
758
      ->method('updateRankingFrom')
759
      ->with($ranking, new DateTime("2017-01-01 00:00:00"));
760
761
    /** @var RankingSystemService $service */
762
    $service->updateRankingForTournament($ranking, $tournament, $oldInfluence);
763
  }
764
765
  /**
766
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
767
   * @throws PreconditionFailedException
768
   * @throws ReflectionException
769
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
770
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
771
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
772
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
773
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
774
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
775
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
776
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
777
   * @uses   \Tfboe\FmLib\Helpers\DateTime::eq
778
   */
779
  public function testUpdateRankingForTournamentOldEarliestIsNotNullAndTournamentNotRanked()
780
  {
781
    $ranking = $this->createStubWithId(RankingSystem::class);
782
    /** @var RankingSystemInterface $ranking */
783
    $tournament = new Tournament();
784
    $endedAt = new DateTime("2017-01-01 00:00:00");
785
    $tournament->setUpdatedAt($endedAt);
786
    $service = $this->getMockWithMockedArguments(RankingSystemService::class, [], ['updateRankingFrom']);
787
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
788
    $oldInfluence = new DateTime("2017-02-01 00:00:00");
789
    $service->expects(static::once())
790
      ->method('updateRankingFrom')
791
      ->with($ranking, new DateTime("2017-02-01 00:00:00"));
792
793
    /** @var RankingSystemService $service */
794
    $service->updateRankingForTournament($ranking, $tournament, $oldInfluence);
795
  }
796
797
  /**
798
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
799
   * @throws PreconditionFailedException
800
   * @throws ReflectionException
801
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
802
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
803
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
804
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
805
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
806
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
807
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
808
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
809
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
810
   */
811
  public function testUpdateRankingForTournamentOldEarliestIsNull()
812
  {
813
    $ranking = $this->createStubWithId(RankingSystem::class);
814
    /** @var RankingSystemInterface $ranking */
815
    $tournament = new Tournament();
816
    $endedAt = new DateTime("2017-01-01 00:00:00");
817
    $tournament->setEndTime($endedAt);
818
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
819
    $timeService = $this->createMock(TimeServiceInterface::class);
820
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
821
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
822
      return $entity->getEndTime();
823
    })->after('clearTimes');
824
    $service = $this->getMockWithMockedArguments(RankingSystemService::class,
825
      [$this->createMock(EntityManagerInterface::class),
826
        $timeService], ['updateRankingFrom']);
827
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
828
    $service->expects(static::once())
829
      ->method('updateRankingFrom')
830
      ->with($ranking, new DateTime("2017-01-01 00:00:00"));
831
832
    /** @var RankingSystemService $service */
833
    $service->updateRankingForTournament($ranking, $tournament, null);
834
  }
835
836
  //TODO split this up in multiple unit tests!!!
837
838
  /**
839
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
840
   * @throws PreconditionFailedException
841
   * @throws ReflectionException
842
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
843
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
844
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
845
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
846
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
847
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
848
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
849
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
850
   * @uses   \Tfboe\FmLib\Helpers\DateTime::eq
851
   */
852
  public function testUpdateRankingForTournamentOldEarliestIsNullAndTournamentNotRanked()
853
  {
854
    $ranking = $this->createStubWithId(RankingSystem::class);
855
    /** @var RankingSystemInterface $ranking */
856
    $tournament = new Tournament();
857
    $endedAt = new DateTime("2017-01-01 00:00:00");
858
    $tournament->setUpdatedAt($endedAt);
859
    $service = $this->getMockWithMockedArguments(RankingSystemService::class,
860
      [], ['updateRankingFrom']);
861
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
862
    $service->expects(self::never())
863
      ->method('updateRankingFrom');
864
865
    /** @var RankingSystemService $service */
866
    $service->updateRankingForTournament($ranking, $tournament, null);
867
  }
868
869
  /**
870
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
871
   * @throws PreconditionFailedException
872
   * @throws ReflectionException
873
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
874
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
875
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
876
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
877
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
878
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
879
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
880
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
881
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
882
   */
883
  public function testUpdateRankingForTournamentTournamentIsEarlier()
884
  {
885
    $ranking = $this->createStubWithId(RankingSystem::class);
886
    /** @var RankingSystemInterface $ranking */
887
    $tournament = new Tournament();
888
    $endedAt = new DateTime("2017-01-01");
889
    $tournament->setEndTime($endedAt);
890
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
891
    $timeService = $this->createMock(TimeServiceInterface::class);
892
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
893
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
894
      return $entity->getEndTime();
895
    })->after('clearTimes');
896
    $service = $this->getMockWithMockedArguments(RankingSystemService::class,
897
      [$this->createMock(EntityManagerInterface::class), $timeService], ['updateRankingFrom']);
898
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
899
    $oldInfluence = new DateTime("2017-02-01");
900
    $service->expects(static::once())
901
      ->method('updateRankingFrom')
902
      ->with($ranking, new DateTime("2017-01-01"));
903
904
    /** @var RankingSystemService $service */
905
    $service->updateRankingForTournament($ranking, $tournament, $oldInfluence);
906
  }
907
908
  /**
909
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
910
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
911
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
912
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
913
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
914
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::resetListEntry
915
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
916
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
917
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
918
   * @throws ReflectionException
919
   * @throws ReflectionException
920
   * @throws PreconditionFailedException
921
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
922
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
923
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
924
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemListEntry
925
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::cloneSubClassDataFrom
926
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
927
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
928
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::getProperty
929
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::setProperty
930
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
931
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::startPoints
932
   */
933
  public function testUpdateRankingFrom()
934
  {
935
    //create mock for input
936
    $ranking = $this->createStubWithId(RankingSystem::class);
937
    $ranking->method('getGenerationInterval')->willReturn(-1);
938
939
    //create mocks for ranking lists
940
    $list1 = $this->createMock(RankingSystemList::class);
941
    $list1->method('isCurrent')->willReturn(false);
942
    $list1->method('getLastEntryTime')->willReturn(new DateTime("2017-01-01"));
943
    $list1->method('getRankingSystem')->willReturn($ranking);
944
945
    $entry1 = $this->createEmptyEntry();
946
    $entry2 = $this->createEmptyEntry();
947
    $entry3 = $this->createEmptyEntry();
948
949
    $list2 = $this->createMock(RankingSystemList::class);
950
    $list2->method('isCurrent')->willReturn(false);
951
    $list2->method('getLastEntryTime')->willReturn(new DateTime("2017-02-01"));
952
    $list2->method('getEntries')->willReturn(new ArrayCollection([1 => $entry1, 3 => $entry3]));
953
    $list2->method('getRankingSystem')->willReturn($ranking);
954
955
    $list3 = $this->createMock(RankingSystemList::class);
956
    $list3->method('isCurrent')->willReturn(false);
957
    $list3->method('getLastEntryTime')->willReturn(new DateTime("2017-03-01"));
958
    $list3->method('getEntries')->willReturn(new ArrayCollection([1 => $entry1, 2 => $entry2]));
959
    $list3->method('getRankingSystem')->willReturn($ranking);
960
961
    $list4 = $this->createMock(RankingSystemList::class);
962
    $list4->method('isCurrent')->willReturn(false);
963
    $list4->method('getLastEntryTime')->willReturn(new DateTime("2017-04-01"));
964
    $list4->method('getEntries')->willReturn(new ArrayCollection());
965
    $list4->method('getRankingSystem')->willReturn($ranking);
966
967
    $list5 = $this->createMock(RankingSystemList::class);
968
    $list5->method('isCurrent')->willReturn(true);
969
    $list5->method('getLastEntryTime')->willReturn(new DateTime("2017-05-01"));
970
    $list5->method('getEntries')->willReturn(new ArrayCollection());
971
    $list5->method('getRankingSystem')->willReturn($ranking);
972
973
    $lists = $this->createMock(Collection::class);
974
    $lists->expects(static::once())->method('toArray')->willReturn([$list1, $list2, $list3, $list4, $list5]);
975
976
    //finish mock for input
977
    $ranking->expects(static::once())->method('getLists')->willReturn($lists);
978
979
    //create time service, entity comparer and ranking service mock
980
    $timeService = $this->createMock(TimeServiceInterface::class);
981
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
982
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
983
      return $entity->getEndTime();
984
    })->after('clearTimes');
985
    $entityComparer = $this->createMock(EntityComparerInterface::class);
986
    $entityComparer->method('compareEntities')->willReturnCallback(
987
      function (TournamentHierarchyInterface $entity1, TournamentHierarchyInterface $entity2) {
988
        return $entity1->getEndTime() <=> $entity2->getEndTime();
989
      });
990
    $entityManager = $this->getEntityManagerMockForQuery([],
991
      'SELECT c FROM Tfboe\FmLib\Entity\RankingSystemChangeInterface c WHERE c.rankingSystem = :ranking' .
992
      ' AND c.hierarchyEntity IN(:entities)', ['persist', 'remove', 'flush', 'detach'], 3);
993
    $service = $this->getMockWithMockedArguments(RankingSystemService::class,
994
      [$entityManager,
995
        $timeService,
996
        $this->createMock(EntityComparerInterface::class),
997
        $this->getObjectCreator()]);
998
999
    //create entities mocks
1000
    $entity1 = $this->createStubWithId(TournamentHierarchyEntity::class, "e1");
1001
    $entity1->method('getEndTime')->willReturn(new DateTime("2017-03-01"));
1002
1003
    $entity2 = $this->createStubWithId(TournamentHierarchyEntity::class, "e2");
1004
    $entity2->method('getEndTime')->willReturn(new DateTime("2017-02-01 00:00:01"));
1005
1006
    $entity3 = $this->createStubWithId(TournamentHierarchyEntity::class, "e3");
1007
    $entity3->method('getEndTime')->willReturn(new DateTime("2017-05-02"));
1008
1009
    $entity4 = $this->createStubWithId(TournamentHierarchyEntity::class, "e4");
1010
    $entity4->method('getEndTime')->willReturn(new DateTime("2017-03-02"));
1011
1012
    $parent = $this->createStubWithId(TournamentHierarchyEntity::class, "e4");
1013
    $parent->method('getEndTime')->willReturn(new DateTime("2017-12-02"));
1014
    $entity4->method('getParent')->willReturn($parent);
1015
1016
    //create query mock for getEntities
1017
    $query3 = $this->createMock(AbstractQuery::class);
1018
    $query3->expects(static::once())->method('getResult')->willReturn([$entity1, $entity2, $entity3, $entity4]);
1019
    $queryBuilder3 = $this->createMock(QueryBuilder::class);
1020
    $queryBuilder3->expects(static::once())->method('getQuery')->willReturn($query3);
1021
1022
    $query4 = $this->createMock(AbstractQuery::class);
1023
    $query4->expects(static::once())->method('getResult')->willReturn([$entity1, $entity2, $entity3, $entity4]);
1024
    $queryBuilder4 = $this->createMock(QueryBuilder::class);
1025
    $queryBuilder4->expects(static::once())->method('getQuery')->willReturn($query4);
1026
1027
    $query5 = $this->createMock(AbstractQuery::class);
1028
    $query5->expects(static::once())->method('getResult')->willReturn([$entity1, $entity2, $entity3, $entity4]);
1029
    $queryBuilder5 = $this->createMock(QueryBuilder::class);
1030
    $queryBuilder5->expects(static::once())->method('getQuery')->willReturn($query5);
1031
1032
    $service->method('getEntitiesQueryBuilder')
1033
      ->withConsecutive([$ranking, new DateTime("2017-02-01"), new DateTime("2017-03-01")],
1034
        [$ranking, new DateTime("2017-03-01"), new DateTime("2017-04-01")],
1035
        [$ranking, new DateTime("2017-04-01")])
1036
      ->willReturnOnConsecutiveCalls($queryBuilder3, $queryBuilder4, $queryBuilder5);
1037
    $changes = [
1038
      $this->createEmptyChange(),
1039
      $this->createEmptyChange(),
1040
    ];
1041
    $service->method('getChanges')->willReturn($changes);
1042
    $service->method('getAdditionalFields')->willReturn(['additional' => 0.0]);
1043
1044
    /** @var RankingSystemService $service */
1045
    /** @var RankingSystemInterface $ranking */
1046
    /** @noinspection PhpUnhandledExceptionInspection */
1047
    $service->updateRankingFrom($ranking, new DateTime('2017-02-28'));
1048
  }
1049
1050
  /**
1051
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
1052
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
1053
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
1054
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
1055
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
1056
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
1057
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
1058
   * @throws ReflectionException
1059
   * @throws ReflectionException
1060
   * @throws PreconditionFailedException
1061
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
1062
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
1063
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
1064
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
1065
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
1066
   */
1067
  public function testUpdateRankingFromCalledTwice()
1068
  {
1069
    $ranking = $this->createStubWithId(RankingSystem::class);
1070
    $service = $this->prepareUpdateRankingFrom($ranking, $this->getEntityManagerMockForQuery([], null, ['flush']));
1071
1072
    /** @var RankingSystemInterface $ranking */
1073
1074
    /** @noinspection PhpUnhandledExceptionInspection */
1075
    $service->updateRankingFrom($ranking, new DateTime('2017-02-28'));
1076
1077
    $this->expectException(PreconditionFailedException::class);
1078
1079
    /** @noinspection PhpUnhandledExceptionInspection */
1080
    $service->updateRankingFrom($ranking, new DateTime('2017-02-28'));
1081
  }
1082
1083
  /**
1084
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
1085
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
1086
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
1087
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
1088
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
1089
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
1090
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
1091
   * @throws ReflectionException
1092
   * @throws ReflectionException
1093
   * @throws PreconditionFailedException
1094
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
1095
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
1096
   * @uses   \Tfboe\FmLib\Entity\Helpers\UUIDEntity::getId
1097
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
1098
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
1099
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
1100
   */
1101
  public function testUpdateRankingFromNoCurrent()
1102
  {
1103
    //create mock for input
1104
    $ranking = $this->createStubWithId(RankingSystem::class, 'r1');
1105
    $ranking->method('getGenerationInterval')->willReturn(AutomaticInstanceGeneration::MONTHLY);
1106
1107
    //create mocks for ranking lists
1108
    $list = $this->createMock(RankingSystemList::class);
1109
    $list->method('isCurrent')->willReturn(false);
1110
    $list->method('getLastEntryTime')->willReturn(new DateTime("2017-12-01"));
1111
    $list->method('getEntries')->willReturn(new ArrayCollection());
1112
    $list->method('getRankingSystem')->willReturn($ranking);
1113
1114
    $lists = $this->createMock(Collection::class);
1115
    $lists->expects(static::once())->method('toArray')->willReturn([$list]);
1116
    $lists->expects(static::once())->method('set')->with('new')->willReturnSelf();
1117
1118
    //finish mock for input
1119
    $ranking->expects(static::exactly(2))->method('getLists')->willReturn($lists);
1120
1121
    //create service mock
1122
    $entityManager = $this->getEntityManagerMockForQuery([],
1123
      'SELECT c FROM Tfboe\FmLib\Entity\RankingSystemChangeInterface c WHERE c.rankingSystem = :ranking' .
1124
      ' AND c.hierarchyEntity IN(:entities)', ['persist', 'flush']);
1125
    $entityManager->expects(static::once())->method('persist')->willReturnCallback(
1126
      function (RankingSystemListInterface $entity) {
1127
        self::assertInstanceOf(RankingSystemList::class, $entity);
1128
        self::assertTrue($entity->isCurrent());
1129
        static::getProperty(get_class($entity), 'id')->setValue($entity, 'new');
1130
      });
1131
    $service = $this->getMockWithMockedArguments(RankingSystemService::class, [$entityManager,
1132
      $this->createMock(TimeServiceInterface::class), $this->createMock(EntityComparerInterface::class),
1133
      $this->getObjectCreator()]);
1134
1135
    //create query mock for getEntities
1136
    $query = $this->createMock(AbstractQuery::class);
1137
    $query->expects(static::once())->method('getResult')->willReturn([]);
1138
    //create query builder mock for getEntities
1139
    $queryBuilder = $this->createMock(QueryBuilder::class);
1140
    $queryBuilder->expects(static::once())->method('getQuery')->willReturn($query);
1141
    $service->expects(static::once())->method('getEntitiesQueryBuilder')
1142
      ->with($ranking, new DateTime("2017-12-01"))->willReturn($queryBuilder);
1143
1144
    /** @var RankingSystemService $service */
1145
    /** @var RankingSystemInterface $ranking */
1146
    /** @noinspection PhpUnhandledExceptionInspection */
1147
    /** @noinspection PhpUnhandledExceptionInspection */
1148
    /** @noinspection PhpUnhandledExceptionInspection */
1149
    /** @noinspection PhpUnhandledExceptionInspection */
1150
    $service->updateRankingFrom($ranking, new DateTime('2018-02-28'));
1151
  }
1152
1153
  /**
1154
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
1155
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
1156
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
1157
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
1158
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
1159
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
1160
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
1161
   * @throws ReflectionException
1162
   * @throws ReflectionException
1163
   * @throws PreconditionFailedException
1164
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
1165
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
1166
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
1167
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
1168
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
1169
   */
1170
  public function testUpdateRankingFromNoEntities()
1171
  {
1172
    $ranking = $this->createStubWithId(RankingSystem::class);
1173
1174
    //create mocks for ranking lists
1175
    $list = $this->createMock(RankingSystemList::class);
1176
    $list->method('isCurrent')->willReturn(false);
1177
    $list->method('getLastEntryTime')->willReturn(new DateTime("2017-12-01"));
1178
    $list->method('getEntries')->willReturn(new ArrayCollection());
1179
    $list->method('getRankingSystem')->willReturn($ranking);
1180
1181
    $current = $this->createMock(RankingSystemList::class);
1182
    $current->method('isCurrent')->willReturn(true);
1183
    $current->method('getLastEntryTime')->willReturn(new DateTime("2017-12-01"));
1184
    $current->method('getEntries')->willReturn(new ArrayCollection());
1185
    $current->method('getRankingSystem')->willReturn($ranking);
1186
1187
    $service = $this->prepareUpdateRankingFrom($ranking, $this->getEntityManagerMockForQuery([], null,
1188
      ['flush', 'persist'], 2), [$list, $current], 2);
1189
    /** @var RankingSystemInterface $ranking */
1190
1191
    /** @var RankingSystemService $service */
1192
    /** @var RankingSystemInterface $ranking */
1193
    /** @noinspection PhpUnhandledExceptionInspection */
1194
    $service->updateRankingFrom($ranking, new DateTime('2017-02-28'));
1195
  }
1196
1197
  /**
1198
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
1199
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
1200
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
1201
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
1202
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
1203
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
1204
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
1205
   * @throws ReflectionException
1206
   * @throws ReflectionException
1207
   * @throws PreconditionFailedException
1208
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
1209
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
1210
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
1211
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
1212
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
1213
   */
1214
  public function testUpdateRankingFromNoReusable()
1215
  {
1216
    $ranking = $this->createStubWithId(RankingSystem::class);
1217
    $service = $this->prepareUpdateRankingFrom($ranking, $this->getEntityManagerMockForQuery([], null, ['flush']));
1218
1219
    /** @var RankingSystemInterface $ranking */
1220
1221
    /** @var RankingSystemService $service */
1222
    /** @var RankingSystemInterface $ranking */
1223
    /** @noinspection PhpUnhandledExceptionInspection */
1224
    $service->updateRankingFrom($ranking, new DateTime('2017-02-28'));
1225
  }
1226
//</editor-fold desc="Public Methods">
1227
1228
//<editor-fold desc="Private Methods">
1229
  /**
1230
   * Creates an empty RankingSystemChange
1231
   * @return MockObject|RankingSystemChangeInterface
1232
   * @throws ReflectionException
1233
   */
1234
  private function createEmptyChange(): MockObject
1235
  {
1236
    $change = $this->getMockForAbstractClass(RankingSystemChange::class, [['additional']], '', true, true, true,
1237
      ['getPlayer', 'getPointsChange']);
1238
    return $change;
1239
  }
1240
1241
  /**
1242
   * Creates an empty RankingSystemListEntry
1243
   * @return MockObject|RankingSystemListEntryInterface
1244
   * @throws ReflectionException
1245
   */
1246
  private function createEmptyEntry(): MockObject
1247
  {
1248
    $entry = $this->getMockForAbstractClass(RankingSystemListEntry::class, [['additional']], '', true, true, true,
1249
      ['getPlayer', 'getPoints']);
1250
    return $entry;
1251
  }
1252
1253
  /**
1254
   * Creates different entities used for create change
1255
   * @return array, a hierarchy entity, a ranking system and a player
1256
   */
1257
  private function createEntities()
1258
  {
1259
    $entity = $this->createStubWithId(TournamentHierarchyEntity::class, 'h1');
1260
    $ranking = $this->createStubWithId(RankingSystem::class, 'r1');
1261
    $player = $this->createStubWithId(Player::class, 1, 'getId');
1262
    return [$entity, $ranking, $player];
1263
  }
1264
1265
  /**
1266
   * Prepares a ranking system service for creating a change
1267
   * @return array, the service entity and its corresponding entity manager
1268
   * @throws ReflectionException
1269
   */
1270
  private function prepareCreateChange()
1271
  {
1272
    $entityManager = $this->createStub(EntityManager::class, []);
1273
    /** @var RankingSystemService $service */
1274
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [
1275
      $entityManager, $this->createMock(TimeServiceInterface::class),
1276
      $this->createMock(EntityComparerInterface::class),
1277
      $this->getObjectCreator()
1278
    ]);
1279
    return [$service, $entityManager];
1280
  }
1281
1282
  /** @noinspection PhpTooManyParametersInspection */
1283
  /**
1284
   * prepares a new ranking system service for update ranking from
1285
   * @param MockObject $ranking
1286
   * @param EntityManagerInterface|null $entityManager
1287
   * @param null $listsArray
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $listsArray is correct as it would always require null to be passed?
Loading history...
1288
   * @param int $numListsToUpdate
1289
   * @param array $mockedMethods
1290
   * @param array $entities
1291
   * @return MockObject|RankingSystemService
1292
   * @throws ReflectionException
1293
   */
1294
  private function prepareUpdateRankingFrom(MockObject $ranking, ?EntityManagerInterface $entityManager = null,
1295
                                            $listsArray = null, $numListsToUpdate = 1, $mockedMethods = [],
1296
                                            $entities = [])
1297
  {
1298
    if ($entityManager === null) {
1299
      $entityManager = $this->getEntityManagerMockForQuery([]);
1300
    }
1301
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
1302
      [$entityManager, $this->createMock(TimeServiceInterface::class),
1303
        $this->createMock(EntityComparerInterface::class),
1304
        $this->getObjectCreator()], '', true, true, true, $mockedMethods);
1305
1306
    if ($listsArray == null) {
0 ignored issues
show
introduced by
The condition $listsArray == null is always true.
Loading history...
1307
      //create mocks for current lists
1308
      $list = $this->createMock(RankingSystemList::class);
1309
      $list->method('isCurrent')->willReturn(true);
1310
      $list->method('getLastEntryTime')->willReturn(new DateTime("2017-06-01"));
1311
      $list->method('getEntries')->willReturn(new ArrayCollection());
1312
      $listsArray = [$list];
1313
    }
1314
1315
    $lists = $this->createMock(Collection::class);
1316
    $lists->expects(static::once())->method('toArray')->willReturn($listsArray);
1317
1318
    //finish mock for input
1319
    $ranking->method('getLists')->willReturn($lists);
1320
1321
    //create query mock for getEntities
1322
    $query = $this->createMock(AbstractQuery::class);
1323
    $query->expects(static::exactly($numListsToUpdate))->method('getResult')->willReturn($entities);
1324
    //create query builder mock for getEntities
1325
    $queryBuilder = $this->createMock(QueryBuilder::class);
1326
    $queryBuilder->expects(static::exactly($numListsToUpdate))->method('getQuery')->willReturn($query);
1327
    $service->expects(static::exactly($numListsToUpdate))->method('getEntitiesQueryBuilder')
1328
      ->with($ranking)->willReturn($queryBuilder);
1329
    /** @var RankingSystemService $service */
1330
1331
    return $service;
1332
  }
1333
//</editor-fold desc="Private Methods">
1334
}