Issues (58)

Tests/Service/AtlassianRestClientTest.php (4 issues)

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
    private HttpClientInterface|MockObject $client;
23
    private TokenStorageInterface|MockObject $tokenStorage;
24
    private AtlassianRestClient $restClient;
25
26
    protected function setUp(): void
27
    {
28
        $this->client = $this->createMock(HttpClientInterface::class);
29
        $this->tokenStorage = $this->createMock(TokenStorageInterface::class);
30
31
        $this->restClient = new AtlassianRestClient($this->client, $this->tokenStorage);
32
    }
33
34
    public function testGetWithTenantBaseUrl(): void
35
    {
36
        $this->restClient->setTenant($tenant = $this->getTenant());
37
38
        $this->client
39
            ->expects($this->once())
0 ignored issues
show
The method expects() does not exist on Symfony\Contracts\HttpClient\HttpClientInterface. ( Ignorable by Annotation )

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

39
            ->/** @scrutinizer ignore-call */ 
40
              expects($this->once())

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...
40
            ->method('request')
41
            ->with('GET', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => null])
42
            ->willReturn($this->getResponse('OK'));
43
44
        $this->restClient->get('/resource');
45
    }
46
47
    public function testWithFullUrl(): void
48
    {
49
        $this->restClient->setTenant($tenant = $this->getTenant());
50
51
        $this->client
52
            ->expects($this->once())
53
            ->method('request')
54
            ->with('GET', 'https://other-app.atlassian.com/resource', ['tenant' => $tenant, 'user_id' => null])
55
            ->willReturn($this->getResponse('OK'));
56
57
        $this->restClient->get('https://other-app.atlassian.com/resource');
58
    }
59
60
    public function testGetWithUserIdentifier(): void
61
    {
62
        $this->restClient->setTenant($tenant = $this->getTenant())
63
            ->actAsUser('user_id');
64
65
        $this->client
66
            ->expects($this->once())
67
            ->method('request')
68
            ->with('GET', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => 'user_id'])
69
            ->willReturn($this->getResponse('OK'));
70
71
        $this->restClient->get('/resource');
72
    }
73
74
    public function testPost(): void
75
    {
76
        $this->restClient->setTenant($tenant = $this->getTenant());
77
78
        $this->client
79
            ->expects($this->once())
80
            ->method('request')
81
            ->with('POST', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => null, 'headers' => ['Content-Type' => 'application/json'], 'json' => ['data' => 'data']])
82
            ->willReturn($this->getResponse('OK'));
83
84
        $this->restClient->post('/resource', ['data' => 'data']);
85
    }
86
87
    public function testPut(): void
88
    {
89
        $this->restClient->setTenant($tenant = $this->getTenant());
90
91
        $this->client
92
            ->expects($this->once())
93
            ->method('request')
94
            ->with('PUT', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => null, 'headers' => ['Content-Type' => 'application/json'], 'json' => ['data' => 'data']])->willReturn($this->getResponse('OK'));
95
96
        $this->restClient->put('/resource', ['data' => 'data']);
97
    }
98
99
    public function testDelete(): void
100
    {
101
        $this->restClient->setTenant($tenant = $this->getTenant());
102
103
        $this->client
104
            ->expects($this->once())
105
            ->method('request')
106
            ->with('DELETE', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => null])
107
            ->willReturn($this->getResponse('OK'));
108
109
        $this->restClient->delete('/resource');
110
    }
111
112
    public function testSendFile(): void
113
    {
114
        $file = fopen(__DIR__.'/file.txt', 'w');
115
        fwrite($file, 'text');
116
117
        $uploadedFile = new File(__DIR__.'/file.txt');
118
119
        $this->restClient->setTenant($tenant = $this->getTenant());
120
121
        $this->client
122
            ->expects($this->once())
123
            ->method('request')
124
            ->with('POST', self::APP_URL.'/resource', $this->anything())
125
            ->willReturn($this->getResponse('OK'));
126
127
        $this->restClient->sendFile($uploadedFile, '/resource');
128
    }
129
130
    public function testGetTenantFromTokenStorage(): void
131
    {
132
        $this->tokenStorage
133
            ->expects($this->once())
0 ignored issues
show
The method expects() does not exist on Symfony\Component\Securi...e\TokenStorageInterface. ( Ignorable by Annotation )

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

133
            ->/** @scrutinizer ignore-call */ 
134
              expects($this->once())

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...
134
            ->method('getToken')
135
            ->willReturn($token = $this->createMock(TokenInterface::class));
136
137
        $token
138
            ->expects($this->once())
139
            ->method('getUser')
140
            ->willReturn($tenant = $this->getTenant());
141
142
        $this->client
143
            ->expects($this->once())
144
            ->method('request')
145
            ->with('GET', self::APP_URL.'/resource', ['tenant' => $tenant, 'user_id' => null])
146
            ->willReturn($this->getResponse('OK'));
147
148
        $this->restClient->get('/resource');
149
    }
150
151
    public function testNoTenantInToken(): void
152
    {
153
        $this->expectException(\RuntimeException::class);
154
        $this->expectDeprecationMessage('Could not get tenant from token');
155
156
        $this->tokenStorage
157
            ->expects($this->once())
158
            ->method('getToken')
159
            ->willReturn(null);
160
161
        $this->restClient->get('/resource');
162
    }
163
164
    public function testNotInTenantContext(): void
165
    {
166
        $this->expectException(\RuntimeException::class);
167
        $this->expectDeprecationMessage('Current user is not a Tenant');
168
169
        $this->tokenStorage
170
            ->expects($this->once())
171
            ->method('getToken')
172
            ->willReturn($token = $this->createMock(TokenInterface::class));
173
        $token->expects($this->once())
174
            ->method('getUser')
175
            ->willReturn($this->createMock(UserInterface::class));
176
177
        $this->restClient->get('/resource');
178
    }
179
180
    private function getResponse(string $content): ResponseInterface
181
    {
182
        $response = $this->createMock(ResponseInterface::class);
183
        $response->method('getContent')->willReturn($content);
184
185
        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...
186
    }
187
188
    private function getTenant(): TenantInterface
189
    {
190
        $tenant = $this->createMock(TenantInterface::class);
191
        $tenant->method('getBaseUrl')
192
            ->willReturn(self::APP_URL);
193
194
        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...
195
    }
196
}
197