1<?php
2
3namespace OAuthTest\Unit\OAuth2\Service;
4
5use OAuth\OAuth2\Service\Heroku;
6use OAuth\Common\Token\TokenInterface;
7
8class HerokuTest extends \PHPUnit_Framework_TestCase
9{
10    /**
11     * @covers OAuth\OAuth2\Service\Heroku::__construct
12     */
13    public function testConstructCorrectInterfaceWithoutCustomUri()
14    {
15        $service = new Heroku(
16            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
17            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
18            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
19        );
20
21        $this->assertInstanceOf('\\OAuth\\OAuth2\\Service\\ServiceInterface', $service);
22    }
23
24    /**
25     * @covers OAuth\OAuth2\Service\Heroku::__construct
26     */
27    public function testConstructCorrectInstanceWithoutCustomUri()
28    {
29        $service = new Heroku(
30            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
31            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
32            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
33        );
34
35        $this->assertInstanceOf('\\OAuth\\OAuth2\\Service\\AbstractService', $service);
36    }
37
38    /**
39     * @covers OAuth\OAuth2\Service\Heroku::__construct
40     */
41    public function testConstructCorrectInstanceWithCustomUri()
42    {
43        $service = new Heroku(
44            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
45            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
46            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface'),
47            array(),
48            $this->getMock('\\OAuth\\Common\\Http\\Uri\\UriInterface')
49        );
50
51        $this->assertInstanceOf('\\OAuth\\OAuth2\\Service\\AbstractService', $service);
52    }
53
54    /**
55     * @covers OAuth\OAuth2\Service\Heroku::__construct
56     * @covers OAuth\OAuth2\Service\Heroku::getAuthorizationEndpoint
57     */
58    public function testGetAuthorizationEndpoint()
59    {
60        $service = new Heroku(
61            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
62            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
63            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
64        );
65
66        $this->assertSame(
67            'https://id.heroku.com/oauth/authorize',
68            $service->getAuthorizationEndpoint()->getAbsoluteUri()
69        );
70    }
71
72    /**
73     * @covers OAuth\OAuth2\Service\Heroku::__construct
74     * @covers OAuth\OAuth2\Service\Heroku::getAccessTokenEndpoint
75     */
76    public function testGetAccessTokenEndpoint()
77    {
78        $service = new Heroku(
79            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
80            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
81            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
82        );
83
84        $this->assertSame('https://id.heroku.com/oauth/token', $service->getAccessTokenEndpoint()->getAbsoluteUri());
85    }
86
87    /**
88     * @covers OAuth\OAuth2\Service\Heroku::__construct
89     * @covers OAuth\OAuth2\Service\Heroku::getAuthorizationMethod
90     */
91    public function testGetAuthorizationMethod()
92    {
93        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
94        $client->expects($this->once())->method('retrieveResponse')->will($this->returnArgument(2));
95
96        $token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface');
97        $token->expects($this->once())->method('getEndOfLife')->will($this->returnValue(TokenInterface::EOL_NEVER_EXPIRES));
98        $token->expects($this->once())->method('getAccessToken')->will($this->returnValue('foo'));
99
100        $storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface');
101        $storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token));
102
103        $service = new Heroku(
104            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
105            $client,
106            $storage
107        );
108
109        $headers = $service->request('https://pieterhordijk.com/my/awesome/path');
110
111        $this->assertTrue(array_key_exists('Authorization', $headers));
112        $this->assertTrue(in_array('Bearer foo', $headers, true));
113    }
114
115    /**
116     * @covers OAuth\OAuth2\Service\Heroku::__construct
117     * @covers OAuth\OAuth2\Service\Heroku::parseAccessTokenResponse
118     */
119    public function testParseAccessTokenResponseThrowsExceptionOnNulledResponse()
120    {
121        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
122        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue(null));
123
124        $service = new Heroku(
125            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
126            $client,
127            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
128        );
129
130        $this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException');
131
132        $service->requestAccessToken('foo');
133    }
134
135    /**
136     * @covers OAuth\OAuth2\Service\Heroku::__construct
137     * @covers OAuth\OAuth2\Service\Heroku::parseAccessTokenResponse
138     */
139    public function testParseAccessTokenResponseThrowsExceptionOnErrorDescription()
140    {
141        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
142        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('error_description=some_error'));
143
144        $service = new Heroku(
145            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
146            $client,
147            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
148        );
149
150        $this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException');
151
152        $service->requestAccessToken('foo');
153    }
154
155    /**
156     * @covers OAuth\OAuth2\Service\Heroku::__construct
157     * @covers OAuth\OAuth2\Service\Heroku::parseAccessTokenResponse
158     */
159    public function testParseAccessTokenResponseThrowsExceptionOnError()
160    {
161        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
162        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('error=some_error'));
163
164        $service = new Heroku(
165            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
166            $client,
167            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
168        );
169
170        $this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException');
171
172        $service->requestAccessToken('foo');
173    }
174
175    /**
176     * @covers OAuth\OAuth2\Service\Heroku::__construct
177     * @covers OAuth\OAuth2\Service\Heroku::parseAccessTokenResponse
178     */
179    public function testParseAccessTokenResponseValidWithoutRefreshToken()
180    {
181        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
182        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('{"access_token":"foo","expires_in":"bar"}'));
183
184        $service = new Heroku(
185            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
186            $client,
187            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
188        );
189
190        $this->assertInstanceOf('\\OAuth\\OAuth2\\Token\\StdOAuth2Token', $service->requestAccessToken('foo'));
191    }
192
193    /**
194     * @covers OAuth\OAuth2\Service\Heroku::__construct
195     * @covers OAuth\OAuth2\Service\Heroku::parseAccessTokenResponse
196     */
197    public function testParseAccessTokenResponseValidWithRefreshToken()
198    {
199        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
200        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('{"access_token":"foo","expires_in":"bar","refresh_token":"baz"}'));
201
202        $service = new Heroku(
203            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
204            $client,
205            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
206        );
207
208        $this->assertInstanceOf('\\OAuth\\OAuth2\\Token\\StdOAuth2Token', $service->requestAccessToken('foo'));
209    }
210
211    /**
212     * @covers OAuth\OAuth2\Service\Heroku::__construct
213     * @covers OAuth\OAuth2\Service\Heroku::getExtraOAuthHeaders
214     */
215    public function testGetExtraOAuthHeaders()
216    {
217        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
218        $client->expects($this->once())->method('retrieveResponse')->will($this->returnCallback(function($uri, $params, $extraHeaders) {
219            \PHPUnit_Framework_Assert::assertTrue(array_key_exists('Accept', $extraHeaders));
220            \PHPUnit_Framework_Assert::assertTrue(in_array('application/vnd.heroku+json; version=3', $extraHeaders, true));
221
222            return '{"access_token":"foo","expires_in":"bar"}';
223        }));
224
225        $service = new Heroku(
226            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
227            $client,
228            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
229        );
230
231        $this->assertInstanceOf('\\OAuth\\OAuth2\\Token\\StdOAuth2Token', $service->requestAccessToken('foo'));
232    }
233
234    /**
235     * @covers OAuth\OAuth2\Service\Heroku::__construct
236     * @covers OAuth\OAuth2\Service\Heroku::getExtraApiHeaders
237     */
238    public function testGetExtraApiHeaders()
239    {
240        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
241        $client->expects($this->once())->method('retrieveResponse')->will($this->returnArgument(2));
242
243        $token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface');
244        $token->expects($this->once())->method('getEndOfLife')->will($this->returnValue(TokenInterface::EOL_NEVER_EXPIRES));
245        $token->expects($this->once())->method('getAccessToken')->will($this->returnValue('foo'));
246
247        $storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface');
248        $storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token));
249
250        $service = new Heroku(
251            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
252            $client,
253            $storage
254        );
255
256        $headers = $service->request('https://pieterhordijk.com/my/awesome/path');
257
258        $this->assertTrue(array_key_exists('Accept', $headers));
259        $this->assertSame('application/vnd.heroku+json; version=3', $headers['Accept']);
260    }
261}
262