PageRenderTime 123ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 1ms

/custom/include/social/facebook/facebook_sdk/tests/tests.php

https://github.com/BarnetikKoop/SuiteCRM
PHP | 2125 lines | 1837 code | 214 blank | 74 comment | 8 complexity | ae9cc21f0c90dd921e69f680334709b5 MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.1, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Copyright 2011 Facebook, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  6. * not use this file except in compliance with the License. You may obtain
  7. * a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  14. * License for the specific language governing permissions and limitations
  15. * under the License.
  16. */
  17. class PHPSDKTestCase extends PHPUnit_Framework_TestCase {
  18. const APP_ID = '117743971608120';
  19. const SECRET = '9c8ea2071859659bea1246d33a9207cf';
  20. const MIGRATED_APP_ID = '174236045938435';
  21. const MIGRATED_SECRET = '0073dce2d95c4a5c2922d1827ea0cca6';
  22. const TEST_USER = 499834690;
  23. const TEST_USER_2 = 499835484;
  24. private static $kExpiredAccessToken = 'AAABrFmeaJjgBAIshbq5ZBqZBICsmveZCZBi6O4w9HSTkFI73VMtmkL9jLuWsZBZC9QMHvJFtSulZAqonZBRIByzGooCZC8DWr0t1M4BL9FARdQwPWPnIqCiFQ';
  25. private static function kValidSignedRequest($id = self::TEST_USER, $oauth_token = null) {
  26. $facebook = new FBPublic(array(
  27. 'appId' => self::APP_ID,
  28. 'secret' => self::SECRET,
  29. ));
  30. return $facebook->publicMakeSignedRequest(
  31. array(
  32. 'user_id' => $id,
  33. 'oauth_token' => $oauth_token
  34. )
  35. );
  36. }
  37. private static function kNonTosedSignedRequest() {
  38. $facebook = new FBPublic(array(
  39. 'appId' => self::APP_ID,
  40. 'secret' => self::SECRET,
  41. ));
  42. return $facebook->publicMakeSignedRequest(array());
  43. }
  44. private static function kSignedRequestWithEmptyValue() {
  45. return '';
  46. }
  47. private static function kSignedRequestWithBogusSignature() {
  48. $facebook = new FBPublic(array(
  49. 'appId' => self::APP_ID,
  50. 'secret' => 'bogus',
  51. ));
  52. return $facebook->publicMakeSignedRequest(
  53. array(
  54. 'algorithm' => 'HMAC-SHA256',
  55. )
  56. );
  57. }
  58. private static function kSignedRequestWithWrongAlgo() {
  59. $facebook = new FBPublic(array(
  60. 'appId' => self::APP_ID,
  61. 'secret' => self::SECRET,
  62. ));
  63. $data['algorithm'] = 'foo';
  64. $json = json_encode($data);
  65. $b64 = $facebook->publicBase64UrlEncode($json);
  66. $raw_sig = hash_hmac('sha256', $b64, self::SECRET, $raw = true);
  67. $sig = $facebook->publicBase64UrlEncode($raw_sig);
  68. return $sig.'.'.$b64;
  69. }
  70. public function testConstructor() {
  71. $facebook = new TransientFacebook(array(
  72. 'appId' => self::APP_ID,
  73. 'secret' => self::SECRET,
  74. ));
  75. $this->assertEquals($facebook->getAppId(), self::APP_ID,
  76. 'Expect the App ID to be set.');
  77. $this->assertEquals($facebook->getAppSecret(), self::SECRET,
  78. 'Expect the API secret to be set.');
  79. }
  80. public function testConstructorWithFileUpload() {
  81. $facebook = new TransientFacebook(array(
  82. 'appId' => self::APP_ID,
  83. 'secret' => self::SECRET,
  84. 'fileUpload' => true,
  85. ));
  86. $this->assertEquals($facebook->getAppId(), self::APP_ID,
  87. 'Expect the App ID to be set.');
  88. $this->assertEquals($facebook->getAppSecret(), self::SECRET,
  89. 'Expect the API secret to be set.');
  90. $this->assertTrue($facebook->getFileUploadSupport(),
  91. 'Expect file upload support to be on.');
  92. // alias (depricated) for getFileUploadSupport -- test until removed
  93. $this->assertTrue($facebook->useFileUploadSupport(),
  94. 'Expect file upload support to be on.');
  95. }
  96. public function testSetAppId() {
  97. $facebook = new TransientFacebook(array(
  98. 'appId' => self::APP_ID,
  99. 'secret' => self::SECRET,
  100. ));
  101. $facebook->setAppId('dummy');
  102. $this->assertEquals($facebook->getAppId(), 'dummy',
  103. 'Expect the App ID to be dummy.');
  104. }
  105. public function testSetAPISecret() {
  106. $facebook = new TransientFacebook(array(
  107. 'appId' => self::APP_ID,
  108. 'secret' => self::SECRET,
  109. ));
  110. $facebook->setApiSecret('dummy');
  111. $this->assertEquals($facebook->getApiSecret(), 'dummy',
  112. 'Expect the API secret to be dummy.');
  113. }
  114. public function testSetAPPSecret() {
  115. $facebook = new TransientFacebook(array(
  116. 'appId' => self::APP_ID,
  117. 'secret' => self::SECRET,
  118. ));
  119. $facebook->setAppSecret('dummy');
  120. $this->assertEquals($facebook->getAppSecret(), 'dummy',
  121. 'Expect the API secret to be dummy.');
  122. }
  123. public function testSetAccessToken() {
  124. $facebook = new TransientFacebook(array(
  125. 'appId' => self::APP_ID,
  126. 'secret' => self::SECRET,
  127. ));
  128. $facebook->setAccessToken('saltydog');
  129. $this->assertEquals($facebook->getAccessToken(), 'saltydog',
  130. 'Expect installed access token to remain \'saltydog\'');
  131. }
  132. public function testSetFileUploadSupport() {
  133. $facebook = new TransientFacebook(array(
  134. 'appId' => self::APP_ID,
  135. 'secret' => self::SECRET,
  136. ));
  137. $this->assertFalse($facebook->getFileUploadSupport(),
  138. 'Expect file upload support to be off.');
  139. // alias for getFileUploadSupport (depricated), testing until removed
  140. $this->assertFalse($facebook->useFileUploadSupport(),
  141. 'Expect file upload support to be off.');
  142. $facebook->setFileUploadSupport(true);
  143. $this->assertTrue($facebook->getFileUploadSupport(),
  144. 'Expect file upload support to be on.');
  145. // alias for getFileUploadSupport (depricated), testing until removed
  146. $this->assertTrue($facebook->useFileUploadSupport(),
  147. 'Expect file upload support to be on.');
  148. }
  149. public function testGetCurrentURL() {
  150. $facebook = new FBGetCurrentURLFacebook(array(
  151. 'appId' => self::APP_ID,
  152. 'secret' => self::SECRET,
  153. ));
  154. // fake the HPHP $_SERVER globals
  155. $_SERVER['HTTP_HOST'] = 'www.test.com';
  156. $_SERVER['REQUEST_URI'] = '/unit-tests.php?one=one&two=two&three=three';
  157. $current_url = $facebook->publicGetCurrentUrl();
  158. $this->assertEquals(
  159. 'http://www.test.com/unit-tests.php?one=one&two=two&three=three',
  160. $current_url,
  161. 'getCurrentUrl function is changing the current URL');
  162. // ensure structure of valueless GET params is retained (sometimes
  163. // an = sign was present, and sometimes it was not)
  164. // first test when equal signs are present
  165. $_SERVER['HTTP_HOST'] = 'www.test.com';
  166. $_SERVER['REQUEST_URI'] = '/unit-tests.php?one=&two=&three=';
  167. $current_url = $facebook->publicGetCurrentUrl();
  168. $this->assertEquals(
  169. 'http://www.test.com/unit-tests.php?one=&two=&three=',
  170. $current_url,
  171. 'getCurrentUrl function is changing the current URL');
  172. // now confirm that
  173. $_SERVER['HTTP_HOST'] = 'www.test.com';
  174. $_SERVER['REQUEST_URI'] = '/unit-tests.php?one&two&three';
  175. $current_url = $facebook->publicGetCurrentUrl();
  176. $this->assertEquals(
  177. 'http://www.test.com/unit-tests.php?one&two&three',
  178. $current_url,
  179. 'getCurrentUrl function is changing the current URL');
  180. }
  181. public function testGetLoginURL() {
  182. $facebook = new Facebook(array(
  183. 'appId' => self::APP_ID,
  184. 'secret' => self::SECRET,
  185. ));
  186. // fake the HPHP $_SERVER globals
  187. $_SERVER['HTTP_HOST'] = 'www.test.com';
  188. $_SERVER['REQUEST_URI'] = '/unit-tests.php';
  189. $login_url = parse_url($facebook->getLoginUrl());
  190. $this->assertEquals($login_url['scheme'], 'https');
  191. $this->assertEquals($login_url['host'], 'www.facebook.com');
  192. $this->assertEquals($login_url['path'], '/dialog/oauth');
  193. $expected_login_params =
  194. array('client_id' => self::APP_ID,
  195. 'redirect_uri' => 'http://www.test.com/unit-tests.php');
  196. $query_map = array();
  197. parse_str($login_url['query'], $query_map);
  198. $this->assertIsSubset($expected_login_params, $query_map);
  199. // we don't know what the state is, but we know it's an md5 and should
  200. // be 32 characters long.
  201. $this->assertEquals(strlen($query_map['state']), $num_characters = 32);
  202. }
  203. public function testGetLoginURLWithExtraParams() {
  204. $facebook = new Facebook(array(
  205. 'appId' => self::APP_ID,
  206. 'secret' => self::SECRET,
  207. ));
  208. // fake the HPHP $_SERVER globals
  209. $_SERVER['HTTP_HOST'] = 'www.test.com';
  210. $_SERVER['REQUEST_URI'] = '/unit-tests.php';
  211. $extra_params = array('scope' => 'email, sms',
  212. 'nonsense' => 'nonsense');
  213. $login_url = parse_url($facebook->getLoginUrl($extra_params));
  214. $this->assertEquals($login_url['scheme'], 'https');
  215. $this->assertEquals($login_url['host'], 'www.facebook.com');
  216. $this->assertEquals($login_url['path'], '/dialog/oauth');
  217. $expected_login_params =
  218. array_merge(
  219. array('client_id' => self::APP_ID,
  220. 'redirect_uri' => 'http://www.test.com/unit-tests.php'),
  221. $extra_params);
  222. $query_map = array();
  223. parse_str($login_url['query'], $query_map);
  224. $this->assertIsSubset($expected_login_params, $query_map);
  225. // we don't know what the state is, but we know it's an md5 and should
  226. // be 32 characters long.
  227. $this->assertEquals(strlen($query_map['state']), $num_characters = 32);
  228. }
  229. public function testGetLoginURLWithScopeParamsAsArray() {
  230. $facebook = new Facebook(array(
  231. 'appId' => self::APP_ID,
  232. 'secret' => self::SECRET,
  233. ));
  234. // fake the HPHP $_SERVER globals
  235. $_SERVER['HTTP_HOST'] = 'www.test.com';
  236. $_SERVER['REQUEST_URI'] = '/unit-tests.php';
  237. $scope_params_as_array = array('email','sms','read_stream');
  238. $extra_params = array('scope' => $scope_params_as_array,
  239. 'nonsense' => 'nonsense');
  240. $login_url = parse_url($facebook->getLoginUrl($extra_params));
  241. $this->assertEquals($login_url['scheme'], 'https');
  242. $this->assertEquals($login_url['host'], 'www.facebook.com');
  243. $this->assertEquals($login_url['path'], '/dialog/oauth');
  244. // expect api to flatten array params to comma separated list
  245. // should do the same here before asserting to make sure API is behaving
  246. // correctly;
  247. $extra_params['scope'] = implode(',', $scope_params_as_array);
  248. $expected_login_params =
  249. array_merge(
  250. array('client_id' => self::APP_ID,
  251. 'redirect_uri' => 'http://www.test.com/unit-tests.php'),
  252. $extra_params);
  253. $query_map = array();
  254. parse_str($login_url['query'], $query_map);
  255. $this->assertIsSubset($expected_login_params, $query_map);
  256. // we don't know what the state is, but we know it's an md5 and should
  257. // be 32 characters long.
  258. $this->assertEquals(strlen($query_map['state']), $num_characters = 32);
  259. }
  260. public function testGetCodeWithValidCSRFState() {
  261. $facebook = new FBCode(array(
  262. 'appId' => self::APP_ID,
  263. 'secret' => self::SECRET,
  264. ));
  265. $facebook->setCSRFStateToken();
  266. $code = $_REQUEST['code'] = $this->generateMD5HashOfRandomValue();
  267. $_REQUEST['state'] = $facebook->getCSRFStateToken();
  268. $this->assertEquals($code,
  269. $facebook->publicGetCode(),
  270. 'Expect code to be pulled from $_REQUEST[\'code\']');
  271. }
  272. public function testGetCodeWithInvalidCSRFState() {
  273. $facebook = new FBCode(array(
  274. 'appId' => self::APP_ID,
  275. 'secret' => self::SECRET,
  276. ));
  277. $facebook->setCSRFStateToken();
  278. $code = $_REQUEST['code'] = $this->generateMD5HashOfRandomValue();
  279. $_REQUEST['state'] = $facebook->getCSRFStateToken().'forgery!!!';
  280. $this->assertFalse($facebook->publicGetCode(),
  281. 'Expect getCode to fail, CSRF state should not match.');
  282. }
  283. public function testGetCodeWithMissingCSRFState() {
  284. $facebook = new FBCode(array(
  285. 'appId' => self::APP_ID,
  286. 'secret' => self::SECRET,
  287. ));
  288. $code = $_REQUEST['code'] = $this->generateMD5HashOfRandomValue();
  289. // intentionally don't set CSRF token at all
  290. $this->assertFalse($facebook->publicGetCode(),
  291. 'Expect getCode to fail, CSRF state not sent back.');
  292. }
  293. public function testPersistentCSRFState()
  294. {
  295. $facebook = new FBCode(array(
  296. 'appId' => self::APP_ID,
  297. 'secret' => self::SECRET,
  298. ));
  299. $facebook->setCSRFStateToken();
  300. $code = $facebook->getCSRFStateToken();
  301. $facebook = new FBCode(array(
  302. 'appId' => self::APP_ID,
  303. 'secret' => self::SECRET,
  304. ));
  305. $this->assertEquals($code, $facebook->publicGetState(),
  306. 'Persisted CSRF state token not loaded correctly');
  307. }
  308. public function testPersistentCSRFStateWithSharedSession()
  309. {
  310. $_SERVER['HTTP_HOST'] = 'fbrell.com';
  311. $facebook = new FBCode(array(
  312. 'appId' => self::APP_ID,
  313. 'secret' => self::SECRET,
  314. 'sharedSession' => true,
  315. ));
  316. $facebook->setCSRFStateToken();
  317. $code = $facebook->getCSRFStateToken();
  318. $facebook = new FBCode(array(
  319. 'appId' => self::APP_ID,
  320. 'secret' => self::SECRET,
  321. 'sharedSession' => true,
  322. ));
  323. $this->assertEquals($code, $facebook->publicGetState(),
  324. 'Persisted CSRF state token not loaded correctly with shared session');
  325. }
  326. public function testGetUserFromSignedRequest() {
  327. $facebook = new TransientFacebook(array(
  328. 'appId' => self::APP_ID,
  329. 'secret' => self::SECRET,
  330. ));
  331. $_REQUEST['signed_request'] = self::kValidSignedRequest();
  332. $this->assertEquals('499834690', $facebook->getUser(),
  333. 'Failed to get user ID from a valid signed request.');
  334. }
  335. public function testDisallowSignedRequest() {
  336. $facebook = new TransientFacebook(array(
  337. 'appId' => self::APP_ID,
  338. 'secret' => self::SECRET,
  339. 'allowSignedRequest' => false
  340. ));
  341. $_REQUEST['signed_request'] = self::kValidSignedRequest();
  342. $this->assertEquals(0, $facebook->getUser(),
  343. 'Should not have received valid user from signed_request.');
  344. }
  345. public function testSignedRequestRewrite(){
  346. $facebook = new FBRewrite(array(
  347. 'appId' => self::APP_ID,
  348. 'secret' => self::SECRET,
  349. ));
  350. $_REQUEST['signed_request'] = self::kValidSignedRequest(self::TEST_USER, 'Hello sweetie');
  351. $this->assertEquals(self::TEST_USER, $facebook->getUser(),
  352. 'Failed to get user ID from a valid signed request.');
  353. $this->assertEquals('Hello sweetie', $facebook->getAccessToken(),
  354. 'Failed to get access token from signed request');
  355. $facebook->uncache();
  356. $_REQUEST['signed_request'] = self::kValidSignedRequest(self::TEST_USER_2, 'spoilers');
  357. $this->assertEquals(self::TEST_USER_2, $facebook->getUser(),
  358. 'Failed to get user ID from a valid signed request.');
  359. $_REQUEST['signed_request'] = null;
  360. $facebook ->uncacheSignedRequest();
  361. $this->assertNotEquals('Hello sweetie', $facebook->getAccessToken(),
  362. 'Failed to clear access token');
  363. }
  364. public function testGetSignedRequestFromCookie() {
  365. $facebook = new FBPublicCookie(array(
  366. 'appId' => self::APP_ID,
  367. 'secret' => self::SECRET,
  368. ));
  369. $_COOKIE[$facebook->publicGetSignedRequestCookieName()] =
  370. self::kValidSignedRequest();
  371. $this->assertNotNull($facebook->publicGetSignedRequest());
  372. $this->assertEquals('499834690', $facebook->getUser(),
  373. 'Failed to get user ID from a valid signed request.');
  374. }
  375. public function testGetSignedRequestWithIncorrectSignature() {
  376. $facebook = new FBPublicCookie(array(
  377. 'appId' => self::APP_ID,
  378. 'secret' => self::SECRET,
  379. ));
  380. $_COOKIE[$facebook->publicGetSignedRequestCookieName()] =
  381. self::kSignedRequestWithBogusSignature();
  382. $this->assertNull($facebook->publicGetSignedRequest());
  383. }
  384. public function testNonUserAccessToken() {
  385. $facebook = new FBAccessToken(array(
  386. 'appId' => self::APP_ID,
  387. 'secret' => self::SECRET,
  388. ));
  389. // no cookies, and no request params, so no user or code,
  390. // so no user access token (even with cookie support)
  391. $this->assertEquals($facebook->publicGetApplicationAccessToken(),
  392. $facebook->getAccessToken(),
  393. 'Access token should be that for logged out users.');
  394. }
  395. public function testMissingMetadataCookie() {
  396. $fb = new FBPublicCookie(array(
  397. 'appId' => self::APP_ID,
  398. 'secret' => self::SECRET,
  399. ));
  400. $this->assertEmpty($fb->publicGetMetadataCookie());
  401. }
  402. public function testEmptyMetadataCookie() {
  403. $fb = new FBPublicCookie(array(
  404. 'appId' => self::APP_ID,
  405. 'secret' => self::SECRET,
  406. ));
  407. $_COOKIE[$fb->publicGetMetadataCookieName()] = '';
  408. $this->assertEmpty($fb->publicGetMetadataCookie());
  409. }
  410. public function testMetadataCookie() {
  411. $fb = new FBPublicCookie(array(
  412. 'appId' => self::APP_ID,
  413. 'secret' => self::SECRET,
  414. ));
  415. $key = 'foo';
  416. $val = '42';
  417. $_COOKIE[$fb->publicGetMetadataCookieName()] = "$key=$val";
  418. $this->assertEquals(array($key => $val), $fb->publicGetMetadataCookie());
  419. }
  420. public function testQuotedMetadataCookie() {
  421. $fb = new FBPublicCookie(array(
  422. 'appId' => self::APP_ID,
  423. 'secret' => self::SECRET,
  424. ));
  425. $key = 'foo';
  426. $val = '42';
  427. $_COOKIE[$fb->publicGetMetadataCookieName()] = "\"$key=$val\"";
  428. $this->assertEquals(array($key => $val), $fb->publicGetMetadataCookie());
  429. }
  430. public function testAPIForLoggedOutUsers() {
  431. $facebook = new TransientFacebook(array(
  432. 'appId' => self::APP_ID,
  433. 'secret' => self::SECRET,
  434. ));
  435. $response = $facebook->api(array(
  436. 'method' => 'fql.query',
  437. 'query' => 'SELECT name FROM user WHERE uid=4',
  438. ));
  439. $this->assertEquals(count($response), 1,
  440. 'Expect one row back.');
  441. $this->assertEquals($response[0]['name'], 'Mark Zuckerberg',
  442. 'Expect the name back.');
  443. }
  444. public function testAPIWithBogusAccessToken() {
  445. $facebook = new TransientFacebook(array(
  446. 'appId' => self::APP_ID,
  447. 'secret' => self::SECRET,
  448. ));
  449. $facebook->setAccessToken('this-is-not-really-an-access-token');
  450. // if we don't set an access token and there's no way to
  451. // get one, then the FQL query below works beautifully, handing
  452. // over Zuck's public data. But if you specify a bogus access
  453. // token as I have right here, then the FQL query should fail.
  454. // We could return just Zuck's public data, but that wouldn't
  455. // advertise the issue that the access token is at worst broken
  456. // and at best expired.
  457. try {
  458. $response = $facebook->api(array(
  459. 'method' => 'fql.query',
  460. 'query' => 'SELECT name FROM profile WHERE id=4',
  461. ));
  462. $this->fail('Should not get here.');
  463. } catch(FacebookApiException $e) {
  464. $result = $e->getResult();
  465. $this->assertTrue(is_array($result), 'expect a result object');
  466. $this->assertEquals('190', $result['error_code'], 'expect code');
  467. }
  468. }
  469. public function testAPIGraphPublicData() {
  470. $facebook = new TransientFacebook(array(
  471. 'appId' => self::APP_ID,
  472. 'secret' => self::SECRET,
  473. ));
  474. $response = $facebook->api('/jerry');
  475. $this->assertEquals(
  476. $response['id'], '214707', 'should get expected id.');
  477. }
  478. public function testGraphAPIWithBogusAccessToken() {
  479. $facebook = new TransientFacebook(array(
  480. 'appId' => self::APP_ID,
  481. 'secret' => self::SECRET,
  482. ));
  483. $facebook->setAccessToken('this-is-not-really-an-access-token');
  484. try {
  485. $response = $facebook->api('/me');
  486. $this->fail('Should not get here.');
  487. } catch(FacebookApiException $e) {
  488. // means the server got the access token and didn't like it
  489. $msg = 'OAuthException: Invalid OAuth access token.';
  490. $this->assertEquals($msg, (string) $e,
  491. 'Expect the invalid OAuth token message.');
  492. }
  493. }
  494. public function testGraphAPIWithExpiredAccessToken() {
  495. $facebook = new TransientFacebook(array(
  496. 'appId' => self::APP_ID,
  497. 'secret' => self::SECRET,
  498. ));
  499. $facebook->setAccessToken(self::$kExpiredAccessToken);
  500. try {
  501. $response = $facebook->api('/me');
  502. $this->fail('Should not get here.');
  503. } catch(FacebookApiException $e) {
  504. // means the server got the access token and didn't like it
  505. $error_msg_start = 'OAuthException: Error validating access token:';
  506. $this->assertTrue(strpos((string) $e, $error_msg_start) === 0,
  507. 'Expect the token validation error message.');
  508. }
  509. }
  510. public function testGraphAPIOAuthSpecError() {
  511. $facebook = new TransientFacebook(array(
  512. 'appId' => self::MIGRATED_APP_ID,
  513. 'secret' => self::MIGRATED_SECRET,
  514. ));
  515. try {
  516. $response = $facebook->api('/me', array(
  517. 'client_id' => self::MIGRATED_APP_ID));
  518. $this->fail('Should not get here.');
  519. } catch(FacebookApiException $e) {
  520. // means the server got the access token
  521. $msg = 'invalid_request: An active access token must be used '.
  522. 'to query information about the current user.';
  523. $this->assertEquals($msg, (string) $e,
  524. 'Expect the invalid session message.');
  525. }
  526. }
  527. public function testGraphAPIMethodOAuthSpecError() {
  528. $facebook = new TransientFacebook(array(
  529. 'appId' => self::MIGRATED_APP_ID,
  530. 'secret' => self::MIGRATED_SECRET,
  531. ));
  532. try {
  533. $response = $facebook->api('/daaku.shah', 'DELETE', array(
  534. 'client_id' => self::MIGRATED_APP_ID));
  535. $this->fail('Should not get here.');
  536. } catch(FacebookApiException $e) {
  537. $this->assertEquals(strpos($e, 'invalid_request'), 0);
  538. }
  539. }
  540. public function testCurlFailure() {
  541. $facebook = new TransientFacebook(array(
  542. 'appId' => self::APP_ID,
  543. 'secret' => self::SECRET,
  544. ));
  545. if (!defined('CURLOPT_TIMEOUT_MS')) {
  546. // can't test it if we don't have millisecond timeouts
  547. return;
  548. }
  549. $exception = null;
  550. try {
  551. // we dont expect facebook will ever return in 1ms
  552. Facebook::$CURL_OPTS[CURLOPT_TIMEOUT_MS] = 50;
  553. $facebook->api('/naitik');
  554. } catch(FacebookApiException $e) {
  555. $exception = $e;
  556. }
  557. unset(Facebook::$CURL_OPTS[CURLOPT_TIMEOUT_MS]);
  558. if (!$exception) {
  559. $this->fail('no exception was thrown on timeout.');
  560. }
  561. $code = $exception->getCode();
  562. if ($code != CURLE_OPERATION_TIMEOUTED && $code != CURLE_COULDNT_CONNECT) {
  563. $this->fail("Expected curl error code 7 or 28 but got: $code");
  564. }
  565. $this->assertEquals('CurlException', $exception->getType(), 'expect type');
  566. }
  567. public function testGraphAPIWithOnlyParams() {
  568. $facebook = new TransientFacebook(array(
  569. 'appId' => self::APP_ID,
  570. 'secret' => self::SECRET,
  571. ));
  572. $response = $facebook->api('/jerry');
  573. $this->assertTrue(isset($response['id']),
  574. 'User ID should be public.');
  575. $this->assertTrue(isset($response['name']),
  576. 'User\'s name should be public.');
  577. $this->assertTrue(isset($response['first_name']),
  578. 'User\'s first name should be public.');
  579. $this->assertTrue(isset($response['last_name']),
  580. 'User\'s last name should be public.');
  581. $this->assertFalse(isset($response['work']),
  582. 'User\'s work history should only be available with '.
  583. 'a valid access token.');
  584. $this->assertFalse(isset($response['education']),
  585. 'User\'s education history should only be '.
  586. 'available with a valid access token.');
  587. $this->assertFalse(isset($response['verified']),
  588. 'User\'s verification status should only be '.
  589. 'available with a valid access token.');
  590. }
  591. public function testLoginURLDefaults() {
  592. $_SERVER['HTTP_HOST'] = 'fbrell.com';
  593. $_SERVER['REQUEST_URI'] = '/examples';
  594. $facebook = new TransientFacebook(array(
  595. 'appId' => self::APP_ID,
  596. 'secret' => self::SECRET,
  597. ));
  598. $encodedUrl = rawurlencode('http://fbrell.com/examples');
  599. $this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl),
  600. 'Expect the current url to exist.');
  601. }
  602. public function testLoginURLDefaultsDropStateQueryParam() {
  603. $_SERVER['HTTP_HOST'] = 'fbrell.com';
  604. $_SERVER['REQUEST_URI'] = '/examples?state=xx42xx';
  605. $facebook = new TransientFacebook(array(
  606. 'appId' => self::APP_ID,
  607. 'secret' => self::SECRET,
  608. ));
  609. $expectEncodedUrl = rawurlencode('http://fbrell.com/examples');
  610. $this->assertTrue(strpos($facebook->getLoginUrl(), $expectEncodedUrl) > -1,
  611. 'Expect the current url to exist.');
  612. $this->assertFalse(strpos($facebook->getLoginUrl(), 'xx42xx'),
  613. 'Expect the session param to be dropped.');
  614. }
  615. public function testLoginURLDefaultsDropCodeQueryParam() {
  616. $_SERVER['HTTP_HOST'] = 'fbrell.com';
  617. $_SERVER['REQUEST_URI'] = '/examples?code=xx42xx';
  618. $facebook = new TransientFacebook(array(
  619. 'appId' => self::APP_ID,
  620. 'secret' => self::SECRET,
  621. ));
  622. $expectEncodedUrl = rawurlencode('http://fbrell.com/examples');
  623. $this->assertTrue(strpos($facebook->getLoginUrl(), $expectEncodedUrl) > -1,
  624. 'Expect the current url to exist.');
  625. $this->assertFalse(strpos($facebook->getLoginUrl(), 'xx42xx'),
  626. 'Expect the session param to be dropped.');
  627. }
  628. public function testLoginURLDefaultsDropSignedRequestParamButNotOthers() {
  629. $_SERVER['HTTP_HOST'] = 'fbrell.com';
  630. $_SERVER['REQUEST_URI'] =
  631. '/examples?signed_request=xx42xx&do_not_drop=xx43xx';
  632. $facebook = new TransientFacebook(array(
  633. 'appId' => self::APP_ID,
  634. 'secret' => self::SECRET,
  635. ));
  636. $expectEncodedUrl = rawurlencode('http://fbrell.com/examples');
  637. $this->assertFalse(strpos($facebook->getLoginUrl(), 'xx42xx'),
  638. 'Expect the session param to be dropped.');
  639. $this->assertTrue(strpos($facebook->getLoginUrl(), 'xx43xx') > -1,
  640. 'Expect the do_not_drop param to exist.');
  641. }
  642. public function testLoginURLCustomNext() {
  643. $_SERVER['HTTP_HOST'] = 'fbrell.com';
  644. $_SERVER['REQUEST_URI'] = '/examples';
  645. $facebook = new TransientFacebook(array(
  646. 'appId' => self::APP_ID,
  647. 'secret' => self::SECRET,
  648. ));
  649. $next = 'http://fbrell.com/custom';
  650. $loginUrl = $facebook->getLoginUrl(array(
  651. 'redirect_uri' => $next,
  652. 'cancel_url' => $next
  653. ));
  654. $currentEncodedUrl = rawurlencode('http://fbrell.com/examples');
  655. $expectedEncodedUrl = rawurlencode($next);
  656. $this->assertNotNull(strpos($loginUrl, $expectedEncodedUrl),
  657. 'Expect the custom url to exist.');
  658. $this->assertFalse(strpos($loginUrl, $currentEncodedUrl),
  659. 'Expect the current url to not exist.');
  660. }
  661. public function testLogoutURLDefaults() {
  662. $_SERVER['HTTP_HOST'] = 'fbrell.com';
  663. $_SERVER['REQUEST_URI'] = '/examples';
  664. $facebook = new TransientFacebook(array(
  665. 'appId' => self::APP_ID,
  666. 'secret' => self::SECRET,
  667. ));
  668. $encodedUrl = rawurlencode('http://fbrell.com/examples');
  669. $this->assertNotNull(strpos($facebook->getLogoutUrl(), $encodedUrl),
  670. 'Expect the current url to exist.');
  671. $this->assertFalse(strpos($facebook->getLogoutUrl(), self::SECRET));
  672. }
  673. public function testLoginStatusURLDefaults() {
  674. $_SERVER['HTTP_HOST'] = 'fbrell.com';
  675. $_SERVER['REQUEST_URI'] = '/examples';
  676. $facebook = new TransientFacebook(array(
  677. 'appId' => self::APP_ID,
  678. 'secret' => self::SECRET,
  679. ));
  680. $encodedUrl = rawurlencode('http://fbrell.com/examples');
  681. $this->assertNotNull(strpos($facebook->getLoginStatusUrl(), $encodedUrl),
  682. 'Expect the current url to exist.');
  683. }
  684. public function testLoginStatusURLCustom() {
  685. $_SERVER['HTTP_HOST'] = 'fbrell.com';
  686. $_SERVER['REQUEST_URI'] = '/examples';
  687. $facebook = new TransientFacebook(array(
  688. 'appId' => self::APP_ID,
  689. 'secret' => self::SECRET,
  690. ));
  691. $encodedUrl1 = rawurlencode('http://fbrell.com/examples');
  692. $okUrl = 'http://fbrell.com/here1';
  693. $encodedUrl2 = rawurlencode($okUrl);
  694. $loginStatusUrl = $facebook->getLoginStatusUrl(array(
  695. 'ok_session' => $okUrl,
  696. ));
  697. $this->assertNotNull(strpos($loginStatusUrl, $encodedUrl1),
  698. 'Expect the current url to exist.');
  699. $this->assertNotNull(strpos($loginStatusUrl, $encodedUrl2),
  700. 'Expect the custom url to exist.');
  701. }
  702. public function testNonDefaultPort() {
  703. $_SERVER['HTTP_HOST'] = 'fbrell.com:8080';
  704. $_SERVER['REQUEST_URI'] = '/examples';
  705. $facebook = new TransientFacebook(array(
  706. 'appId' => self::APP_ID,
  707. 'secret' => self::SECRET,
  708. ));
  709. $encodedUrl = rawurlencode('http://fbrell.com:8080/examples');
  710. $this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl),
  711. 'Expect the current url to exist.');
  712. }
  713. public function testSecureCurrentUrl() {
  714. $_SERVER['HTTP_HOST'] = 'fbrell.com';
  715. $_SERVER['REQUEST_URI'] = '/examples';
  716. $_SERVER['HTTPS'] = 'on';
  717. $facebook = new TransientFacebook(array(
  718. 'appId' => self::APP_ID,
  719. 'secret' => self::SECRET,
  720. ));
  721. $encodedUrl = rawurlencode('https://fbrell.com/examples');
  722. $this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl),
  723. 'Expect the current url to exist.');
  724. }
  725. public function testSecureCurrentUrlWithNonDefaultPort() {
  726. $_SERVER['HTTP_HOST'] = 'fbrell.com:8080';
  727. $_SERVER['REQUEST_URI'] = '/examples';
  728. $_SERVER['HTTPS'] = 'on';
  729. $facebook = new TransientFacebook(array(
  730. 'appId' => self::APP_ID,
  731. 'secret' => self::SECRET,
  732. ));
  733. $encodedUrl = rawurlencode('https://fbrell.com:8080/examples');
  734. $this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl),
  735. 'Expect the current url to exist.');
  736. }
  737. public function testBase64UrlEncode() {
  738. $input = 'Facebook rocks';
  739. $output = 'RmFjZWJvb2sgcm9ja3M';
  740. $this->assertEquals(FBPublic::publicBase64UrlDecode($output), $input);
  741. }
  742. public function testSignedToken() {
  743. $facebook = new FBPublic(array(
  744. 'appId' => self::APP_ID,
  745. 'secret' => self::SECRET
  746. ));
  747. $sr = self::kValidSignedRequest();
  748. $payload = $facebook->publicParseSignedRequest($sr);
  749. $this->assertNotNull($payload, 'Expected token to parse');
  750. $this->assertEquals($facebook->getSignedRequest(), null);
  751. $_REQUEST['signed_request'] = $sr;
  752. $this->assertEquals($facebook->getSignedRequest(), $payload);
  753. }
  754. public function testNonTossedSignedtoken() {
  755. $facebook = new FBPublic(array(
  756. 'appId' => self::APP_ID,
  757. 'secret' => self::SECRET
  758. ));
  759. $payload = $facebook->publicParseSignedRequest(
  760. self::kNonTosedSignedRequest());
  761. $this->assertNotNull($payload, 'Expected token to parse');
  762. $this->assertNull($facebook->getSignedRequest());
  763. $_REQUEST['signed_request'] = self::kNonTosedSignedRequest();
  764. $sr = $facebook->getSignedRequest();
  765. $this->assertTrue(isset($sr['algorithm']));
  766. }
  767. public function testSignedRequestWithEmptyValue() {
  768. $fb = new FBPublicCookie(array(
  769. 'appId' => self::APP_ID,
  770. 'secret' => self::SECRET
  771. ));
  772. $_REQUEST['signed_request'] = self::kSignedRequestWithEmptyValue();
  773. $this->assertNull($fb->getSignedRequest());
  774. $_COOKIE[$fb->publicGetSignedRequestCookieName()] =
  775. self::kSignedRequestWithEmptyValue();
  776. $this->assertNull($fb->getSignedRequest());
  777. }
  778. public function testSignedRequestWithWrongAlgo() {
  779. $fb = new FBPublic(array(
  780. 'appId' => self::APP_ID,
  781. 'secret' => self::SECRET
  782. ));
  783. $payload = $fb->publicParseSignedRequest(
  784. self::kSignedRequestWithWrongAlgo());
  785. $this->assertNull($payload, 'Expected nothing back.');
  786. }
  787. public function testMakeAndParse() {
  788. $fb = new FBPublic(array(
  789. 'appId' => self::APP_ID,
  790. 'secret' => self::SECRET
  791. ));
  792. $data = array('foo' => 42);
  793. $sr = $fb->publicMakeSignedRequest($data);
  794. $decoded = $fb->publicParseSignedRequest($sr);
  795. $this->assertEquals($data['foo'], $decoded['foo']);
  796. }
  797. /**
  798. * @expectedException InvalidArgumentException
  799. */
  800. public function testMakeSignedRequestExpectsArray() {
  801. $fb = new FBPublic(array(
  802. 'appId' => self::APP_ID,
  803. 'secret' => self::SECRET
  804. ));
  805. $sr = $fb->publicMakeSignedRequest('');
  806. }
  807. public function testBundledCACert() {
  808. $facebook = new TransientFacebook(array(
  809. 'appId' => self::APP_ID,
  810. 'secret' => self::SECRET
  811. ));
  812. // use the bundled cert from the start
  813. Facebook::$CURL_OPTS[CURLOPT_CAINFO] =
  814. dirname(__FILE__) . '/../src/fb_ca_chain_bundle.crt';
  815. $response = $facebook->api('/naitik');
  816. unset(Facebook::$CURL_OPTS[CURLOPT_CAINFO]);
  817. $this->assertEquals(
  818. $response['id'], '5526183', 'should get expected id.');
  819. }
  820. public function testVideoUpload() {
  821. $facebook = new FBRecordURL(array(
  822. 'appId' => self::APP_ID,
  823. 'secret' => self::SECRET
  824. ));
  825. $facebook->api(array('method' => 'video.upload'));
  826. $this->assertContains('//api-video.', $facebook->getRequestedURL(),
  827. 'video.upload should go against api-video');
  828. }
  829. public function testVideoUploadGraph() {
  830. $facebook = new FBRecordURL(array(
  831. 'appId' => self::APP_ID,
  832. 'secret' => self::SECRET
  833. ));
  834. $facebook->api('/me/videos', 'POST');
  835. $this->assertContains('//graph-video.', $facebook->getRequestedURL(),
  836. '/me/videos should go against graph-video');
  837. }
  838. public function testGetUserAndAccessTokenFromSession() {
  839. $facebook = new PersistentFBPublic(array(
  840. 'appId' => self::APP_ID,
  841. 'secret' => self::SECRET
  842. ));
  843. $facebook->publicSetPersistentData('access_token',
  844. self::$kExpiredAccessToken);
  845. $facebook->publicSetPersistentData('user_id', 12345);
  846. $this->assertEquals(self::$kExpiredAccessToken,
  847. $facebook->getAccessToken(),
  848. 'Get access token from persistent store.');
  849. $this->assertEquals('12345',
  850. $facebook->getUser(),
  851. 'Get user id from persistent store.');
  852. }
  853. public function testGetUserAndAccessTokenFromSignedRequestNotSession() {
  854. $facebook = new PersistentFBPublic(array(
  855. 'appId' => self::APP_ID,
  856. 'secret' => self::SECRET
  857. ));
  858. $_REQUEST['signed_request'] = self::kValidSignedRequest();
  859. $facebook->publicSetPersistentData('user_id', 41572);
  860. $facebook->publicSetPersistentData('access_token',
  861. self::$kExpiredAccessToken);
  862. $this->assertNotEquals('41572', $facebook->getUser(),
  863. 'Got user from session instead of signed request.');
  864. $this->assertEquals('499834690', $facebook->getUser(),
  865. 'Failed to get correct user ID from signed request.');
  866. $this->assertNotEquals(
  867. self::$kExpiredAccessToken,
  868. $facebook->getAccessToken(),
  869. 'Got access token from session instead of signed request.');
  870. $this->assertNotEmpty(
  871. $facebook->getAccessToken(),
  872. 'Failed to extract an access token from the signed request.');
  873. }
  874. public function testGetUserWithoutCodeOrSignedRequestOrSession() {
  875. $facebook = new PersistentFBPublic(array(
  876. 'appId' => self::APP_ID,
  877. 'secret' => self::SECRET
  878. ));
  879. // deliberately leave $_REQUEST and _$SESSION empty
  880. $this->assertEmpty($_REQUEST,
  881. 'GET, POST, and COOKIE params exist even though '.
  882. 'they should. Test cannot succeed unless all of '.
  883. '$_REQUEST is empty.');
  884. $this->assertEmpty($_SESSION,
  885. 'Session is carrying state and should not be.');
  886. $this->assertEmpty($facebook->getUser(),
  887. 'Got a user id, even without a signed request, '.
  888. 'access token, or session variable.');
  889. $this->assertEmpty($_SESSION,
  890. 'Session superglobal incorrectly populated by getUser.');
  891. }
  892. public function testGetAccessTokenUsingCodeInJsSdkCookie() {
  893. $code = 'code1';
  894. $access_token = 'at1';
  895. $methods_to_stub = array('getSignedRequest', 'getAccessTokenFromCode');
  896. $constructor_args = array(array(
  897. 'appId' => self::APP_ID,
  898. 'secret' => self::SECRET
  899. ));
  900. $stub = $this->getMock(
  901. 'TransientFacebook', $methods_to_stub, $constructor_args);
  902. $stub
  903. ->expects($this->once())
  904. ->method('getSignedRequest')
  905. ->will($this->returnValue(array('code' => $code)));
  906. $stub
  907. ->expects($this->once())
  908. ->method('getAccessTokenFromCode')
  909. ->will($this->returnValueMap(array(array($code, '', $access_token))));
  910. $this->assertEquals($stub->getAccessToken(), $access_token);
  911. }
  912. public function testSignedRequestWithoutAuthClearsData() {
  913. $methods_to_stub = array('getSignedRequest', 'clearAllPersistentData');
  914. $constructor_args = array(array(
  915. 'appId' => self::APP_ID,
  916. 'secret' => self::SECRET
  917. ));
  918. $stub = $this->getMock(
  919. 'TransientFacebook', $methods_to_stub, $constructor_args);
  920. $stub
  921. ->expects($this->once())
  922. ->method('getSignedRequest')
  923. ->will($this->returnValue(array('foo' => 1)));
  924. $stub
  925. ->expects($this->once())
  926. ->method('clearAllPersistentData');
  927. $this->assertEquals(self::APP_ID.'|'.self::SECRET, $stub->getAccessToken());
  928. }
  929. public function testInvalidCodeInSignedRequestWillClearData() {
  930. $code = 'code1';
  931. $methods_to_stub = array(
  932. 'getSignedRequest',
  933. 'getAccessTokenFromCode',
  934. 'clearAllPersistentData',
  935. );
  936. $constructor_args = array(array(
  937. 'appId' => self::APP_ID,
  938. 'secret' => self::SECRET
  939. ));
  940. $stub = $this->getMock(
  941. 'TransientFacebook', $methods_to_stub, $constructor_args);
  942. $stub
  943. ->expects($this->once())
  944. ->method('getSignedRequest')
  945. ->will($this->returnValue(array('code' => $code)));
  946. $stub
  947. ->expects($this->once())
  948. ->method('getAccessTokenFromCode')
  949. ->will($this->returnValue(null));
  950. $stub
  951. ->expects($this->once())
  952. ->method('clearAllPersistentData');
  953. $this->assertEquals(self::APP_ID.'|'.self::SECRET, $stub->getAccessToken());
  954. }
  955. public function testInvalidCodeWillClearData() {
  956. $code = 'code1';
  957. $methods_to_stub = array(
  958. 'getCode',
  959. 'getAccessTokenFromCode',
  960. 'clearAllPersistentData',
  961. );
  962. $constructor_args = array(array(
  963. 'appId' => self::APP_ID,
  964. 'secret' => self::SECRET
  965. ));
  966. $stub = $this->getMock(
  967. 'TransientFacebook', $methods_to_stub, $constructor_args);
  968. $stub
  969. ->expects($this->once())
  970. ->method('getCode')
  971. ->will($this->returnValue($code));
  972. $stub
  973. ->expects($this->once())
  974. ->method('getAccessTokenFromCode')
  975. ->will($this->returnValue(null));
  976. $stub
  977. ->expects($this->once())
  978. ->method('clearAllPersistentData');
  979. $this->assertEquals(self::APP_ID.'|'.self::SECRET, $stub->getAccessToken());
  980. }
  981. public function testValidCodeToToken() {
  982. $code = 'code1';
  983. $access_token = 'at1';
  984. $methods_to_stub = array(
  985. 'getSignedRequest',
  986. 'getCode',
  987. 'getAccessTokenFromCode',
  988. );
  989. $constructor_args = array(array(
  990. 'appId' => self::APP_ID,
  991. 'secret' => self::SECRET
  992. ));
  993. $stub = $this->getMock(
  994. 'TransientFacebook', $methods_to_stub, $constructor_args);
  995. $stub
  996. ->expects($this->once())
  997. ->method('getCode')
  998. ->will($this->returnValue($code));
  999. $stub
  1000. ->expects($this->once())
  1001. ->method('getAccessTokenFromCode')
  1002. ->will($this->returnValueMap(array(array($code, null, $access_token))));
  1003. $this->assertEquals($stub->getAccessToken(), $access_token);
  1004. }
  1005. public function testSignedRequestWithoutAuthClearsDataInAvailData() {
  1006. $methods_to_stub = array('getSignedRequest', 'clearAllPersistentData');
  1007. $constructor_args = array(array(
  1008. 'appId' => self::APP_ID,
  1009. 'secret' => self::SECRET
  1010. ));
  1011. $stub = $this->getMock(
  1012. 'TransientFacebook', $methods_to_stub, $constructor_args);
  1013. $stub
  1014. ->expects($this->once())
  1015. ->method('getSignedRequest')
  1016. ->will($this->returnValue(array('foo' => 1)));
  1017. $stub
  1018. ->expects($this->once())
  1019. ->method('clearAllPersistentData');
  1020. $this->assertEquals(0, $stub->getUser());
  1021. }
  1022. public function testFailedToGetUserFromAccessTokenClearsData() {
  1023. $methods_to_stub = array(
  1024. 'getAccessToken',
  1025. 'getUserFromAccessToken',
  1026. 'clearAllPersistentData',
  1027. );
  1028. $constructor_args = array(array(
  1029. 'appId' => self::APP_ID,
  1030. 'secret' => self::SECRET
  1031. ));
  1032. $stub = $this->getMock(
  1033. 'TransientFacebook', $methods_to_stub, $constructor_args);
  1034. $stub
  1035. ->expects($this->once())
  1036. ->method('getAccessToken')
  1037. ->will($this->returnValue('at1'));
  1038. $stub
  1039. ->expects($this->once())
  1040. ->method('getUserFromAccessToken');
  1041. $stub
  1042. ->expects($this->once())
  1043. ->method('clearAllPersistentData');
  1044. $this->assertEquals(0, $stub->getUser());
  1045. }
  1046. public function testUserFromAccessTokenIsStored() {
  1047. $methods_to_stub = array(
  1048. 'getAccessToken',
  1049. 'getUserFromAccessToken',
  1050. 'setPersistentData',
  1051. );
  1052. $constructor_args = array(array(
  1053. 'appId' => self::APP_ID,
  1054. 'secret' => self::SECRET
  1055. ));
  1056. $user = 42;
  1057. $stub = $this->getMock(
  1058. 'TransientFacebook', $methods_to_stub, $constructor_args);
  1059. $stub
  1060. ->expects($this->once())
  1061. ->method('getAccessToken')
  1062. ->will($this->returnValue('at1'));
  1063. $stub
  1064. ->expects($this->once())
  1065. ->method('getUserFromAccessToken')
  1066. ->will($this->returnValue($user));
  1067. $stub
  1068. ->expects($this->once())
  1069. ->method('setPersistentData');
  1070. $this->assertEquals($user, $stub->getUser());
  1071. }
  1072. public function testUserFromAccessTokenPullsID() {
  1073. $methods_to_stub = array(
  1074. 'getAccessToken',
  1075. 'api',
  1076. );
  1077. $constructor_args = array(array(
  1078. 'appId' => self::APP_ID,
  1079. 'secret' => self::SECRET
  1080. ));
  1081. $user = 42;
  1082. $stub = $this->getMock(
  1083. 'TransientFacebook', $methods_to_stub, $constructor_args);
  1084. $stub
  1085. ->expects($this->once())
  1086. ->method('getAccessToken')
  1087. ->will($this->returnValue('at1'));
  1088. $stub
  1089. ->expects($this->once())
  1090. ->method('api')
  1091. ->will($this->returnValue(array('id' => $user)));
  1092. $this->assertEquals($user, $stub->getUser());
  1093. }
  1094. public function testUserFromAccessTokenResetsOnApiException() {
  1095. $methods_to_stub = array(
  1096. 'getAccessToken',
  1097. 'clearAllPersistentData',
  1098. 'api',
  1099. );
  1100. $constructor_args = array(array(
  1101. 'appId' => self::APP_ID,
  1102. 'secret' => self::SECRET
  1103. ));
  1104. $stub = $this->getMock(
  1105. 'TransientFacebook', $methods_to_stub, $constructor_args);
  1106. $stub
  1107. ->expects($this->once())
  1108. ->method('getAccessToken')
  1109. ->will($this->returnValue('at1'));
  1110. $stub
  1111. ->expects($this->once())
  1112. ->method('api')
  1113. ->will($this->throwException(new FacebookApiException(false)));
  1114. $stub
  1115. ->expects($this->once())
  1116. ->method('clearAllPersistentData');
  1117. $this->assertEquals(0, $stub->getUser());
  1118. }
  1119. public function testEmptyCodeReturnsFalse() {
  1120. $fb = new FBPublicGetAccessTokenFromCode(array(
  1121. 'appId' => self::APP_ID,
  1122. 'secret' => self::SECRET
  1123. ));
  1124. $this->assertFalse($fb->publicGetAccessTokenFromCode(''));
  1125. $this->assertFalse($fb->publicGetAccessTokenFromCode(null));
  1126. $this->assertFalse($fb->publicGetAccessTokenFromCode(false));
  1127. }
  1128. public function testNullRedirectURIUsesCurrentURL() {
  1129. $methods_to_stub = array(
  1130. '_oauthRequest',
  1131. 'getCurrentUrl',
  1132. );
  1133. $constructor_args = array(array(
  1134. 'appId' => self::APP_ID,
  1135. 'secret' => self::SECRET
  1136. ));
  1137. $access_token = 'at1';
  1138. $stub = $this->getMock(
  1139. 'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args);
  1140. $stub
  1141. ->expects($this->once())
  1142. ->method('_oauthRequest')
  1143. ->will($this->returnValue("access_token=$access_token"));
  1144. $stub
  1145. ->expects($this->once())
  1146. ->method('getCurrentUrl');
  1147. $this->assertEquals(
  1148. $access_token, $stub->publicGetAccessTokenFromCode('c'));
  1149. }
  1150. public function testNullRedirectURIAllowsEmptyStringForCookie() {
  1151. $methods_to_stub = array(
  1152. '_oauthRequest',
  1153. 'getCurrentUrl',
  1154. );
  1155. $constructor_args = array(array(
  1156. 'appId' => self::APP_ID,
  1157. 'secret' => self::SECRET
  1158. ));
  1159. $access_token = 'at1';
  1160. $stub = $this->getMock(
  1161. 'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args);
  1162. $stub
  1163. ->expects($this->once())
  1164. ->method('_oauthRequest')
  1165. ->will($this->returnValue("access_token=$access_token"));
  1166. $stub
  1167. ->expects($this->never())
  1168. ->method('getCurrentUrl');
  1169. $this->assertEquals(
  1170. $access_token, $stub->publicGetAccessTokenFromCode('c', ''));
  1171. }
  1172. public function testAPIExceptionDuringCodeExchangeIsIgnored() {
  1173. $methods_to_stub = array(
  1174. '_oauthRequest',
  1175. );
  1176. $constructor_args = array(array(
  1177. 'appId' => self::APP_ID,
  1178. 'secret' => self::SECRET
  1179. ));
  1180. $stub = $this->getMock(
  1181. 'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args);
  1182. $stub
  1183. ->expects($this->once())
  1184. ->method('_oauthRequest')
  1185. ->will($this->throwException(new FacebookApiException(false)));
  1186. $this->assertFalse($stub->publicGetAccessTokenFromCode('c', ''));
  1187. }
  1188. public function testEmptyResponseInCodeExchangeIsIgnored() {
  1189. $methods_to_stub = array(
  1190. '_oauthRequest',
  1191. );
  1192. $constructor_args = array(array(
  1193. 'appId' => self::APP_ID,
  1194. 'secret' => self::SECRET
  1195. ));
  1196. $stub = $this->getMock(
  1197. 'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args);
  1198. $stub
  1199. ->expects($this->once())
  1200. ->method('_oauthRequest')
  1201. ->will($this->returnValue(''));
  1202. $this->assertFalse($stub->publicGetAccessTokenFromCode('c', ''));
  1203. }
  1204. public function testExistingStateRestoredInConstructor() {
  1205. $fb = new FBPublicState(array(
  1206. 'appId' => self::APP_ID,
  1207. 'secret' => self::SECRET
  1208. ));
  1209. $this->assertEquals(FBPublicState::STATE, $fb->publicGetState());
  1210. }
  1211. public function testMissingAccessTokenInCodeExchangeIsIgnored() {
  1212. $methods_to_stub = array(
  1213. '_oauthRequest',
  1214. );
  1215. $constructor_args = array(array(
  1216. 'appId' => self::APP_ID,
  1217. 'secret' => self::SECRET
  1218. ));
  1219. $stub = $this->getMock(
  1220. 'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args);
  1221. $stub
  1222. ->expects($this->once())
  1223. ->method('_oauthRequest')
  1224. ->will($this->returnValue('foo=1'));
  1225. $this->assertFalse($stub->publicGetAccessTokenFromCode('c', ''));
  1226. }
  1227. public function testAppsecretProofNoParams() {
  1228. $fb = new FBRecordMakeRequest(array(
  1229. 'appId' => self::APP_ID,
  1230. 'secret' => self::SECRET,
  1231. ));
  1232. $token = $fb->getAccessToken();
  1233. $proof = $fb->publicGetAppSecretProof($token);
  1234. $params = array();
  1235. $fb->api('/mattynoce', $params);
  1236. $requests = $fb->publicGetRequests();
  1237. $this->assertEquals($proof, $requests[0]['params']['appsecret_proof']);
  1238. }
  1239. public function testAppsecretProofWithParams() {
  1240. $fb = new FBRecordMakeRequest(array(
  1241. 'appId' => self::APP_ID,
  1242. 'secret' => self::SECRET,
  1243. ));
  1244. $proof = 'foo';
  1245. $params = array('appsecret_proof' => $proof);
  1246. $fb->api('/mattynoce', $params);
  1247. $requests = $fb->publicGetRequests();
  1248. $this->assertEquals($proof, $requests[0]['params']['appsecret_proof']);
  1249. }
  1250. public function testExceptionConstructorWithErrorCode() {
  1251. $code = 404;
  1252. $e = new FacebookApiException(array('error_code' => $code));
  1253. $this->assertEquals($code, $e->getCode());
  1254. }
  1255. public function testExceptionConstructorWithInvalidErrorCode() {
  1256. $e = new FacebookApiException(array('error_code' => 'not an int'));
  1257. $this->assertEquals(0, $e->getCode());
  1258. }
  1259. // this happens often despite the fact that it is useless
  1260. public function testExceptionTypeFalse() {
  1261. $e = new FacebookApiException(false);
  1262. $this->assertEquals('Exception', $e->getType());
  1263. }
  1264. public function testExceptionTypeMixedDraft00() {
  1265. $e = new FacebookApiException(array('error' => array('message' => 'foo')));
  1266. $this->assertEquals('Exception', $e->getType());
  1267. }
  1268. public function testExceptionTypeDraft00() {
  1269. $error = 'foo';
  1270. $e = new FacebookApiException(
  1271. array('error' => array('type' => $error, 'message' => 'hello world')));
  1272. $this->assertEquals($error, $e->getType());
  1273. }
  1274. public function testExceptionTypeDraft10() {
  1275. $error = 'foo';
  1276. $e = new FacebookApiException(array('error' => $error));
  1277. $this->assertEquals($error, $e->getType());
  1278. }
  1279. public function testExceptionTypeDefault() {
  1280. $e = new FacebookApiException(array('error' => false));
  1281. $this->assertEquals('Exception', $e->getType());
  1282. }
  1283. public function testExceptionToString() {
  1284. $e = new FacebookApiException(array(
  1285. 'error_cod…

Large files files are truncated, but you can click here to view the full file