Completed
Push — master ( 4c45e0...1a7b7a )
by Дмитрий
02:22
created

AbstractProviderTestCase::getProvider()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 27
rs 9.6666
c 0
b 0
f 0
cc 3
nc 4
nop 2
1
<?php
2
/**
3
 * SocialConnect project
4
 * @author: Patsura Dmitry https://github.com/ovr <[email protected]>
5
 */
6
7
namespace Test\OAuth2\Provider;
8
9
use ReflectionClass;
10
use SocialConnect\Common\Http\Client\ClientInterface;
11
use SocialConnect\OAuth2\AccessToken;
12
use SocialConnect\Provider\Consumer;
13
use SocialConnect\Provider\Session\SessionInterface;
14
use Test\TestCase;
15
16
abstract class AbstractProviderTestCase extends TestCase
17
{
18
    /**
19
     * @return string
20
     */
21
    abstract protected function getProviderClassName();
22
23
    /**
24
     * @param mixed $responseData
25
     * @param int $responseCode
26
     * @param bool $mockFromRequest
27
     * @return \PHPUnit_Framework_MockObject_MockObject
28
     */
29
    protected function mockClientResponse($responseData, $responseCode = 200, $mockFromRequest = false)
30
    {
31
        $mockedHttpClient = $this->getMockBuilder(\SocialConnect\Common\Http\Client\Curl::class)
32
            ->getMock();
33
34
        $response = new \SocialConnect\Common\Http\Response(
35
            $responseCode,
36
            $responseData,
37
            []
38
        );
39
40
        if ($mockFromRequest) {
41
            $mockedHttpClient->expects($this->once())
42
                ->method('fromRequest')
43
                ->willReturn($response);
44
        } else {
45
            $mockedHttpClient->expects($this->once())
46
                ->method('request')
47
                ->willReturn($response);
48
        }
49
50
        return $mockedHttpClient;
51
    }
52
53
    /**
54
     * @param object $object
55
     * @param string $name
56
     * @param array $params
57
     * @return mixed
58
     */
59
    protected static function callProtectedMethod($object, $name, array $params = [])
60
    {
61
        $class = new ReflectionClass($object);
62
63
        $method = $class->getMethod($name);
64
        $method->setAccessible(true);
65
66
        return $method->invokeArgs($object, $params);
67
    }
68
69
    /**
70
     * @param ClientInterface|null $httpClient
71
     * @return \SocialConnect\OAuth2\AbstractProvider
72
     */
73
    protected function getProvider(ClientInterface $httpClient = null, SessionInterface $session = null)
74
    {
75
        if (!$httpClient) {
76
            $httpClient = $this->getMockBuilder(\SocialConnect\Common\Http\Client\Curl::class)
77
                ->disableOriginalConstructor()
78
                ->disableProxyingToOriginalMethods()
79
                ->getMock();
80
        }
81
82
        if (!$session) {
83
            $session = $this->getMockBuilder(\SocialConnect\Provider\Session\Session::class)
84
                ->disableOriginalConstructor()
85
                ->disableProxyingToOriginalMethods()
86
                ->getMock();
87
        }
88
89
        $className = $this->getProviderClassName();
90
91
        return new $className(
92
            $httpClient,
93
            $session,
94
            new Consumer(
95
                'unknown',
96
                'unkwown'
97
            ),
98
            [
99
                'redirectUri' => 'http://localhost:8000/'
100
            ]
101
        );
102
    }
103
104
    /**
105
     * @expectedException \InvalidArgumentException
106
     * @expectedExceptionMessage Parameter $code must be a string
107
     */
108
    public function testGetAccessTokenFail()
109
    {
110
        $this->getProvider()->getAccessToken(null);
111
    }
112
113
    public function testGetBaseUriReturnString()
114
    {
115
        parent::assertInternalType('string', $this->getProvider()->getBaseUri());
116
    }
117
118
    public function testGetAuthorizeUriReturnString()
119
    {
120
        parent::assertInternalType('string', $this->getProvider()->getAuthorizeUri());
121
    }
122
123
    public function testGetRequestTokenUriReturnString()
124
    {
125
        parent::assertInternalType('string', $this->getProvider()->getRequestTokenUri());
126
    }
127
128
    public function testGetNameReturnString()
129
    {
130
        parent::assertInternalType('string', $this->getProvider()->getName());
131
    }
132
133
    public function testMakeAuthUrl()
134
    {
135
        $provider = $this->getProvider();
136
137
        $authUrl = $provider->makeAuthUrl();
138
        parent::assertInternalType('string', $authUrl);
139
140
        /**
141
         * Auth url must be started from getAuthorizeUri
142
         */
143
        parent::assertSame(
144
            0,
145
            strpos($authUrl, $provider->getAuthorizeUri())
146
        );
147
148
        $query = parse_url($authUrl, PHP_URL_QUERY);
149
        parent::assertInternalType('string', $query);
150
151
        parse_str($query, $queryParameters);
152
        parent::assertInternalType('array', $queryParameters);
153
154
        parent::assertArrayHasKey('client_id', $queryParameters);
155
        parent::assertArrayHasKey('redirect_uri', $queryParameters);
156
        parent::assertArrayHasKey('response_type', $queryParameters);
157
        parent::assertArrayHasKey('state', $queryParameters);
158
    }
159
160
    /**
161
     * @expectedException \SocialConnect\Provider\Exception\InvalidResponse
162
     * @expectedExceptionMessage API response with error code
163
     */
164
    public function testGetAccessTokenResponseInternalServerErrorFail()
165
    {
166
        $this->getProvider(
167
            $this->mockClientResponse(
168
                null,
169
                500,
170
                true
171
            )
172
        )->getAccessToken('XXXXXXXXXXXX');
173
    }
174
175
    /**
176
     * @expectedException \SocialConnect\Provider\Exception\InvalidResponse
177
     * @expectedExceptionMessage API response with error code
178
     */
179
    public function testGetIdentityInternalServerError()
180
    {
181
        $mockedHttpClient = $this->mockClientResponse(
182
            [],
183
            500
184
        );
185
186
        $this->getProvider($mockedHttpClient)->getIdentity(
187
            new AccessToken(
188
                [
189
                    'access_token' => '123456789'
190
                ]
191
            )
192
        );
193
    }
194
195
    /**
196
     * @expectedException \SocialConnect\Provider\Exception\InvalidResponse
197
     * @expectedExceptionMessage API response is not a valid JSON object
198
     */
199
    public function testGetIdentityNotValidJSON()
200
    {
201
        $mockedHttpClient = $this->mockClientResponse(
202
            'NOT VALID JSON',
203
            200
204
        );
205
206
        $this->getProvider($mockedHttpClient)->getIdentity(
207
            new AccessToken(
208
                [
209
                    'access_token' => '123456789'
210
                ]
211
            )
212
        );
213
    }
214
215
    /**
216
     * @expectedException \SocialConnect\Provider\Exception\InvalidAccessToken
217
     */
218
    public function testParseTokenNotToken()
219
    {
220
        $this->getProvider()->parseToken(
221
            json_encode([])
222
        );
223
    }
224
225
    /**
226
     * @expectedException \SocialConnect\Provider\Exception\InvalidAccessToken
227
     */
228
    public function testParseTokenNotValidJSON()
229
    {
230
        $this->getProvider()->parseToken(
231
            'lelelelel'
232
        );
233
    }
234
235
    public function testParseTokenSuccess()
236
    {
237
        $expectedToken = 'XXXXXXXX';
238
        $expectedUserId = 123456;
239
240
        $accessToken = $this->getProvider()->parseToken(
241
            json_encode(
242
                [
243
                    'access_token' => $expectedToken,
244
                    'user_id' => $expectedUserId
245
                ]
246
            )
247
        );
248
249
        parent::assertInstanceOf(AccessToken::class, $accessToken);
250
        parent::assertSame($expectedToken, $accessToken->getToken());
251
        parent::assertSame($expectedUserId, $accessToken->getUserId());
252
    }
253
254
    /**
255
     * @expectedException \SocialConnect\OAuth2\Exception\Unauthorized
256
     */
257
    public function testAccessDenied()
258
    {
259
        $sessionMock = $this->getMockBuilder(\SocialConnect\Provider\Session\Session::class)
260
            ->disableOriginalConstructor()
261
            ->disableProxyingToOriginalMethods()
262
            ->getMock();
263
264
        $provider = $this->getProvider(null, $sessionMock);
265
266
        $provider->getAccessTokenByRequestParameters(['error' => 'access_denied']);
267
    }
268
269
    public function testGenerateState()
270
    {
271
        $state = $this->callProtectedMethod($this->getProvider(), 'generateState', []);
272
273
        parent::assertInternalType('string', $state);
274
        parent::assertEquals(32, mb_strlen($state));
275
    }
276
}
277