XingServerTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php namespace League\OAuth1\Client\Tests;
  2. use InvalidArgumentException;
  3. use League\OAuth1\Client\Credentials\ClientCredentials;
  4. use League\OAuth1\Client\Server\Xing;
  5. use Mockery as m;
  6. use PHPUnit\Framework\TestCase;
  7. use Psr\Http\Message\ResponseInterface;
  8. class XingTest extends TestCase
  9. {
  10. protected function tearDown(): void
  11. {
  12. m::close();
  13. parent::tearDown();
  14. }
  15. public function testCreatingWithArray()
  16. {
  17. $server = new Xing($this->getMockClientCredentials());
  18. $credentials = $server->getClientCredentials();
  19. $this->assertInstanceOf('League\OAuth1\Client\Credentials\ClientCredentialsInterface', $credentials);
  20. $this->assertEquals($this->getApplicationKey(), $credentials->getIdentifier());
  21. $this->assertEquals('mysecret', $credentials->getSecret());
  22. $this->assertEquals('http://app.dev/', $credentials->getCallbackUri());
  23. }
  24. public function testCreatingWithObject()
  25. {
  26. $credentials = new ClientCredentials;
  27. $credentials->setIdentifier('myidentifier');
  28. $credentials->setSecret('mysecret');
  29. $credentials->setCallbackUri('http://app.dev/');
  30. $server = new Xing($credentials);
  31. $this->assertEquals($credentials, $server->getClientCredentials());
  32. }
  33. public function testGettingTemporaryCredentials()
  34. {
  35. $server = m::mock('League\OAuth1\Client\Server\Xing[createHttpClient]', [$this->getMockClientCredentials()]);
  36. $server->shouldReceive('createHttpClient')->andReturn($client = m::mock('stdClass'));
  37. $me = $this;
  38. $client->shouldReceive('post')->with('https://api.xing.com/v1/request_token', m::on(function ($options) use ($me) {
  39. $headers = $options['headers'];
  40. $me->assertTrue(isset($headers['Authorization']));
  41. // OAuth protocol specifies a strict number of
  42. // headers should be sent, in the correct order.
  43. // We'll validate that here.
  44. $pattern = '/OAuth oauth_consumer_key=".*?", oauth_nonce="[a-zA-Z0-9]+", oauth_signature_method="HMAC-SHA1", oauth_timestamp="\d{10}", oauth_version="1.0", oauth_callback="' . preg_quote('http%3A%2F%2Fapp.dev%2F', '/') . '", oauth_signature=".*?"/';
  45. $matches = preg_match($pattern, $headers['Authorization']);
  46. $me->assertEquals(1, $matches, 'Asserting that the authorization header contains the correct expression.');
  47. return true;
  48. }))->once()->andReturn($response = m::mock(ResponseInterface::class));
  49. $response->shouldReceive('getBody')->andReturn('oauth_token=temporarycredentialsidentifier&oauth_token_secret=temporarycredentialssecret&oauth_callback_confirmed=true');
  50. $credentials = $server->getTemporaryCredentials();
  51. $this->assertInstanceOf('League\OAuth1\Client\Credentials\TemporaryCredentials', $credentials);
  52. $this->assertEquals('temporarycredentialsidentifier', $credentials->getIdentifier());
  53. $this->assertEquals('temporarycredentialssecret', $credentials->getSecret());
  54. }
  55. public function testGettingDefaultAuthorizationUrl()
  56. {
  57. $server = new Xing($this->getMockClientCredentials());
  58. $expected = 'https://api.xing.com/v1/authorize?oauth_token=foo';
  59. $this->assertEquals($expected, $server->getAuthorizationUrl('foo'));
  60. $credentials = m::mock('League\OAuth1\Client\Credentials\TemporaryCredentials');
  61. $credentials->shouldReceive('getIdentifier')->andReturn('foo');
  62. $this->assertEquals($expected, $server->getAuthorizationUrl($credentials));
  63. }
  64. public function testGettingTokenCredentialsFailsWithManInTheMiddle()
  65. {
  66. $server = new Xing($this->getMockClientCredentials());
  67. $credentials = m::mock('League\OAuth1\Client\Credentials\TemporaryCredentials');
  68. $credentials->shouldReceive('getIdentifier')->andReturn('foo');
  69. $this->expectException(InvalidArgumentException::class);
  70. $server->getTokenCredentials($credentials, 'bar', 'verifier');
  71. }
  72. public function testGettingTokenCredentials()
  73. {
  74. $server = m::mock('League\OAuth1\Client\Server\Xing[createHttpClient]', [$this->getMockClientCredentials()]);
  75. $temporaryCredentials = m::mock('League\OAuth1\Client\Credentials\TemporaryCredentials');
  76. $temporaryCredentials->shouldReceive('getIdentifier')->andReturn('temporarycredentialsidentifier');
  77. $temporaryCredentials->shouldReceive('getSecret')->andReturn('temporarycredentialssecret');
  78. $server->shouldReceive('createHttpClient')->andReturn($client = m::mock('stdClass'));
  79. $me = $this;
  80. $client->shouldReceive('post')->with('https://api.xing.com/v1/access_token', m::on(function ($options) use ($me) {
  81. $headers = $options['headers'];
  82. $body = $options['form_params'];
  83. $me->assertTrue(isset($headers['Authorization']));
  84. // OAuth protocol specifies a strict number of
  85. // headers should be sent, in the correct order.
  86. // We'll validate that here.
  87. $pattern = '/OAuth oauth_consumer_key=".*?", oauth_nonce="[a-zA-Z0-9]+", oauth_signature_method="HMAC-SHA1", oauth_timestamp="\d{10}", oauth_version="1.0", oauth_token="temporarycredentialsidentifier", oauth_signature=".*?"/';
  88. $matches = preg_match($pattern, $headers['Authorization']);
  89. $me->assertEquals(1, $matches, 'Asserting that the authorization header contains the correct expression.');
  90. $me->assertSame($body, ['oauth_verifier' => 'myverifiercode']);
  91. return true;
  92. }))->once()->andReturn($response = m::mock(ResponseInterface::class));
  93. $response->shouldReceive('getBody')->andReturn('oauth_token=tokencredentialsidentifier&oauth_token_secret=tokencredentialssecret');
  94. $credentials = $server->getTokenCredentials($temporaryCredentials, 'temporarycredentialsidentifier', 'myverifiercode');
  95. $this->assertInstanceOf('League\OAuth1\Client\Credentials\TokenCredentials', $credentials);
  96. $this->assertEquals('tokencredentialsidentifier', $credentials->getIdentifier());
  97. $this->assertEquals('tokencredentialssecret', $credentials->getSecret());
  98. }
  99. public function testGettingUserDetails()
  100. {
  101. $server = m::mock('League\OAuth1\Client\Server\Xing[createHttpClient,protocolHeader]', [$this->getMockClientCredentials()]);
  102. $temporaryCredentials = m::mock('League\OAuth1\Client\Credentials\TokenCredentials');
  103. $temporaryCredentials->shouldReceive('getIdentifier')->andReturn('tokencredentialsidentifier');
  104. $temporaryCredentials->shouldReceive('getSecret')->andReturn('tokencredentialssecret');
  105. $server->shouldReceive('createHttpClient')->andReturn($client = m::mock('stdClass'));
  106. $me = $this;
  107. $client->shouldReceive('get')->with('https://api.xing.com/v1/users/me', m::on(function ($options) use ($me) {
  108. $headers = $options['headers'];
  109. $me->assertTrue(isset($headers['Authorization']));
  110. // OAuth protocol specifies a strict number of
  111. // headers should be sent, in the correct order.
  112. // We'll validate that here.
  113. $pattern = '/OAuth oauth_consumer_key=".*?", oauth_nonce="[a-zA-Z0-9]+", oauth_signature_method="HMAC-SHA1", oauth_timestamp="\d{10}", oauth_version="1.0", oauth_token="tokencredentialsidentifier", oauth_signature=".*?"/';
  114. $matches = preg_match($pattern, $headers['Authorization']);
  115. $me->assertEquals(1, $matches, 'Asserting that the authorization header contains the correct expression.');
  116. return true;
  117. }))->once()->andReturn($response = m::mock(ResponseInterface::class));
  118. $response->shouldReceive('getBody')->once()->andReturn($this->getUserPayload());
  119. $user = $server->getUserDetails($temporaryCredentials);
  120. $this->assertInstanceOf('League\OAuth1\Client\Server\User', $user);
  121. $this->assertEquals('Roman Gelembjuk', $user->name);
  122. $this->assertEquals('17144430_0f9409', $server->getUserUid($temporaryCredentials));
  123. $this->assertEquals('XXXXXXXXXX@gmail.com', $server->getUserEmail($temporaryCredentials));
  124. $this->assertEquals('Roman Gelembjuk', $server->getUserScreenName($temporaryCredentials));
  125. }
  126. protected function getMockClientCredentials()
  127. {
  128. return [
  129. 'identifier' => $this->getApplicationKey(),
  130. 'secret' => 'mysecret',
  131. 'callback_uri' => 'http://app.dev/',
  132. ];
  133. }
  134. protected function getApplicationKey()
  135. {
  136. return 'abcdefghijk';
  137. }
  138. protected function getApplicationExpiration($days = 0)
  139. {
  140. return is_numeric($days) && $days > 0 ? $days . 'day' . ($days == 1 ? '' : 's') : 'never';
  141. }
  142. protected function getApplicationName()
  143. {
  144. return 'fizz buzz';
  145. }
  146. private function getUserPayload()
  147. {
  148. return '{
  149. "users":[
  150. {
  151. "id":"17144430_0f9409",
  152. "active_email":"XXXXXXXXXX@gmail.com",
  153. "time_zone":
  154. {
  155. "utc_offset":3.0,
  156. "name":"Europe/Kiev"
  157. },
  158. "display_name":"Roman Gelembjuk",
  159. "first_name":"Roman",
  160. "last_name":"Gelembjuk",
  161. "gender":"m",
  162. "page_name":"Roman_Gelembjuk",
  163. "birth_date":
  164. {"year":null,"month":null,"day":null},
  165. "wants":null,
  166. "haves":null,
  167. "interests":null,
  168. "web_profiles":{},
  169. "badges":[],
  170. "photo_urls":
  171. {
  172. "large":"https://x1.xingassets.com/assets/frontend_minified/img/users/nobody_m.140x185.jpg",
  173. "maxi_thumb":"https://x1.xingassets.com/assets/frontend_minified/img/users/nobody_m.70x93.jpg",
  174. "medium_thumb":"https://x1.xingassets.com/assets/frontend_minified/img/users/nobody_m.57x75.jpg"
  175. },
  176. "permalink":"https://www.xing.com/profile/Roman_Gelembjuk",
  177. "languages":{"en":null},
  178. "employment_status":"EMPLOYEE",
  179. "organisation_member":null,
  180. "instant_messaging_accounts":{},
  181. "educational_background":
  182. {"degree":null,"primary_school":null,"schools":[],"qualifications":[]},
  183. "private_address":{
  184. "street":null,
  185. "zip_code":null,
  186. "city":null,
  187. "province":null,
  188. "country":null,
  189. "email":"XXXXXXXX@gmail.com",
  190. "fax":null,
  191. "phone":null,
  192. "mobile_phone":null}
  193. ,"business_address":
  194. {
  195. "street":null,
  196. "zip_code":null,
  197. "city":"Ivano-Frankivsk",
  198. "province":null,
  199. "country":"UA",
  200. "email":null,
  201. "fax":null,"phone":null,"mobile_phone":null
  202. },
  203. "premium_services":[]
  204. }]}';
  205. }
  206. }