Passed
Pull Request — master (#71)
by Matthieu
05:14 queued 01:08
created

AtlassianRestClientTest::testWithFullUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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