ApiTest   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 231
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 7
eloc 141
c 2
b 0
f 0
dl 0
loc 231
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A testHandleRetrievesUserByClientIdIfUserIdIsNotSet() 0 38 1
A testHandleRetrievesUserByClientIdIfUserIsNotFoundById() 0 39 1
A testHandleReturnsJsonResponseOnValidationError() 0 21 1
A testHandleReturnsJsonResponseOnUserRetrievalError() 0 26 1
A setUp() 0 14 1
A testHandleRetrievesUserByUserId() 0 37 1
A testHandleReturnsJsonResponseOnValidationFailure() 0 26 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Admin\Http\Middleware;
6
7
use AbterPhp\Admin\Domain\Entities\User;
8
use AbterPhp\Admin\Domain\Entities\UserLanguage;
9
use AbterPhp\Admin\Orm\UserRepo;
10
use AbterPhp\Admin\Psr7\RequestConverter;
11
use League\OAuth2\Server\Exception\OAuthServerException;
12
use League\OAuth2\Server\ResourceServer;
13
use Nyholm\Psr7\ServerRequest as Psr7Request;
14
use Opulence\Http\Requests\Request;
15
use Opulence\Http\Requests\RequestMethods;
16
use Opulence\Http\Responses\Response;
17
use Opulence\Http\Responses\ResponseHeaders;
18
use PHPUnit\Framework\MockObject\MockObject;
19
use PHPUnit\Framework\TestCase;
20
use Psr\Log\LoggerInterface;
21
22
class ApiTest extends TestCase
23
{
24
    /** @var Api - System Under Test */
25
    protected Api $sut;
26
27
    /** @var MockObject|ResourceServer */
28
    protected $resourceServerMock;
29
30
    /** @var MockObject|RequestConverter */
31
    protected $requestConverterMock;
32
33
    /** @var MockObject|UserRepo */
34
    protected $userRepoMock;
35
36
    /** @var MockObject|LoggerInterface */
37
    protected $loggerMock;
38
39
    public function setUp(): void
40
    {
41
        $this->resourceServerMock   = $this->createMock(ResourceServer::class);
42
        $this->requestConverterMock = $this->createMock(RequestConverter::class);
43
        $this->userRepoMock         = $this->createMock(UserRepo::class);
44
        $this->loggerMock           = $this->createMock(LoggerInterface::class);
45
        $problemUrlStub             = 'https://example.com/foo';
46
47
        $this->sut = new Api(
48
            $this->resourceServerMock,
49
            $this->requestConverterMock,
50
            $this->userRepoMock,
51
            $this->loggerMock,
52
            $problemUrlStub
53
        );
54
    }
55
56
    public function testHandleReturnsJsonResponseOnValidationFailure()
57
    {
58
        $errorMsg        = 'Foo failure';
59
        $errorCode       = 17;
60
        $errorType       = 'FOO';
61
        $errorStatusCode = ResponseHeaders::HTTP_GONE;
62
63
        $exception = new OAuthServerException($errorMsg, $errorCode, $errorType, $errorStatusCode);
64
65
        $this->resourceServerMock
66
            ->expects($this->once())
67
            ->method('validateAuthenticatedRequest')
68
            ->willThrowException($exception);
69
70
        $requestStub  = new Request([], [], [], [], [], [], null);
71
        $responseStub = new Response();
72
73
        $next = function () use ($responseStub) {
74
            return $responseStub;
75
        };
76
77
        $actualResult = $this->sut->handle($requestStub, $next);
78
79
        $this->assertInstanceOf(Response::class, $actualResult);
80
        $this->assertSame($errorStatusCode, $actualResult->getStatusCode());
81
        $this->assertJson($actualResult->getContent());
82
    }
83
84
    public function testHandleReturnsJsonResponseOnValidationError()
85
    {
86
        $exception = new \Exception();
87
88
        $this->resourceServerMock
89
            ->expects($this->once())
90
            ->method('validateAuthenticatedRequest')
91
            ->willThrowException($exception);
92
93
        $requestStub  = new Request([], [], [], [], [], [], null);
94
        $responseStub = new Response();
95
96
        $next = function () use ($responseStub) {
97
            return $responseStub;
98
        };
99
100
        $actualResult = $this->sut->handle($requestStub, $next);
101
102
        $this->assertInstanceOf(Response::class, $actualResult);
103
        $this->assertSame(ResponseHeaders::HTTP_INTERNAL_SERVER_ERROR, $actualResult->getStatusCode());
104
        $this->assertJson($actualResult->getContent());
105
    }
106
107
    public function testHandleRetrievesUserByUserId()
108
    {
109
        $uri      = 'https://example.com/foo';
110
        $username = 'Foo Lee';
111
        $userId   = '604155e4-10f2-4d2d-857b-97d841317e5c';
112
113
        $psr7Request = new Psr7Request(RequestMethods::GET, $uri);
114
        $psr7Request = $psr7Request->withAttribute(Api::ATTRIBUTE_USER_ID, $userId);
115
116
        $this->resourceServerMock
117
            ->expects($this->once())
118
            ->method('validateAuthenticatedRequest')
119
            ->willReturn($psr7Request);
120
121
        $languageStub = new UserLanguage('', '', '');
122
        $userStub     = new User($userId, $username, '', '', true, true, $languageStub);
123
124
        $this->userRepoMock->expects($this->once())->method('getById')->willReturn($userStub);
125
        $this->userRepoMock->expects($this->never())->method('getByClientId');
126
127
        $requestStub  = new Request([], [], [], [], [], [], null);
128
        $responseStub = new Response();
129
130
        $next = function () use ($responseStub) {
131
            return $responseStub;
132
        };
133
134
        $actualResult = $this->sut->handle($requestStub, $next);
135
136
        $this->assertSame($responseStub, $actualResult);
137
        $this->assertSame(ResponseHeaders::HTTP_OK, $actualResult->getStatusCode());
138
139
        $headers = $requestStub->getHeaders();
140
        $this->assertArrayHasKey(Api::HEADER_USER_ID, $headers);
141
        $this->assertArrayHasKey(Api::HEADER_USER_USERNAME, $headers);
142
        $this->assertSame($userId, $headers[Api::HEADER_USER_ID]);
143
        $this->assertSame($username, $headers[Api::HEADER_USER_USERNAME]);
144
    }
145
146
    public function testHandleRetrievesUserByClientIdIfUserIdIsNotSet()
147
    {
148
        $uri      = 'https://example.com/foo';
149
        $username = 'Foo Lee';
150
        $userId   = '604155e4-10f2-4d2d-857b-97d841317e5c';
151
        $clientId = '1fde89de-9f5b-4d90-a0a5-072ea3cfc7b3';
152
153
        $psr7Request = (new Psr7Request(RequestMethods::GET, $uri))
154
            ->withAttribute(Api::ATTRIBUTE_CLIENT_ID, $clientId);
155
156
        $this->resourceServerMock
157
            ->expects($this->once())
158
            ->method('validateAuthenticatedRequest')
159
            ->willReturn($psr7Request);
160
161
        $languageStub = new UserLanguage('', '', '');
162
        $userStub     = new User($userId, $username, '', '', true, true, $languageStub);
163
164
        $this->userRepoMock->expects($this->never())->method('getById');
165
        $this->userRepoMock->expects($this->once())->method('getByClientId')->willReturn($userStub);
166
167
        $requestStub  = new Request([], [], [], [], [], [], null);
168
        $responseStub = new Response();
169
170
        $next = function () use ($responseStub) {
171
            return $responseStub;
172
        };
173
174
        $actualResult = $this->sut->handle($requestStub, $next);
175
176
        $this->assertSame($responseStub, $actualResult);
177
        $this->assertSame(ResponseHeaders::HTTP_OK, $actualResult->getStatusCode());
178
179
        $headers = $requestStub->getHeaders();
180
        $this->assertArrayHasKey(Api::HEADER_USER_ID, $headers);
181
        $this->assertArrayHasKey(Api::HEADER_USER_USERNAME, $headers);
182
        $this->assertSame($userId, $headers[Api::HEADER_USER_ID]);
183
        $this->assertSame($username, $headers[Api::HEADER_USER_USERNAME]);
184
    }
185
186
    public function testHandleRetrievesUserByClientIdIfUserIsNotFoundById()
187
    {
188
        $uri      = 'https://example.com/foo';
189
        $username = 'Foo Lee';
190
        $userId   = '604155e4-10f2-4d2d-857b-97d841317e5c';
191
        $clientId = '1fde89de-9f5b-4d90-a0a5-072ea3cfc7b3';
192
193
        $psr7Request = (new Psr7Request(RequestMethods::GET, $uri))
194
            ->withAttribute(Api::ATTRIBUTE_USER_ID, $userId)
195
            ->withAttribute(Api::ATTRIBUTE_CLIENT_ID, $clientId);
196
197
        $this->resourceServerMock
198
            ->expects($this->once())
199
            ->method('validateAuthenticatedRequest')
200
            ->willReturn($psr7Request);
201
202
        $languageStub = new UserLanguage('', '', '');
203
        $userStub     = new User($userId, $username, '', '', true, true, $languageStub);
204
205
        $this->userRepoMock->expects($this->once())->method('getById')->willReturn(null);
206
        $this->userRepoMock->expects($this->once())->method('getByClientId')->willReturn($userStub);
207
208
        $requestStub  = new Request([], [], [], [], [], [], null);
209
        $responseStub = new Response();
210
211
        $next = function () use ($responseStub) {
212
            return $responseStub;
213
        };
214
215
        $actualResult = $this->sut->handle($requestStub, $next);
216
217
        $this->assertSame($responseStub, $actualResult);
218
        $this->assertSame(ResponseHeaders::HTTP_OK, $actualResult->getStatusCode());
219
220
        $headers = $requestStub->getHeaders();
221
        $this->assertArrayHasKey(Api::HEADER_USER_ID, $headers);
222
        $this->assertArrayHasKey(Api::HEADER_USER_USERNAME, $headers);
223
        $this->assertSame($userId, $headers[Api::HEADER_USER_ID]);
224
        $this->assertSame($username, $headers[Api::HEADER_USER_USERNAME]);
225
    }
226
227
    public function testHandleReturnsJsonResponseOnUserRetrievalError()
228
    {
229
        $uri = 'https://example.com/foo';
230
231
        $psr7Request = new Psr7Request(RequestMethods::GET, $uri);
232
233
        $this->resourceServerMock
234
            ->expects($this->once())
235
            ->method('validateAuthenticatedRequest')
236
            ->willReturn($psr7Request);
237
238
        $this->userRepoMock->expects($this->never())->method('getById');
239
        $this->userRepoMock->expects($this->never())->method('getByClientId');
240
241
        $requestStub  = new Request([], [], [], [], [], [], null);
242
        $responseStub = new Response();
243
244
        $next = function () use ($responseStub) {
245
            return $responseStub;
246
        };
247
248
        $actualResult = $this->sut->handle($requestStub, $next);
249
250
        $this->assertInstanceOf(Response::class, $actualResult);
251
        $this->assertSame(ResponseHeaders::HTTP_INTERNAL_SERVER_ERROR, $actualResult->getStatusCode());
252
        $this->assertJson($actualResult->getContent());
253
    }
254
}
255