1<?php
2
3namespace OAuthTest\Unit\OAuth2\Service;
4
5use OAuthTest\Mocks\OAuth2\Service\Mock;
6use OAuth\Common\Http\Uri\Uri;
7use OAuth\Common\Token\TokenInterface;
8
9class AbstractServiceTest extends \PHPUnit_Framework_TestCase
10{
11    /**
12     * @covers OAuth\OAuth2\Service\AbstractService::__construct
13     */
14    public function testConstructCorrectInterface()
15    {
16        $service = $this->getMockForAbstractClass(
17            '\\OAuth\\OAuth2\\Service\\AbstractService',
18            array(
19                $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
20                $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
21                $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface'),
22                array(),
23            )
24        );
25
26        $this->assertInstanceOf('\\OAuth\\OAuth2\\Service\\ServiceInterface', $service);
27    }
28
29    /**
30     * @covers OAuth\OAuth2\Service\AbstractService::__construct
31     */
32    public function testConstructCorrectParent()
33    {
34        $service = $this->getMockForAbstractClass(
35            '\\OAuth\\OAuth2\\Service\\AbstractService',
36            array(
37                $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
38                $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
39                $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface'),
40                array(),
41            )
42        );
43
44        $this->assertInstanceOf('\\OAuth\\Common\\Service\\AbstractService', $service);
45    }
46
47    /**
48     * @covers OAuth\OAuth2\Service\AbstractService::__construct
49     */
50    public function testConstructCorrectParentCustomUri()
51    {
52        $service = $this->getMockForAbstractClass(
53            '\\OAuth\\OAuth2\\Service\\AbstractService',
54            array(
55                $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
56                $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
57                $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface'),
58                array(),
59                $this->getMock('\\OAuth\\Common\\Http\\Uri\\UriInterface'),
60            )
61        );
62
63        $this->assertInstanceOf('\\OAuth\\Common\\Service\\AbstractService', $service);
64    }
65
66    /**
67     * @covers OAuth\OAuth2\Service\AbstractService::__construct
68     * @covers OAuth\OAuth2\Service\AbstractService::isValidScope
69     */
70    public function testConstructThrowsExceptionOnInvalidScope()
71    {
72        $this->setExpectedException('\\OAuth\\OAuth2\\Service\\Exception\\InvalidScopeException');
73
74        $service = new Mock(
75            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
76            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
77            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface'),
78            array('invalidscope')
79        );
80    }
81
82    /**
83     * @covers OAuth\OAuth2\Service\AbstractService::__construct
84     * @covers OAuth\OAuth2\Service\AbstractService::getAuthorizationUri
85     * @covers OAuth\OAuth2\Service\AbstractService::getAuthorizationEndpoint
86     */
87    public function testGetAuthorizationUriWithoutParametersOrScopes()
88    {
89        $credentials = $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface');
90        $credentials->expects($this->once())->method('getConsumerId')->will($this->returnValue('foo'));
91        $credentials->expects($this->once())->method('getCallbackUrl')->will($this->returnValue('bar'));
92
93        $service = new Mock(
94            $credentials,
95            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
96            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
97        );
98
99        $this->assertSame(
100            'http://pieterhordijk.com/auth?type=web_server&client_id=foo&redirect_uri=bar&response_type=code&scope=',
101            $service->getAuthorizationUri()->getAbsoluteUri()
102        );
103    }
104
105    /**
106     * @covers OAuth\OAuth2\Service\AbstractService::__construct
107     * @covers OAuth\OAuth2\Service\AbstractService::getAuthorizationUri
108     * @covers OAuth\OAuth2\Service\AbstractService::getAuthorizationEndpoint
109     */
110    public function testGetAuthorizationUriWithParametersWithoutScopes()
111    {
112        $credentials = $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface');
113        $credentials->expects($this->once())->method('getConsumerId')->will($this->returnValue('foo'));
114        $credentials->expects($this->once())->method('getCallbackUrl')->will($this->returnValue('bar'));
115
116        $service = new Mock(
117            $credentials,
118            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
119            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
120        );
121
122        $this->assertSame(
123            'http://pieterhordijk.com/auth?foo=bar&baz=beer&type=web_server&client_id=foo&redirect_uri=bar&response_type=code&scope=',
124            $service->getAuthorizationUri(array('foo' => 'bar', 'baz' => 'beer'))->getAbsoluteUri()
125        );
126    }
127
128    /**
129     * @covers OAuth\OAuth2\Service\AbstractService::__construct
130     * @covers OAuth\OAuth2\Service\AbstractService::isValidScope
131     * @covers OAuth\OAuth2\Service\AbstractService::getAuthorizationUri
132     * @covers OAuth\OAuth2\Service\AbstractService::getAuthorizationEndpoint
133     */
134    public function testGetAuthorizationUriWithParametersAndScopes()
135    {
136        $credentials = $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface');
137        $credentials->expects($this->once())->method('getConsumerId')->will($this->returnValue('foo'));
138        $credentials->expects($this->once())->method('getCallbackUrl')->will($this->returnValue('bar'));
139
140        $service = new Mock(
141            $credentials,
142            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
143            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface'),
144            array('mock', 'mock2')
145        );
146
147        $this->assertSame(
148            'http://pieterhordijk.com/auth?foo=bar&baz=beer&type=web_server&client_id=foo&redirect_uri=bar&response_type=code&scope=mock+mock2',
149            $service->getAuthorizationUri(array('foo' => 'bar', 'baz' => 'beer'))->getAbsoluteUri()
150        );
151    }
152
153    /**
154     * @covers OAuth\OAuth2\Service\AbstractService::__construct
155     * @covers OAuth\OAuth2\Service\AbstractService::requestAccessToken
156     * @covers OAuth\OAuth2\Service\AbstractService::getAccessTokenEndpoint
157     * @covers OAuth\OAuth2\Service\AbstractService::getExtraOAuthHeaders
158     * @covers OAuth\OAuth2\Service\AbstractService::parseAccessTokenResponse
159     * @covers OAuth\OAuth2\Service\AbstractService::service
160     */
161    public function testRequestAccessToken()
162    {
163        $service = new Mock(
164            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
165            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
166            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
167        );
168
169        $this->assertInstanceof('\\OAuth\\OAuth2\\Token\\StdOAuth2Token', $service->requestAccessToken('code'));
170    }
171
172    /**
173     * @covers OAuth\OAuth2\Service\AbstractService::__construct
174     * @covers OAuth\OAuth2\Service\AbstractService::request
175     * @covers OAuth\OAuth2\Service\AbstractService::determineRequestUriFromPath
176     */
177    public function testRequestThrowsExceptionWhenTokenIsExpired()
178    {
179        $tokenExpiration = new \DateTime('26-03-1984 00:00:00');
180
181        $token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface');
182        $token->expects($this->any())->method('getEndOfLife')->will($this->returnValue($tokenExpiration->format('U')));
183
184        $storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface');
185        $storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token));
186
187        $service = new Mock(
188            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
189            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
190            $storage
191        );
192
193        $this->setExpectedException('\\OAuth\\Common\\Token\\Exception\\ExpiredTokenException', 'Token expired on 03/26/1984 at 12:00:00 AM');
194
195        $service->request('https://pieterhordijk.com/my/awesome/path');
196    }
197
198    /**
199     * @covers OAuth\OAuth2\Service\AbstractService::__construct
200     * @covers OAuth\OAuth2\Service\AbstractService::request
201     * @covers OAuth\OAuth2\Service\AbstractService::determineRequestUriFromPath
202     * @covers OAuth\OAuth2\Service\AbstractService::getAuthorizationMethod
203     * @covers OAuth\OAuth2\Service\AbstractService::parseAccessTokenResponse
204     * @covers OAuth\OAuth2\Service\AbstractService::service
205     * @covers OAuth\OAuth2\Service\AbstractService::getExtraApiHeaders
206     */
207    public function testRequestOauthAuthorizationMethod()
208    {
209        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
210        $client->expects($this->once())->method('retrieveResponse')->will($this->returnArgument(2));
211
212        $token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface');
213        $token->expects($this->once())->method('getEndOfLife')->will($this->returnValue(TokenInterface::EOL_NEVER_EXPIRES));
214        $token->expects($this->once())->method('getAccessToken')->will($this->returnValue('foo'));
215
216        $storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface');
217        $storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token));
218
219        $service = new Mock(
220            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
221            $client,
222            $storage
223        );
224
225        $headers = $service->request('https://pieterhordijk.com/my/awesome/path');
226
227        $this->assertTrue(array_key_exists('Authorization', $headers));
228        $this->assertTrue(in_array('OAuth foo', $headers, true));
229    }
230
231    /**
232     * @covers OAuth\OAuth2\Service\AbstractService::__construct
233     * @covers OAuth\OAuth2\Service\AbstractService::request
234     * @covers OAuth\OAuth2\Service\AbstractService::determineRequestUriFromPath
235     * @covers OAuth\OAuth2\Service\AbstractService::getAuthorizationMethod
236     * @covers OAuth\OAuth2\Service\AbstractService::parseAccessTokenResponse
237     * @covers OAuth\OAuth2\Service\AbstractService::service
238     * @covers OAuth\OAuth2\Service\AbstractService::getExtraApiHeaders
239     */
240    public function testRequestQueryStringMethod()
241    {
242        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
243        $client->expects($this->once())->method('retrieveResponse')->will($this->returnArgument(0));
244
245        $token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface');
246        $token->expects($this->once())->method('getEndOfLife')->will($this->returnValue(TokenInterface::EOL_NEVER_EXPIRES));
247        $token->expects($this->once())->method('getAccessToken')->will($this->returnValue('foo'));
248
249        $storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface');
250        $storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token));
251
252        $service = new Mock(
253            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
254            $client,
255            $storage
256        );
257
258        $service->setAuthorizationMethod('querystring');
259
260        $uri         = $service->request('https://pieterhordijk.com/my/awesome/path');
261        $absoluteUri = parse_url($uri->getAbsoluteUri());
262
263        $this->assertSame('access_token=foo', $absoluteUri['query']);
264    }
265
266    /**
267     * @covers OAuth\OAuth2\Service\AbstractService::__construct
268     * @covers OAuth\OAuth2\Service\AbstractService::request
269     * @covers OAuth\OAuth2\Service\AbstractService::determineRequestUriFromPath
270     * @covers OAuth\OAuth2\Service\AbstractService::getAuthorizationMethod
271     * @covers OAuth\OAuth2\Service\AbstractService::parseAccessTokenResponse
272     * @covers OAuth\OAuth2\Service\AbstractService::service
273     * @covers OAuth\OAuth2\Service\AbstractService::getExtraApiHeaders
274     */
275    public function testRequestQueryStringTwoMethod()
276    {
277        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
278        $client->expects($this->once())->method('retrieveResponse')->will($this->returnArgument(0));
279
280        $token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface');
281        $token->expects($this->once())->method('getEndOfLife')->will($this->returnValue(TokenInterface::EOL_NEVER_EXPIRES));
282        $token->expects($this->once())->method('getAccessToken')->will($this->returnValue('foo'));
283
284        $storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface');
285        $storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token));
286
287        $service = new Mock(
288            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
289            $client,
290            $storage
291        );
292
293        $service->setAuthorizationMethod('querystring2');
294
295        $uri         = $service->request('https://pieterhordijk.com/my/awesome/path');
296        $absoluteUri = parse_url($uri->getAbsoluteUri());
297
298        $this->assertSame('oauth2_access_token=foo', $absoluteUri['query']);
299    }
300
301    /**
302     * @covers OAuth\OAuth2\Service\AbstractService::__construct
303     * @covers OAuth\OAuth2\Service\AbstractService::request
304     * @covers OAuth\OAuth2\Service\AbstractService::determineRequestUriFromPath
305     * @covers OAuth\OAuth2\Service\AbstractService::getAuthorizationMethod
306     * @covers OAuth\OAuth2\Service\AbstractService::parseAccessTokenResponse
307     * @covers OAuth\OAuth2\Service\AbstractService::service
308     * @covers OAuth\OAuth2\Service\AbstractService::getExtraApiHeaders
309     */
310    public function testRequestBearerMethod()
311    {
312        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
313        $client->expects($this->once())->method('retrieveResponse')->will($this->returnArgument(2));
314
315        $token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface');
316        $token->expects($this->once())->method('getEndOfLife')->will($this->returnValue(TokenInterface::EOL_NEVER_EXPIRES));
317        $token->expects($this->once())->method('getAccessToken')->will($this->returnValue('foo'));
318
319        $storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface');
320        $storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token));
321
322        $service = new Mock(
323            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
324            $client,
325            $storage
326        );
327
328        $service->setAuthorizationMethod('bearer');
329
330        $headers = $service->request('https://pieterhordijk.com/my/awesome/path');
331
332        $this->assertTrue(array_key_exists('Authorization', $headers));
333        $this->assertTrue(in_array('Bearer foo', $headers, true));
334    }
335
336    /**
337     * @covers OAuth\OAuth2\Service\AbstractService::__construct
338     * @covers OAuth\OAuth2\Service\AbstractService::getStorage
339     */
340    public function testGetStorage()
341    {
342        $service = new Mock(
343            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
344            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
345            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
346        );
347
348        $this->assertInstanceOf('\\OAuth\\Common\\Storage\\TokenStorageInterface', $service->getStorage());
349    }
350
351    /**
352     * @covers OAuth\OAuth2\Service\AbstractService::__construct
353     * @covers OAuth\OAuth2\Service\AbstractService::refreshAccessToken
354     * @covers OAuth\OAuth2\Service\AbstractService::getAccessTokenEndpoint
355     * @covers OAuth\OAuth2\Service\AbstractService::getExtraOAuthHeaders
356     * @covers OAuth\OAuth2\Service\AbstractService::parseAccessTokenResponse
357     */
358    public function testRefreshAccessTokenSuccess()
359    {
360        $service = new Mock(
361            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
362            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
363            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
364        );
365
366        $token = $this->getMock('\\OAuth\\OAuth2\\Token\\StdOAuth2Token');
367        $token->expects($this->once())->method('getRefreshToken')->will($this->returnValue('foo'));
368
369        $this->assertInstanceOf('\\OAuth\\OAuth2\\Token\\StdOAuth2Token', $service->refreshAccessToken($token));
370    }
371
372    /**
373     * @covers OAuth\OAuth2\Service\AbstractService::__construct
374     * @covers OAuth\OAuth2\Service\AbstractService::isValidScope
375     */
376    public function testIsValidScopeTrue()
377    {
378        $service = new Mock(
379            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
380            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
381            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
382        );
383
384        $this->assertTrue($service->isValidScope('mock'));
385    }
386
387    /**
388     * @covers OAuth\OAuth2\Service\AbstractService::__construct
389     * @covers OAuth\OAuth2\Service\AbstractService::isValidScope
390     */
391    public function testIsValidScopeFalse()
392    {
393        $service = new Mock(
394            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
395            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
396            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
397        );
398
399        $this->assertFalse($service->isValidScope('invalid'));
400    }
401}
402