Completed
Pull Request — master (#554)
by Alejandro
11:37 queued 08:50
created

AuthenticationTest   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Importance

Changes 6
Bugs 0 Features 1
Metric Value
eloc 54
dl 0
loc 99
rs 10
c 6
b 0
f 1
wmc 5

5 Methods

Rating   Name   Duplication   Size   Complexity  
A apiKeyErrorIsReturnedWhenProvidedApiKeyIsInvalid() 0 18 1
A authorizationErrorIsReturnedIfNoApiKeyIsSent() 0 17 1
A provideInvalidAuthorizations() 0 20 1
A provideInvalidApiKeys() 0 5 1
A authorizationErrorIsReturnedIfInvalidDataIsProvided() 0 20 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioApiTest\Shlink\Rest\Middleware;
6
7
use Shlinkio\Shlink\Rest\Authentication\Plugin;
8
use Shlinkio\Shlink\Rest\Authentication\RequestToHttpAuthPlugin;
9
use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
10
11
use function implode;
12
use function sprintf;
13
14
class AuthenticationTest extends ApiTestCase
15
{
16
    /** @test */
17
    public function authorizationErrorIsReturnedIfNoApiKeyIsSent(): void
18
    {
19
        $expectedDetail = sprintf(
20
            'Expected one of the following authentication headers, but none were provided, ["%s"]',
21
            implode('", "', RequestToHttpAuthPlugin::SUPPORTED_AUTH_HEADERS)
22
        );
23
24
        $resp = $this->callApi(self::METHOD_GET, '/short-codes');
25
        $payload = $this->getJsonResponsePayload($resp);
26
27
        $this->assertEquals(self::STATUS_UNAUTHORIZED, $resp->getStatusCode());
28
        $this->assertEquals(self::STATUS_UNAUTHORIZED, $payload['status']);
29
        $this->assertEquals('INVALID_AUTHORIZATION', $payload['type']);
30
        $this->assertEquals('INVALID_AUTHORIZATION', $payload['error']); // Deprecated
31
        $this->assertEquals($expectedDetail, $payload['detail']);
32
        $this->assertEquals($expectedDetail, $payload['message']); // Deprecated
33
        $this->assertEquals('Invalid authorization', $payload['title']);
34
    }
35
36
    /**
37
     * @test
38
     * @dataProvider provideInvalidApiKeys
39
     */
40
    public function apiKeyErrorIsReturnedWhenProvidedApiKeyIsInvalid(string $apiKey): void
41
    {
42
        $expectedDetail = 'Provided API key does not exist or is invalid.';
43
44
        $resp = $this->callApi(self::METHOD_GET, '/short-codes', [
45
            'headers' => [
46
                Plugin\ApiKeyHeaderPlugin::HEADER_NAME => $apiKey,
47
            ],
48
        ]);
49
        $payload = $this->getJsonResponsePayload($resp);
50
51
        $this->assertEquals(self::STATUS_UNAUTHORIZED, $resp->getStatusCode());
52
        $this->assertEquals(self::STATUS_UNAUTHORIZED, $payload['status']);
53
        $this->assertEquals('INVALID_API_KEY', $payload['type']);
54
        $this->assertEquals('INVALID_API_KEY', $payload['error']); // Deprecated
55
        $this->assertEquals($expectedDetail, $payload['detail']);
56
        $this->assertEquals($expectedDetail, $payload['message']); // Deprecated
57
        $this->assertEquals('Invalid API key', $payload['title']);
58
    }
59
60
    public function provideInvalidApiKeys(): iterable
61
    {
62
        yield 'key which does not exist' => ['invalid'];
63
        yield 'key which is expired' => ['expired_api_key'];
64
        yield 'key which is disabled' => ['disabled_api_key'];
65
    }
66
67
    /**
68
     * @test
69
     * @dataProvider provideInvalidAuthorizations
70
     */
71
    public function authorizationErrorIsReturnedIfInvalidDataIsProvided(
72
        string $authValue,
73
        string $expectedDetail,
74
        string $expectedType,
75
        string $expectedTitle
76
    ): void {
77
        $resp = $this->callApi(self::METHOD_GET, '/short-codes', [
78
            'headers' => [
79
                Plugin\AuthorizationHeaderPlugin::HEADER_NAME => $authValue,
80
            ],
81
        ]);
82
        $payload = $this->getJsonResponsePayload($resp);
83
84
        $this->assertEquals(self::STATUS_UNAUTHORIZED, $resp->getStatusCode());
85
        $this->assertEquals(self::STATUS_UNAUTHORIZED, $payload['status']);
86
        $this->assertEquals($expectedType, $payload['type']);
87
        $this->assertEquals($expectedType, $payload['error']); // Deprecated
88
        $this->assertEquals($expectedDetail, $payload['detail']);
89
        $this->assertEquals($expectedDetail, $payload['message']); // Deprecated
90
        $this->assertEquals($expectedTitle, $payload['title']);
91
    }
92
93
    public function provideInvalidAuthorizations(): iterable
94
    {
95
        yield 'no type' => [
96
            'invalid',
97
            'You need to provide the Bearer type in the Authorization header.',
98
            'INVALID_AUTHORIZATION',
99
            'Invalid authorization',
100
        ];
101
        yield 'invalid type' => [
102
            'Basic invalid',
103
            'Provided authorization type Basic is not supported. Use Bearer instead.',
104
            'INVALID_AUTHORIZATION',
105
            'Invalid authorization',
106
        ];
107
        yield 'invalid JWT' => [
108
            'Bearer invalid',
109
            'Missing or invalid auth token provided. Perform a new authentication request and send provided '
110
            . 'token on every new request on the Authorization header',
111
            'INVALID_AUTH_TOKEN',
112
            'Invalid auth token',
113
        ];
114
    }
115
}
116