Completed
Push — master ( db359b...0e30e5 )
by Ross
13s
created

testAbstainOrDenyScenarios()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 12
rs 9.4285
c 1
b 0
f 0
cc 1
eloc 5
nc 1
nop 3
1
<?php
2
3
namespace League\Tactician\Bundle\Tests\Security\Voter;
4
5
use League\Tactician\Bundle\Security\Voter\HandleCommandVoter;
6
use League\Tactician\Bundle\Tests\Fake\FakeCommand;
7
use Mockery;
8
use Mockery\MockInterface;
9
use PHPUnit\Framework\TestCase;
10
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
11
use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
12
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
13
14
/**
15
 * Unit test for the handle command voter
16
 *
17
 * @author Ron Rademaker
18
 */
19
class HandleCommandVoterTest extends TestCase
20
{
21
    /**
22
     * @var AccessDecisionManager|MockInterface
23
     */
24
    private $decisionManager;
25
26
    public function setUp()
27
    {
28
        $this->decisionManager = Mockery::mock(AccessDecisionManager::class);
29
    }
30
31
    public function testAKnownCommandWillBeDelegatedToTheDecisionManager()
32
    {
33
        $tokenMock = Mockery::mock(TokenInterface::class);
34
35
        $voter = new HandleCommandVoter($this->decisionManager, [FakeCommand::class => ['ROLE_USER']]);
36
37
        $this->decisionManager
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Symfony\Component\Securi...n\AccessDecisionManager.

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...
38
            ->shouldReceive('decide')
39
            ->with($tokenMock, ['ROLE_USER'])
40
            ->andReturn(true)
41
            ->once();
42
43
        $this->assertEquals(VoterInterface::ACCESS_GRANTED, $voter->vote($tokenMock, new FakeCommand(), ['handle']));
44
    }
45
46
    /**
47
     * @dataProvider provideTestVoteData
48
     */
49
    public function testAbstainOrDenyScenarios($attribute, $subject, $expected)
50
    {
51
        // In the test cases provided, we either abstain from voting or refuse
52
        // to do it since there's no declared mapping. Therefore, it would be
53
        // an error to ever call the decision manager.
54
        $this->decisionManager->shouldReceive('decide')->never();
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Symfony\Component\Securi...n\AccessDecisionManager.

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...
55
56
        $voter = new HandleCommandVoter($this->decisionManager, []);
57
        $tokenMock = Mockery::mock(TokenInterface::class);
58
59
        $this->assertEquals($expected, $voter->vote($tokenMock, $subject, [$attribute]));
60
    }
61
62
    /**
63
     * Gets the testdata for the vote test.
64
     *
65
     * @return array
66
     */
67
    public function provideTestVoteData()
68
    {
69
        return [
70
            'abstain when not handling a command, but using the handle attribute' => [
71
                'handle',
72
                null,
73
                VoterInterface::ACCESS_ABSTAIN
74
            ],
75
            'abstain when not handling a command and not using the handle attribute' => [
76
                'create',
77
                null,
78
                VoterInterface::ACCESS_ABSTAIN
79
            ],
80
            'abstain when handling a command and not using the handle attribute' => [
81
                'create',
82
                new FakeCommand,
83
                VoterInterface::ACCESS_ABSTAIN
84
            ],
85
            'default access is false' => [
86
                'handle',
87
                new FakeCommand,
88
                VoterInterface::ACCESS_DENIED
89
            ],
90
        ];
91
    }
92
}
93