Completed
Push — master ( 916c4f...7f572e )
by Benedikt
06:01
created

RankingSystemServiceTest::testDoubleOldChange()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 13
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 17
rs 9.4285
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 Doctrine\Common\Collections\ArrayCollection;
13
use Doctrine\Common\Collections\Collection;
14
use Doctrine\ORM\AbstractQuery;
15
use Doctrine\ORM\EntityManager;
16
use Doctrine\ORM\EntityManagerInterface;
17
use Doctrine\ORM\QueryBuilder;
18
use PHPUnit\Framework\MockObject\MockObject;
19
use Tfboe\FmLib\Entity\Helpers\AutomaticInstanceGeneration;
20
use Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity;
21
use Tfboe\FmLib\Entity\Helpers\TournamentHierarchyInterface;
22
use Tfboe\FmLib\Entity\RankingSystemChangeInterface;
23
use Tfboe\FmLib\Entity\RankingSystemInterface;
24
use Tfboe\FmLib\Entity\RankingSystemListEntryInterface;
25
use Tfboe\FmLib\Entity\RankingSystemListInterface;
26
use Tfboe\FmLib\Exceptions\PreconditionFailedException;
27
use Tfboe\FmLib\Helpers\Level;
28
use Tfboe\FmLib\Service\ObjectCreatorServiceInterface;
29
use Tfboe\FmLib\Service\RankingSystem\EntityComparerInterface;
30
use Tfboe\FmLib\Service\RankingSystem\RankingSystemService;
31
use Tfboe\FmLib\Service\RankingSystem\TimeServiceInterface;
32
use Tfboe\FmLib\Tests\Entity\Competition;
33
use Tfboe\FmLib\Tests\Entity\Game;
34
use Tfboe\FmLib\Tests\Entity\Match;
35
use Tfboe\FmLib\Tests\Entity\Phase;
36
use Tfboe\FmLib\Tests\Entity\Player;
37
use Tfboe\FmLib\Tests\Entity\RankingSystem;
38
use Tfboe\FmLib\Tests\Entity\RankingSystemChange;
39
use Tfboe\FmLib\Tests\Entity\RankingSystemList;
40
use Tfboe\FmLib\Tests\Entity\RankingSystemListEntry;
41
use Tfboe\FmLib\Tests\Entity\Tournament;
42
use Tfboe\FmLib\Tests\Helpers\UnitTestCase;
43
44
45
/**
46
 * Class RankingSystemServiceTest
47
 * @packageTfboe\FmLib\Tests\Unit\Service\RankingSystemService
48
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
49
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
50
 * @SuppressWarnings(PHPMD.TooManyMethods)
51
 * @SuppressWarnings(PHPMD.ExcessiveClassLength)
52
 */
53
class RankingSystemServiceTest extends UnitTestCase
54
{
55
//<editor-fold desc="Public Methods">
56
57
  /**
58
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
59
   */
60
  public function testConstruct()
61
  {
62
    $entityManager = $this->createMock(EntityManagerInterface::class);
63
    $timeService = $this->createMock(TimeServiceInterface::class);
64
    $entityComparer = $this->createMock(EntityComparerInterface::class);
65
    $objectCreator = $this->createMock(ObjectCreatorServiceInterface::class);
66
    $system = $this->getMockForAbstractClass(RankingSystemService::class,
67
      [$entityManager, $timeService, $entityComparer, $objectCreator]);
68
    self::assertInstanceOf(RankingSystemService::class, $system);
69
    /** @noinspection PhpUnhandledExceptionInspection */
70
    self::assertEquals($entityManager, self::getProperty(get_class($system), 'entityManager')->getValue($system));
71
    /** @noinspection PhpUnhandledExceptionInspection */
72
    self::assertEquals($timeService, self::getProperty(get_class($system), 'timeService')->getValue($system));
73
    /** @noinspection PhpUnhandledExceptionInspection */
74
    self::assertEquals($entityComparer, self::getProperty(get_class($system), 'entityComparer')->getValue($system));
75
    /** @noinspection PhpUnhandledExceptionInspection */
76
    self::assertEquals($objectCreator, self::getProperty(get_class($system), 'objectCreatorService')
77
      ->getValue($system));
78
  }
79
80
  /**
81
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getAverage
82
   */
83
  public function testGetAverage()
84
  {
85
    /** @var $service RankingSystemService */
86
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
87
88
    $entry1 = $this->createMock(RankingSystemListEntry::class);
89
    $entry1->method('getPoints')->willReturn(1.0);
90
    $entry2 = $this->createMock(RankingSystemListEntry::class);
91
    $entry2->method('getPoints')->willReturn(2.0);
92
93
    self::assertEquals(1.5, static::callProtectedMethod($service, 'getAverage', [[$entry1, $entry2]]));
94
  }
95
96
  /**
97
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
98
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
99
   * @uses   \Tfboe\FmLib\Entity\Traits\Competition
100
   * @uses   \Tfboe\FmLib\Entity\Traits\Competition
101
   * @uses   \Tfboe\FmLib\Entity\Traits\Game
102
   * @uses   \Tfboe\FmLib\Entity\Traits\Game
103
   * @uses   \Tfboe\FmLib\Entity\Helpers\NameEntity
104
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
105
   * @uses   \Tfboe\FmLib\Entity\Traits\Match
106
   * @uses   \Tfboe\FmLib\Entity\Traits\Match
107
   * @uses   \Tfboe\FmLib\Entity\Traits\Phase
108
   * @uses   \Tfboe\FmLib\Entity\Traits\Phase
109
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
110
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
111
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
112
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
113
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
114
   */
115
  public function testGetEarliestInfluenceGameLevel()
116
  {
117
    $ranking = $this->createStubWithId(RankingSystem::class);
118
    $timeService = $this->createMock(TimeServiceInterface::class);
119
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
120
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
121
      return $entity->getEndTime();
122
    })->after('clearTimes');
123
    /** @var RankingSystemInterface $ranking */
124
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
125
      [$this->createMock(EntityManagerInterface::class),
126
        $timeService,
127
        $this->createMock(EntityComparerInterface::class),
128
        $this->createMock(ObjectCreatorServiceInterface::class)]);
129
    $service->method("getLevel")->willReturn(Level::GAME);
130
    /** @var RankingSystemService $service */
131
    $tournament = new Tournament();
132
    $competition = new Competition();
133
    $competition->setName("TestCompetition")->setTournament($tournament);
0 ignored issues
show
Bug introduced by
It seems like setTournament() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
134
    $phase = new Phase();
135
    $phase->setPhaseNumber(1);
136
    $phase->setCompetition($competition);
137
    $match = new Match();
138
    $match->setMatchNumber(1);
139
    $match->setPhase($phase);
140
    self::assertNull($service->getEarliestInfluence($ranking, $tournament));
141
142
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
143
    self::assertNull($service->getEarliestInfluence($ranking, $tournament));
144
145
    $game = new Game();
146
    $game->setGameNumber(1);
147
    $game->setMatch($match);
148
    $gameEndTime = new \DateTime("2017-06-01 00:00:00");
149
    $game->setEndTime($gameEndTime);
150
    self::assertEquals($gameEndTime, $service->getEarliestInfluence($ranking, $tournament));
151
152
    $game2 = new Game();
153
    $game2->setGameNumber(2);
154
    $game2->setMatch($match);
155
    $game2EndTime = new \DateTime("2017-05-01 00:00:00");
156
    $game2->setEndTime($game2EndTime);
157
    self::assertEquals($game2EndTime, $service->getEarliestInfluence($ranking, $tournament));
158
159
    $game3 = new Game();
160
    $game3->setGameNumber(3);
161
    $game3->setMatch($match);
162
    $game3EndTime = new \DateTime("2017-07-01 00:00:00");
163
    $game3->setEndTime($game3EndTime);
164
    self::assertEquals($game2EndTime, $service->getEarliestInfluence($ranking, $tournament));
165
  }
166
167
  /**
168
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
169
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
170
   * @uses   \Tfboe\FmLib\Entity\Traits\Competition
171
   * @uses   \Tfboe\FmLib\Entity\Traits\Competition
172
   * @uses   \Tfboe\FmLib\Entity\Traits\Game
173
   * @uses   \Tfboe\FmLib\Entity\Traits\Game
174
   * @uses   \Tfboe\FmLib\Entity\Helpers\NameEntity
175
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
176
   * @uses   \Tfboe\FmLib\Entity\Traits\Match
177
   * @uses   \Tfboe\FmLib\Entity\Traits\Match
178
   * @uses   \Tfboe\FmLib\Entity\Traits\Phase
179
   * @uses   \Tfboe\FmLib\Entity\Traits\Phase
180
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
181
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
182
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
183
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
184
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
185
   * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
186
   */
187
  public function testGetEarliestInfluenceGameLevelWithDifferentImpactLevels()
188
  {
189
    $ranking = $this->createStubWithId(RankingSystem::class);
190
    $timeService = $this->createMock(TimeServiceInterface::class);
191
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
192
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
193
      return $entity->getEndTime();
194
    })->after('clearTimes');
195
    /** @var RankingSystemInterface $ranking */
196
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
197
      [$this->createMock(EntityManagerInterface::class),
198
        $timeService,
199
        $this->createMock(EntityComparerInterface::class),
200
        $this->createMock(ObjectCreatorServiceInterface::class)]);
201
    $service->method("getLevel")->willReturn(Level::GAME);
202
    /** @var RankingSystemService $service */
203
    $tournament = new Tournament();
204
    $competition = new Competition();
205
    $competition->setName("TestCompetition")->setTournament($tournament);
0 ignored issues
show
Bug introduced by
It seems like setTournament() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
206
    $phase = new Phase();
207
    $phase->setPhaseNumber(1);
208
    $phase->setCompetition($competition);
209
    $match = new Match();
210
    $match->setMatchNumber(1);
211
    $match->setPhase($phase);
212
    $game = new Game();
213
    $game->setGameNumber(1);
214
    $game->setMatch($match);
215
    $endTime1 = new \DateTime("2017-12-01 00:00:00");
216
    $game->setEndTime($endTime1);
217
    $game->getRankingSystems()->set($ranking->getId(), $ranking);
218
    self::assertEquals($endTime1, $service->getEarliestInfluence($ranking, $tournament));
219
220
    $game2 = new Game();
221
    $game2->setGameNumber(2);
222
    $game2->setMatch($match);
223
    $endTime2 = new \DateTime("2017-11-01 00:00:00");
224
    $game2->setEndTime($endTime2);
225
    self::assertEquals($endTime1, $service->getEarliestInfluence($ranking, $tournament));
226
227
    $match->getRankingSystems()->set($ranking->getId(), $ranking);
228
    self::assertEquals($endTime2, $service->getEarliestInfluence($ranking, $tournament));
229
230
    $match2 = new Match();
231
    $match2->setMatchNumber(2);
232
    $match2->setPhase($phase);
233
    $game3 = new Game();
234
    $game3->setGameNumber(1);
235
    $game3->setMatch($match2);
236
    $endTime3 = new \DateTime("2017-10-01 00:00:00");
237
    $game3->setEndTime($endTime3);
238
    self::assertEquals($endTime2, $service->getEarliestInfluence($ranking, $tournament));
239
240
    $phase->getRankingSystems()->set($ranking->getId(), $ranking);
241
    self::assertEquals($endTime3, $service->getEarliestInfluence($ranking, $tournament));
242
243
    $phase2 = new Phase();
244
    $phase2->setPhaseNumber(2);
245
    $phase2->setCompetition($competition);
246
    $match3 = new Match();
247
    $match3->setMatchNumber(1);
248
    $match3->setPhase($phase2);
249
    $game4 = new Game();
250
    $game4->setGameNumber(1);
251
    $game4->setMatch($match3);
252
    $endTime4 = new \DateTime("2017-09-01 00:00:00");
253
    $game4->setEndTime($endTime4);
254
    self::assertEquals($endTime3, $service->getEarliestInfluence($ranking, $tournament));
255
256
    $competition->getRankingSystems()->set($ranking->getId(), $ranking);
257
    self::assertEquals($endTime4, $service->getEarliestInfluence($ranking, $tournament));
258
259
    $competition2 = new Competition();
260
    $competition2->setName("TestCompetition2")->setTournament($tournament);
0 ignored issues
show
Bug introduced by
It seems like setTournament() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
261
    $phase3 = new Phase();
262
    $phase3->setPhaseNumber(1);
263
    $phase3->setCompetition($competition2);
264
    $match4 = new Match();
265
    $match4->setMatchNumber(1);
266
    $match4->setPhase($phase3);
267
    $game5 = new Game();
268
    $game5->setGameNumber(1);
269
    $game5->setMatch($match4);
270
    $endTime5 = new \DateTime("2017-01-01 00:00:00");
271
    $game5->setEndTime($endTime5);
272
    self::assertEquals($endTime4, $service->getEarliestInfluence($ranking, $tournament));
273
274
    $game6 = new Game();
275
    $game6->setGameNumber(2);
276
    $game6->setMatch($match4);
277
    $endTime6 = new \DateTime("2017-10-01 00:00:00");
278
    $game6->setEndTime($endTime6);
279
    $game6->getRankingSystems()->set($ranking->getId(), $ranking);
280
    self::assertEquals($endTime4, $service->getEarliestInfluence($ranking, $tournament));
281
282
    $game7 = new Game();
283
    $game7->setGameNumber(3);
284
    $game7->setMatch($match4);
285
    $endTime7 = new \DateTime("2017-08-01 00:00:00");
286
    $game7->setEndTime($endTime7);
287
    $game7->getRankingSystems()->set($ranking->getId(), $ranking);
288
    self::assertEquals($endTime7, $service->getEarliestInfluence($ranking, $tournament));
289
  }
290
291
  /**
292
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
293
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
294
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
295
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
296
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
297
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
298
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
299
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
300
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
301
   */
302
  public function testGetEarliestInfluenceTournamentLevel()
303
  {
304
    $ranking = $this->createStubWithId(RankingSystem::class);
305
    $timeService = $this->createMock(TimeServiceInterface::class);
306
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
307
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
308
      return $entity->getEndTime();
309
    })->after('clearTimes');
310
    /** @var RankingSystemInterface $ranking */
311
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
312
      [$this->createMock(EntityManagerInterface::class),
313
        $timeService,
314
        $this->createMock(EntityComparerInterface::class),
315
        $this->createMock(ObjectCreatorServiceInterface::class)]);
316
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
317
    /** @var RankingSystemService $service */
318
    $tournament = new Tournament();
319
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
320
    $endTime = new \DateTime("2017-03-01 00:00:00");
321
    $tournament->setEndTime($endTime);
322
    self::assertEquals($endTime, $service->getEarliestInfluence($ranking, $tournament));
323
  }
324
325
  /**
326
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getAverage
327
   */
328
  public function testGetEmptyAverage()
329
  {
330
    /** @var $service RankingSystemService */
331
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
332
333
    self::assertEquals(0.0, static::callProtectedMethod($service, 'getAverage', [[]]));
334
  }
335
336
  /**
337
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
338
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
339
   */
340
  public function testGetEntities()
341
  {
342
    //create mock for input
343
    $ranking = $this->createMock(RankingSystem::class);
344
345
    //create service mock
346
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
347
      [$this->createMock(EntityManagerInterface::class), $this->createMock(TimeServiceInterface::class),
348
        $this->createMock(EntityComparerInterface::class),
349
        $this->createMock(ObjectCreatorServiceInterface::class)]);
350
351
    //create mock for queryBuilder
352
    $entityList = ['e1', 'e2'];
353
    $query = $this->createMock(AbstractQuery::class);
354
    $query->expects(static::once())->method('getResult')->willReturn($entityList);
355
    //create query builder mock for getEntities
356
    $queryBuilder = $this->createMock(QueryBuilder::class);
357
    $queryBuilder->expects(static::once())->method('getQuery')->willReturn($query);
358
    $service->expects(static::once())->method('getEntitiesQueryBuilder')
359
      ->with($ranking, new \DateTime("2017-01-01"))->willReturn($queryBuilder);
360
361
    /** @var $service RankingSystemService */
362
    /** @noinspection PhpUnhandledExceptionInspection */
363
    self::assertEquals($entityList, static::getMethod(get_class($service), 'getEntities')
364
      ->invokeArgs($service, [$ranking, new \DateTime("2017-01-01"), new \DateTime("2018-01-01")]));
365
  }
366
367
  /**
368
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntityManager
369
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
370
   */
371
  public function testGetEntityManager()
372
  {
373
    $entityManager = $this->createMock(EntityManagerInterface::class);
374
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [$entityManager,
375
      $this->createMock(TimeServiceInterface::class), $this->createMock(EntityComparerInterface::class),
376
      $this->createMock(ObjectCreatorServiceInterface::class)]);
377
    $em = static::callProtectedMethod($service, 'getEntityManager');
378
    self::assertEquals($entityManager, $em);
379
  }
380
381
  /**
382
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntriesOfPlayers
383
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
384
   */
385
  public function testGetEntriesOfPlayers()
386
  {
387
388
    /** @var $service RankingSystemService */
389
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
390
391
    $entry1 = $this->createMock(RankingSystemListEntry::class);
392
    $entry2 = $this->createMock(RankingSystemListEntry::class);
393
    $entry3 = $this->createMock(RankingSystemListEntry::class);
394
395
    $entries = new ArrayCollection([1 => $entry1, 2 => $entry2, 3 => $entry3]);
396
    $list = $this->createStub(RankingSystemList::class, ['getEntries' => $entries]);
397
398
    $player1 = $this->createStub(Player::class, ['getId' => 1]);
399
    $player3 = $this->createStub(Player::class, ['getId' => 3]);
400
401
    $returnedEntries = static::callProtectedMethod($service, 'getEntriesOfPlayers',
402
      [new ArrayCollection([$player1, $player3]), $list]);
403
    self::assertEquals([$entry1, $entry3], $returnedEntries);
404
  }
405
406
  /**
407
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
408
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
409
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
410
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
411
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::setProperty
412
   */
413
  public function testGetOrCreateChangeCreateNewOne()
414
  {
415
    $persisted = null;
416
417
    [$entity, $ranking, $player] = $this->createEntities();
0 ignored issues
show
Bug introduced by
The variable $entity does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $ranking does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $player does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
418
    [$service, $entityManager] = $this->prepareCreateChange();
0 ignored issues
show
Bug introduced by
The variable $service does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $entityManager does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
419
    $entityManager->expects(self::once())->method('persist')->willReturnCallback(
420
      function (RankingSystemChangeInterface $change) use (&$persisted, $entity, $ranking, $player) {
421
        $persisted = $change;
422
        self::assertInstanceOf(RankingSystemChange::class, $change);
423
        self::assertEquals($entity, $change->getHierarchyEntity());
424
        self::assertEquals($ranking, $change->getRankingSystem());
425
        self::assertEquals($player, $change->getPlayer());
426
      });
427
    $service->method('getAdditionalFields')->willReturn(['additional' => 0.0]);
428
429
    $change = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
430
    self::assertEquals($persisted, $change);
431
  }
432
433
  /**
434
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
435
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
436
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
437
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
438
   */
439
  public function testGetOrCreateChangeCreateTwice()
440
  {
441
    [$entity, $ranking, $player] = $this->createEntities();
0 ignored issues
show
Bug introduced by
The variable $entity does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $ranking does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $player does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
442
    [$service, $entityManager] = $this->prepareCreateChange();
0 ignored issues
show
Bug introduced by
The variable $service does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $entityManager does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
443
    $entityManager->expects(self::once())->method('persist');
444
445
    $change = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
446
    $change2 = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
447
    self::assertEquals($change, $change2);
448
  }
449
450
  /**
451
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
452
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
453
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
454
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
455
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
456
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
457
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange::init
458
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
459
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
460
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
461
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
462
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
463
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
464
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
465
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
466
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
467
   */
468
  public function testGetOrCreateGetDeletedChange()
469
  {
470
    [$entity, $ranking, $player] = $this->createEntities();
0 ignored issues
show
Bug introduced by
The variable $entity does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $ranking does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $player does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
471
    $change = $this->createStub(RankingSystemChange::class,
472
      ['getRankingSystem' => $ranking, 'getPlayer' => $player, 'getHierarchyEntity' => $entity, 'getId' => "c1"]);
473
474
    $entityManager = $this->getEntityManagerMockForQuery([$change], null, ['persist', 'flush', 'detach', 'remove',
475
      'getRepository']);
476
    $entityManager->expects(self::once())->method('flush');
477
    $service = $this->prepareUpdateRankingFrom($ranking, $entityManager, null, 1, ['getChanges'], [$entity]);
0 ignored issues
show
Documentation introduced by
$entityManager is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
478
    $service->expects(self::once())->method('getChanges')->willReturnCallback(
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Tfboe\FmLib\Servi...m\RankingSystemService>.

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...
479
      function ($e) use ($service, $ranking, $player, $change) {
480
        $foundChange = static::callProtectedMethod($service, 'getOrCreateChange', [$e, $ranking, $player]);
481
        self::assertEquals($foundChange->getId(), $change->getId());
482
        return [];
483
      });
484
    /** @noinspection PhpUnhandledExceptionInspection */
485
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
486
  }
487
488
  /**
489
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
490
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
491
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
492
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
493
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
494
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
495
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange::init
496
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
497
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
498
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
499
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
500
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
501
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
502
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
503
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
504
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
505
   */
506
  public function testDontUseDeletedChange()
507
  {
508
    [$entity, $ranking, $player] = $this->createEntities();
0 ignored issues
show
Bug introduced by
The variable $entity does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $ranking does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $player does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
509
    $change = $this->createStub(RankingSystemChange::class,
510
      ['getRankingSystem' => $ranking, 'getPlayer' => $player, 'getHierarchyEntity' => $entity, 'getId' => "c1"]);
511
512
    $entityManager = $this->getEntityManagerMockForQuery([$change], null, ['persist', 'flush', 'detach', 'remove',
513
      'getRepository']);
514
    $entityManager->expects(self::once())->method('flush');
515
    $entityManager->expects(self::once())->method('remove')->with($change);
516
    $service = $this->prepareUpdateRankingFrom($ranking, $entityManager, null, 1, [], [$entity]);
0 ignored issues
show
Documentation introduced by
$entityManager is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
517
    /** @noinspection PhpUnhandledExceptionInspection */
518
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
519
  }
520
521
  /**
522
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
523
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
524
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
525
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
526
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange::init
527
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
528
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
529
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
530
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
531
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
532
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
533
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
534
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
535
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
536
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
537
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
538
   */
539
  public function testDoubleOldChange()
540
  {
541
    [$entity, $ranking, $player] = $this->createEntities();
0 ignored issues
show
Bug introduced by
The variable $entity does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $ranking does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $player does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
542
    $change1 = $this->createStub(RankingSystemChange::class,
543
      ['getRankingSystem' => $ranking, 'getPlayer' => $player, 'getHierarchyEntity' => $entity, 'getId' => "c1"]);
544
    $change2 = $this->createStub(RankingSystemChange::class,
545
      ['getRankingSystem' => $ranking, 'getPlayer' => $player, 'getHierarchyEntity' => $entity, 'getId' => "c2"]);
546
    self::assertNotEquals($change1->getId(), $change2->getId());
547
548
    $entityManager = $this->getEntityManagerMockForQuery([$change1, $change2], null, ['persist', 'flush', 'remove',
549
      'getRepository']);
550
    $entityManager->expects(self::once())->method('flush');
551
    $entityManager->expects(self::exactly(2))->method('remove')->withConsecutive($change2, $change1);
552
    $service = $this->prepareUpdateRankingFrom($ranking, $entityManager, null, 1, ['deleteOldChanges']);
0 ignored issues
show
Documentation introduced by
$entityManager is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
553
    /** @noinspection PhpUnhandledExceptionInspection */
554
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
555
  }
556
557
  /**
558
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
559
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::startPoints
560
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
561
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemListEntry
562
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
563
   */
564
  public function testGetOrCreateRankingSystemListEntryExistingEntry()
565
  {
566
    $player = $this->createStubWithId(Player::class, 1, 'getId');
567
    $entries = new ArrayCollection([]);
568
    $list = $this->createStub(RankingSystemList::class, ['getEntries' => $entries]);
569
    $entry = $this->createStub(RankingSystemListEntry::class,
570
      ['getPlayer' => $player, 'getRankingSystemList' => $list]);
571
    $entries->set(1, $entry);
572
573
    /** @var RankingSystemService $service */
574
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
575
    $foundEntry = static::callProtectedMethod($service, 'getOrCreateRankingSystemListEntry', [$list, $player]);
576
    self::assertEquals($entry, $foundEntry);
577
  }
578
579
  /**
580
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
581
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::startPoints
582
   * @covers   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::resetListEntry
583
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
584
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemListEntry
585
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
586
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::setProperty
587
   */
588
  public function testGetOrCreateRankingSystemListEntryNewEntry()
589
  {
590
    $player = $this->createStubWithId(Player::class, 1, 'getId');
591
    $entries = new ArrayCollection([]);
592
    $list = $this->createStub(RankingSystemList::class, ['getEntries' => $entries]);
593
594
    /** @var RankingSystemListEntryInterface $createdEntry */
595
    $createdEntry = null;
596
    $entityManager = $this->createMock(EntityManager::class);
597
    $entityManager->expects(self::once())->method('persist')->willReturnCallback(
598
      function (RankingSystemListEntryInterface $entry) use (&$createdEntry, $player, $list) {
599
        $createdEntry = $entry;
600
      });
601
602
603
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [$entityManager,
604
      $this->createMock(TimeServiceInterface::class), $this->createMock(EntityComparerInterface::class),
605
      $this->getObjectCreator()]);
606
    $service->method('getAdditionalFields')->willReturn(['additional' => 0.0]);
607
    /** @var RankingSystemService $service */
608
609
    $entry = static::callProtectedMethod($service, 'getOrCreateRankingSystemListEntry', [$list, $player]);
610
    self::assertEquals($createdEntry, $entry);
611
    self::assertInstanceOf(RankingSystemListEntry::class, $entry);
612
    self::assertEquals($player, $entry->getPlayer());
613
    self::assertEquals($list, $entry->getRankingSystemList());
614
    self::assertEquals(1, $entries->count());
615
    self::assertEquals($entry, $entries[1]);
616
  }
617
618
  /**
619
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
620
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
621
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
622
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
623
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
624
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
625
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
626
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
627
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
628
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
629
   */
630
  public function testUpdateRankingForTournamentOldEarliestIsEarlier()
631
  {
632
    $ranking = $this->createStubWithId(RankingSystem::class);
633
    $timeService = $this->createMock(TimeServiceInterface::class);
634
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
635
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
636
      return $entity->getEndTime();
637
    })->after('clearTimes');
638
    $service = $this->getMockWithMockedArguments(RankingSystemService::class,
639
      [$this->createMock(EntityManagerInterface::class),
640
        $timeService], ['updateRankingFrom']);
641
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
642
    /** @var RankingSystemInterface $ranking */
643
    $tournament = new Tournament();
644
    $endedAt = new \DateTime("2017-02-01 00:00:00");
645
    $tournament->setUpdatedAt($endedAt);
646
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
647
    $oldInfluence = new \DateTime("2017-01-01 00:00:00");
648
    $service->expects(static::once())
649
      ->method('updateRankingFrom')
650
      ->with($ranking, new \DateTime("2017-01-01 00:00:00"));
651
652
    /** @var RankingSystemService $service */
653
    $service->updateRankingForTournament($ranking, $tournament, $oldInfluence);
654
  }
655
656
  /**
657
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
658
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
659
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
660
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
661
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
662
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
663
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
664
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
665
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
666
   */
667
  public function testUpdateRankingForTournamentOldEarliestIsNotNullAndTournamentNotRanked()
668
  {
669
    $ranking = $this->createStubWithId(RankingSystem::class);
670
    /** @var RankingSystemInterface $ranking */
671
    $tournament = new Tournament();
672
    $endedAt = new \DateTime("2017-01-01 00:00:00");
673
    $tournament->setUpdatedAt($endedAt);
674
    $service = $this->getMockWithMockedArguments(RankingSystemService::class, [], ['updateRankingFrom']);
675
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
676
    $oldInfluence = new \DateTime("2017-02-01 00:00:00");
677
    $service->expects(static::once())
678
      ->method('updateRankingFrom')
679
      ->with($ranking, new \DateTime("2017-02-01 00:00:00"));
680
681
    /** @var RankingSystemService $service */
682
    $service->updateRankingForTournament($ranking, $tournament, $oldInfluence);
683
  }
684
685
  /**
686
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
687
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
688
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
689
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
690
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
691
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
692
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
693
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
694
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
695
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
696
   */
697
  public function testUpdateRankingForTournamentOldEarliestIsNull()
698
  {
699
    $ranking = $this->createStubWithId(RankingSystem::class);
700
    /** @var RankingSystemInterface $ranking */
701
    $tournament = new Tournament();
702
    $endedAt = new \DateTime("2017-01-01 00:00:00");
703
    $tournament->setEndTime($endedAt);
704
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
705
    $timeService = $this->createMock(TimeServiceInterface::class);
706
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
707
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
708
      return $entity->getEndTime();
709
    })->after('clearTimes');
710
    $service = $this->getMockWithMockedArguments(RankingSystemService::class,
711
      [$this->createMock(EntityManagerInterface::class),
712
        $timeService], ['updateRankingFrom']);
713
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
714
    $service->expects(static::once())
715
      ->method('updateRankingFrom')
716
      ->with($ranking, new \DateTime("2017-01-01 00:00:00"));
717
718
    /** @var RankingSystemService $service */
719
    $service->updateRankingForTournament($ranking, $tournament, null);
720
  }
721
722
  /**
723
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
724
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
725
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
726
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
727
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
728
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
729
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
730
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
731
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
732
   */
733
  public function testUpdateRankingForTournamentOldEarliestIsNullAndTournamentNotRanked()
734
  {
735
    $ranking = $this->createStubWithId(RankingSystem::class);
736
    /** @var RankingSystemInterface $ranking */
737
    $tournament = new Tournament();
738
    $endedAt = new \DateTime("2017-01-01 00:00:00");
739
    $tournament->setUpdatedAt($endedAt);
740
    $service = $this->getMockWithMockedArguments(RankingSystemService::class,
741
      [], ['updateRankingFrom']);
742
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
743
    $service->expects(self::never())
744
      ->method('updateRankingFrom');
745
746
    /** @var RankingSystemService $service */
747
    $service->updateRankingForTournament($ranking, $tournament, null);
748
  }
749
750
  //TODO split this up in multiple unit tests!!!
751
752
  /**
753
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
754
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
755
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
756
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
757
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
758
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
759
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
760
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
761
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
762
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
763
   */
764
  public function testUpdateRankingForTournamentTournamentIsEarlier()
765
  {
766
    $ranking = $this->createStubWithId(RankingSystem::class);
767
    /** @var RankingSystemInterface $ranking */
768
    $tournament = new Tournament();
769
    $endedAt = new \DateTime("2017-01-01");
770
    $tournament->setEndTime($endedAt);
771
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
772
    $timeService = $this->createMock(TimeServiceInterface::class);
773
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
774
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
775
      return $entity->getEndTime();
776
    })->after('clearTimes');
777
    $service = $this->getMockWithMockedArguments(RankingSystemService::class,
778
      [$this->createMock(EntityManagerInterface::class), $timeService], ['updateRankingFrom']);
779
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
780
    $oldInfluence = new \DateTime("2017-02-01");
781
    $service->expects(static::once())
782
      ->method('updateRankingFrom')
783
      ->with($ranking, new \DateTime("2017-01-01"));
784
785
    /** @var RankingSystemService $service */
786
    $service->updateRankingForTournament($ranking, $tournament, $oldInfluence);
787
  }
788
789
  /**
790
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
791
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
792
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
793
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
794
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
795
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::resetListEntry
796
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
797
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
798
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
799
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
800
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
801
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
802
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemListEntry
803
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::cloneSubClassDataFrom
804
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
805
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
806
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::getProperty
807
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::setProperty
808
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemChange
809
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::startPoints
810
   */
811
  public function testUpdateRankingFrom()
812
  {
813
    //create mock for input
814
    $ranking = $this->createStubWithId(RankingSystem::class);
815
    $ranking->method('getGenerationInterval')->willReturn(-1);
816
817
    //create mocks for ranking lists
818
    $list1 = $this->createMock(RankingSystemList::class);
819
    $list1->method('isCurrent')->willReturn(false);
820
    $list1->method('getLastEntryTime')->willReturn(new \DateTime("2017-01-01"));
821
    $list1->method('getRankingSystem')->willReturn($ranking);
822
823
    $entry1 = $this->createEmptyEntry();
824
    $entry2 = $this->createEmptyEntry();
825
    $entry3 = $this->createEmptyEntry();
826
827
    $list2 = $this->createMock(RankingSystemList::class);
828
    $list2->method('isCurrent')->willReturn(false);
829
    $list2->method('getLastEntryTime')->willReturn(new \DateTime("2017-02-01"));
830
    $list2->method('getEntries')->willReturn(new ArrayCollection([1 => $entry1, 3 => $entry3]));
831
    $list2->method('getRankingSystem')->willReturn($ranking);
832
833
    $list3 = $this->createMock(RankingSystemList::class);
834
    $list3->method('isCurrent')->willReturn(false);
835
    $list3->method('getLastEntryTime')->willReturn(new \DateTime("2017-03-01"));
836
    $list3->method('getEntries')->willReturn(new ArrayCollection([1 => $entry1, 2 => $entry2]));
837
    $list3->method('getRankingSystem')->willReturn($ranking);
838
839
    $list4 = $this->createMock(RankingSystemList::class);
840
    $list4->method('isCurrent')->willReturn(false);
841
    $list4->method('getLastEntryTime')->willReturn(new \DateTime("2017-04-01"));
842
    $list4->method('getEntries')->willReturn(new ArrayCollection());
843
    $list4->method('getRankingSystem')->willReturn($ranking);
844
845
    $list5 = $this->createMock(RankingSystemList::class);
846
    $list5->method('isCurrent')->willReturn(true);
847
    $list5->method('getLastEntryTime')->willReturn(new \DateTime("2017-05-01"));
848
    $list5->method('getEntries')->willReturn(new ArrayCollection());
849
    $list5->method('getRankingSystem')->willReturn($ranking);
850
851
    $lists = $this->createMock(Collection::class);
852
    $lists->expects(static::once())->method('toArray')->willReturn([$list1, $list2, $list3, $list4, $list5]);
853
854
    //finish mock for input
855
    $ranking->expects(static::once())->method('getLists')->willReturn($lists);
856
857
    //create time service, entity comparer and ranking service mock
858
    $timeService = $this->createMock(TimeServiceInterface::class);
859
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
860
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
861
      return $entity->getEndTime();
862
    })->after('clearTimes');
863
    $entityComparer = $this->createMock(EntityComparerInterface::class);
864
    $entityComparer->method('compareEntities')->willReturnCallback(
865
      function (TournamentHierarchyInterface $entity1, TournamentHierarchyInterface $entity2) {
866
        return $entity1->getEndTime() <=> $entity2->getEndTime();
867
      });
868
    $entityManager = $this->getEntityManagerMockForQuery([],
869
      'SELECT c FROM Tfboe\FmLib\Entity\RankingSystemChangeInterface c WHERE c.rankingSystem = :ranking' .
870
      ' AND c.hierarchyEntity IN(:entities)', ['persist', 'remove', 'flush', 'detach'], 3);
871
    $service = $this->getMockWithMockedArguments(RankingSystemService::class,
872
      [$entityManager,
873
        $timeService,
874
        $this->createMock(EntityComparerInterface::class),
875
        $this->getObjectCreator()]);
876
877
    //create entities mocks
878
    $entity1 = $this->createStubWithId(TournamentHierarchyEntity::class, "e1");
879
    $entity1->method('getEndTime')->willReturn(new \DateTime("2017-03-01"));
880
881
    $entity2 = $this->createStubWithId(TournamentHierarchyEntity::class, "e2");
882
    $entity2->method('getEndTime')->willReturn(new \DateTime("2017-02-01 00:00:01"));
883
884
    $entity3 = $this->createStubWithId(TournamentHierarchyEntity::class, "e3");
885
    $entity3->method('getEndTime')->willReturn(new \DateTime("2017-05-02"));
886
887
    $entity4 = $this->createStubWithId(TournamentHierarchyEntity::class, "e4");
888
    $entity4->method('getEndTime')->willReturn(new \DateTime("2017-03-02"));
889
890
    $parent = $this->createStubWithId(TournamentHierarchyEntity::class, "e4");
891
    $parent->method('getEndTime')->willReturn(new \DateTime("2017-12-02"));
892
    $entity4->method('getParent')->willReturn($parent);
893
894
    //create query mock for getEntities
895
    $query3 = $this->createMock(AbstractQuery::class);
896
    $query3->expects(static::once())->method('getResult')->willReturn([$entity1, $entity2, $entity3, $entity4]);
897
    $queryBuilder3 = $this->createMock(QueryBuilder::class);
898
    $queryBuilder3->expects(static::once())->method('getQuery')->willReturn($query3);
899
900
    $query4 = $this->createMock(AbstractQuery::class);
901
    $query4->expects(static::once())->method('getResult')->willReturn([$entity1, $entity2, $entity3, $entity4]);
902
    $queryBuilder4 = $this->createMock(QueryBuilder::class);
903
    $queryBuilder4->expects(static::once())->method('getQuery')->willReturn($query4);
904
905
    $query5 = $this->createMock(AbstractQuery::class);
906
    $query5->expects(static::once())->method('getResult')->willReturn([$entity1, $entity2, $entity3, $entity4]);
907
    $queryBuilder5 = $this->createMock(QueryBuilder::class);
908
    $queryBuilder5->expects(static::once())->method('getQuery')->willReturn($query5);
909
910
    $service->method('getEntitiesQueryBuilder')
911
      ->withConsecutive([$ranking, new \DateTime("2017-02-01"), new \DateTime("2017-03-01")],
912
        [$ranking, new \DateTime("2017-03-01"), new \DateTime("2017-04-01")],
913
        [$ranking, new \DateTime("2017-04-01")])
914
      ->willReturnOnConsecutiveCalls($queryBuilder3, $queryBuilder4, $queryBuilder5);
915
    $changes = [
916
      $this->createEmptyChange(),
917
      $this->createEmptyChange(),
918
    ];
919
    $service->method('getChanges')->willReturn($changes);
920
    $service->method('getAdditionalFields')->willReturn(['additional' => 0.0]);
921
922
    /** @var RankingSystemService $service */
923
    /** @var RankingSystemInterface $ranking */
924
    /** @noinspection PhpUnhandledExceptionInspection */
925
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
926
  }
927
928
  /**
929
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
930
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
931
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
932
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
933
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
934
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
935
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
936
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
937
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
938
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
939
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
940
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
941
   */
942
  public function testUpdateRankingFromCalledTwice()
943
  {
944
    $ranking = $this->createStubWithId(RankingSystem::class);
945
    $service = $this->prepareUpdateRankingFrom($ranking, $this->getEntityManagerMockForQuery([], null, ['flush']));
0 ignored issues
show
Documentation introduced by
$this->getEntityManagerM..., null, array('flush')) is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
946
947
    /** @var RankingSystemInterface $ranking */
948
949
    /** @noinspection PhpUnhandledExceptionInspection */
950
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
0 ignored issues
show
Documentation introduced by
$ranking is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Entity\RankingSystemInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
951
952
    $this->expectException(PreconditionFailedException::class);
953
954
    /** @noinspection PhpUnhandledExceptionInspection */
955
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
0 ignored issues
show
Documentation introduced by
$ranking is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Entity\RankingSystemInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
956
  }
957
958
  /**
959
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
960
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
961
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
962
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
963
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
964
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
965
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
966
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
967
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
968
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
969
   * @uses   \Tfboe\FmLib\Entity\Helpers\UUIDEntity::getId
970
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
971
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
972
   */
973
  public function testUpdateRankingFromNoCurrent()
974
  {
975
    //create mock for input
976
    $ranking = $this->createStubWithId(RankingSystem::class, 'r1');
977
    $ranking->method('getGenerationInterval')->willReturn(AutomaticInstanceGeneration::MONTHLY);
978
979
    //create mocks for ranking lists
980
    $list = $this->createMock(RankingSystemList::class);
981
    $list->method('isCurrent')->willReturn(false);
982
    $list->method('getLastEntryTime')->willReturn(new \DateTime("2017-12-01"));
983
    $list->method('getEntries')->willReturn(new ArrayCollection());
984
    $list->method('getRankingSystem')->willReturn($ranking);
985
986
    $lists = $this->createMock(Collection::class);
987
    $lists->expects(static::once())->method('toArray')->willReturn([$list]);
988
    $lists->expects(static::once())->method('set')->with('new')->willReturnSelf();
989
990
    //finish mock for input
991
    $ranking->expects(static::exactly(2))->method('getLists')->willReturn($lists);
992
993
    //create service mock
994
    $entityManager = $this->getEntityManagerMockForQuery([],
995
      'SELECT c FROM Tfboe\FmLib\Entity\RankingSystemChangeInterface c WHERE c.rankingSystem = :ranking' .
996
      ' AND c.hierarchyEntity IN(:entities)', ['persist', 'flush']);
997
    $entityManager->expects(static::once())->method('persist')->willReturnCallback(
998
      function (RankingSystemListInterface $entity) {
999
        self::assertInstanceOf(RankingSystemList::class, $entity);
1000
        self::assertTrue($entity->isCurrent());
1001
        static::getProperty(get_class($entity), 'id')->setValue($entity, 'new');
1002
      });
1003
    $service = $this->getMockWithMockedArguments(RankingSystemService::class, [$entityManager,
1004
      $this->createMock(TimeServiceInterface::class), $this->createMock(EntityComparerInterface::class),
1005
      $this->getObjectCreator()]);
1006
1007
    //create query mock for getEntities
1008
    $query = $this->createMock(AbstractQuery::class);
1009
    $query->expects(static::once())->method('getResult')->willReturn([]);
1010
    //create query builder mock for getEntities
1011
    $queryBuilder = $this->createMock(QueryBuilder::class);
1012
    $queryBuilder->expects(static::once())->method('getQuery')->willReturn($query);
1013
    $service->expects(static::once())->method('getEntitiesQueryBuilder')
1014
      ->with($ranking, new \DateTime("2017-12-01"))->willReturn($queryBuilder);
1015
1016
    /** @var RankingSystemService $service */
1017
    /** @var RankingSystemInterface $ranking */
1018
    /** @noinspection PhpUnhandledExceptionInspection */
1019
    /** @noinspection PhpUnhandledExceptionInspection */
1020
    /** @noinspection PhpUnhandledExceptionInspection */
1021
    /** @noinspection PhpUnhandledExceptionInspection */
1022
    $service->updateRankingFrom($ranking, new \DateTime('2018-02-28'));
1023
  }
1024
1025
  /**
1026
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
1027
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
1028
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
1029
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
1030
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
1031
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
1032
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
1033
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
1034
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
1035
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
1036
   * @uses   \Tfboe\FmLib\Entity\Helpers\UUIDEntity::getId
1037
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
1038
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
1039
   */
1040
  public function testUpdateRankingCreateMonthlyLists()
1041
  {
1042
    //create mock for input
1043
    $ranking = $this->createStubWithId(RankingSystem::class, 'r1');
1044
    $ranking->method('getGenerationInterval')->willReturn(AutomaticInstanceGeneration::MONTHLY);
1045
1046
    //create mocks for ranking lists
1047
    $list = $this->createMock(RankingSystemList::class);
1048
    $list->method('isCurrent')->willReturn(true);
1049
    $list->method('getLastEntryTime')->willReturn(new \DateTime("2017-12-01"));
1050
    $list->method('getEntries')->willReturn(new ArrayCollection());
1051
    $list->method('getRankingSystem')->willReturn($ranking);
1052
1053
    $lists = $this->createMock(Collection::class);
1054
    $lists->expects(static::once())->method('toArray')->willReturn([$list]);
1055
    $lists->expects(static::once())->method('set')->with('new')->willReturnSelf();
1056
1057
    //create entities mocks
1058
    $entity1 = $this->createStubWithId(TournamentHierarchyEntity::class, "e1");
1059
    $entity1->method('getEndTime')->willReturn(new \DateTime("2018-03-01"));
1060
1061
    $entity2 = $this->createStubWithId(TournamentHierarchyEntity::class, "e2");
1062
    $entity2->method('getEndTime')->willReturn(new \DateTime("2018-04-01 00:00:01"));
1063
1064
    //finish mock for input
1065
    $ranking->expects(static::exactly(2))->method('getLists')->willReturn($lists);
1066
1067
    //create service mock
1068
    $entityManager = $this->getEntityManagerMockForQuery([],
1069
      'SELECT c FROM Tfboe\FmLib\Entity\RankingSystemChangeInterface c WHERE c.rankingSystem = :ranking' .
1070
      ' AND c.hierarchyEntity IN(:entities)', ['persist', 'flush', 'detach']);
1071
    $entityManager->expects(static::once())->method('persist')->willReturnCallback(
1072
      function (RankingSystemListInterface $entity) {
1073
        self::assertInstanceOf(RankingSystemList::class, $entity);
1074
        static::getProperty(get_class($entity), 'id')->setValue($entity, 'new');
1075
      });
1076
    $timeService = $this->createMock(TimeServiceInterface::class);
1077
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
1078
      return $entity->getEndTime();
1079
    });
1080
    $service = $this->getMockWithMockedArguments(RankingSystemService::class, [$entityManager,
1081
      $timeService, $this->createMock(EntityComparerInterface::class),
1082
      $this->getObjectCreator()]);
1083
1084
    //create query mock for getEntities
1085
    $query = $this->createMock(AbstractQuery::class);
1086
    $query->expects(static::once())->method('getResult')->willReturn([$entity1, $entity2]);
1087
    //create query builder mock for getEntities
1088
    $queryBuilder = $this->createMock(QueryBuilder::class);
1089
    $queryBuilder->expects(static::once())->method('getQuery')->willReturn($query);
1090
    $service->expects(static::once())->method('getEntitiesQueryBuilder')
1091
      ->with($ranking, new \DateTime("2017-12-01"))->willReturn($queryBuilder);
1092
1093
    /** @var RankingSystemService $service */
1094
    /** @var RankingSystemInterface $ranking */
1095
    /** @noinspection PhpUnhandledExceptionInspection */
1096
    /** @noinspection PhpUnhandledExceptionInspection */
1097
    /** @noinspection PhpUnhandledExceptionInspection */
1098
    /** @noinspection PhpUnhandledExceptionInspection */
1099
    $service->updateRankingFrom($ranking, new \DateTime('2018-02-28'));
1100
  }
1101
1102
  /**
1103
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
1104
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
1105
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
1106
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
1107
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
1108
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
1109
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
1110
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
1111
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
1112
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
1113
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
1114
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
1115
   */
1116
  public function testUpdateRankingFromNoReusable()
1117
  {
1118
    $ranking = $this->createStubWithId(RankingSystem::class);
1119
    $service = $this->prepareUpdateRankingFrom($ranking, $this->getEntityManagerMockForQuery([], null, ['flush']));
0 ignored issues
show
Documentation introduced by
$this->getEntityManagerM..., null, array('flush')) is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1120
1121
    /** @var RankingSystemInterface $ranking */
1122
1123
    /** @var RankingSystemService $service */
1124
    /** @var RankingSystemInterface $ranking */
1125
    /** @noinspection PhpUnhandledExceptionInspection */
1126
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
0 ignored issues
show
Documentation introduced by
$ranking is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Entity\RankingSystemInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1127
  }
1128
1129
  /**
1130
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
1131
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
1132
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
1133
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextGenerationTime
1134
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getNextEntities
1135
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::flushAndForgetEntities
1136
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::markOldChangesAsDeleted
1137
   * @uses   \Tfboe\FmLib\Entity\Traits\RankingSystemList
1138
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
1139
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
1140
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
1141
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getMaxDate
1142
   */
1143
  public function testUpdateRankingFromNoEntities()
1144
  {
1145
    $ranking = $this->createStubWithId(RankingSystem::class);
1146
1147
    //create mocks for ranking lists
1148
    $list = $this->createMock(RankingSystemList::class);
1149
    $list->method('isCurrent')->willReturn(false);
1150
    $list->method('getLastEntryTime')->willReturn(new \DateTime("2017-12-01"));
1151
    $list->method('getEntries')->willReturn(new ArrayCollection());
1152
    $list->method('getRankingSystem')->willReturn($ranking);
1153
1154
    $current = $this->createMock(RankingSystemList::class);
1155
    $current->method('isCurrent')->willReturn(true);
1156
    $current->method('getLastEntryTime')->willReturn(new \DateTime("2017-12-01"));
1157
    $current->method('getEntries')->willReturn(new ArrayCollection());
1158
    $current->method('getRankingSystem')->willReturn($ranking);
1159
1160
    $service = $this->prepareUpdateRankingFrom($ranking, $this->getEntityManagerMockForQuery([], null,
0 ignored issues
show
Documentation introduced by
$this->getEntityManagerM...'flush', 'persist'), 2) is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1161
      ['flush', 'persist'], 2), [$list, $current], 2);
1162
    /** @var RankingSystemInterface $ranking */
1163
1164
    /** @var RankingSystemService $service */
1165
    /** @var RankingSystemInterface $ranking */
1166
    /** @noinspection PhpUnhandledExceptionInspection */
1167
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
0 ignored issues
show
Documentation introduced by
$ranking is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Entity\RankingSystemInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1168
  }
1169
//</editor-fold desc="Public Methods">
1170
1171
//<editor-fold desc="Private Methods">
1172
  /**
1173
   * Creates an empty RankingSystemChange
1174
   * @return MockObject|RankingSystemChangeInterface
1175
   */
1176
  private function createEmptyChange(): MockObject
1177
  {
1178
    $change = $this->getMockForAbstractClass(RankingSystemChange::class, [['additional']], '', true, true, true,
1179
      ['getPlayer', 'getPointsChange']);
1180
    return $change;
1181
  }
1182
1183
  /**
1184
   * Creates an empty RankingSystemListEntry
1185
   * @return MockObject|RankingSystemListEntryInterface
1186
   */
1187
  private function createEmptyEntry(): MockObject
1188
  {
1189
    $entry = $this->getMockForAbstractClass(RankingSystemListEntry::class, [['additional']], '', true, true, true,
1190
      ['getPlayer', 'getPoints']);
1191
    return $entry;
1192
  }
1193
1194
  /**
1195
   * Creates different entities used for create change
1196
   * @return array, a hierarchy entity, a ranking system and a player
0 ignored issues
show
Documentation introduced by
The doc-type array, could not be parsed: Expected "|" or "end of type", but got "," at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1197
   */
1198
  private function createEntities()
1199
  {
1200
    $entity = $this->createStubWithId(TournamentHierarchyEntity::class, 'h1');
1201
    $ranking = $this->createStubWithId(RankingSystem::class, 'r1');
1202
    $player = $this->createStubWithId(Player::class, 1, 'getId');
1203
    return [$entity, $ranking, $player];
1204
  }
1205
1206
  /**
1207
   * Prepares a ranking system service for creating a change
1208
   * @return array, the service entity and its corresponding entity manager
0 ignored issues
show
Documentation introduced by
The doc-type array, could not be parsed: Expected "|" or "end of type", but got "," at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1209
   */
1210
  private function prepareCreateChange()
1211
  {
1212
    $entityManager = $this->createStub(EntityManager::class, []);
1213
    /** @var $service RankingSystemService */
1214
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [
1215
      $entityManager, $this->createMock(TimeServiceInterface::class),
1216
      $this->createMock(EntityComparerInterface::class),
1217
      $this->getObjectCreator()
1218
    ]);
1219
    return [$service, $entityManager];
1220
  }
1221
1222
  /**
1223
   * prepares a new ranking system service for update ranking from
1224
   * @param MockObject $ranking the ranking entity
1225
   * @param EntityManagerInterface|null $entityManager the entity manager or null if a mock should be used
1226
   * @return RankingSystemService
1227
   */
1228
  private function prepareUpdateRankingFrom(MockObject $ranking, ?EntityManagerInterface $entityManager = null,
1229
                                            $listsArray = null, $numListsToUpdate = 1, $mockedMethods = [],
1230
                                            $entities = [])
1231
  {
1232
    if ($entityManager === null) {
1233
      $entityManager = $this->getEntityManagerMockForQuery([]);
1234
    }
1235
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
1236
      [$entityManager, $this->createMock(TimeServiceInterface::class),
1237
        $this->createMock(EntityComparerInterface::class),
1238
        $this->getObjectCreator()], '', true, true, true, $mockedMethods);
1239
1240
    if ($listsArray == null) {
1241
      //create mocks for current lists
1242
      $list = $this->createMock(RankingSystemList::class);
1243
      $list->method('isCurrent')->willReturn(true);
1244
      $list->method('getLastEntryTime')->willReturn(new \DateTime("2017-06-01"));
1245
      $list->method('getEntries')->willReturn(new ArrayCollection());
1246
      $listsArray = [$list];
1247
    }
1248
1249
    $lists = $this->createMock(Collection::class);
1250
    $lists->expects(static::once())->method('toArray')->willReturn($listsArray);
1251
1252
    //finish mock for input
1253
    $ranking->method('getLists')->willReturn($lists);
1254
1255
    //create query mock for getEntities
1256
    $query = $this->createMock(AbstractQuery::class);
1257
    $query->expects(static::exactly($numListsToUpdate))->method('getResult')->willReturn($entities);
1258
    //create query builder mock for getEntities
1259
    $queryBuilder = $this->createMock(QueryBuilder::class);
1260
    $queryBuilder->expects(static::exactly($numListsToUpdate))->method('getQuery')->willReturn($query);
1261
    $service->expects(static::exactly($numListsToUpdate))->method('getEntitiesQueryBuilder')
1262
      ->with($ranking)->willReturn($queryBuilder);
1263
    /** @var $service RankingSystemService */
1264
1265
    return $service;
1266
  }
1267
//</editor-fold desc="Private Methods">
1268
}