OAuthTwoTest.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <?php
  2. namespace SocialiteProviders\Manager\Test;
  3. use Illuminate\Contracts\Session\Session as SessionContract;
  4. use Illuminate\Http\Request;
  5. use Laravel\Socialite\Two\InvalidStateException;
  6. use Laravel\Socialite\Two\User as SocialiteOAuth2User;
  7. use Mockery as m;
  8. use PHPUnit\Framework\TestCase;
  9. use SocialiteProviders\Manager\OAuth2\User;
  10. use SocialiteProviders\Manager\Test\Stubs\OAuthTwoTestProviderStub;
  11. use stdClass;
  12. use Symfony\Component\HttpFoundation\RedirectResponse;
  13. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  14. class OAuthTwoTest extends TestCase
  15. {
  16. use ManagerTestTrait;
  17. /**
  18. * @test
  19. */
  20. public function redirectGeneratesTheProperSymfonyRedirectResponse(): void
  21. {
  22. $session = m::mock(SessionContract::class);
  23. $request = Request::create('foo');
  24. $request->setLaravelSession($session);
  25. $session
  26. ->shouldReceive('put')
  27. ->once();
  28. $provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect');
  29. $response = $provider->redirect();
  30. $this->assertInstanceOf(RedirectResponse::class, $response);
  31. $this->assertSame('http://auth.url', $response->getTargetUrl());
  32. }
  33. /**
  34. * @test
  35. */
  36. public function it_can_return_the_service_container_key(): void
  37. {
  38. $result = OAuthTwoTestProviderStub::serviceContainerKey(OAuthTwoTestProviderStub::PROVIDER_NAME);
  39. $this->assertSame('SocialiteProviders.config.test', $result);
  40. }
  41. /**
  42. * @test
  43. */
  44. public function userReturnsAUserInstanceForTheAuthenticatedRequest(): void
  45. {
  46. $session = m::mock(SessionInterface::class);
  47. $request = Request::create('foo', 'GET', [
  48. 'state' => str_repeat('A', 40),
  49. 'code' => 'code',
  50. ]);
  51. $request->setSession($session);
  52. $session
  53. ->shouldReceive('pull')
  54. ->once()
  55. ->with('state')
  56. ->andReturn(str_repeat('A', 40));
  57. $provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect_uri');
  58. $provider->http = m::mock(stdClass::class);
  59. $provider->http
  60. ->shouldReceive('post')
  61. ->once()
  62. ->with('http://token.url', [
  63. 'headers' => [
  64. 'Accept' => 'application/json',
  65. ],
  66. 'form_params' => [
  67. 'grant_type' => 'authorization_code',
  68. 'client_id' => 'client_id',
  69. 'client_secret' => 'client_secret',
  70. 'code' => 'code',
  71. 'redirect_uri' => 'redirect_uri',
  72. ],
  73. ])
  74. ->andReturn($response = m::mock(stdClass::class));
  75. $response
  76. ->shouldReceive('getBody')
  77. ->andReturn('{"access_token": "access_token", "test": "test"}');
  78. $user = $provider->user();
  79. $this->assertInstanceOf(User::class, $user);
  80. $this->assertSame('foo', $user->id);
  81. }
  82. /**
  83. * @test
  84. */
  85. public function access_token_response_body_is_accessible_from_user(): void
  86. {
  87. $session = m::mock(SessionInterface::class);
  88. $accessTokenResponseBody = '{"access_token": "access_token", "test": "test"}';
  89. $request = Request::create('foo', 'GET', [
  90. 'state' => str_repeat('A', 40),
  91. 'code' => 'code',
  92. ]);
  93. $request->setSession($session);
  94. $session
  95. ->shouldReceive('pull')
  96. ->once()
  97. ->with('state')
  98. ->andReturn(str_repeat('A', 40));
  99. $provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect_uri');
  100. $provider->http = m::mock(stdClass::class);
  101. $provider->http
  102. ->shouldReceive('post')
  103. ->once()
  104. ->with('http://token.url', [
  105. 'headers' => [
  106. 'Accept' => 'application/json',
  107. ],
  108. 'form_params' => [
  109. 'grant_type' => 'authorization_code',
  110. 'client_id' => 'client_id',
  111. 'client_secret' => 'client_secret',
  112. 'code' => 'code',
  113. 'redirect_uri' => 'redirect_uri',
  114. ],
  115. ])
  116. ->andReturn($response = m::mock(stdClass::class));
  117. $response
  118. ->shouldReceive('getBody')
  119. ->andReturn($accessTokenResponseBody);
  120. $user = $provider->user();
  121. $this->assertInstanceOf(User::class, $user);
  122. $this->assertSame('foo', $user->id);
  123. $this->assertSame($user->accessTokenResponseBody, json_decode($accessTokenResponseBody, true));
  124. }
  125. /**
  126. * @test
  127. */
  128. public function regular_laravel_socialite_class_works_as_well(): void
  129. {
  130. $session = m::mock(SessionInterface::class);
  131. $accessTokenResponseBody = '{"access_token": "access_token", "test": "test"}';
  132. $request = Request::create('foo', 'GET', [
  133. 'state' => str_repeat('A', 40),
  134. 'code' => 'code',
  135. ]);
  136. $request->setSession($session);
  137. $session
  138. ->shouldReceive('pull')
  139. ->once()
  140. ->with('state')
  141. ->andReturn(str_repeat('A', 40));
  142. $provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect_uri');
  143. $provider->http = m::mock(stdClass::class);
  144. $provider->http
  145. ->shouldReceive('post')
  146. ->once()
  147. ->with('http://token.url', [
  148. 'headers' => [
  149. 'Accept' => 'application/json',
  150. ],
  151. 'form_params' => [
  152. 'grant_type' => 'authorization_code',
  153. 'client_id' => 'client_id',
  154. 'client_secret' => 'client_secret',
  155. 'code' => 'code',
  156. 'redirect_uri' => 'redirect_uri',
  157. ],
  158. ])
  159. ->andReturn($response = m::mock(stdClass::class));
  160. $response
  161. ->shouldReceive('getBody')
  162. ->andReturn($accessTokenResponseBody);
  163. $user = $provider->user();
  164. $this->assertInstanceOf(SocialiteOAuth2User::class, $user);
  165. $this->assertSame('foo', $user->id);
  166. }
  167. /**
  168. * @test
  169. */
  170. public function exceptionIsThrownIfStateIsInvalid(): void
  171. {
  172. $this->expectExceptionObject(new InvalidStateException());
  173. $session = m::mock(SessionInterface::class);
  174. $request = Request::create('foo', 'GET', [
  175. 'state' => str_repeat('B', 40),
  176. 'code' => 'code',
  177. ]);
  178. $request->setSession($session);
  179. $session
  180. ->shouldReceive('pull')
  181. ->once()
  182. ->with('state')
  183. ->andReturn(str_repeat('A', 40));
  184. $provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect');
  185. $provider->user();
  186. }
  187. /**
  188. * @test
  189. */
  190. public function exceptionIsThrownIfStateIsNotSet(): void
  191. {
  192. $this->expectExceptionObject(new InvalidStateException());
  193. $session = m::mock(SessionInterface::class);
  194. $request = Request::create('foo', 'GET', [
  195. 'state' => 'state',
  196. 'code' => 'code',
  197. ]);
  198. $request->setSession($session);
  199. $session
  200. ->shouldReceive('pull')
  201. ->once()
  202. ->with('state');
  203. $provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect');
  204. $provider->user();
  205. }
  206. /**
  207. * @test
  208. */
  209. public function userObjectShouldBeCachedOnFirstCall(): void
  210. {
  211. $session = m::mock(SessionInterface::class);
  212. $accessTokenResponseBody = '{"access_token": "access_token", "test": "test"}';
  213. $request = Request::create('foo', 'GET', [
  214. 'state' => str_repeat('A', 40),
  215. 'code' => 'code',
  216. ]);
  217. $request->setSession($session);
  218. $session
  219. ->shouldReceive('pull')
  220. ->once()
  221. ->with('state')
  222. ->andReturn(str_repeat('A', 40));
  223. $provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect_uri');
  224. $provider->http = m::mock(stdClass::class);
  225. $provider->http
  226. ->shouldReceive('post')
  227. ->once()
  228. ->with('http://token.url', [
  229. 'headers' => [
  230. 'Accept' => 'application/json',
  231. ],
  232. 'form_params' => [
  233. 'grant_type' => 'authorization_code',
  234. 'client_id' => 'client_id',
  235. 'client_secret' => 'client_secret',
  236. 'code' => 'code',
  237. 'redirect_uri' => 'redirect_uri',
  238. ],
  239. ])
  240. ->andReturn($response = m::mock(stdClass::class));
  241. $response
  242. ->shouldReceive('getBody')
  243. ->andReturn($accessTokenResponseBody);
  244. $reflection = new \ReflectionClass($provider);
  245. $reflectionProperty = $reflection->getProperty('user');
  246. $reflectionProperty->setAccessible(true);
  247. $this->assertNull($reflectionProperty->getValue($provider));
  248. $firstCall = $provider->user();
  249. $this->assertInstanceOf(SocialiteOAuth2User::class, $reflectionProperty->getValue($provider));
  250. $secondCall = $provider->user();
  251. $this->assertSame($firstCall, $secondCall);
  252. }
  253. }