1<?php
2
3namespace OAuthTest\Unit\OAuth2\Service;
4
5use OAuth\OAuth2\Service\GitHub;
6use OAuth\Common\Token\TokenInterface;
7
8class GitHubTest extends \PHPUnit_Framework_TestCase
9{
10    /**
11     * @covers OAuth\OAuth2\Service\GitHub::__construct
12     */
13    public function testConstructCorrectInterfaceWithoutCustomUri()
14    {
15        $service = new GitHub(
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\GitHub::__construct
26     */
27    public function testConstructCorrectInstanceWithoutCustomUri()
28    {
29        $service = new GitHub(
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\GitHub::__construct
40     */
41    public function testConstructCorrectInstanceWithCustomUri()
42    {
43        $service = new GitHub(
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\GitHub::__construct
56     * @covers OAuth\OAuth2\Service\GitHub::getAuthorizationEndpoint
57     */
58    public function testGetAuthorizationEndpoint()
59    {
60        $service = new GitHub(
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('https://github.com/login/oauth/authorize', $service->getAuthorizationEndpoint()->getAbsoluteUri());
67    }
68
69    /**
70     * @covers OAuth\OAuth2\Service\GitHub::__construct
71     * @covers OAuth\OAuth2\Service\GitHub::getAccessTokenEndpoint
72     */
73    public function testGetAccessTokenEndpoint()
74    {
75        $service = new GitHub(
76            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
77            $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
78            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
79        );
80
81        $this->assertSame('https://github.com/login/oauth/access_token', $service->getAccessTokenEndpoint()->getAbsoluteUri());
82    }
83
84    /**
85     * @covers OAuth\OAuth2\Service\GitHub::__construct
86     * @covers OAuth\OAuth2\Service\GitHub::getAuthorizationMethod
87     */
88    public function testGetAuthorizationMethod()
89    {
90        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
91        $client->expects($this->once())->method('retrieveResponse')->will($this->returnArgument(0));
92
93        $token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface');
94        $token->expects($this->once())->method('getEndOfLife')->will($this->returnValue(TokenInterface::EOL_NEVER_EXPIRES));
95        $token->expects($this->once())->method('getAccessToken')->will($this->returnValue('foo'));
96
97        $storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface');
98        $storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token));
99
100        $service = new GitHub(
101            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
102            $client,
103            $storage
104        );
105
106        $uri         = $service->request('https://pieterhordijk.com/my/awesome/path');
107        $absoluteUri = parse_url($uri->getAbsoluteUri());
108
109        $this->assertSame('access_token=foo', $absoluteUri['query']);
110    }
111
112    /**
113     * @covers OAuth\OAuth2\Service\GitHub::__construct
114     * @covers OAuth\OAuth2\Service\GitHub::parseAccessTokenResponse
115     */
116    public function testParseAccessTokenResponseThrowsExceptionOnNulledResponse()
117    {
118        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
119        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue(null));
120
121        $service = new GitHub(
122            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
123            $client,
124            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
125        );
126
127        $this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException');
128
129        $service->requestAccessToken('foo');
130    }
131
132    /**
133     * @covers OAuth\OAuth2\Service\GitHub::__construct
134     * @covers OAuth\OAuth2\Service\GitHub::parseAccessTokenResponse
135     */
136    public function testParseAccessTokenResponseThrowsExceptionOnError()
137    {
138        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
139        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('{"error":"some_error"}'));
140
141        $service = new GitHub(
142            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
143            $client,
144            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
145        );
146
147        $this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException');
148
149        $service->requestAccessToken('foo');
150    }
151
152    /**
153     * @covers OAuth\OAuth2\Service\GitHub::__construct
154     * @covers OAuth\OAuth2\Service\GitHub::parseAccessTokenResponse
155     */
156    public function testParseAccessTokenResponseValidWithoutRefreshToken()
157    {
158        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
159        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('{"access_token":"foo","expires_in":"bar"}'));
160
161        $service = new GitHub(
162            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
163            $client,
164            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
165        );
166
167        $this->assertInstanceOf('\\OAuth\\OAuth2\\Token\\StdOAuth2Token', $service->requestAccessToken('foo'));
168    }
169
170    /**
171     * @covers OAuth\OAuth2\Service\GitHub::__construct
172     * @covers OAuth\OAuth2\Service\GitHub::getExtraOAuthHeaders
173     */
174    public function testGetExtraOAuthHeaders()
175    {
176        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
177        $client->expects($this->once())->method('retrieveResponse')->will($this->returnCallback(function($uri, $params, $extraHeaders) {
178            \PHPUnit_Framework_Assert::assertTrue(array_key_exists('Accept', $extraHeaders));
179            \PHPUnit_Framework_Assert::assertTrue(in_array('application/json', $extraHeaders, true));
180
181            return '{"access_token":"foo","expires_in":"bar"}';
182        }));
183
184        $service = new GitHub(
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\GitHub::__construct
195     * @covers OAuth\OAuth2\Service\GitHub::getExtraApiHeaders
196     */
197    public function testGetExtraApiHeaders()
198    {
199        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
200        $client->expects($this->once())->method('retrieveResponse')->will($this->returnArgument(2));
201
202        $token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface');
203        $token->expects($this->once())->method('getEndOfLife')->will($this->returnValue(TokenInterface::EOL_NEVER_EXPIRES));
204        $token->expects($this->once())->method('getAccessToken')->will($this->returnValue('foo'));
205
206        $storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface');
207        $storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token));
208
209        $service = new GitHub(
210            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
211            $client,
212            $storage
213        );
214
215        $headers = $service->request('https://pieterhordijk.com/my/awesome/path');
216
217        $this->assertTrue(array_key_exists('Accept', $headers));
218        $this->assertSame('application/vnd.github.beta+json', $headers['Accept']);
219    }
220}
221