Completed
Push — master ( 685463...a3ac99 )
by Benedikt
13:47
created

testGetEarliestInfluenceGameLevel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 50
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 50
c 0
b 0
f 0
cc 1
eloc 42
nc 1
nop 0
rs 9.3333
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\Common\Persistence\ObjectRepository;
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 Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity;
21
use Tfboe\FmLib\Entity\Helpers\TournamentHierarchyInterface;
22
use Tfboe\FmLib\Entity\Player;
23
use Tfboe\FmLib\Entity\RankingSystem;
24
use Tfboe\FmLib\Entity\RankingSystemChange;
25
use Tfboe\FmLib\Entity\RankingSystemList;
26
use Tfboe\FmLib\Entity\RankingSystemListEntry;
27
use Tfboe\FmLib\Exceptions\PreconditionFailedException;
28
use Tfboe\FmLib\Helpers\Level;
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\TestHelpers\UnitTestCase;
33
use Tfboe\FmLib\Tests\Entity\Competition;
34
use Tfboe\FmLib\Tests\Entity\Game;
35
use Tfboe\FmLib\Tests\Entity\Match;
36
use Tfboe\FmLib\Tests\Entity\Phase;
37
use Tfboe\FmLib\Tests\Entity\Tournament;
38
39
40
/**
41
 * Class RankingSystemServiceTest
42
 * @packageTfboe\FmLib\Tests\Unit\Service\RankingSystemService
43
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
44
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
45
 * @SuppressWarnings(PHPMD.TooManyMethods)
46
 * @SuppressWarnings(PHPMD.ExcessiveClassLength)
47
 */
48
class RankingSystemServiceTest extends UnitTestCase
49
{
50
//<editor-fold desc="Public Methods">
51
52
  /**
53
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
54
   */
55
  public function testConstruct()
56
  {
57
    $entityManager = $this->createMock(EntityManagerInterface::class);
58
    $timeService = $this->createMock(TimeServiceInterface::class);
59
    $entityComparer = $this->createMock(EntityComparerInterface::class);
60
    $system = $this->getMockForAbstractClass(RankingSystemService::class,
61
      [$entityManager, $timeService, $entityComparer]);
62
    self::assertInstanceOf(RankingSystemService::class, $system);
63
    /** @noinspection PhpUnhandledExceptionInspection */
64
    self::assertEquals($entityManager, self::getProperty(get_class($system), 'entityManager')->getValue($system));
65
    /** @noinspection PhpUnhandledExceptionInspection */
66
    self::assertEquals($timeService, self::getProperty(get_class($system), 'timeService')->getValue($system));
67
    /** @noinspection PhpUnhandledExceptionInspection */
68
    self::assertEquals($entityComparer, self::getProperty(get_class($system), 'entityComparer')->getValue($system));
69
  }
70
71
  /**
72
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getAverage
73
   */
74
  public function testGetAverage()
75
  {
76
    /** @var $service RankingSystemService */
77
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
78
79
    $entry1 = $this->createMock(RankingSystemListEntry::class);
80
    $entry1->method('getPoints')->willReturn(1.0);
81
    $entry2 = $this->createMock(RankingSystemListEntry::class);
82
    $entry2->method('getPoints')->willReturn(2.0);
83
84
    self::assertEquals(1.5, static::callProtectedMethod($service, 'getAverage', [[$entry1, $entry2]]));
85
  }
86
87
  /**
88
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
89
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
90
   * @uses   \Tfboe\FmLib\Tests\Entity\Competition
91
   * @uses   \Tfboe\FmLib\Entity\Traits\Competition
92
   * @uses   \Tfboe\FmLib\Tests\Entity\Game
93
   * @uses   \Tfboe\FmLib\Entity\Traits\Game
94
   * @uses   \Tfboe\FmLib\Entity\Helpers\NameEntity
95
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
96
   * @uses   \Tfboe\FmLib\Tests\Entity\Match
97
   * @uses   \Tfboe\FmLib\Entity\Traits\Match
98
   * @uses   \Tfboe\FmLib\Tests\Entity\Phase
99
   * @uses   \Tfboe\FmLib\Entity\Traits\Phase
100
   * @uses   \Tfboe\FmLib\Tests\Entity\Tournament
101
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
102
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
103
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
104
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
105
   */
106
  public function testGetEarliestInfluenceGameLevel()
107
  {
108
    $ranking = $this->createStubWithId(RankingSystem::class);
109
    $timeService = $this->createMock(TimeServiceInterface::class);
110
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
111
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
112
      return $entity->getEndTime();
113
    })->after('clearTimes');
114
    /** @var RankingSystem $ranking */
115
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
116
      [$this->createMock(EntityManagerInterface::class),
117
        $timeService,
118
        $this->createMock(EntityComparerInterface::class)]);
119
    $service->method("getLevel")->willReturn(Level::GAME);
120
    /** @var RankingSystemService $service */
121
    $tournament = new Tournament();
122
    $competition = new Competition();
123
    $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...
124
    $phase = new Phase();
125
    $phase->setPhaseNumber(1);
126
    $phase->setCompetition($competition);
127
    $match = new Match();
128
    $match->setMatchNumber(1);
129
    $match->setPhase($phase);
130
    self::assertNull($service->getEarliestInfluence($ranking, $tournament));
131
132
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
133
    self::assertNull($service->getEarliestInfluence($ranking, $tournament));
134
135
    $game = new Game();
136
    $game->setGameNumber(1);
137
    $game->setMatch($match);
138
    $gameEndTime = new \DateTime("2017-06-01 00:00:00");
139
    $game->setEndTime($gameEndTime);
140
    self::assertEquals($gameEndTime, $service->getEarliestInfluence($ranking, $tournament));
141
142
    $game2 = new Game();
143
    $game2->setGameNumber(2);
144
    $game2->setMatch($match);
145
    $game2EndTime = new \DateTime("2017-05-01 00:00:00");
146
    $game2->setEndTime($game2EndTime);
147
    self::assertEquals($game2EndTime, $service->getEarliestInfluence($ranking, $tournament));
148
149
    $game3 = new Game();
150
    $game3->setGameNumber(3);
151
    $game3->setMatch($match);
152
    $game3EndTime = new \DateTime("2017-07-01 00:00:00");
153
    $game3->setEndTime($game3EndTime);
154
    self::assertEquals($game2EndTime, $service->getEarliestInfluence($ranking, $tournament));
155
  }
156
157
  /**
158
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
159
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
160
   * @uses   \Tfboe\FmLib\Tests\Entity\Competition
161
   * @uses   \Tfboe\FmLib\Entity\Traits\Competition
162
   * @uses   \Tfboe\FmLib\Tests\Entity\Game
163
   * @uses   \Tfboe\FmLib\Entity\Traits\Game
164
   * @uses   \Tfboe\FmLib\Entity\Helpers\NameEntity
165
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
166
   * @uses   \Tfboe\FmLib\Tests\Entity\Match
167
   * @uses   \Tfboe\FmLib\Entity\Traits\Match
168
   * @uses   \Tfboe\FmLib\Tests\Entity\Phase
169
   * @uses   \Tfboe\FmLib\Entity\Traits\Phase
170
   * @uses   \Tfboe\FmLib\Tests\Entity\Tournament
171
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
172
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
173
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
174
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
175
   * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
176
   */
177
  public function testGetEarliestInfluenceGameLevelWithDifferentImpactLevels()
178
  {
179
    $ranking = $this->createStubWithId(RankingSystem::class);
180
    $timeService = $this->createMock(TimeServiceInterface::class);
181
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
182
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
183
      return $entity->getEndTime();
184
    })->after('clearTimes');
185
    /** @var RankingSystem $ranking */
186
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
187
      [$this->createMock(EntityManagerInterface::class),
188
        $timeService,
189
        $this->createMock(EntityComparerInterface::class)]);
190
    $service->method("getLevel")->willReturn(Level::GAME);
191
    /** @var RankingSystemService $service */
192
    $tournament = new Tournament();
193
    $competition = new Competition();
194
    $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...
195
    $phase = new Phase();
196
    $phase->setPhaseNumber(1);
197
    $phase->setCompetition($competition);
198
    $match = new Match();
199
    $match->setMatchNumber(1);
200
    $match->setPhase($phase);
201
    $game = new Game();
202
    $game->setGameNumber(1);
203
    $game->setMatch($match);
204
    $endTime1 = new \DateTime("2017-12-01 00:00:00");
205
    $game->setEndTime($endTime1);
206
    $game->getRankingSystems()->set($ranking->getId(), $ranking);
207
    self::assertEquals($endTime1, $service->getEarliestInfluence($ranking, $tournament));
208
209
    $game2 = new Game();
210
    $game2->setGameNumber(2);
211
    $game2->setMatch($match);
212
    $endTime2 = new \DateTime("2017-11-01 00:00:00");
213
    $game2->setEndTime($endTime2);
214
    self::assertEquals($endTime1, $service->getEarliestInfluence($ranking, $tournament));
215
216
    $match->getRankingSystems()->set($ranking->getId(), $ranking);
217
    self::assertEquals($endTime2, $service->getEarliestInfluence($ranking, $tournament));
218
219
    $match2 = new Match();
220
    $match2->setMatchNumber(2);
221
    $match2->setPhase($phase);
222
    $game3 = new Game();
223
    $game3->setGameNumber(1);
224
    $game3->setMatch($match2);
225
    $endTime3 = new \DateTime("2017-10-01 00:00:00");
226
    $game3->setEndTime($endTime3);
227
    self::assertEquals($endTime2, $service->getEarliestInfluence($ranking, $tournament));
228
229
    $phase->getRankingSystems()->set($ranking->getId(), $ranking);
230
    self::assertEquals($endTime3, $service->getEarliestInfluence($ranking, $tournament));
231
232
    $phase2 = new Phase();
233
    $phase2->setPhaseNumber(2);
234
    $phase2->setCompetition($competition);
235
    $match3 = new Match();
236
    $match3->setMatchNumber(1);
237
    $match3->setPhase($phase2);
238
    $game4 = new Game();
239
    $game4->setGameNumber(1);
240
    $game4->setMatch($match3);
241
    $endTime4 = new \DateTime("2017-09-01 00:00:00");
242
    $game4->setEndTime($endTime4);
243
    self::assertEquals($endTime3, $service->getEarliestInfluence($ranking, $tournament));
244
245
    $competition->getRankingSystems()->set($ranking->getId(), $ranking);
246
    self::assertEquals($endTime4, $service->getEarliestInfluence($ranking, $tournament));
247
248
    $competition2 = new Competition();
249
    $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...
250
    $phase3 = new Phase();
251
    $phase3->setPhaseNumber(1);
252
    $phase3->setCompetition($competition2);
253
    $match4 = new Match();
254
    $match4->setMatchNumber(1);
255
    $match4->setPhase($phase3);
256
    $game5 = new Game();
257
    $game5->setGameNumber(1);
258
    $game5->setMatch($match4);
259
    $endTime5 = new \DateTime("2017-01-01 00:00:00");
260
    $game5->setEndTime($endTime5);
261
    self::assertEquals($endTime4, $service->getEarliestInfluence($ranking, $tournament));
262
263
    $game6 = new Game();
264
    $game6->setGameNumber(2);
265
    $game6->setMatch($match4);
266
    $endTime6 = new \DateTime("2017-10-01 00:00:00");
267
    $game6->setEndTime($endTime6);
268
    $game6->getRankingSystems()->set($ranking->getId(), $ranking);
269
    self::assertEquals($endTime4, $service->getEarliestInfluence($ranking, $tournament));
270
271
    $game7 = new Game();
272
    $game7->setGameNumber(3);
273
    $game7->setMatch($match4);
274
    $endTime7 = new \DateTime("2017-08-01 00:00:00");
275
    $game7->setEndTime($endTime7);
276
    $game7->getRankingSystems()->set($ranking->getId(), $ranking);
277
    self::assertEquals($endTime7, $service->getEarliestInfluence($ranking, $tournament));
278
  }
279
280
  /**
281
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
282
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
283
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
284
   * @uses   \Tfboe\FmLib\Tests\Entity\Tournament
285
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
286
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
287
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
288
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
289
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
290
   */
291
  public function testGetEarliestInfluenceTournamentLevel()
292
  {
293
    $ranking = $this->createStubWithId(RankingSystem::class);
294
    $timeService = $this->createMock(TimeServiceInterface::class);
295
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
296
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
297
      return $entity->getEndTime();
298
    })->after('clearTimes');
299
    /** @var RankingSystem $ranking */
300
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
301
      [$this->createMock(EntityManagerInterface::class),
302
        $timeService,
303
        $this->createMock(EntityComparerInterface::class)]);
304
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
305
    /** @var RankingSystemService $service */
306
    $tournament = new Tournament();
307
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
308
    $endTime = new \DateTime("2017-03-01 00:00:00");
309
    $tournament->setEndTime($endTime);
310
    self::assertEquals($endTime, $service->getEarliestInfluence($ranking, $tournament));
311
  }
312
313
  /**
314
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getAverage
315
   */
316
  public function testGetEmptyAverage()
317
  {
318
    /** @var $service RankingSystemService */
319
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
320
321
    self::assertEquals(0.0, static::callProtectedMethod($service, 'getAverage', [[]]));
322
  }
323
324
  /**
325
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
326
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
327
   */
328
  public function testGetEntities()
329
  {
330
    //create mock for input
331
    $ranking = $this->createMock(RankingSystem::class);
332
333
    //create service mock
334
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
335
      [$this->createMock(EntityManagerInterface::class), $this->createMock(TimeServiceInterface::class),
336
        $this->createMock(EntityComparerInterface::class)]);
337
338
    //create mock for queryBuilder
339
    $entityList = ['e1', 'e2'];
340
    $query = $this->createMock(AbstractQuery::class);
341
    $query->expects(static::once())->method('getResult')->willReturn($entityList);
342
    //create query builder mock for getEntities
343
    $queryBuilder = $this->createMock(QueryBuilder::class);
344
    $queryBuilder->expects(static::once())->method('getQuery')->willReturn($query);
345
    $service->expects(static::once())->method('getEntitiesQueryBuilder')
346
      ->with($ranking, new \DateTime("2017-01-01"))->willReturn($queryBuilder);
347
348
    /** @var $service RankingSystemService */
349
    /** @noinspection PhpUnhandledExceptionInspection */
350
    self::assertEquals($entityList, static::getMethod(get_class($service), 'getEntities')
351
      ->invokeArgs($service, [$ranking, new \DateTime("2017-01-01")]));
352
  }
353
354
  /**
355
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntityManager
356
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
357
   */
358
  public function testGetEntityManager()
359
  {
360
    $entityManager = $this->createMock(EntityManagerInterface::class);
361
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [$entityManager,
362
      $this->createMock(TimeServiceInterface::class), $this->createMock(EntityComparerInterface::class)]);
363
    $em = static::callProtectedMethod($service, 'getEntityManager');
364
    self::assertEquals($entityManager, $em);
365
  }
366
367
  /**
368
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntriesOfPlayers
369
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
370
   */
371
  public function testGetEntriesOfPlayers()
372
  {
373
374
    /** @var $service RankingSystemService */
375
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
376
377
    $entry1 = $this->createMock(RankingSystemListEntry::class);
378
    $entry2 = $this->createMock(RankingSystemListEntry::class);
379
    $entry3 = $this->createMock(RankingSystemListEntry::class);
380
381
    $entries = new ArrayCollection([1 => $entry1, 2 => $entry2, 3 => $entry3]);
382
    $list = $this->createStub(RankingSystemList::class, ['getEntries' => $entries]);
383
384
    $player1 = $this->createStub(Player::class, ['getPlayerId' => 1]);
385
    $player3 = $this->createStub(Player::class, ['getPlayerId' => 3]);
386
387
    $returnedEntries = static::callProtectedMethod($service, 'getEntriesOfPlayers',
388
      [new ArrayCollection([$player1, $player3]), $list]);
389
    self::assertEquals([$entry1, $entry3], $returnedEntries);
390
  }
391
392
  /**
393
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
394
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
395
   * @uses   \Tfboe\FmLib\Entity\RankingSystemChange
396
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
397
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::setProperty
398
   */
399
  public function testGetOrCreateChangeCreateNewOne()
400
  {
401
    $persisted = null;
402
403
    [$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...
404
    [$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...
405
    $entityManager->expects(self::once())->method('persist')->willReturnCallback(
406
      function (RankingSystemChange $change) use (&$persisted, $entity, $ranking, $player) {
407
        $persisted = $change;
408
        self::assertInstanceOf(RankingSystemChange::class, $change);
409
        self::assertEquals($entity, $change->getHierarchyEntity());
410
        self::assertEquals($ranking, $change->getRankingSystem());
411
        self::assertEquals($player, $change->getPlayer());
412
      });
413
    $service->method('getAdditionalFields')->willReturn(['additional' => 0.0]);
414
415
    $change = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
416
    self::assertEquals($persisted, $change);
417
  }
418
419
  /**
420
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
421
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
422
   * @uses   \Tfboe\FmLib\Entity\RankingSystemChange
423
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
424
   */
425
  public function testGetOrCreateChangeCreateTwice()
426
  {
427
    $repository = $this->createMock(ObjectRepository::class);
428
    $repository->expects(self::once())->method('findBy')->willReturn([]);
429
430
    [$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...
431
    [$service, $entityManager] = $this->prepareCreateChange($repository);
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...
Documentation introduced by
$repository is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\Common\P...\ObjectRepository>|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...
432
    $entityManager->expects(self::once())->method('persist');
433
434
    $change = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
435
    $change2 = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
436
    self::assertEquals($change, $change2);
437
  }
438
439
  /**
440
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
441
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
442
   * @uses   \Tfboe\FmLib\Entity\RankingSystemChange
443
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
444
   */
445
  public function testGetOrCreateChangeFindInRepo()
446
  {
447
    [$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...
448
    $change = $this->createStub(RankingSystemChange::class, ['getRankingSystem' => $ranking, 'getPlayer' => $player]);
449
450
    $repository = $this->createStub(ObjectRepository::class, ['findBy' => [$change]]);
451
452
453
    [$service, $entityManager] = $this->prepareCreateChange($repository);
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...
Documentation introduced by
$repository is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\Common\P...\ObjectRepository>|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...
454
    $entityManager->expects(self::never())->method('persist');
455
456
    $foundChange = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
457
    self::assertEquals($change, $foundChange);
458
  }
459
460
  /**
461
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
462
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
463
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
464
   * @uses   \Tfboe\FmLib\Entity\RankingSystemChange::__construct
465
   * @uses   \Tfboe\FmLib\Entity\RankingSystemChange
466
   * @uses   \Tfboe\FmLib\Entity\RankingSystemList
467
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
468
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
469
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
470
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
471
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
472
   */
473
  public function testGetOrCreateGetDeletedChange()
474
  {
475
    [$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...
476
    $change = $this->createStub(RankingSystemChange::class,
477
      ['getRankingSystem' => $ranking, 'getPlayer' => $player, 'getHierarchyEntity' => $entity]);
478
479
    $entityManager = $this->getEntityManagerMockForQuery([$change], null, ['persist', 'remove', 'getRepository']);
480
    $entityManager->expects(self::once())->method('persist');
481
    $service = $this->prepareUpdateRankingFrom($ranking, $entityManager);
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...
482
    /** @noinspection PhpUnhandledExceptionInspection */
483
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
484
    $repository = $this->createStub(ObjectRepository::class, ['findBy' => [$change]]);
485
    $entityManager->method('getRepository')->willReturn($repository);
486
    $foundChange = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
487
    self::assertNotEquals($change, $foundChange);
488
  }
489
490
  /**
491
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
492
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
493
   * @uses   \Tfboe\FmLib\Entity\RankingSystemChange::__construct
494
   * @uses   \Tfboe\FmLib\Entity\RankingSystemChange
495
   * @uses   \Tfboe\FmLib\Entity\RankingSystemList
496
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
497
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
498
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
499
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
500
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
501
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
502
   */
503
  public function testGetOrCreateGetDeletedChangeTwice()
504
  {
505
    [$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...
506
    $change = $this->createStub(RankingSystemChange::class,
507
      ['getRankingSystem' => $ranking, 'getPlayer' => $player, 'getHierarchyEntity' => $entity]);
508
509
    $entityManager = $this->getEntityManagerMockForQuery([$change], null, ['persist', 'remove', 'getRepository']);
510
    $entityManager->expects(self::once())->method('persist');
511
    $service = $this->prepareUpdateRankingFrom($ranking, $entityManager);
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...
512
    /** @noinspection PhpUnhandledExceptionInspection */
513
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
514
    $repository = $this->createStub(ObjectRepository::class, ['findBy' => [$change]]);
515
    $entityManager->method('getRepository')->willReturn($repository);
516
    $foundChange = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
517
    self::assertNotEquals($change, $foundChange);
518
    $foundChange2 = static::callProtectedMethod($service, 'getOrCreateChange', [$entity, $ranking, $player]);
519
    self::assertEquals($foundChange, $foundChange2);
520
  }
521
522
  /**
523
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
524
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::startPoints
525
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
526
   * @uses   \Tfboe\FmLib\Entity\RankingSystemListEntry
527
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
528
   */
529
  public function testGetOrCreateRankingSystemListEntryExistingEntry()
530
  {
531
    $player = $this->createStubWithId(Player::class, 1, 'getPlayerId');
532
    $entries = new ArrayCollection([]);
533
    $list = $this->createStub(RankingSystemList::class, ['getEntries' => $entries]);
534
    $entry = $this->createStub(RankingSystemListEntry::class,
535
      ['getPlayer' => $player, 'getRankingSystemList' => $list]);
536
    $entries->set(1, $entry);
537
538
    /** @var RankingSystemService $service */
539
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [], '', false);
540
    $foundEntry = static::callProtectedMethod($service, 'getOrCreateRankingSystemListEntry', [$list, $player]);
541
    self::assertEquals($entry, $foundEntry);
542
  }
543
544
  /**
545
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
546
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::startPoints
547
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
548
   * @uses   \Tfboe\FmLib\Entity\RankingSystemListEntry
549
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
550
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::setProperty
551
   */
552
  public function testGetOrCreateRankingSystemListEntryNewEntry()
553
  {
554
    $player = $this->createStubWithId(Player::class, 1, 'getPlayerId');
555
    $entries = new ArrayCollection([]);
556
    $list = $this->createStub(RankingSystemList::class, ['getEntries' => $entries]);
557
558
    /** @var RankingSystemListEntry $createdEntry */
559
    $createdEntry = null;
560
    $entityManager = $this->createMock(EntityManager::class);
561
    $entityManager->expects(self::once())->method('persist')->willReturnCallback(
562
      function (RankingSystemListEntry $entry) use (&$createdEntry, $player, $list) {
563
        $createdEntry = $entry;
564
      });
565
566
567
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [$entityManager,
568
      $this->createMock(TimeServiceInterface::class), $this->createMock(EntityComparerInterface::class)]);
569
    $service->method('getAdditionalFields')->willReturn(['additional' => 0.0]);
570
    /** @var RankingSystemService $service */
571
572
    $entry = static::callProtectedMethod($service, 'getOrCreateRankingSystemListEntry', [$list, $player]);
573
    self::assertEquals($createdEntry, $entry);
574
    self::assertInstanceOf(RankingSystemListEntry::class, $entry);
575
    self::assertEquals($player, $entry->getPlayer());
576
    self::assertEquals($list, $entry->getRankingSystemList());
577
    self::assertEquals(1, $entries->count());
578
    self::assertEquals($entry, $entries[1]);
579
  }
580
581
  /**
582
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
583
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
584
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
585
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
586
   * @uses   \Tfboe\FmLib\Tests\Entity\Tournament
587
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
588
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
589
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
590
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
591
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
592
   */
593
  public function testUpdateRankingForTournamentOldEarliestIsEarlier()
594
  {
595
    $ranking = $this->createStubWithId(RankingSystem::class);
596
    $timeService = $this->createMock(TimeServiceInterface::class);
597
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
598
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
599
      return $entity->getEndTime();
600
    })->after('clearTimes');
601
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
602
      [$this->createMock(EntityManagerInterface::class),
603
        $timeService,
604
        $this->createMock(EntityComparerInterface::class)], '', true, true, true, ['updateRankingFrom']);
605
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
606
    /** @var RankingSystem $ranking */
607
    $tournament = new Tournament();
608
    $endedAt = new \DateTime("2017-02-01 00:00:00");
609
    $tournament->setUpdatedAt($endedAt);
610
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
611
    $oldInfluence = new \DateTime("2017-01-01 00:00:00");
612
    $service->expects(static::once())
613
      ->method('updateRankingFrom')
614
      ->with($ranking, new \DateTime("2017-01-01 00:00:00"));
615
616
    /** @var RankingSystemService $service */
617
    $service->updateRankingForTournament($ranking, $tournament, $oldInfluence);
618
  }
619
620
  /**
621
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
622
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
623
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
624
   * @uses   \Tfboe\FmLib\Tests\Entity\Tournament
625
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
626
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
627
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
628
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
629
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
630
   */
631
  public function testUpdateRankingForTournamentOldEarliestIsNotNullAndTournamentNotRanked()
632
  {
633
    $ranking = $this->createStubWithId(RankingSystem::class);
634
    /** @var RankingSystem $ranking */
635
    $tournament = new Tournament();
636
    $endedAt = new \DateTime("2017-01-01 00:00:00");
637
    $tournament->setUpdatedAt($endedAt);
638
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
639
      [$this->createMock(EntityManagerInterface::class),
640
        $this->createMock(TimeServiceInterface::class),
641
        $this->createMock(EntityComparerInterface::class)], '', true, true, true, ['updateRankingFrom']);
642
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
643
    $oldInfluence = new \DateTime("2017-02-01 00:00:00");
644
    $service->expects(static::once())
645
      ->method('updateRankingFrom')
646
      ->with($ranking, new \DateTime("2017-02-01 00:00:00"));
647
648
    /** @var RankingSystemService $service */
649
    $service->updateRankingForTournament($ranking, $tournament, $oldInfluence);
650
  }
651
652
  /**
653
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
654
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
655
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
656
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
657
   * @uses   \Tfboe\FmLib\Tests\Entity\Tournament
658
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
659
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
660
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
661
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
662
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
663
   */
664
  public function testUpdateRankingForTournamentOldEarliestIsNull()
665
  {
666
    $ranking = $this->createStubWithId(RankingSystem::class);
667
    /** @var RankingSystem $ranking */
668
    $tournament = new Tournament();
669
    $endedAt = new \DateTime("2017-01-01 00:00:00");
670
    $tournament->setEndTime($endedAt);
671
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
672
    $timeService = $this->createMock(TimeServiceInterface::class);
673
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
674
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
675
      return $entity->getEndTime();
676
    })->after('clearTimes');
677
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
678
      [$this->createMock(EntityManagerInterface::class),
679
        $timeService,
680
        $this->createMock(EntityComparerInterface::class)], '', true, true, true, ['updateRankingFrom']);
681
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
682
    $service->expects(static::once())
683
      ->method('updateRankingFrom')
684
      ->with($ranking, new \DateTime("2017-01-01 00:00:00"));
685
686
    /** @var RankingSystemService $service */
687
    $service->updateRankingForTournament($ranking, $tournament, null);
688
  }
689
690
  /**
691
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
692
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
693
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
694
   * @uses   \Tfboe\FmLib\Tests\Entity\Tournament
695
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
696
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestEntityInfluence
697
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEarliestInfluence
698
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::__construct
699
   * @uses   \Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity::getRankingSystems
700
   */
701
  public function testUpdateRankingForTournamentOldEarliestIsNullAndTournamentNotRanked()
702
  {
703
    $ranking = $this->createStubWithId(RankingSystem::class);
704
    /** @var RankingSystem $ranking */
705
    $tournament = new Tournament();
706
    $endedAt = new \DateTime("2017-01-01 00:00:00");
707
    $tournament->setUpdatedAt($endedAt);
708
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
709
      [$this->createMock(EntityManagerInterface::class), $this->createMock(TimeServiceInterface::class),
710
        $this->createMock(EntityComparerInterface::class)], '', true, true, true, ['updateRankingFrom']);
711
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
712
    $service->expects(self::never())
713
      ->method('updateRankingFrom');
714
715
    /** @var RankingSystemService $service */
716
    $service->updateRankingForTournament($ranking, $tournament, null);
717
  }
718
719
  //TODO split this up in multiple unit tests!!!
720
721
  /**
722
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingForTournament
723
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimeEntity
724
   * @uses   \Tfboe\FmLib\Entity\Helpers\TimestampableEntity
725
   * @uses   \Tfboe\FmLib\Entity\Traits\Tournament
726
   * @uses   \Tfboe\FmLib\Tests\Entity\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 testUpdateRankingForTournamentTournamentIsEarlier()
734
  {
735
    $ranking = $this->createStubWithId(RankingSystem::class);
736
    /** @var RankingSystem $ranking */
737
    $tournament = new Tournament();
738
    $endedAt = new \DateTime("2017-01-01");
739
    $tournament->setEndTime($endedAt);
740
    $tournament->getRankingSystems()->set($ranking->getId(), $ranking);
741
    $timeService = $this->createMock(TimeServiceInterface::class);
742
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
743
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
744
      return $entity->getEndTime();
745
    })->after('clearTimes');
746
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
747
      [$this->createMock(EntityManagerInterface::class),
748
        $timeService,
749
        $this->createMock(EntityComparerInterface::class)], '', true, true, true, ['updateRankingFrom']);
750
    $service->method("getLevel")->willReturn(Level::TOURNAMENT);
751
    $oldInfluence = new \DateTime("2017-02-01");
752
    $service->expects(static::once())
753
      ->method('updateRankingFrom')
754
      ->with($ranking, new \DateTime("2017-01-01"));
755
756
    /** @var RankingSystemService $service */
757
    $service->updateRankingForTournament($ranking, $tournament, $oldInfluence);
758
  }
759
760
  /**
761
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
762
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
763
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
764
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
765
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
766
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
767
   * @uses   \Tfboe\FmLib\Entity\RankingSystemListEntry
768
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::cloneSubClassDataFrom
769
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
770
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
771
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::getProperty
772
   * @uses   \Tfboe\FmLib\Entity\Helpers\SubClassData::setProperty
773
   * @uses   \Tfboe\FmLib\Entity\RankingSystemChange
774
   */
775
  public function testUpdateRankingFrom()
776
  {
777
    //create mock for input
778
    $ranking = $this->createStubWithId(RankingSystem::class);
779
780
    //create mocks for ranking lists
781
    $list1 = $this->createMock(RankingSystemList::class);
782
    $list1->method('isCurrent')->willReturn(false);
783
    $list1->method('getLastEntryTime')->willReturn(new \DateTime("2017-01-01"));
784
785
    $entry1 = $this->createEmptyEntry();
786
    $entry2 = $this->createEmptyEntry();
787
    $entry3 = $this->createEmptyEntry();
788
789
    $list2 = $this->createMock(RankingSystemList::class);
790
    $list2->method('isCurrent')->willReturn(false);
791
    $list2->method('getLastEntryTime')->willReturn(new \DateTime("2017-02-01"));
792
    $list2->method('getEntries')->willReturn(new ArrayCollection([1 => $entry1, 3 => $entry3]));
793
794
    $list3 = $this->createMock(RankingSystemList::class);
795
    $list3->method('isCurrent')->willReturn(false);
796
    $list3->method('getLastEntryTime')->willReturn(new \DateTime("2017-03-01"));
797
    $list3->method('getEntries')->willReturn(new ArrayCollection([1 => $entry1, 2 => $entry2]));
798
799
    $list4 = $this->createMock(RankingSystemList::class);
800
    $list4->method('isCurrent')->willReturn(false);
801
    $list4->method('getLastEntryTime')->willReturn(new \DateTime("2017-04-01"));
802
    $list4->method('getEntries')->willReturn(new ArrayCollection());
803
804
    $list5 = $this->createMock(RankingSystemList::class);
805
    $list5->method('isCurrent')->willReturn(true);
806
    $list5->method('getLastEntryTime')->willReturn(new \DateTime("2017-05-01"));
807
    $list5->method('getEntries')->willReturn(new ArrayCollection());
808
809
    $lists = $this->createMock(Collection::class);
810
    $lists->expects(static::once())->method('toArray')->willReturn([$list1, $list2, $list3, $list4, $list5]);
811
812
    //finish mock for input
813
    $ranking->expects(static::once())->method('getLists')->willReturn($lists);
814
815
    //create time service, entity comparer and ranking service mock
816
    $timeService = $this->createMock(TimeServiceInterface::class);
817
    $timeService->expects(self::atLeastOnce())->method('clearTimes')->id('clearTimes');
818
    $timeService->method('getTime')->willReturnCallback(function (TournamentHierarchyInterface $entity) {
819
      return $entity->getEndTime();
820
    })->after('clearTimes');
821
    $entityComparer = $this->createMock(EntityComparerInterface::class);
822
    $entityComparer->method('compareEntities')->willReturnCallback(
823
      function (TournamentHierarchyInterface $entity1, TournamentHierarchyInterface $entity2) {
824
        return $entity1->getEndTime() <=> $entity2->getEndTime();
825
      });
826
    $entityManager = $this->getEntityManagerMockForQuery([],
827
      'SELECT c FROM Tfboe\FmLib\Entity\RankingSystemChange c WHERE c.hierarchyEntity IN(:entities)', ['persist',
828
        'remove']);
829
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
830
      [$entityManager,
831
        $timeService,
832
        $this->createMock(EntityComparerInterface::class)]);
833
834
    //create entities mocks
835
    $entity1 = $this->createStubWithId(TournamentHierarchyEntity::class, "e1");
836
    $entity1->method('getEndTime')->willReturn(new \DateTime("2017-03-01"));
837
838
    $entity2 = $this->createStubWithId(TournamentHierarchyEntity::class, "e2");
839
    $entity2->method('getEndTime')->willReturn(new \DateTime("2017-02-01 00:00:01"));
840
841
    $entity3 = $this->createStubWithId(TournamentHierarchyEntity::class, "e3");
842
    $entity3->method('getEndTime')->willReturn(new \DateTime("2017-05-02"));
843
844
    $entity4 = $this->createStubWithId(TournamentHierarchyEntity::class, "e4");
845
    $entity4->method('getEndTime')->willReturn(new \DateTime("2017-03-02"));
846
847
    $parent = $this->createStubWithId(TournamentHierarchyEntity::class, "e4");
848
    $parent->method('getEndTime')->willReturn(new \DateTime("2017-12-02"));
849
    $entity4->method('getParent')->willReturn($parent);
850
851
    //create query mock for getEntities
852
    $query = $this->createMock(AbstractQuery::class);
853
    $query->expects(static::once())->method('getResult')->willReturn([$entity1, $entity2, $entity3, $entity4]);
854
    //create query builder mock for getEntities
855
    $queryBuilder = $this->createMock(QueryBuilder::class);
856
    $queryBuilder->expects(static::once())->method('getQuery')->willReturn($query);
857
    $service->expects(static::once())->method('getEntitiesQueryBuilder')
858
      ->with($ranking, new \DateTime("2017-02-01"))->willReturn($queryBuilder);
859
    $changes = [
860
      $this->createEmptyChange(),
861
      $this->createEmptyChange(),
862
    ];
863
    $service->method('getChanges')->willReturn($changes);
864
    $service->method('getAdditionalFields')->willReturn(['additional' => 0.0]);
865
866
    /** @var RankingSystemService $service */
867
    /** @var RankingSystem $ranking */
868
    /** @noinspection PhpUnhandledExceptionInspection */
869
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
870
  }
871
872
  /**
873
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
874
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
875
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
876
   * @uses   \Tfboe\FmLib\Entity\RankingSystemList
877
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
878
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
879
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
880
   */
881
  public function testUpdateRankingFromCalledTwice()
882
  {
883
    $ranking = $this->createStubWithId(RankingSystem::class);
884
    $service = $this->prepareUpdateRankingFrom($ranking);
885
886
    /** @var RankingSystem $ranking */
887
888
    /** @noinspection PhpUnhandledExceptionInspection */
889
    $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\RankingSystem>.

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...
890
891
    $this->expectException(PreconditionFailedException::class);
892
893
    /** @noinspection PhpUnhandledExceptionInspection */
894
    $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\RankingSystem>.

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...
895
  }
896
897
  /**
898
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
899
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
900
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
901
   * @uses   \Tfboe\FmLib\Entity\RankingSystemList
902
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
903
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
904
   * @uses   \Tfboe\FmLib\Entity\Helpers\UUIDEntity::getId
905
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
906
   */
907
  public function testUpdateRankingFromNoCurrent()
908
  {
909
    //create mock for input
910
    $ranking = $this->createStubWithId(RankingSystem::class, 'r1');
911
912
    //create mocks for ranking lists
913
    $list = $this->createMock(RankingSystemList::class);
914
    $list->method('isCurrent')->willReturn(false);
915
    $list->method('getLastEntryTime')->willReturn(new \DateTime("2017-01-01"));
916
    $list->method('getEntries')->willReturn(new ArrayCollection());
917
918
    $lists = $this->createMock(Collection::class);
919
    $lists->expects(static::once())->method('toArray')->willReturn([$list]);
920
    $lists->expects(static::once())->method('set')->with('new')->willReturnSelf();
921
922
    //finish mock for input
923
    $ranking->expects(static::exactly(2))->method('getLists')->willReturn($lists);
924
925
    //create service mock
926
    $entityManager = $this->getEntityManagerMockForQuery([],
927
      'SELECT c FROM Tfboe\FmLib\Entity\RankingSystemChange c WHERE c.hierarchyEntity IN(:entities)', ['persist']);
928
    $entityManager->expects(static::once())->method('persist')->willReturnCallback(
929
      function (RankingSystemList $entity) {
930
        self::assertInstanceOf(RankingSystemList::class, $entity);
931
        self::assertTrue($entity->isCurrent());
932
        static::getProperty(get_class($entity), 'id')->setValue($entity, 'new');
933
      });
934
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [$entityManager,
935
      $this->createMock(TimeServiceInterface::class), $this->createMock(EntityComparerInterface::class)]);
936
937
    //create query mock for getEntities
938
    $query = $this->createMock(AbstractQuery::class);
939
    $query->expects(static::once())->method('getResult')->willReturn([]);
940
    //create query builder mock for getEntities
941
    $queryBuilder = $this->createMock(QueryBuilder::class);
942
    $queryBuilder->expects(static::once())->method('getQuery')->willReturn($query);
943
    $service->expects(static::once())->method('getEntitiesQueryBuilder')
944
      ->with($ranking, new \DateTime("2017-01-01"))->willReturn($queryBuilder);
945
946
    /** @var RankingSystemService $service */
947
    /** @var RankingSystem $ranking */
948
    /** @noinspection PhpUnhandledExceptionInspection */
949
    /** @noinspection PhpUnhandledExceptionInspection */
950
    /** @noinspection PhpUnhandledExceptionInspection */
951
    /** @noinspection PhpUnhandledExceptionInspection */
952
    $service->updateRankingFrom($ranking, new \DateTime('2017-02-28'));
953
  }
954
955
  /**
956
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::updateRankingFrom
957
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::recomputeBasedOn
958
   * @covers \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::cloneInto
959
   * @uses   \Tfboe\FmLib\Entity\RankingSystemList
960
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
961
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntities
962
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::deleteOldChanges
963
   */
964
  public function testUpdateRankingFromNoReusable()
965
  {
966
    $ranking = $this->createStubWithId(RankingSystem::class);
967
    $service = $this->prepareUpdateRankingFrom($ranking);
968
969
    /** @var RankingSystem $ranking */
970
971
    /** @var RankingSystemService $service */
972
    /** @var RankingSystem $ranking */
973
    /** @noinspection PhpUnhandledExceptionInspection */
974
    $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\RankingSystem>.

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...
975
  }
976
//</editor-fold desc="Public Methods">
977
978
//<editor-fold desc="Private Methods">
979
  /**
980
   * Creates an empty RankingSystemChange
981
   * @return MockObject|RankingSystemChange
982
   */
983
  private function createEmptyChange(): MockObject
984
  {
985
    $change = $this->getMockForAbstractClass(RankingSystemChange::class, [['additional']], '', true, true, true,
986
      ['getPlayer', 'getPointsChange']);
987
    return $change;
988
  }
989
990
  /**
991
   * Creates an empty RankingSystemListEntry
992
   * @return MockObject|RankingSystemListEntry
993
   */
994
  private function createEmptyEntry(): MockObject
995
  {
996
    $entry = $this->getMockForAbstractClass(RankingSystemListEntry::class, [['additional']], '', true, true, true,
997
      ['getPlayer', 'getPoints']);
998
    return $entry;
999
  }
1000
1001
  /**
1002
   * Creates different entities used for create change
1003
   * @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...
1004
   */
1005
  private function createEntities()
1006
  {
1007
    $entity = $this->createStubWithId(TournamentHierarchyEntity::class, 'h1');
1008
    $ranking = $this->createStubWithId(RankingSystem::class, 'r1');
1009
    $player = $this->createStubWithId(Player::class, 1, 'getPlayerId');
1010
    return [$entity, $ranking, $player];
1011
  }
1012
1013
  /**
1014
   * Prepares a ranking system service for creating a change
1015
   * @param ObjectRepository|null $repository the used repository, if not set a stub which finds the empty list is used
1016
   * @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...
1017
   */
1018
  private function prepareCreateChange(?ObjectRepository $repository = null)
1019
  {
1020
    if ($repository === null) {
1021
      $repository = $this->createStub(ObjectRepository::class, ['findBy' => []]);
1022
    }
1023
    $entityManager = $this->createStub(EntityManager::class, ['getRepository' => $repository]);
1024
    /** @var $service RankingSystemService */
1025
    $service = $this->getMockForAbstractClass(RankingSystemService::class, [
1026
      $entityManager, $this->createMock(TimeServiceInterface::class),
1027
      $this->createMock(EntityComparerInterface::class)
1028
    ]);
1029
    return [$service, $entityManager];
1030
  }
1031
1032
  /**
1033
   * prepares a new ranking system service for update ranking from
1034
   * @param MockObject $ranking the ranking entity
1035
   * @param EntityManagerInterface|null $entityManager the entity manager or null if a mock should be used
1036
   * @return RankingSystemService
1037
   */
1038
  private function prepareUpdateRankingFrom(MockObject $ranking, ?EntityManagerInterface $entityManager = null)
1039
  {
1040
    if ($entityManager === null) {
1041
      $entityManager = $this->getEntityManagerMockForQuery([]);
1042
    }
1043
    $service = $this->getMockForAbstractClass(RankingSystemService::class,
1044
      [$entityManager, $this->createMock(TimeServiceInterface::class),
1045
        $this->createMock(EntityComparerInterface::class)]);
1046
1047
    //create mocks for current lists
1048
    $list = $this->createMock(RankingSystemList::class);
1049
    $list->method('isCurrent')->willReturn(true);
1050
    $list->method('getLastEntryTime')->willReturn(new \DateTime("2017-06-01"));
1051
    $list->method('getEntries')->willReturn(new ArrayCollection());
1052
1053
    $lists = $this->createMock(Collection::class);
1054
    $lists->expects(static::once())->method('toArray')->willReturn([$list]);
1055
1056
    //finish mock for input
1057
    $ranking->method('getLists')->willReturn($lists);
1058
1059
    //create query mock for getEntities
1060
    $query = $this->createMock(AbstractQuery::class);
1061
    $query->expects(static::once())->method('getResult')->willReturn([]);
1062
    //create query builder mock for getEntities
1063
    $queryBuilder = $this->createMock(QueryBuilder::class);
1064
    $queryBuilder->expects(static::once())->method('getQuery')->willReturn($query);
1065
    $service->expects(static::once())->method('getEntitiesQueryBuilder')
1066
      ->with($ranking, new \DateTime("2000-01-01"))->willReturn($queryBuilder);
1067
    /** @var $service RankingSystemService */
1068
1069
    return $service;
1070
  }
1071
//</editor-fold desc="Private Methods">
1072
}