1<?php
2
3namespace OAuthTest\Unit\OAuth2\Service;
4
5use OAuth\OAuth2\Service\Reddit;
6use OAuth\Common\Token\TokenInterface;
7
8class RedditTest extends \PHPUnit_Framework_TestCase
9{
10    /**
11     * @covers OAuth\OAuth2\Service\Reddit::__construct
12     */
13    public function testConstructCorrectInterfaceWithoutCustomUri()
14    {
15        $service = new Reddit(
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\Reddit::__construct
26     */
27    public function testConstructCorrectInstanceWithoutCustomUri()
28    {
29        $service = new Reddit(
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\Reddit::__construct
40     */
41    public function testConstructCorrectInstanceWithCustomUri()
42    {
43        $service = new Reddit(
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\Reddit::__construct
56     * @covers OAuth\OAuth2\Service\Reddit::getAuthorizationEndpoint
57     */
58    public function testGetAuthorizationEndpoint()
59    {
60        $service = new Reddit(
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://ssl.reddit.com/api/v1/authorize',
68            $service->getAuthorizationEndpoint()->getAbsoluteUri()
69        );
70    }
71
72    /**
73     * @covers OAuth\OAuth2\Service\Reddit::__construct
74     * @covers OAuth\OAuth2\Service\Reddit::getAccessTokenEndpoint
75     */
76    public function testGetAccessTokenEndpoint()
77    {
78        $service = new Reddit(
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(
85            'https://ssl.reddit.com/api/v1/access_token',
86            $service->getAccessTokenEndpoint()->getAbsoluteUri()
87        );
88    }
89
90    /**
91     * @covers OAuth\OAuth2\Service\Reddit::__construct
92     * @covers OAuth\OAuth2\Service\Reddit::getAuthorizationMethod
93     */
94    public function testGetAuthorizationMethod()
95    {
96        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
97        $client->expects($this->once())->method('retrieveResponse')->will($this->returnArgument(2));
98
99        $token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface');
100        $token->expects($this->once())->method('getEndOfLife')->will($this->returnValue(TokenInterface::EOL_NEVER_EXPIRES));
101        $token->expects($this->once())->method('getAccessToken')->will($this->returnValue('foo'));
102
103        $storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface');
104        $storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token));
105
106        $service = new Reddit(
107            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
108            $client,
109            $storage
110        );
111
112        $headers = $service->request('https://pieterhordijk.com/my/awesome/path');
113
114        $this->assertTrue(array_key_exists('Authorization', $headers));
115        $this->assertTrue(in_array('Bearer foo', $headers, true));
116    }
117
118    /**
119     * @covers OAuth\OAuth2\Service\Reddit::__construct
120     * @covers OAuth\OAuth2\Service\Reddit::parseAccessTokenResponse
121     */
122    public function testParseAccessTokenResponseThrowsExceptionOnNulledResponse()
123    {
124        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
125        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue(null));
126
127        $service = new Reddit(
128            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
129            $client,
130            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
131        );
132
133        $this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException');
134
135        $service->requestAccessToken('foo');
136    }
137
138    /**
139     * @covers OAuth\OAuth2\Service\Reddit::__construct
140     * @covers OAuth\OAuth2\Service\Reddit::parseAccessTokenResponse
141     */
142    public function testParseAccessTokenResponseThrowsExceptionOnError()
143    {
144        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
145        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('error=some_error'));
146
147        $service = new Reddit(
148            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
149            $client,
150            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
151        );
152
153        $this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException');
154
155        $service->requestAccessToken('foo');
156    }
157
158    /**
159     * @covers OAuth\OAuth2\Service\Reddit::__construct
160     * @covers OAuth\OAuth2\Service\Reddit::parseAccessTokenResponse
161     */
162    public function testParseAccessTokenResponseValidWithoutRefreshToken()
163    {
164        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
165        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('{"access_token":"foo","expires_in":"bar"}'));
166
167        $service = new Reddit(
168            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
169            $client,
170            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
171        );
172
173        $this->assertInstanceOf('\\OAuth\\OAuth2\\Token\\StdOAuth2Token', $service->requestAccessToken('foo'));
174    }
175
176    /**
177     * @covers OAuth\OAuth2\Service\Reddit::__construct
178     * @covers OAuth\OAuth2\Service\Reddit::parseAccessTokenResponse
179     */
180    public function testParseAccessTokenResponseValidWithRefreshToken()
181    {
182        $client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
183        $client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('{"access_token":"foo","expires_in":"bar","refresh_token":"baz"}'));
184
185        $service = new Reddit(
186            $this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
187            $client,
188            $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
189        );
190
191        $this->assertInstanceOf('\\OAuth\\OAuth2\\Token\\StdOAuth2Token', $service->requestAccessToken('foo'));
192    }
193}
194