PlayerServiceTest   A
last analyzed

Complexity

Total Complexity 4

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 150
rs 10
wmc 4
lcom 1
cbo 3

4 Methods

Rating   Name   Duplication   Size   Complexity  
A testConstruct() 0 11 1
A testMergeBothPlayersInSameTournament() 0 39 1
A testMergeIdenticalPlayer() 0 14 1
B testMergePlayer() 0 63 1
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Created by PhpStorm.
5
 * User: benedikt
6
 * Date: 1/3/18
7
 * Time: 3:53 PM
8
 */
9
10
namespace Tfboe\FmLib\Tests\Unit\Service;
11
12
use Doctrine\Common\Collections\ArrayCollection;
13
use Doctrine\ORM\EntityManagerInterface;
14
use PHPUnit\Framework\MockObject\MockObject;
15
use Tfboe\FmLib\Entity\CompetitionInterface;
16
use Tfboe\FmLib\Entity\GameInterface;
17
use Tfboe\FmLib\Entity\MatchInterface;
18
use Tfboe\FmLib\Entity\PhaseInterface;
19
use Tfboe\FmLib\Entity\PlayerInterface;
20
use Tfboe\FmLib\Entity\TeamInterface;
21
use Tfboe\FmLib\Entity\TeamMembershipInterface;
22
use Tfboe\FmLib\Entity\TournamentInterface;
23
use Tfboe\FmLib\Service\DeletionServiceInterface;
24
use Tfboe\FmLib\Service\LoadingServiceInterface;
25
use Tfboe\FmLib\Service\PlayerService;
26
use Tfboe\FmLib\Service\RankingSystemServiceInterface;
27
use Tfboe\FmLib\Tests\Helpers\UnitTestCase;
28
29
30
/**
31
 * Class DeletionServiceTest
32
 * @package Tfboe\FmLib\Tests\Unit\Service
33
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
34
 */
35
class PlayerServiceTest extends UnitTestCase
36
{
37
//<editor-fold desc="Public Methods">
38
  /**
39
   * @covers \Tfboe\FmLib\Service\PlayerService::__construct
40
   */
41
  public function testConstruct()
42
  {
43
    /** @var EntityManagerInterface $em */
44
    $em = $this->createMock(EntityManagerInterface::class);
45
    /** @var LoadingServiceInterface $ls */
46
    $ls = $this->createMock(LoadingServiceInterface::class);
47
    /** @var RankingSystemServiceInterface $rankingSystemService */
48
    $rankingSystemService = $this->createMock(RankingSystemServiceInterface::class);
49
    $service = new PlayerService($em, $ls, $rankingSystemService);
50
    self::assertInstanceOf(PlayerService::class, $service);
51
  }
52
53
  /**
54
   * @covers \Tfboe\FmLib\Service\PlayerService::mergePlayers
55
   * @uses   \Tfboe\FmLib\Service\PlayerService::__construct
56
   */
57
  public function testMergeBothPlayersInSameTournament()
58
  {
59
    $player1 = $this->createStubWithId(PlayerInterface::class, "p1");
60
    $player2 = $this->createStubWithId(PlayerInterface::class, "p2");
61
    $team1 = $this->createStub(TeamInterface::class, [
62
      'getMemberships' => new ArrayCollection([$this->createStub(TeamMembershipInterface::class, [
63
        'getPlayer' => $player1
64
      ])])
65
    ]);
66
    $team2 = $this->createStub(TeamInterface::class, [
67
      'getMemberships' => new ArrayCollection([$this->createStub(TeamMembershipInterface::class, [
68
        'getPlayer' => $player2
69
      ])])
70
    ]);
71
72
    $competition = $this->createStub(CompetitionInterface::class, [
73
      'getTeams' => new ArrayCollection([$team1, $team2])
74
    ]);
75
76
    $tournament = $this->createStub(TournamentInterface::class, [
77
      'getCompetitions' => new ArrayCollection([$competition]),
78
      'getName' => 'Tournament',
79
      'getId' => 't',
80
      'getStartTime' => new \DateTime("2000-01-01")
81
    ]);
82
83
    /** @var EntityManagerInterface $em */
84
    $em = $this->getEntityManagerMockForQuery([$tournament],
85
      'SELECT t FROM Tfboe\FmLib\Entity\TournamentInterface t INNER JOIN t.competitions c INNER JOIN c.teams te ' .
86
      'INNER JOIN te.memberships m WHERE m.player = (:id)');
87
88
    $service = new PlayerService($em,
89
      $this->createStub(LoadingServiceInterface::class),
0 ignored issues
show
Documentation introduced by
$this->createStub(\Tfboe...erviceInterface::class) is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Servi...oadingServiceInterface>.

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...
90
      $this->createStub(RankingSystemServiceInterface::class)
0 ignored issues
show
Documentation introduced by
$this->createStub(\Tfboe...erviceInterface::class) is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Servi...SystemServiceInterface>.

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...
91
    );
92
93
    self::assertEquals('Player 1 and player 2 both attended the tournament Tournament(01.01.2000 00:00, id=\'t\')',
94
      $service->mergePlayers($player1, $player2));
0 ignored issues
show
Documentation introduced by
$player1 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Entity\PlayerInterface>.

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...
Documentation introduced by
$player2 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Entity\PlayerInterface>.

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...
95
  }
96
97
  /**
98
   * @covers \Tfboe\FmLib\Service\PlayerService::mergePlayers
99
   * @uses   \Tfboe\FmLib\Service\PlayerService::__construct
100
   */
101
  public function testMergeIdenticalPlayer()
102
  {
103
    $player1 = $this->createStubWithId(PlayerInterface::class, "p1");
104
    $player2 = $this->createStubWithId(PlayerInterface::class, "p1");
105
106
107
    $service = new PlayerService(
108
      $this->createStub(EntityManagerInterface::class),
0 ignored issues
show
Documentation introduced by
$this->createStub(\Doctr...anagerInterface::class) is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

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...
109
      $this->createStub(LoadingServiceInterface::class),
0 ignored issues
show
Documentation introduced by
$this->createStub(\Tfboe...erviceInterface::class) is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Servi...oadingServiceInterface>.

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...
110
      $this->createStub(RankingSystemServiceInterface::class)
0 ignored issues
show
Documentation introduced by
$this->createStub(\Tfboe...erviceInterface::class) is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Servi...SystemServiceInterface>.

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...
111
    );
112
113
    self::assertEquals('Players are identical!', $service->mergePlayers($player1, $player2));
0 ignored issues
show
Documentation introduced by
$player1 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Entity\PlayerInterface>.

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...
Documentation introduced by
$player2 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Entity\PlayerInterface>.

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...
114
  }
115
116
  /**
117
   * @covers \Tfboe\FmLib\Service\PlayerService::mergePlayers
118
   * @uses   \Tfboe\FmLib\Service\PlayerService::__construct
119
   */
120
  public function testMergePlayer()
121
  {
122
    $tournament = $this->createStub(TournamentInterface::class);
123
    $player1 = $this->createStubWithId(PlayerInterface::class, "p1");
124
    $player2 = $this->createStubWithId(PlayerInterface::class, "p2");
125
    $otherPlayer = $this->createStubWithId(PlayerInterface::class, "oP");
126
    $team1Membership = $this->createStub(TeamMembershipInterface::class, ['getPlayer' => $player2]);
127
    $team1Membership->method('setPlayer')->with($player1);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

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...
128
    $team1 = $this->createStub(TeamInterface::class, [
129
      'getMemberships' => new ArrayCollection([$team1Membership])
130
    ]);
131
    $otherTeam = $this->createStub(TeamInterface::class, [
132
      'getMemberships' => new ArrayCollection([$this->createStub(TeamMembershipInterface::class, [
133
        'getPlayer' => $otherPlayer
134
      ])])
135
    ]);
136
137
    $game1PlayersB = new ArrayCollection([$player2->getId() => $player2]);
0 ignored issues
show
Bug introduced by
The method getId() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

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...
138
    $game1 = $this->createStub(GameInterface::class, [
139
      'getPlayersA' => new ArrayCollection([$otherPlayer->getId() => $otherPlayer]),
0 ignored issues
show
Bug introduced by
The method getId() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

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...
140
      'getPlayersB' => $game1PlayersB
141
    ]);
142
143
    $game2PlayersA = new ArrayCollection([$player2->getId() => $player2]);
0 ignored issues
show
Bug introduced by
The method getId() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

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...
144
    $game2 = $this->createStub(GameInterface::class, [
145
      'getPlayersA' => $game2PlayersA,
146
      'getPlayersB' => new ArrayCollection([$otherPlayer->getId() => $otherPlayer])
0 ignored issues
show
Bug introduced by
The method getId() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

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...
147
    ]);
148
149
    $competition = $this->createStub(CompetitionInterface::class, [
150
      'getTeams' => new ArrayCollection([$team1, $otherTeam]),
151
      'getPhases' => new ArrayCollection([$this->createStub(PhaseInterface::class, [
152
        'getMatches' => new ArrayCollection([$this->createStub(MatchInterface::class, [
153
          'getGames' => new ArrayCollection([$game1, $game2])
154
        ])])
155
      ])])
156
    ]);
157
158
159
    /** @var EntityManagerInterface $em */
160
    $em = $this->getEntityManagerMockForQuery([$tournament],
161
      'SELECT t FROM Tfboe\FmLib\Entity\TournamentInterface t INNER JOIN t.competitions c INNER JOIN c.teams te ' .
162
      'INNER JOIN te.memberships m WHERE m.player = (:id)');
163
    /** @var LoadingServiceInterface|MockObject $ls */
164
    $ls = $this->createMock(LoadingServiceInterface::class);
165
    $ls->expects(self::once())->method('loadEntities')->with([$tournament])->willReturnCallback(
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit\Framework\MockObject\MockObject, but not in Tfboe\FmLib\Service\LoadingServiceInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
166
      function ($a) use ($competition) {
167
        /** @var TournamentInterface|MockObject $t */
168
        $t = $a[0];
169
        $t->method('getCompetitions')->willReturn(new ArrayCollection([$competition]));
170
      });
171
172
    /** @var RankingSystemServiceInterface|MockObject $rankingSystemService */
173
    $rankingSystemService = $this->createMock(RankingSystemServiceInterface::class);
174
    $rankingSystemService->method('adaptOpenSyncFromValues')->with($tournament, []);
175
176
    $service = new PlayerService($em, $ls, $rankingSystemService);
0 ignored issues
show
Bug introduced by
It seems like $ls defined by $this->createMock(\Tfboe...erviceInterface::class) on line 164 can also be of type object<PHPUnit\Framework\MockObject\MockObject>; however, Tfboe\FmLib\Service\PlayerService::__construct() does only seem to accept object<Tfboe\FmLib\Servi...oadingServiceInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $rankingSystemService defined by $this->createMock(\Tfboe...erviceInterface::class) on line 173 can also be of type object<PHPUnit\Framework\MockObject\MockObject>; however, Tfboe\FmLib\Service\PlayerService::__construct() does only seem to accept object<Tfboe\FmLib\Servi...SystemServiceInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
177
178
    self::assertEquals(true, $service->mergePlayers($player1, $player2));
0 ignored issues
show
Documentation introduced by
$player1 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Entity\PlayerInterface>.

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...
Documentation introduced by
$player2 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Entity\PlayerInterface>.

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...
179
180
    self::assertEquals($game1PlayersB, new ArrayCollection([$player1->getId() => $player1]));
0 ignored issues
show
Bug introduced by
The method getId() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

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...
181
    self::assertEquals($game2PlayersA, new ArrayCollection([$player1->getId() => $player1]));
0 ignored issues
show
Bug introduced by
The method getId() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

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...
182
  }
183
//</editor-fold desc="Public Methods">
184
}