Passed
Pull Request — master (#71)
by Matthieu
05:19
created

testGetTenantFromTokenStorage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 14
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 19
rs 9.7998
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AtlassianConnectBundle\Tests\Service;
6
7
use AtlassianConnectBundle\Entity\TenantInterface;
8
use AtlassianConnectBundle\Service\AtlassianRestClient;
9
use GuzzleHttp\ClientInterface;
10
use PHPUnit\Framework\MockObject\MockObject;
11
use PHPUnit\Framework\TestCase;
12
use Psr\Http\Message\ResponseInterface;
13
use Psr\Http\Message\StreamInterface;
14
use Symfony\Component\HttpFoundation\File\File;
15
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
16
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
17
use Symfony\Component\Security\Core\User\UserInterface;
18
19
final class AtlassianRestClientTest extends TestCase
20
{
21
    private const APP_URL = 'https://app.atlassian.com';
22
23
    /** @var ClientInterface|MockObject */
24
    private $client;
25
26
    /** @var MockObject|TokenStorageInterface */
27
    private $tokenStorage;
28
29
    private AtlassianRestClient $restClient;
30
31
    protected function setUp(): void
32
    {
33
        $this->client = $this->createMock(ClientInterface::class);
34
        $this->tokenStorage = $this->createMock(TokenStorageInterface::class);
35
36
        $this->restClient = new AtlassianRestClient($this->client, $this->tokenStorage);
37
    }
38
39
    public function testGetWithTenantBaseUrl(): void
40
    {
41
        $this->restClient->setTenant($tenant = $this->getTenant());
42
43
        $this->client
44
            ->expects($this->once())
45
            ->method('request')
46
            ->with('GET', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => null])
47
            ->willReturn($this->getResponse('OK'));
48
49
        $this->restClient->get('/resource');
50
    }
51
52
    public function testWithFullUrl(): void
53
    {
54
        $this->restClient->setTenant($tenant = $this->getTenant());
55
56
        $this->client
57
            ->expects($this->once())
58
            ->method('request')
59
            ->with('GET', 'https://other-app.atlassian.com/resource', ['tenant' => $tenant, 'user_id' => null])
60
            ->willReturn($this->getResponse('OK'));
61
62
        $this->restClient->get('https://other-app.atlassian.com/resource');
63
    }
64
65
    public function testGetWithUserIdentifier(): void
66
    {
67
        $this->restClient->setTenant($tenant = $this->getTenant())
68
            ->actAsUser('user_id');
69
70
        $this->client
71
            ->expects($this->once())
72
            ->method('request')
73
            ->with('GET', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => 'user_id'])
74
            ->willReturn($this->getResponse('OK'));
75
76
        $this->restClient->get('/resource');
77
    }
78
79
    public function testPost(): void
80
    {
81
        $this->restClient->setTenant($tenant = $this->getTenant());
82
83
        $this->client
84
            ->expects($this->once())
85
            ->method('request')
86
            ->with('POST', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => null, 'headers' => ['Content-Type' => 'application/json'], 'json' => ['data' => 'data']])
87
            ->willReturn($this->getResponse('OK'));
88
89
        $this->restClient->post('/resource', ['data' => 'data']);
90
    }
91
92
    public function testPut(): void
93
    {
94
        $this->restClient->setTenant($tenant = $this->getTenant());
95
96
        $this->client
97
            ->expects($this->once())
98
            ->method('request')
99
            ->with('PUT', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => null, 'headers' => ['Content-Type' => 'application/json'], 'json' => ['data' => 'data']])->willReturn($this->getResponse('OK'));
100
101
        $this->restClient->put('/resource', ['data' => 'data']);
102
    }
103
104
    public function testDelete(): void
105
    {
106
        $this->restClient->setTenant($tenant = $this->getTenant());
107
108
        $this->client
109
            ->expects($this->once())
110
            ->method('request')
111
            ->with('DELETE', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => null])
112
            ->willReturn($this->getResponse('OK'));
113
114
        $this->restClient->delete('/resource');
115
    }
116
117
    public function testSendFile(): void
118
    {
119
        $file = fopen(__DIR__.'/file.txt', 'w');
120
        fwrite($file, 'text');
121
122
        $uploadedFile = new File(__DIR__.'/file.txt');
123
124
        $this->restClient->setTenant($tenant = $this->getTenant());
125
126
        $this->client
127
            ->expects($this->once())
128
            ->method('request')
129
            ->with('POST', self::APP_URL.'/resource', $this->anything())
130
            ->willReturn($this->getResponse('OK'));
131
132
        $this->restClient->sendFile($uploadedFile, '/resource');
133
    }
134
135
    public function testGetTenantFromTokenStorage(): void
136
    {
137
        $this->tokenStorage
138
            ->expects($this->once())
139
            ->method('getToken')
140
            ->willReturn($token = $this->createMock(TokenInterface::class));
141
142
        $token
143
            ->expects($this->once())
144
            ->method('getUser')
145
            ->willReturn($tenant = $this->getTenant());
146
147
        $this->client
148
            ->expects($this->once())
149
            ->method('request')
150
            ->with('GET', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => null])
151
            ->willReturn($this->getResponse('OK'));
152
153
        $this->restClient->get('/resource');
154
    }
155
156
    public function testNoTenantInToken(): void
157
    {
158
        $this->expectException(\RuntimeException::class);
159
        $this->expectDeprecationMessage('Could not get tenant from token');
160
161
        $this->tokenStorage
162
            ->expects($this->once())
163
            ->method('getToken')
164
            ->willReturn(null);
165
166
        $this->restClient->get('/resource');
167
    }
168
169
    public function testNotInTenantContext(): void
170
    {
171
        $this->expectException(\RuntimeException::class);
172
        $this->expectDeprecationMessage('Current user is not a Tenant');
173
174
        $this->tokenStorage
175
            ->expects($this->once())
176
            ->method('getToken')
177
            ->willReturn($token = $this->createMock(TokenInterface::class));
178
        $token->expects($this->once())
179
            ->method('getUser')
180
            ->willReturn($this->createMock(UserInterface::class));
181
182
        $this->restClient->get('/resource');
183
    }
184
185
    private function getResponse(string $content): ResponseInterface
186
    {
187
        $response = $this->createMock(ResponseInterface::class);
188
189
        $response->method('getBody')->willReturn($stream = $this->createMock(StreamInterface::class));
190
191
        $stream->method('getContents')->willReturn($content);
192
193
        return $response;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $response returns the type PHPUnit\Framework\MockObject\MockObject which is incompatible with the type-hinted return Psr\Http\Message\ResponseInterface.
Loading history...
194
    }
195
196
    private function getTenant(): TenantInterface
197
    {
198
        $tenant = $this->createMock(TenantInterface::class);
199
        $tenant->method('getBaseUrl')
200
            ->willReturn(self::APP_URL);
201
202
        return $tenant;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $tenant returns the type PHPUnit\Framework\MockObject\MockObject which is incompatible with the type-hinted return AtlassianConnectBundle\Entity\TenantInterface.
Loading history...
203
    }
204
}
205