Completed
Pull Request — master (#39)
by Matthieu
08:47
created

JWTUserProviderTest::testItDecodesAToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 14
nc 1
nop 6
dl 0
loc 19
rs 9.7998
c 0
b 0
f 0
1
<?php declare(strict_types = 1);
2
3
namespace AtlassianConnectBundle\Tests\Security;
4
5
use AtlassianConnectBundle\Entity\Tenant;
6
use AtlassianConnectBundle\Entity\TenantInterface;
7
use AtlassianConnectBundle\Security\JWTUserProvider;
8
use Doctrine\ORM\EntityManagerInterface;
9
use Doctrine\ORM\EntityRepository;
10
use PHPUnit\Framework\MockObject\MockObject;
11
use PHPUnit\Framework\TestCase;
12
use Symfony\Component\Security\Core\User\UserInterface;
13
14
/**
15
 * Class JWTUserProviderTest
16
 */
17
final class JWTUserProviderTest extends TestCase
18
{
19
    /**
20
     * @var EntityManagerInterface|MockObject
21
     */
22
    private $entityManager;
23
24
    /**
25
     * @var JWTUserProvider
26
     */
27
    private $userProvider;
28
29
    /**
30
     * @var EntityRepository|MockObject
31
     */
32
    private $entityRepository;
33
34
    /**
35
     * Setup properties
36
     */
37
    protected function setUp(): void
38
    {
39
        $this->entityManager = $this->createMock(EntityManagerInterface::class);
40
41
        $this->entityRepository = $this->createMock(EntityRepository::class);
42
        $this->entityManager
43
            ->method('getRepository')
0 ignored issues
show
Bug introduced by
The method method() does not exist on PHPUnit\Framework\MockObject\MockObject. ( Ignorable by Annotation )

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

43
            ->/** @scrutinizer ignore-call */ 
44
              method('getRepository')

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...
44
            ->willReturn($this->entityRepository);
45
46
        $this->userProvider = new JWTUserProvider(
47
            $this->entityManager,
48
            Tenant::class
49
        );
50
    }
51
52
    /**
53
     * @dataProvider jwtTokenProvider
54
     *
55
     * @param string $jwt
56
     * @param string $secret
57
     * @param string $isstoken
58
     * @param string $sub
59
     * @param string $name
60
     * @param int    $iat
61
     */
62
    public function testItDecodesAToken(string $jwt, string $secret, string $isstoken, string $sub, string $name, int $iat): void
63
    {
64
        $tenant = $this->createMock(TenantInterface::class);
65
        $tenant
66
            ->expects($this->once())
67
            ->method('getSharedSecret')
68
            ->willReturn($secret);
69
70
        $this->entityRepository->expects($this->once())
71
            ->method('findOneBy')
72
            ->with(['clientKey' => $isstoken])
73
            ->willReturn($tenant);
74
75
        $token = $this->userProvider->getDecodedToken($jwt);
76
77
        $this->assertEquals($sub, $token->sub);
78
        $this->assertEquals($name, $token->name);
79
        $this->assertEquals($isstoken, $token->iss);
80
        $this->assertEquals($iat, $token->iat);
81
    }
82
83
    /**
84
     * @return \Generator
85
     */
86
    public function jwtTokenProvider(): \Generator
87
    {
88
        yield [
89
            'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJpc3MiOiJpc3N0b2tlbiJ9.vcwW8PMPwPF2E-CkWflDrhAulR5dPWbbl-lOJheOwIY',
90
            'secret',
91
            'isstoken',
92
            '1234567890',
93
            'John Doe',
94
            1516239022,
95
        ];
96
        yield [
97
            'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5ODc2NTQzMjEwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNTE2MjM5MDIzLCJpc3MiOiJhbm90aGVySXNzVG9rZW4ifQ.wzTiSSNtS6rXoAYXL4tdmVzEbUvRd7BSuMq3kbboSA4',
98
            'anotherSecret',
99
            'anotherIssToken',
100
            '9876543210',
101
            'Jane Doe',
102
            1516239023,
103
        ];
104
    }
105
106
    /**
107
     * test loadUserByUsername method
108
     */
109
    public function testLoadsUserByUserName(): void
110
    {
111
        $tenant = $this->createMock(TenantInterface::class);
112
113
        $this->entityRepository
114
            ->expects($this->once())
115
            ->method('findOneBy')
116
            ->with([
117
                'clientKey' => 'key',
118
            ])
119
            ->willReturn($tenant);
120
121
        $result = $this->userProvider->loadUserByUsername('key');
122
        $this->assertSame($result, $tenant);
123
    }
124
125
    /**
126
     * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
127
     */
128
    public function testItFailsToLoadAUserByUserName(): void
129
    {
130
        $this->entityRepository
131
            ->expects($this->once())
132
            ->method('findOneBy')
133
            ->with([
134
                'clientKey' => 'key',
135
            ])
136
            ->willReturn(null);
137
138
        $this->userProvider->loadUserByUsername('key');
139
    }
140
141
    /**
142
     * @expectedException \Symfony\Component\Security\Core\Exception\UnsupportedUserException
143
     */
144
    public function testRefreshUserIsNotSupported(): void
145
    {
146
        $this->userProvider->refreshUser($this->createMock(UserInterface::class));
147
    }
148
149
    /**
150
     * @param mixed $class
151
     * @param bool  $isSupported
152
     *
153
     * @dataProvider classProvider
154
     */
155
    public function testItSupportsAclass($class, bool $isSupported): void
156
    {
157
        $result = $this->userProvider->supportsClass($class);
158
159
        $this->assertEquals($isSupported, $result);
160
    }
161
162
    /**
163
     * @return \Generator
164
     */
165
    public function classProvider(): \Generator
166
    {
167
        yield [new Tenant(), true];
168
        yield [new StubbedTenant(), true];
169
        yield [new \stdClass(), false];
170
    }
171
}
172