testCheckResponseThrowIdentityProviderException()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 32
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 23
c 1
b 0
f 1
nc 2
nop 0
dl 0
loc 32
rs 9.552
1
<?php
2
3
/** @noinspection PhpIllegalPsrClassPathInspection */
4
5
namespace Austomos\OAuth2\Client\Test\Provider;
6
7
use Austomos\OAuth2\Client\Provider\ChasterApp;
8
use Austomos\OAuth2\Client\Provider\ChasterAppResourceOwner;
9
use Exception;
10
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
11
use League\OAuth2\Client\Tool\QueryBuilderTrait;
12
use Mockery as m;
13
use PHPUnit\Framework\TestCase;
14
15
class ChasterAppTest extends TestCase
16
{
17
    use QueryBuilderTrait;
18
19
    protected ChasterApp $provider;
20
21
    public function tearDown(): void
22
    {
23
        m::close();
24
        parent::tearDown();
25
    }
26
27
    public function testAuthorizationUrl(): void
28
    {
29
        $url = $this->provider->getAuthorizationUrl();
30
        $uri = parse_url($url);
31
        parse_str($uri['query'], $query);
32
33
        $this->assertArrayHasKey('client_id', $query);
34
        $this->assertArrayHasKey('redirect_uri', $query);
35
        $this->assertArrayHasKey('state', $query);
36
        $this->assertArrayHasKey('scope', $query);
37
        $this->assertArrayHasKey('response_type', $query);
38
        $this->assertArrayHasKey('approval_prompt', $query);
39
        $this->assertNotNull($this->provider->getState());
40
    }
41
42
    /**
43
     * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
44
     */
45
    public function testChasterAppUrls(): void
46
    {
47
        /** @noinspection PhpUndefinedFieldInspection */
48
        $this->provider->oAuthBaseUrl = 'https://sso.chaster.app/auth/realms/app/protocol/openid-connect';
0 ignored issues
show
Bug introduced by
The property oAuthBaseUrl does not seem to exist on Austomos\OAuth2\Client\Provider\ChasterApp.
Loading history...
49
50
        $response = m::mock('Psr\Http\Message\ResponseInterface');
51
        $response->expects('getBody')
52
            ->times(1)
53
            ->andReturns(
54
                http_build_query([
0 ignored issues
show
Unused Code introduced by
The call to Mockery\ExpectationInterface::andReturns() has too many arguments starting with http_build_query(array('... 'scope' => 'profile')). ( Ignorable by Annotation )

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

54
            ->/** @scrutinizer ignore-call */ andReturns(

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
55
                    'access_token' => 'mock_access_token',
56
                    'expires_in' => 300,
57
                    'refresh_expires_in' => 1800,
58
                    'refresh_token' => 'mock_refresh_token',
59
                    'token_type' => 'bearer',
60
                    'not-before-policy' => 0,
61
                    'scope' => 'profile'
62
                ])
63
            );
64
        $response->allows('getHeader')
65
            ->andReturns(['content-type' => 'application/x-www-form-urlencoded']);
0 ignored issues
show
Bug introduced by
The method andReturns() does not exist on Mockery\LegacyMockInterface. It seems like you code against a sub-type of Mockery\LegacyMockInterface such as Mockery\Mock. ( Ignorable by Annotation )

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

65
            ->/** @scrutinizer ignore-call */ andReturns(['content-type' => 'application/x-www-form-urlencoded']);
Loading history...
66
        $response->allows('getStatusCode')
67
            ->andReturns(200);
68
69
        $client = m::mock('GuzzleHttp\ClientInterface');
70
        $client->expects('send')->times(1)->andReturns($response);
71
        /** @noinspection PhpParamsInspection */
72
        $this->provider->setHttpClient($client);
0 ignored issues
show
Bug introduced by
$client of type Mockery\LegacyMockInterface|Mockery\MockInterface is incompatible with the type GuzzleHttp\ClientInterface expected by parameter $client of League\OAuth2\Client\Pro...ovider::setHttpClient(). ( Ignorable by Annotation )

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

72
        $this->provider->setHttpClient(/** @scrutinizer ignore-type */ $client);
Loading history...
73
74
        $token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
75
76
        $providerAuthorizationUrl = $this->provider->oAuthBaseUrl . '/auth';
77
        $providerAccessTokenUrl = $this->provider->oAuthBaseUrl . '/token';
78
        $providerResourceOwnerUrl = 'https://api.chaster.app/auth/profile';
79
80
        $this->assertEquals($providerAuthorizationUrl, $this->provider->getBaseAuthorizationUrl());
81
        $this->assertEquals($providerAccessTokenUrl, $this->provider->getBaseAccessTokenUrl([]));
82
        $this->assertEquals($providerResourceOwnerUrl, $this->provider->getResourceOwnerDetailsUrl($token));
83
    }
84
85
    /**
86
     * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
87
     * @throws \JsonException
88
     */
89
    public function testCheckResponseThrowIdentityProviderException(): void
90
    {
91
        try {
92
            $status = random_int(400, 600);
93
        } catch (Exception $e) {
94
            $status = 500;
95
        }
96
        $postResponse = m::mock('Psr\Http\Message\ResponseInterface');
97
        $postResponse->allows('getBody')
98
            ->andReturns(
99
                json_encode([
0 ignored issues
show
Unused Code introduced by
The call to Mockery\ExpectationInterface::andReturns() has too many arguments starting with json_encode(array('messa...er\JSON_THROW_ON_ERROR). ( Ignorable by Annotation )

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

99
            ->/** @scrutinizer ignore-call */ andReturns(

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
100
                    'message' => 'Validation Failed',
101
                    'errors' => [
102
                        ['resource' => 'Issue', 'field' => 'title', 'code' => 'missing_field'],
103
                    ],
104
                ], JSON_THROW_ON_ERROR)
105
            );
106
        $postResponse->allows('getHeader')
107
            ->andReturns(['content-type' => 'json']);
108
        $postResponse->allows('getStatusCode')
109
            ->andReturns($status);
110
111
        $client = m::mock('GuzzleHttp\ClientInterface');
112
        $client->expects('send')
113
            ->times(1)
114
            ->andReturns($postResponse);
115
        /** @noinspection PhpParamsInspection */
116
        $this->provider->setHttpClient($client);
0 ignored issues
show
Bug introduced by
$client of type Mockery\LegacyMockInterface|Mockery\MockInterface is incompatible with the type GuzzleHttp\ClientInterface expected by parameter $client of League\OAuth2\Client\Pro...ovider::setHttpClient(). ( Ignorable by Annotation )

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

116
        $this->provider->setHttpClient(/** @scrutinizer ignore-type */ $client);
Loading history...
117
118
        $this->expectException(IdentityProviderException::class);
119
120
        $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
121
    }
122
123
    /**
124
     * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
125
     */
126
    public function testGetAccessToken(): void
127
    {
128
        $response = m::mock('Psr\Http\Message\ResponseInterface');
129
        $response->allows('getBody')
130
            ->andReturns('{"access_token":"mock_access_token", "scope":"profile", "token_type":"bearer"}');
0 ignored issues
show
Unused Code introduced by
The call to Mockery\ExpectationInterface::andReturns() has too many arguments starting with '{"access_token":"mock_a..."token_type":"bearer"}'. ( Ignorable by Annotation )

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

130
            ->/** @scrutinizer ignore-call */ andReturns('{"access_token":"mock_access_token", "scope":"profile", "token_type":"bearer"}');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
131
        $response->allows('getHeader')
132
            ->andReturns(['content-type' => 'json']);
133
        $response->allows('getStatusCode')
134
            ->andReturns(200);
135
136
        $client = m::mock('GuzzleHttp\ClientInterface');
137
        $client->expects('send')->times(1)->andReturns($response);
138
        /** @noinspection PhpParamsInspection */
139
        $this->provider->setHttpClient($client);
0 ignored issues
show
Bug introduced by
$client of type Mockery\LegacyMockInterface|Mockery\MockInterface is incompatible with the type GuzzleHttp\ClientInterface expected by parameter $client of League\OAuth2\Client\Pro...ovider::setHttpClient(). ( Ignorable by Annotation )

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

139
        $this->provider->setHttpClient(/** @scrutinizer ignore-type */ $client);
Loading history...
140
141
        $token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
142
143
        $this->assertEquals('mock_access_token', $token->getToken());
144
        $this->assertNull($token->getExpires());
145
        $this->assertNull($token->getRefreshToken());
146
        $this->assertNull($token->getResourceOwnerId());
147
    }
148
149
    public function testGetAuthorizationUrl(): void
150
    {
151
        $url = $this->provider->getAuthorizationUrl();
152
        $uri = parse_url($url);
153
154
        $this->assertEquals('/auth/realms/app/protocol/openid-connect/auth', $uri['path']);
155
    }
156
157
    public function testGetBaseAccessTokenUrl(): void
158
    {
159
        $params = [];
160
161
        $url = $this->provider->getBaseAccessTokenUrl($params);
162
        $uri = parse_url($url);
163
164
        $this->assertEquals('/auth/realms/app/protocol/openid-connect/token', $uri['path']);
165
    }
166
167
    /**
168
     * @throws \JsonException
169
     * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
170
     */
171
    public function testProfileData(): void
172
    {
173
        try {
174
            $userId = random_int(1000, 9999);
175
        } catch (Exception $e) {
176
            $userId = 999;
177
        }
178
        $username = uniqid('', true);
179
        $email = uniqid('', true);
180
        $mockString = 'mock_string_value';
181
        $mockInt = 123;
182
        $mockArray = ['a' => 'A', 'b' => 'B', 'c' => 'C'];
183
184
        $postResponse = m::mock('Psr\Http\Message\ResponseInterface');
185
        $postResponse->allows('getBody')
186
            ->andReturns(
187
                http_build_query([
0 ignored issues
show
Unused Code introduced by
The call to Mockery\ExpectationInterface::andReturns() has too many arguments starting with http_build_query(array('... 'scope' => 'profile')). ( Ignorable by Annotation )

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

187
            ->/** @scrutinizer ignore-call */ andReturns(

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
188
                    'access_token' => 'mock_access_token',
189
                    'expires_in' => 300,
190
                    'refresh_expires_in' => 1800,
191
                    'refresh_token' => 'mock_refresh_token',
192
                    'token_type' => 'bearer',
193
                    'not-before-policy' => 0,
194
                    'scope' => 'profile'
195
                ])
196
            );
197
        $postResponse->allows('getHeader')
198
            ->andReturns(['content-type' => 'application/x-www-form-urlencoded']);
199
        $postResponse->allows('getStatusCode')
200
            ->andReturns(200);
201
202
        $userResponse = m::mock('Psr\Http\Message\ResponseInterface');
203
        $userResponse->allows('getBody')
204
            ->andReturns(
205
                json_encode([
206
                    '_id' => $userId,
207
                    'username' => $username,
208
                    'email' => $email,
209
                    'mock_string' => $mockString,
210
                    'mock_int' => $mockInt,
211
                    'mock_array' => $mockArray,
212
                ], JSON_THROW_ON_ERROR)
213
            );
214
        $userResponse->allows('getHeader')
215
            ->andReturns(['content-type' => 'json']);
216
        $userResponse->allows('getStatusCode')
217
            ->andReturns(200);
218
219
        $client = m::mock('GuzzleHttp\ClientInterface');
220
        $client->expects('send')
221
            ->times(2)
222
            ->andReturns($postResponse, $userResponse);
223
        /** @noinspection PhpParamsInspection */
224
        $this->provider->setHttpClient($client);
0 ignored issues
show
Bug introduced by
$client of type Mockery\LegacyMockInterface|Mockery\MockInterface is incompatible with the type GuzzleHttp\ClientInterface expected by parameter $client of League\OAuth2\Client\Pro...ovider::setHttpClient(). ( Ignorable by Annotation )

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

224
        $this->provider->setHttpClient(/** @scrutinizer ignore-type */ $client);
Loading history...
225
226
        $token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
227
        $profile = $this->provider->getResourceOwner($token);
228
229
        $this->assertInstanceOf(ChasterAppResourceOwner::class, $profile);
230
        $this->assertEquals($userId, $profile->getId());
231
        $this->assertEquals($userId, $profile->toArray()['_id']);
232
        $this->assertEquals($userId, $profile->_id);
0 ignored issues
show
Bug Best Practice introduced by
The property _id does not exist on Austomos\OAuth2\Client\P...ChasterAppResourceOwner. Since you implemented __get, consider adding a @property annotation.
Loading history...
233
234
        $this->assertEquals($username, $profile->getUsername());
235
        $this->assertEquals($username, $profile->toArray()['username']);
236
        $this->assertEquals($username, $profile->username);
0 ignored issues
show
Bug Best Practice introduced by
The property username does not exist on Austomos\OAuth2\Client\P...ChasterAppResourceOwner. Since you implemented __get, consider adding a @property annotation.
Loading history...
237
238
        $this->assertEquals($email, $profile->getEmail());
239
        $this->assertEquals($email, $profile->toArray()['email']);
240
        $this->assertEquals($email, $profile->email);
0 ignored issues
show
Bug Best Practice introduced by
The property email does not exist on Austomos\OAuth2\Client\P...ChasterAppResourceOwner. Since you implemented __get, consider adding a @property annotation.
Loading history...
241
242
        $this->assertEquals($mockString, $profile->toArray()['mock_string']);
243
        $this->assertEquals($mockString, $profile->mock_string);
0 ignored issues
show
Bug Best Practice introduced by
The property mock_string does not exist on Austomos\OAuth2\Client\P...ChasterAppResourceOwner. Since you implemented __get, consider adding a @property annotation.
Loading history...
244
        $this->assertEquals($mockInt, $profile->toArray()['mock_int']);
245
        $this->assertEquals($mockInt, $profile->mock_int);
0 ignored issues
show
Bug Best Practice introduced by
The property mock_int does not exist on Austomos\OAuth2\Client\P...ChasterAppResourceOwner. Since you implemented __get, consider adding a @property annotation.
Loading history...
246
        $this->assertEquals($mockArray, $profile->toArray()['mock_array']);
247
        $this->assertEquals($mockArray, $profile->mock_array);
0 ignored issues
show
Bug Best Practice introduced by
The property mock_array does not exist on Austomos\OAuth2\Client\P...ChasterAppResourceOwner. Since you implemented __get, consider adding a @property annotation.
Loading history...
248
        $this->assertNull($profile->mock_null);
0 ignored issues
show
Bug Best Practice introduced by
The property mock_null does not exist on Austomos\OAuth2\Client\P...ChasterAppResourceOwner. Since you implemented __get, consider adding a @property annotation.
Loading history...
249
    }
250
251
    public function testScopes(): void
252
    {
253
        $scopeSeparator = ' ';
254
        $options = ['scope' => [uniqid('', true), uniqid('', true)]];
255
        $query = ['scope' => implode($scopeSeparator, $options['scope'])];
256
        $url = $this->provider->getAuthorizationUrl($options);
257
        $encodedScope = $this->buildQueryString($query);
258
259
        $this->assertStringContainsString($encodedScope, $url);
260
    }
261
262
    protected function setUp(): void
263
    {
264
        $this->provider = new ChasterApp(
265
            [
266
                'clientId' => 'mock_client_id',
267
                'clientSecret' => 'mock_secret',
268
                'redirectUri' => 'none',
269
            ]
270
        );
271
    }
272
}
273