Passed
Push — master ( bfb540...645113 )
by Bukashk0zzz
01:23 queued 13s
created

JWTUserProviderTest::testItFailsToDecodeToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
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\Exception\AuthenticationException;
13
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
14
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
15
use Symfony\Component\Security\Core\User\UserInterface;
16
17
/**
18
 * Class JWTUserProviderTest
19
 */
20
final class JWTUserProviderTest extends TestCase
21
{
22
    /**
23
     * @var EntityManagerInterface|MockObject
24
     */
25
    private $entityManager;
26
27
    /**
28
     * @var JWTUserProvider
29
     */
30
    private $userProvider;
31
32
    /**
33
     * @var EntityRepository|MockObject
34
     */
35
    private $entityRepository;
36
37
    /**
38
     * Setup properties
39
     */
40
    protected function setUp(): void
41
    {
42
        $this->entityManager = $this->createMock(EntityManagerInterface::class);
43
44
        $this->entityRepository = $this->createMock(EntityRepository::class);
45
        $this->entityManager
46
            ->method('getRepository')
47
            ->willReturn($this->entityRepository);
48
49
        $this->userProvider = new JWTUserProvider(
50
            $this->entityManager,
51
            Tenant::class
52
        );
53
    }
54
55
    /**
56
     * @dataProvider jwtTokenProvider
57
     *
58
     * @param string $jwt
59
     * @param string $secret
60
     * @param string $isstoken
61
     * @param string $sub
62
     * @param string $name
63
     * @param int    $iat
64
     */
65
    public function testItDecodesAToken(string $jwt, string $secret, string $isstoken, string $sub, string $name, int $iat): void
66
    {
67
        $tenant = $this->createMock(TenantInterface::class);
68
        $tenant
69
            ->expects($this->once())
70
            ->method('getSharedSecret')
71
            ->willReturn($secret);
72
73
        $this->entityRepository->expects($this->once())
74
            ->method('findOneBy')
75
            ->with(['clientKey' => $isstoken])
76
            ->willReturn($tenant);
77
78
        $token = $this->userProvider->getDecodedToken($jwt);
79
80
        $this->assertEquals($sub, $token->sub);
81
        $this->assertEquals($name, $token->name);
82
        $this->assertEquals($isstoken, $token->iss);
83
        $this->assertEquals($iat, $token->iat);
84
    }
85
86
    /**
87
     * @return \Generator
88
     */
89
    public function jwtTokenProvider(): \Generator
90
    {
91
        yield [
92
            'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJpc3MiOiJpc3N0b2tlbiJ9.vcwW8PMPwPF2E-CkWflDrhAulR5dPWbbl-lOJheOwIY',
93
            'secret',
94
            'isstoken',
95
            '1234567890',
96
            'John Doe',
97
            1516239022,
98
        ];
99
100
        yield [
101
            'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5ODc2NTQzMjEwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNTE2MjM5MDIzLCJpc3MiOiJhbm90aGVySXNzVG9rZW4ifQ.wzTiSSNtS6rXoAYXL4tdmVzEbUvRd7BSuMq3kbboSA4',
102
            'anotherSecret',
103
            'anotherIssToken',
104
            '9876543210',
105
            'Jane Doe',
106
            1516239023,
107
        ];
108
    }
109
110
    /**
111
     * test decoded token fails
112
     */
113
    public function testItFailsToDecodeToken(): void
114
    {
115
        $this->expectException(AuthenticationException::class);
116
        $this->expectExceptionMessage('Failed to parse token');
117
        $this->userProvider->getDecodedToken('invalid_token');
118
    }
119
120
    /**
121
     * test loadUserByUsername method
122
     */
123
    public function testLoadsUserByUserName(): void
124
    {
125
        $tenant = $this->createMock(TenantInterface::class);
126
127
        $this->entityRepository
128
            ->expects($this->once())
129
            ->method('findOneBy')
130
            ->with([
131
                'clientKey' => 'key',
132
            ])
133
            ->willReturn($tenant);
134
135
        $result = $this->userProvider->loadUserByUsername('key');
136
        $this->assertSame($result, $tenant);
137
    }
138
139
    /**
140
     * Test it fails to load a user by user name
141
     */
142
    public function testItFailsToLoadAUserByUserName(): void
143
    {
144
        $this->expectException(UsernameNotFoundException::class);
145
146
        $this->entityRepository
147
            ->expects($this->once())
148
            ->method('findOneBy')
149
            ->with([
150
                'clientKey' => 'key',
151
            ])
152
            ->willReturn(null);
153
154
        $this->userProvider->loadUserByUsername('key');
155
    }
156
157
    /**
158
     * Test refresh user is not supported
159
     */
160
    public function testRefreshUserIsNotSupported(): void
161
    {
162
        $this->expectException(UnsupportedUserException::class);
163
164
        $this->userProvider->refreshUser($this->createMock(UserInterface::class));
165
    }
166
167
    /**
168
     * @param mixed $class
169
     * @param bool  $isSupported
170
     *
171
     * @dataProvider classProvider
172
     */
173
    public function testItSupportsAclass($class, bool $isSupported): void
174
    {
175
        $result = $this->userProvider->supportsClass($class);
176
177
        $this->assertEquals($isSupported, $result);
178
    }
179
180
    /**
181
     * @return \Generator
182
     */
183
    public function classProvider(): \Generator
184
    {
185
        yield [new Tenant(), true];
186
187
        yield [new StubbedTenant(), true];
188
189
        yield [new \stdClass(), false];
190
    }
191
}
192