diff options
Diffstat (limited to 'lib/facebook-graph-sdk/tests')
51 files changed, 6337 insertions, 0 deletions
diff --git a/lib/facebook-graph-sdk/tests/Authentication/AccessTokenMetadata.php b/lib/facebook-graph-sdk/tests/Authentication/AccessTokenMetadata.php new file mode 100644 index 0000000..1b54503 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Authentication/AccessTokenMetadata.php @@ -0,0 +1,138 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Authentication; + +use Facebook\Authentication\AccessTokenMetadata; + +class AccessTokenMetadataTest extends \PHPUnit_Framework_TestCase +{ + + protected $graphResponseData = [ + 'data' => [ + 'app_id' => '123', + 'application' => 'Foo App', + 'error' => [ + 'code' => 190, + 'message' => 'Foo error message.', + 'subcode' => 463, + ], + 'issued_at' => 1422110200, + 'expires_at' => 1422115200, + 'is_valid' => false, + 'metadata' => [ + 'sso' => 'iphone-sso', + 'auth_type' => 'rerequest', + 'auth_nonce' => 'no-replicatey', + ], + 'scopes' => ['public_profile', 'basic_info', 'user_friends'], + 'profile_id' => '1000', + 'user_id' => '1337', + ], + ]; + + public function testDatesGetCastToDateTime() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + + $expires = $metadata->getExpiresAt(); + $issuedAt = $metadata->getIssuedAt(); + + $this->assertInstanceOf('DateTime', $expires); + $this->assertInstanceOf('DateTime', $issuedAt); + } + + public function testAllTheGettersReturnTheProperValue() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + + $this->assertEquals('123', $metadata->getAppId()); + $this->assertEquals('Foo App', $metadata->getApplication()); + $this->assertTrue($metadata->isError(), 'Expected an error'); + $this->assertEquals('190', $metadata->getErrorCode()); + $this->assertEquals('Foo error message.', $metadata->getErrorMessage()); + $this->assertEquals('463', $metadata->getErrorSubcode()); + $this->assertFalse($metadata->getIsValid(), 'Expected the access token to not be valid'); + $this->assertEquals('iphone-sso', $metadata->getSso()); + $this->assertEquals('rerequest', $metadata->getAuthType()); + $this->assertEquals('no-replicatey', $metadata->getAuthNonce()); + $this->assertEquals('1000', $metadata->getProfileId()); + $this->assertEquals(['public_profile', 'basic_info', 'user_friends'], $metadata->getScopes()); + $this->assertEquals('1337', $metadata->getUserId()); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInvalidMetadataWillThrow() + { + new AccessTokenMetadata(['foo' => 'bar']); + } + + public function testAnExpectedAppIdWillNotThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateAppId('123'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnUnexpectedAppIdWillThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateAppId('foo'); + } + + public function testAnExpectedUserIdWillNotThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateUserId('1337'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnUnexpectedUserIdWillThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateUserId('foo'); + } + + public function testAnActiveAccessTokenWillNotThrow() + { + $this->graphResponseData['data']['expires_at'] = time() + 1000; + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateExpiration(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnExpiredAccessTokenWillThrow() + { + $this->graphResponseData['data']['expires_at'] = time() - 1000; + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateExpiration(); + } +} diff --git a/lib/facebook-graph-sdk/tests/Authentication/AccessTokenTest.php b/lib/facebook-graph-sdk/tests/Authentication/AccessTokenTest.php new file mode 100644 index 0000000..d66a5ba --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Authentication/AccessTokenTest.php @@ -0,0 +1,111 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Authentication; + +use Facebook\Authentication\AccessToken; + +class AccessTokenTest extends \PHPUnit_Framework_TestCase +{ + + public function testAnAccessTokenCanBeReturnedAsAString() + { + $accessToken = new AccessToken('foo_token'); + + $this->assertEquals('foo_token', $accessToken->getValue()); + $this->assertEquals('foo_token', (string)$accessToken); + } + + public function testAnAppSecretProofWillBeProperlyGenerated() + { + $accessToken = new AccessToken('foo_token'); + + $appSecretProof = $accessToken->getAppSecretProof('shhhhh!is.my.secret'); + + $this->assertEquals('796ba0d8a6b339e476a7b166a9e8ac0a395f7de736dc37de5f2f4397f5854eb8', $appSecretProof); + } + + public function testAnAppAccessTokenCanBeDetected() + { + $normalToken = new AccessToken('foo_token'); + $isNormalToken = $normalToken->isAppAccessToken(); + + $this->assertFalse($isNormalToken, 'Normal access token not expected to look like an app access token.'); + + $appToken = new AccessToken('123|secret'); + $isAppToken = $appToken->isAppAccessToken(); + + $this->assertTrue($isAppToken, 'App access token expected to look like an app access token.'); + } + + public function testShortLivedAccessTokensCanBeDetected() + { + $anHourAndAHalf = time() + (1.5 * 60); + $accessToken = new AccessToken('foo_token', $anHourAndAHalf); + + $isLongLived = $accessToken->isLongLived(); + + $this->assertFalse($isLongLived, 'Expected access token to be short lived.'); + } + + public function testLongLivedAccessTokensCanBeDetected() + { + $accessToken = new AccessToken('foo_token', $this->aWeekFromNow()); + + $isLongLived = $accessToken->isLongLived(); + + $this->assertTrue($isLongLived, 'Expected access token to be long lived.'); + } + + public function testAnAppAccessTokenDoesNotExpire() + { + $appToken = new AccessToken('123|secret'); + $hasExpired = $appToken->isExpired(); + + $this->assertFalse($hasExpired, 'App access token not expected to expire.'); + } + + public function testAnAccessTokenCanExpire() + { + $expireTime = time() - 100; + $appToken = new AccessToken('foo_token', $expireTime); + $hasExpired = $appToken->isExpired(); + + $this->assertTrue($hasExpired, 'Expected 100 second old access token to be expired.'); + } + + public function testAccessTokenCanBeSerialized() + { + $accessToken = new AccessToken('foo', time(), 'bar'); + + $newAccessToken = unserialize(serialize($accessToken)); + + $this->assertEquals((string)$accessToken, (string)$newAccessToken); + $this->assertEquals($accessToken->getExpiresAt(), $newAccessToken->getExpiresAt()); + } + + private function aWeekFromNow() + { + return time() + (60 * 60 * 24 * 7);//a week from now + } +} diff --git a/lib/facebook-graph-sdk/tests/Authentication/FooFacebookClientForOAuth2Test.php b/lib/facebook-graph-sdk/tests/Authentication/FooFacebookClientForOAuth2Test.php new file mode 100644 index 0000000..1199b00 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Authentication/FooFacebookClientForOAuth2Test.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Authentication; + +use Facebook\FacebookClient; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; + +class FooFacebookClientForOAuth2Test extends FacebookClient +{ + protected $response = ''; + + public function setMetadataResponse() + { + $this->response = '{"data":{"user_id":"444"}}'; + } + + public function setAccessTokenResponse() + { + $this->response = '{"access_token":"my_access_token","expires":"1422115200"}'; + } + + public function setCodeResponse() + { + $this->response = '{"code":"my_neat_code"}'; + } + + public function sendRequest(FacebookRequest $request) + { + return new FacebookResponse( + $request, + $this->response, + 200, + [] + ); + } +} diff --git a/lib/facebook-graph-sdk/tests/Authentication/OAuth2ClientTest.php b/lib/facebook-graph-sdk/tests/Authentication/OAuth2ClientTest.php new file mode 100644 index 0000000..72a8e2a --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Authentication/OAuth2ClientTest.php @@ -0,0 +1,167 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Authentication; + +use Mockery as m; +use Facebook\Facebook; +use Facebook\FacebookApp; +use Facebook\Authentication\OAuth2Client; + +class OAuth2ClientTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @const The foo Graph version + */ + const TESTING_GRAPH_VERSION = 'v1337'; + + /** + * @var FooFacebookClientForOAuth2Test + */ + protected $client; + + /** + * @var OAuth2Client + */ + protected $oauth; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_secret'); + $this->client = new FooFacebookClientForOAuth2Test(); + $this->oauth = new OAuth2Client($app, $this->client, static::TESTING_GRAPH_VERSION); + } + + public function testCanGetMetadataFromAnAccessToken() + { + $this->client->setMetadataResponse(); + + $metadata = $this->oauth->debugToken('baz_token'); + + $this->assertInstanceOf('Facebook\Authentication\AccessTokenMetadata', $metadata); + $this->assertEquals('444', $metadata->getUserId()); + + $expectedParams = [ + 'input_token' => 'baz_token', + 'access_token' => '123|foo_secret', + 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals('GET', $request->getMethod()); + $this->assertEquals('/debug_token', $request->getEndpoint()); + $this->assertEquals($expectedParams, $request->getParams()); + $this->assertEquals(static::TESTING_GRAPH_VERSION, $request->getGraphVersion()); + } + + public function testCanBuildAuthorizationUrl() + { + $scope = ['email', 'base_foo']; + $authUrl = $this->oauth->getAuthorizationUrl('https://foo.bar', 'foo_state', $scope, ['foo' => 'bar'], '*'); + + $this->assertContains('*', $authUrl); + + $expectedUrl = 'https://www.facebook.com/' . static::TESTING_GRAPH_VERSION . '/dialog/oauth?'; + $this->assertTrue(strpos($authUrl, $expectedUrl) === 0, 'Unexpected base authorization URL returned from getAuthorizationUrl().'); + + $params = [ + 'client_id' => '123', + 'redirect_uri' => 'https://foo.bar', + 'state' => 'foo_state', + 'sdk' => 'php-sdk-' . Facebook::VERSION, + 'scope' => implode(',', $scope), + 'foo' => 'bar', + ]; + foreach ($params as $key => $value) { + $this->assertContains($key . '=' . urlencode($value), $authUrl); + } + } + + public function testCanGetAccessTokenFromCode() + { + $this->client->setAccessTokenResponse(); + + $accessToken = $this->oauth->getAccessTokenFromCode('bar_code', 'foo_uri'); + + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('my_access_token', $accessToken->getValue()); + + $expectedParams = [ + 'code' => 'bar_code', + 'redirect_uri' => 'foo_uri', + 'client_id' => '123', + 'client_secret' => 'foo_secret', + 'access_token' => '123|foo_secret', + 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals('GET', $request->getMethod()); + $this->assertEquals('/oauth/access_token', $request->getEndpoint()); + $this->assertEquals($expectedParams, $request->getParams()); + $this->assertEquals(static::TESTING_GRAPH_VERSION, $request->getGraphVersion()); + } + + public function testCanGetLongLivedAccessToken() + { + $this->client->setAccessTokenResponse(); + + $accessToken = $this->oauth->getLongLivedAccessToken('short_token'); + + $this->assertEquals('my_access_token', $accessToken->getValue()); + + $expectedParams = [ + 'grant_type' => 'fb_exchange_token', + 'fb_exchange_token' => 'short_token', + 'client_id' => '123', + 'client_secret' => 'foo_secret', + 'access_token' => '123|foo_secret', + 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals($expectedParams, $request->getParams()); + } + + public function testCanGetCodeFromLongLivedAccessToken() + { + $this->client->setCodeResponse(); + + $code = $this->oauth->getCodeFromLongLivedAccessToken('long_token', 'foo_uri'); + + $this->assertEquals('my_neat_code', $code); + + $expectedParams = [ + 'access_token' => 'long_token', + 'redirect_uri' => 'foo_uri', + 'client_id' => '123', + 'client_secret' => 'foo_secret', + 'appsecret_proof' => '7e91300ea91be4166282611d4fc700b473466f3ea2981dafbf492fc096995bf1', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals($expectedParams, $request->getParams()); + $this->assertEquals('/oauth/client_code', $request->getEndpoint()); + } +} diff --git a/lib/facebook-graph-sdk/tests/Exceptions/FacebookResponseExceptionTest.php b/lib/facebook-graph-sdk/tests/Exceptions/FacebookResponseExceptionTest.php new file mode 100644 index 0000000..107a9b9 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Exceptions/FacebookResponseExceptionTest.php @@ -0,0 +1,278 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Exceptions; + +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; +use Facebook\Exceptions\FacebookResponseException; + +class FacebookResponseExceptionTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var FacebookRequest + */ + protected $request; + + public function setUp() + { + $this->request = new FacebookRequest(new FacebookApp('123', 'foo')); + } + + public function testAuthenticationExceptions() + { + $params = [ + 'error' => [ + 'code' => 100, + 'message' => 'errmsg', + 'error_subcode' => 0, + 'type' => 'exception' + ], + ]; + + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(100, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(401, $exception->getHttpStatusCode()); + + $params['error']['code'] = 102; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(102, $exception->getCode()); + + $params['error']['code'] = 190; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(190, $exception->getCode()); + + $params['error']['type'] = 'OAuthException'; + $params['error']['code'] = 0; + $params['error']['error_subcode'] = 458; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(458, $exception->getSubErrorCode()); + + $params['error']['error_subcode'] = 460; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(460, $exception->getSubErrorCode()); + + $params['error']['error_subcode'] = 463; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(463, $exception->getSubErrorCode()); + + $params['error']['error_subcode'] = 467; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(467, $exception->getSubErrorCode()); + + $params['error']['error_subcode'] = 0; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(0, $exception->getSubErrorCode()); + } + + public function testServerExceptions() + { + $params = [ + 'error' => [ + 'code' => 1, + 'message' => 'errmsg', + 'error_subcode' => 0, + 'type' => 'exception' + ], + ]; + + $response = new FacebookResponse($this->request, json_encode($params), 500); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookServerException', $exception->getPrevious()); + $this->assertEquals(1, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(500, $exception->getHttpStatusCode()); + + $params['error']['code'] = 2; + $response = new FacebookResponse($this->request, json_encode($params), 500); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookServerException', $exception->getPrevious()); + $this->assertEquals(2, $exception->getCode()); + } + + public function testThrottleExceptions() + { + $params = [ + 'error' => [ + 'code' => 4, + 'message' => 'errmsg', + 'error_subcode' => 0, + 'type' => 'exception' + ], + ]; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); + $this->assertEquals(4, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(401, $exception->getHttpStatusCode()); + + $params['error']['code'] = 17; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); + $this->assertEquals(17, $exception->getCode()); + + $params['error']['code'] = 341; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); + $this->assertEquals(341, $exception->getCode()); + } + + public function testUserIssueExceptions() + { + $params = [ + 'error' => [ + 'code' => 230, + 'message' => 'errmsg', + 'error_subcode' => 459, + 'type' => 'exception' + ], + ]; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(230, $exception->getCode()); + $this->assertEquals(459, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(401, $exception->getHttpStatusCode()); + + $params['error']['error_subcode'] = 464; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(464, $exception->getSubErrorCode()); + } + + public function testAuthorizationExceptions() + { + $params = [ + 'error' => [ + 'code' => 10, + 'message' => 'errmsg', + 'error_subcode' => 0, + 'type' => 'exception' + ], + ]; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertEquals(10, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(401, $exception->getHttpStatusCode()); + + $params['error']['code'] = 200; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertEquals(200, $exception->getCode()); + + $params['error']['code'] = 250; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertEquals(250, $exception->getCode()); + + $params['error']['code'] = 299; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertEquals(299, $exception->getCode()); + } + + public function testClientExceptions() + { + $params = [ + 'error' => [ + 'code' => 506, + 'message' => 'errmsg', + 'error_subcode' => 0, + 'type' => 'exception' + ], + ]; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookClientException', $exception->getPrevious()); + $this->assertEquals(506, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(401, $exception->getHttpStatusCode()); + } + + public function testOtherException() + { + $params = [ + 'error' => [ + 'code' => 42, + 'message' => 'ship love', + 'error_subcode' => 0, + 'type' => 'feature' + ], + ]; + $response = new FacebookResponse($this->request, json_encode($params), 200); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookOtherException', $exception->getPrevious()); + $this->assertEquals(42, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('feature', $exception->getErrorType()); + $this->assertEquals('ship love', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(200, $exception->getHttpStatusCode()); + } +} diff --git a/lib/facebook-graph-sdk/tests/FacebookAppTest.php b/lib/facebook-graph-sdk/tests/FacebookAppTest.php new file mode 100644 index 0000000..d1b453d --- /dev/null +++ b/lib/facebook-graph-sdk/tests/FacebookAppTest.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests; + +use Facebook\FacebookApp; + +class FacebookAppTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FacebookApp + */ + private $app; + + public function setUp() + { + $this->app = new FacebookApp('id', 'secret'); + } + + public function testGetId() + { + $this->assertEquals('id', $this->app->getId()); + } + + public function testGetSecret() + { + $this->assertEquals('secret', $this->app->getSecret()); + } + + public function testAnAppAccessTokenCanBeGenerated() + { + $accessToken = $this->app->getAccessToken(); + + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('id|secret', (string)$accessToken); + } + + public function testSerialization() + { + $newApp = unserialize(serialize($this->app)); + + $this->assertInstanceOf('Facebook\FacebookApp', $newApp); + $this->assertEquals('id', $newApp->getId()); + $this->assertEquals('secret', $newApp->getSecret()); + } +} diff --git a/lib/facebook-graph-sdk/tests/FacebookBatchRequestTest.php b/lib/facebook-graph-sdk/tests/FacebookBatchRequestTest.php new file mode 100755 index 0000000..cef0586 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/FacebookBatchRequestTest.php @@ -0,0 +1,381 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests; + +use Facebook\Facebook; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookBatchRequest; +use Facebook\FileUpload\FacebookFile; + +class FacebookBatchRequestTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FacebookApp + */ + private $app; + + public function setUp() + { + $this->app = new FacebookApp('123', 'foo_secret'); + } + + public function testABatchRequestWillInstantiateWithTheProperProperties() + { + $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token', 'v0.1337'); + + $this->assertSame($this->app, $batchRequest->getApp()); + $this->assertEquals('foo_token', $batchRequest->getAccessToken()); + $this->assertEquals('POST', $batchRequest->getMethod()); + $this->assertEquals('', $batchRequest->getEndpoint()); + $this->assertEquals('v0.1337', $batchRequest->getGraphVersion()); + } + + public function testEmptyRequestWillFallbackToBatchDefaults() + { + $request = new FacebookRequest(); + + $this->createBatchRequest()->addFallbackDefaults($request); + + $this->assertRequestContainsAppAndToken($request, $this->app, 'foo_token'); + } + + public function testRequestWithTokenOnlyWillFallbackToBatchDefaults() + { + $request = new FacebookRequest(null, 'bar_token'); + + $this->createBatchRequest()->addFallbackDefaults($request); + + $this->assertRequestContainsAppAndToken($request, $this->app, 'bar_token'); + } + + public function testRequestWithAppOnlyWillFallbackToBatchDefaults() + { + $customApp = new FacebookApp('1337', 'bar_secret'); + $request = new FacebookRequest($customApp); + + $this->createBatchRequest()->addFallbackDefaults($request); + + $this->assertRequestContainsAppAndToken($request, $customApp, 'foo_token'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testWillThrowWhenNoThereIsNoAppFallback() + { + $batchRequest = new FacebookBatchRequest(); + + $batchRequest->addFallbackDefaults(new FacebookRequest(null, 'foo_token')); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testWillThrowWhenNoThereIsNoAccessTokenFallback() + { + $request = new FacebookBatchRequest(); + + $request->addFallbackDefaults(new FacebookRequest($this->app)); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testAnInvalidTypeGivenToAddWillThrow() + { + $request = new FacebookBatchRequest(); + + $request->add('foo'); + } + + public function testAddingRequestsWillBeFormattedInAnArrayProperly() + { + $requests = [ + null => new FacebookRequest(null, null, 'GET', '/foo'), + 'my-second-request' => new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + 'my-third-request' => new FacebookRequest(null, null, 'DELETE', '/baz') + ]; + + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($requests[null]); + $batchRequest->add($requests['my-second-request'], 'my-second-request'); + $batchRequest->add($requests['my-third-request'], 'my-third-request'); + + $formattedRequests = $batchRequest->getRequests(); + + $this->assertRequestsMatch($requests, $formattedRequests); + } + + public function testANumericArrayOfRequestsCanBeAdded() + { + $requests = [ + new FacebookRequest(null, null, 'GET', '/foo'), + new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + new FacebookRequest(null, null, 'DELETE', '/baz'), + ]; + + $formattedRequests = $this->createBatchRequestWithRequests($requests)->getRequests(); + + $this->assertRequestsMatch($requests, $formattedRequests); + } + + public function testAnAssociativeArrayOfRequestsCanBeAdded() + { + $requests = [ + 'req-one' => new FacebookRequest(null, null, 'GET', '/foo'), + 'req-two' => new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + 'req-three' => new FacebookRequest(null, null, 'DELETE', '/baz'), + ]; + + $formattedRequests = $this->createBatchRequestWithRequests($requests)->getRequests(); + + $this->assertRequestsMatch($requests, $formattedRequests); + } + + public function testRequestsCanBeInjectedIntoConstructor() + { + $requests = [ + new FacebookRequest(null, null, 'GET', '/foo'), + new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + new FacebookRequest(null, null, 'DELETE', '/baz'), + ]; + + $batchRequest = new FacebookBatchRequest($this->app, $requests, 'foo_token'); + $formattedRequests = $batchRequest->getRequests(); + + $this->assertRequestsMatch($requests, $formattedRequests); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAZeroRequestCountWithThrow() + { + $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token'); + + $batchRequest->validateBatchRequestCount(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testMoreThanFiftyRequestsWillThrow() + { + $batchRequest = $this->createBatchRequest(); + + $this->createAndAppendRequestsTo($batchRequest, 51); + + $batchRequest->validateBatchRequestCount(); + } + + public function testLessOrEqualThanFiftyRequestsWillNotThrow() + { + $batchRequest = $this->createBatchRequest(); + + $this->createAndAppendRequestsTo($batchRequest, 50); + + $batchRequest->validateBatchRequestCount(); + } + + /** + * @dataProvider requestsAndExpectedResponsesProvider + */ + public function testBatchRequestEntitiesProperlyGetConvertedToAnArray($request, $expectedArray) + { + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($request, 'foo_name'); + + $requests = $batchRequest->getRequests(); + $batchRequestArray = $batchRequest->requestEntityToBatchArray($requests[0]['request'], $requests[0]['name']); + + $this->assertEquals($expectedArray, $batchRequestArray); + } + + public function requestsAndExpectedResponsesProvider() + { + $headers = $this->defaultHeaders(); + $apiVersion = Facebook::DEFAULT_GRAPH_VERSION; + + return [ + [ + new FacebookRequest(null, null, 'GET', '/foo', ['foo' => 'bar']), + [ + 'headers' => $headers, + 'method' => 'GET', + 'relative_url' => '/' . $apiVersion . '/foo?foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + ], + ], + [ + new FacebookRequest(null, null, 'POST', '/bar', ['bar' => 'baz']), + [ + 'headers' => $headers, + 'method' => 'POST', + 'relative_url' => '/' . $apiVersion . '/bar', + 'body' => 'bar=baz&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + ], + ], + [ + new FacebookRequest(null, null, 'DELETE', '/bar'), + [ + 'headers' => $headers, + 'method' => 'DELETE', + 'relative_url' => '/' . $apiVersion . '/bar?access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + ], + ], + ]; + } + + public function testBatchRequestsWithFilesGetConvertedToAnArray() + { + $request = new FacebookRequest(null, null, 'POST', '/bar', [ + 'message' => 'foobar', + 'source' => new FacebookFile(__DIR__ . '/foo.txt'), + ]); + + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($request, 'foo_name'); + + $requests = $batchRequest->getRequests(); + + $attachedFiles = $requests[0]['attached_files']; + + $batchRequestArray = $batchRequest->requestEntityToBatchArray( + $requests[0]['request'], + $requests[0]['name'], + $attachedFiles + ); + + $this->assertEquals([ + 'headers' => $this->defaultHeaders(), + 'method' => 'POST', + 'relative_url' => '/' . Facebook::DEFAULT_GRAPH_VERSION . '/bar', + 'body' => 'message=foobar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + 'attached_files' => $attachedFiles, + ], $batchRequestArray); + } + + public function testPreppingABatchRequestProperlySetsThePostParams() + { + $batchRequest = $this->createBatchRequest(); + $batchRequest->add(new FacebookRequest(null, 'bar_token', 'GET', '/foo'), 'foo_name'); + $batchRequest->add(new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar'])); + $batchRequest->prepareRequestsForBatch(); + + $params = $batchRequest->getParams(); + + $expectedHeaders = json_encode($this->defaultHeaders()); + $version = Facebook::DEFAULT_GRAPH_VERSION; + $expectedBatchParams = [ + 'batch' => '[{"headers":' . $expectedHeaders . ',"method":"GET","relative_url":"\\/' . $version . '\\/foo?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd","name":"foo_name"},' + . '{"headers":' . $expectedHeaders . ',"method":"POST","relative_url":"\\/' . $version . '\\/bar","body":"foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9"}]', + 'include_headers' => true, + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + ]; + $this->assertEquals($expectedBatchParams, $params); + } + + public function testPreppingABatchRequestProperlyMovesTheFiles() + { + $batchRequest = $this->createBatchRequest(); + $batchRequest->add(new FacebookRequest(null, 'bar_token', 'GET', '/foo'), 'foo_name'); + $batchRequest->add(new FacebookRequest(null, null, 'POST', '/me/photos', [ + 'message' => 'foobar', + 'source' => new FacebookFile(__DIR__ . '/foo.txt'), + ])); + $batchRequest->prepareRequestsForBatch(); + + $params = $batchRequest->getParams(); + $files = $batchRequest->getFiles(); + + $attachedFiles = implode(',', array_keys($files)); + + $expectedHeaders = json_encode($this->defaultHeaders()); + $version = Facebook::DEFAULT_GRAPH_VERSION; + $expectedBatchParams = [ + 'batch' => '[{"headers":' . $expectedHeaders . ',"method":"GET","relative_url":"\\/' . $version . '\\/foo?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd","name":"foo_name"},' + . '{"headers":' . $expectedHeaders . ',"method":"POST","relative_url":"\\/' . $version . '\\/me\\/photos","body":"message=foobar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9","attached_files":"' . $attachedFiles . '"}]', + 'include_headers' => true, + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + ]; + $this->assertEquals($expectedBatchParams, $params); + } + + private function assertRequestContainsAppAndToken(FacebookRequest $request, FacebookApp $expectedApp, $expectedToken) + { + $app = $request->getApp(); + $token = $request->getAccessToken(); + + $this->assertSame($expectedApp, $app); + $this->assertEquals($expectedToken, $token); + } + + private function defaultHeaders() + { + $headers = []; + foreach (FacebookRequest::getDefaultHeaders() as $name => $value) { + $headers[] = $name . ': ' . $value; + } + + return $headers; + } + + private function createAndAppendRequestsTo(FacebookBatchRequest $batchRequest, $number) + { + for ($i = 0; $i < $number; $i++) { + $batchRequest->add(new FacebookRequest()); + } + } + + private function createBatchRequest() + { + return new FacebookBatchRequest($this->app, [], 'foo_token'); + } + + private function createBatchRequestWithRequests(array $requests) + { + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($requests); + + return $batchRequest; + } + + private function assertRequestsMatch($requests, $formattedRequests) + { + $expectedRequests = []; + foreach ($requests as $name => $request) { + $expectedRequests[] = [ + 'name' => $name, + 'request' => $request + ]; + } + $this->assertEquals($expectedRequests, $formattedRequests); + } +} diff --git a/lib/facebook-graph-sdk/tests/FacebookBatchResponseTest.php b/lib/facebook-graph-sdk/tests/FacebookBatchResponseTest.php new file mode 100755 index 0000000..dec92a1 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/FacebookBatchResponseTest.php @@ -0,0 +1,138 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests; + +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; +use Facebook\FacebookBatchRequest; +use Facebook\FacebookBatchResponse; + +class FacebookBatchResponseTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Facebook\FacebookApp + */ + protected $app; + + /** + * @var \Facebook\FacebookRequest + */ + protected $request; + + public function setUp() + { + $this->app = new FacebookApp('123', 'foo_secret'); + $this->request = new FacebookRequest( + $this->app, + 'foo_token', + 'POST', + '/', + ['batch' => 'foo'], + 'foo_eTag', + 'v1337' + ); + } + + public function testASuccessfulJsonBatchResponseWillBeDecoded() + { + $graphResponseJson = '['; + // Single Graph object. + $graphResponseJson .= '{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Last-Modified","value":"2013-12-24T00:34:20+0000"},{"name":"Facebook-API-Version","value":"v2.0"},{"name":"ETag","value":"\"fooTag\""},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Pragma","value":"no-cache"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"}],"body":"{\"id\":\"123\",\"name\":\"Foo McBar\",\"updated_time\":\"2013-12-24T00:34:20+0000\",\"verified\":true}"}'; + // Paginated list of Graph objects. + $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Facebook-API-Version","value":"v1.0"},{"name":"ETag","value":"\"barTag\""},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Pragma","value":"no-cache"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"}],"body":"{\"data\":[{\"id\":\"1337\",\"story\":\"Foo story.\"},{\"id\":\"1338\",\"story\":\"Bar story.\"}],\"paging\":{\"previous\":\"previous_url\",\"next\":\"next_url\"}}"}'; + // After POST operation. + $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Pragma","value":"no-cache"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Facebook-API-Version","value":"v2.0"}],"body":"{\"id\":\"123_1337\"}"}'; + // After DELETE operation. + $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Pragma","value":"no-cache"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Facebook-API-Version","value":"v2.0"}],"body":"true"}'; + $graphResponseJson .= ']'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + $batchRequest = new FacebookBatchRequest($this->app, [ + new FacebookRequest($this->app, 'token'), + new FacebookRequest($this->app, 'token'), + new FacebookRequest($this->app, 'token'), + new FacebookRequest($this->app, 'token'), + ]); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); + + $decodedResponses = $batchResponse->getResponses(); + + // Single Graph object. + $this->assertFalse($decodedResponses[0]->isError(), 'Did not expect Response to return an error for single Graph object.'); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $decodedResponses[0]->getGraphNode()); + // Paginated list of Graph objects. + $this->assertFalse($decodedResponses[1]->isError(), 'Did not expect Response to return an error for paginated list of Graph objects.'); + $graphEdge = $decodedResponses[1]->getGraphEdge(); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[0]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[1]); + } + + public function testABatchResponseCanBeIteratedOver() + { + $graphResponseJson = '['; + $graphResponseJson .= '{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ']'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + $batchRequest = new FacebookBatchRequest($this->app, [ + 'req_one' => new FacebookRequest($this->app, 'token'), + 'req_two' => new FacebookRequest($this->app, 'token'), + 'req_three' => new FacebookRequest($this->app, 'token'), + ]); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); + + $this->assertInstanceOf('IteratorAggregate', $batchResponse); + + foreach ($batchResponse as $key => $responseEntity) { + $this->assertTrue(in_array($key, ['req_one', 'req_two', 'req_three'])); + $this->assertInstanceOf('Facebook\FacebookResponse', $responseEntity); + } + } + + public function testTheOriginalRequestCanBeObtainedForEachRequest() + { + $graphResponseJson = '['; + $graphResponseJson .= '{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ']'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + + $requests = [ + new FacebookRequest($this->app, 'foo_token_one', 'GET', '/me'), + new FacebookRequest($this->app, 'foo_token_two', 'POST', '/you'), + new FacebookRequest($this->app, 'foo_token_three', 'DELETE', '/123456'), + ]; + + $batchRequest = new FacebookBatchRequest($this->app, $requests); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); + + $this->assertInstanceOf('Facebook\FacebookResponse', $batchResponse[0]); + $this->assertInstanceOf('Facebook\FacebookRequest', $batchResponse[0]->getRequest()); + $this->assertEquals('foo_token_one', $batchResponse[0]->getAccessToken()); + $this->assertEquals('foo_token_two', $batchResponse[1]->getAccessToken()); + $this->assertEquals('foo_token_three', $batchResponse[2]->getAccessToken()); + } +} diff --git a/lib/facebook-graph-sdk/tests/FacebookClientTest.php b/lib/facebook-graph-sdk/tests/FacebookClientTest.php new file mode 100644 index 0000000..6e9bb6c --- /dev/null +++ b/lib/facebook-graph-sdk/tests/FacebookClientTest.php @@ -0,0 +1,308 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests; + +use Facebook\Exceptions\FacebookSDKException; +use Facebook\Facebook; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookBatchRequest; +use Facebook\FacebookClient; +use Facebook\Http\GraphRawResponse; +use Facebook\HttpClients\FacebookHttpClientInterface; +use Facebook\FileUpload\FacebookFile; +use Facebook\FileUpload\FacebookVideo; +// These are needed when you uncomment the HTTP clients below. +use Facebook\HttpClients\FacebookCurlHttpClient; +use Facebook\HttpClients\FacebookGuzzleHttpClient; +use Facebook\HttpClients\FacebookStreamHttpClient; + +class MyFooClientHandler implements FacebookHttpClientInterface +{ + public function send($url, $method, $body, array $headers, $timeOut) + { + return new GraphRawResponse( + "HTTP/1.1 200 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", + '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' + ); + } +} + +class MyFooBatchClientHandler implements FacebookHttpClientInterface +{ + public function send($url, $method, $body, array $headers, $timeOut) + { + return new GraphRawResponse( + "HTTP/1.1 200 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", + '[{"code":"123","body":"Foo"},{"code":"1337","body":"Bar"}]' + ); + } +} + +class FacebookClientTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FacebookApp + */ + public $fbApp; + + /** + * @var FacebookClient + */ + public $fbClient; + + /** + * @var FacebookApp + */ + public static $testFacebookApp; + + /** + * @var FacebookClient + */ + public static $testFacebookClient; + + public function setUp() + { + $this->fbApp = new FacebookApp('id', 'shhhh!'); + $this->fbClient = new FacebookClient(new MyFooClientHandler()); + } + + public function testACustomHttpClientCanBeInjected() + { + $handler = new MyFooClientHandler(); + $client = new FacebookClient($handler); + $httpHandler = $client->getHttpClientHandler(); + + $this->assertInstanceOf('Facebook\Tests\MyFooClientHandler', $httpHandler); + } + + public function testTheHttpClientWillFallbackToDefault() + { + $client = new FacebookClient(); + $httpHandler = $client->getHttpClientHandler(); + + if (function_exists('curl_init')) { + $this->assertInstanceOf('Facebook\HttpClients\FacebookCurlHttpClient', $httpHandler); + } else { + $this->assertInstanceOf('Facebook\HttpClients\FacebookStreamHttpClient', $httpHandler); + } + } + + public function testBetaModeCanBeDisabledOrEnabledViaConstructor() + { + $client = new FacebookClient(null, false); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL, $url); + + $client = new FacebookClient(null, true); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $url); + } + + public function testBetaModeCanBeDisabledOrEnabledViaMethod() + { + $client = new FacebookClient(); + $client->enableBetaMode(false); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL, $url); + + $client->enableBetaMode(true); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $url); + } + + public function testGraphVideoUrlCanBeSet() + { + $client = new FacebookClient(); + $client->enableBetaMode(false); + $url = $client->getBaseGraphUrl($postToVideoUrl = true); + $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL, $url); + + $client->enableBetaMode(true); + $url = $client->getBaseGraphUrl($postToVideoUrl = true); + $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL_BETA, $url); + } + + public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() + { + $fbRequest = new FacebookRequest($this->fbApp, 'token', 'GET', '/foo'); + $response = $this->fbClient->sendRequest($fbRequest); + + $this->assertInstanceOf('Facebook\FacebookResponse', $response); + $this->assertEquals(200, $response->getHttpStatusCode()); + $this->assertEquals('{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}', $response->getBody()); + } + + public function testAFacebookBatchRequestEntityCanBeUsedToSendABatchRequestToGraph() + { + $fbRequests = [ + new FacebookRequest($this->fbApp, 'token', 'GET', '/foo'), + new FacebookRequest($this->fbApp, 'token', 'POST', '/bar'), + ]; + $fbBatchRequest = new FacebookBatchRequest($this->fbApp, $fbRequests); + + $fbBatchClient = new FacebookClient(new MyFooBatchClientHandler()); + $response = $fbBatchClient->sendBatchRequest($fbBatchRequest); + + $this->assertInstanceOf('Facebook\FacebookBatchResponse', $response); + $this->assertEquals('GET', $response[0]->getRequest()->getMethod()); + $this->assertEquals('POST', $response[1]->getRequest()->getMethod()); + } + + public function testAFacebookBatchRequestWillProperlyBatchFiles() + { + $fbRequests = [ + new FacebookRequest($this->fbApp, 'token', 'POST', '/photo', [ + 'message' => 'foobar', + 'source' => new FacebookFile(__DIR__ . '/foo.txt'), + ]), + new FacebookRequest($this->fbApp, 'token', 'POST', '/video', [ + 'message' => 'foobar', + 'source' => new FacebookVideo(__DIR__ . '/foo.txt'), + ]), + ]; + $fbBatchRequest = new FacebookBatchRequest($this->fbApp, $fbRequests); + $fbBatchRequest->prepareRequestsForBatch(); + + list($url, $method, $headers, $body) = $this->fbClient->prepareRequestMessage($fbBatchRequest); + + $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL . '/' . Facebook::DEFAULT_GRAPH_VERSION, $url); + $this->assertEquals('POST', $method); + $this->assertContains('multipart/form-data; boundary=', $headers['Content-Type']); + $this->assertContains('Content-Disposition: form-data; name="batch"', $body); + $this->assertContains('Content-Disposition: form-data; name="include_headers"', $body); + $this->assertContains('"name":0,"attached_files":', $body); + $this->assertContains('"name":1,"attached_files":', $body); + $this->assertContains('"; filename="foo.txt"', $body); + } + + public function testARequestOfParamsWillBeUrlEncoded() + { + $fbRequest = new FacebookRequest($this->fbApp, 'token', 'POST', '/foo', ['foo' => 'bar']); + $response = $this->fbClient->sendRequest($fbRequest); + + $headersSent = $response->getRequest()->getHeaders(); + + $this->assertEquals('application/x-www-form-urlencoded', $headersSent['Content-Type']); + } + + public function testARequestWithFilesWillBeMultipart() + { + $myFile = new FacebookFile(__DIR__ . '/foo.txt'); + $fbRequest = new FacebookRequest($this->fbApp, 'token', 'POST', '/foo', ['file' => $myFile]); + $response = $this->fbClient->sendRequest($fbRequest); + + $headersSent = $response->getRequest()->getHeaders(); + + $this->assertContains('multipart/form-data; boundary=', $headersSent['Content-Type']); + } + + /** + * @group integration + */ + public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() + { + $this->initializeTestApp(); + + // Create a test user + $testUserPath = '/' . FacebookTestCredentials::$appId . '/accounts/test-users'; + $params = [ + 'installed' => true, + 'name' => 'Foo Phpunit User', + 'locale' => 'en_US', + 'permissions' => implode(',', ['read_stream', 'user_photos']), + ]; + + $request = new FacebookRequest( + static::$testFacebookApp, + static::$testFacebookApp->getAccessToken(), + 'POST', + $testUserPath, + $params + ); + $response = static::$testFacebookClient->sendRequest($request)->getGraphNode(); + + $testUserId = $response->getField('id'); + $testUserAccessToken = $response->getField('access_token'); + + // Get the test user's profile + $request = new FacebookRequest( + static::$testFacebookApp, + $testUserAccessToken, + 'GET', + '/me' + ); + $graphNode = static::$testFacebookClient->sendRequest($request)->getGraphNode(); + + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphNode); + $this->assertNotNull($graphNode->getField('id')); + $this->assertEquals('Foo Phpunit User', $graphNode->getField('name')); + + // Delete test user + $request = new FacebookRequest( + static::$testFacebookApp, + static::$testFacebookApp->getAccessToken(), + 'DELETE', + '/' . $testUserId + ); + $graphNode = static::$testFacebookClient->sendRequest($request)->getGraphNode(); + + $this->assertTrue($graphNode->getField('success')); + } + + public function initializeTestApp() + { + if (!file_exists(__DIR__ . '/FacebookTestCredentials.php')) { + throw new FacebookSDKException( + 'You must create a FacebookTestCredentials.php file from FacebookTestCredentials.php.dist' + ); + } + + if (!strlen(FacebookTestCredentials::$appId) || + !strlen(FacebookTestCredentials::$appSecret) + ) { + throw new FacebookSDKException( + 'You must fill out FacebookTestCredentials.php' + ); + } + static::$testFacebookApp = new FacebookApp( + FacebookTestCredentials::$appId, + FacebookTestCredentials::$appSecret + ); + + // Use default client + $client = null; + + // Uncomment to enable curl implementation. + //$client = new FacebookCurlHttpClient(); + + // Uncomment to enable stream wrapper implementation. + //$client = new FacebookStreamHttpClient(); + + // Uncomment to enable Guzzle implementation. + //$client = new FacebookGuzzleHttpClient(); + + static::$testFacebookClient = new FacebookClient($client); + } +} diff --git a/lib/facebook-graph-sdk/tests/FacebookRequestTest.php b/lib/facebook-graph-sdk/tests/FacebookRequestTest.php new file mode 100755 index 0000000..fdea644 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/FacebookRequestTest.php @@ -0,0 +1,207 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests; + +use Facebook\Facebook; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FileUpload\FacebookFile; +use Facebook\FileUpload\FacebookVideo; + +class FacebookRequestTest extends \PHPUnit_Framework_TestCase +{ + public function testAnEmptyRequestEntityCanInstantiate() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app); + + $this->assertInstanceOf('Facebook\FacebookRequest', $request); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAMissingAccessTokenWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app); + + $request->validateAccessToken(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAMissingMethodWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app); + + $request->validateMethod(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnInvalidMethodWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'FOO'); + + $request->validateMethod(); + } + + public function testGetHeadersWillAutoAppendETag() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, null, 'GET', '/foo', [], 'fooETag'); + + $headers = $request->getHeaders(); + + $expectedHeaders = FacebookRequest::getDefaultHeaders(); + $expectedHeaders['If-None-Match'] = 'fooETag'; + + $this->assertEquals($expectedHeaders, $headers); + } + + public function testGetParamsWillAutoAppendAccessTokenAndAppSecretProof() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo', ['foo' => 'bar']); + + $params = $request->getParams(); + + $this->assertEquals([ + 'foo' => 'bar', + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + ], $params); + } + + public function testAnAccessTokenCanBeSetFromTheParams() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, null, 'POST', '/me', ['access_token' => 'bar_token']); + + $accessToken = $request->getAccessToken(); + + $this->assertEquals('bar_token', $accessToken); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAccessTokenConflictsWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + new FacebookRequest($app, 'foo_token', 'POST', '/me', ['access_token' => 'bar_token']); + } + + public function testAProperUrlWillBeGenerated() + { + $app = new FacebookApp('123', 'foo_secret'); + $getRequest = new FacebookRequest($app, 'foo_token', 'GET', '/foo', ['foo' => 'bar']); + + $getUrl = $getRequest->getUrl(); + $expectedParams = 'foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9'; + $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/foo?' . $expectedParams; + + $this->assertEquals($expectedUrl, $getUrl); + + $postRequest = new FacebookRequest($app, 'foo_token', 'POST', '/bar', ['foo' => 'bar']); + + $postUrl = $postRequest->getUrl(); + $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/bar'; + + $this->assertEquals($expectedUrl, $postUrl); + } + + public function testAuthenticationParamsAreStrippedAndReapplied() + { + $app = new FacebookApp('123', 'foo_secret'); + + $request = new FacebookRequest( + $app, + $accessToken = 'foo_token', + $method = 'GET', + $endpoint = '/foo', + $params = [ + 'access_token' => 'foo_token', + 'appsecret_proof' => 'bar_app_secret', + 'bar' => 'baz', + ] + ); + + $url = $request->getUrl(); + + $expectedParams = 'bar=baz&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9'; + $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/foo?' . $expectedParams; + $this->assertEquals($expectedUrl, $url); + + $params = $request->getParams(); + + $expectedParams = [ + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'bar' => 'baz', + ]; + $this->assertEquals($expectedParams, $params); + } + + public function testAFileCanBeAddedToParams() + { + $myFile = new FacebookFile(__DIR__ . '/foo.txt'); + $params = [ + 'name' => 'Foo Bar', + 'source' => $myFile, + ]; + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo/photos', $params); + + $actualParams = $request->getParams(); + + $this->assertTrue($request->containsFileUploads()); + $this->assertFalse($request->containsVideoUploads()); + $this->assertTrue(!isset($actualParams['source'])); + $this->assertEquals('Foo Bar', $actualParams['name']); + } + + public function testAVideoCanBeAddedToParams() + { + $myFile = new FacebookVideo(__DIR__ . '/foo.txt'); + $params = [ + 'name' => 'Foo Bar', + 'source' => $myFile, + ]; + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo/videos', $params); + + $actualParams = $request->getParams(); + + $this->assertTrue($request->containsFileUploads()); + $this->assertTrue($request->containsVideoUploads()); + $this->assertTrue(!isset($actualParams['source'])); + $this->assertEquals('Foo Bar', $actualParams['name']); + } +} diff --git a/lib/facebook-graph-sdk/tests/FacebookResponseTest.php b/lib/facebook-graph-sdk/tests/FacebookResponseTest.php new file mode 100755 index 0000000..21f90ae --- /dev/null +++ b/lib/facebook-graph-sdk/tests/FacebookResponseTest.php @@ -0,0 +1,121 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests; + +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; + +class FacebookResponseTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Facebook\FacebookRequest + */ + protected $request; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337' + ); + } + + public function testAnETagCanBeProperlyAccessed() + { + $response = new FacebookResponse($this->request, '', 200, ['ETag' => 'foo_tag']); + + $eTag = $response->getETag(); + + $this->assertEquals('foo_tag', $eTag); + } + + public function testAProperAppSecretProofCanBeGenerated() + { + $response = new FacebookResponse($this->request); + + $appSecretProof = $response->getAppSecretProof(); + + $this->assertEquals('df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', $appSecretProof); + } + + public function testASuccessfulJsonResponseWillBeDecodedToAGraphNode() + { + $graphResponseJson = '{"id":"123","name":"Foo"}'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + + $decodedResponse = $response->getDecodedBody(); + $graphNode = $response->getGraphNode(); + + $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); + $this->assertEquals([ + 'id' => '123', + 'name' => 'Foo', + ], $decodedResponse); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphNode); + } + + public function testASuccessfulJsonResponseWillBeDecodedToAGraphEdge() + { + $graphResponseJson = '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + + $graphEdge = $response->getGraphEdge(); + + $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[0]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[1]); + } + + public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() + { + $graphResponseKeyValuePairs = 'id=123&name=Foo'; + $response = new FacebookResponse($this->request, $graphResponseKeyValuePairs, 200); + + $decodedResponse = $response->getDecodedBody(); + + $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); + $this->assertEquals([ + 'id' => '123', + 'name' => 'Foo', + ], $decodedResponse); + } + + public function testErrorStatusCanBeCheckedWhenAnErrorResponseIsReturned() + { + $graphResponse = '{"error":{"message":"Foo error.","type":"OAuthException","code":190,"error_subcode":463}}'; + $response = new FacebookResponse($this->request, $graphResponse, 401); + + $exception = $response->getThrownException(); + + $this->assertTrue($response->isError(), 'Expected Response to return an error.'); + $this->assertInstanceOf('Facebook\Exceptions\FacebookResponseException', $exception); + } +} diff --git a/lib/facebook-graph-sdk/tests/FacebookTest.php b/lib/facebook-graph-sdk/tests/FacebookTest.php new file mode 100644 index 0000000..3648665 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/FacebookTest.php @@ -0,0 +1,381 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests; + +use Facebook\Facebook; +use Facebook\FacebookClient; +use Facebook\Http\GraphRawResponse; +use Facebook\HttpClients\FacebookHttpClientInterface; +use Facebook\PersistentData\PersistentDataInterface; +use Facebook\Url\UrlDetectionInterface; +use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; +use Facebook\FacebookRequest; +use Facebook\Authentication\AccessToken; +use Facebook\GraphNodes\GraphEdge; + +class FooClientInterface implements FacebookHttpClientInterface +{ + public function send($url, $method, $body, array $headers, $timeOut) + { + return new GraphRawResponse( + "HTTP/1.1 1337 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", + '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' + ); + } +} + +class FooPersistentDataInterface implements PersistentDataInterface +{ + public function get($key) + { + return 'foo'; + } + + public function set($key, $value) + { + } +} + +class FooUrlDetectionInterface implements UrlDetectionInterface +{ + public function getCurrentUrl() + { + return 'https://foo.bar'; + } +} + +class FooBarPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface +{ + public function getPseudoRandomString($length) + { + return 'csprs123'; + } +} + +class FacebookTest extends \PHPUnit_Framework_TestCase +{ + protected $config = [ + 'app_id' => '1337', + 'app_secret' => 'foo_secret', + ]; + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInstantiatingWithoutAppIdThrows() + { + // unset value so there is no fallback to test expected Exception + putenv(Facebook::APP_ID_ENV_NAME.'='); + $config = [ + 'app_secret' => 'foo_secret', + ]; + $fb = new Facebook($config); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInstantiatingWithoutAppSecretThrows() + { + // unset value so there is no fallback to test expected Exception + putenv(Facebook::APP_SECRET_ENV_NAME.'='); + $config = [ + 'app_id' => 'foo_id', + ]; + $fb = new Facebook($config); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidHttpClientHandlerThrows() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'foo_handler', + ]); + $fb = new Facebook($config); + } + + public function testCurlHttpClientHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'curl' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\HttpClients\FacebookCurlHttpClient', + $fb->getClient()->getHttpClientHandler() + ); + } + + public function testStreamHttpClientHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'stream' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\HttpClients\FacebookStreamHttpClient', + $fb->getClient()->getHttpClientHandler() + ); + } + + public function testGuzzleHttpClientHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'guzzle' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\HttpClients\FacebookGuzzleHttpClient', + $fb->getClient()->getHttpClientHandler() + ); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidPersistentDataHandlerThrows() + { + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'foo_handler', + ]); + $fb = new Facebook($config); + } + + public function testPersistentDataHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\PersistentData\FacebookMemoryPersistentDataHandler', + $fb->getRedirectLoginHelper()->getPersistentDataHandler() + ); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidUrlHandlerThrows() + { + $config = array_merge($this->config, [ + 'url_detection_handler' => 'foo_handler', + ]); + $fb = new Facebook($config); + } + + public function testTheUrlHandlerWillDefaultToTheFacebookImplementation() + { + $fb = new Facebook($this->config); + $this->assertInstanceOf('Facebook\Url\FacebookUrlDetectionHandler', $fb->getUrlDetectionHandler()); + } + + public function testAnAccessTokenCanBeSetAsAString() + { + $fb = new Facebook($this->config); + $fb->setDefaultAccessToken('foo_token'); + $accessToken = $fb->getDefaultAccessToken(); + + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('foo_token', (string)$accessToken); + } + + public function testAnAccessTokenCanBeSetAsAnAccessTokenEntity() + { + $fb = new Facebook($this->config); + $fb->setDefaultAccessToken(new AccessToken('bar_token')); + $accessToken = $fb->getDefaultAccessToken(); + + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('bar_token', (string)$accessToken); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidPseudoRandomStringGeneratorThrows() + { + $config = array_merge($this->config, [ + 'pseudo_random_string_generator' => 'foo_generator', + ]); + new Facebook($config); + } + + public function testMcryptCsprgCanBeForced() + { + if (!function_exists('mcrypt_create_iv')) { + $this->markTestSkipped( + 'Mcrypt must be installed to test mcrypt_create_iv().' + ); + } + + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory', // To keep session errors from happening + 'pseudo_random_string_generator' => 'mcrypt' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() + ); + } + + public function testOpenSslCsprgCanBeForced() + { + if (!function_exists('openssl_random_pseudo_bytes')) { + $this->markTestSkipped( + 'The OpenSSL extension must be enabled to test openssl_random_pseudo_bytes().' + ); + } + + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory', // To keep session errors from happening + 'pseudo_random_string_generator' => 'openssl' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() + ); + } + + public function testUrandomCsprgCanBeForced() + { + if (ini_get('open_basedir')) { + $this->markTestSkipped( + 'Cannot test /dev/urandom generator due to open_basedir constraint.' + ); + } + + if (!is_readable('/dev/urandom')) { + $this->markTestSkipped( + '/dev/urandom not found or is not readable.' + ); + } + + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory', // To keep session errors from happening + 'pseudo_random_string_generator' => 'urandom' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() + ); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnAccessThatIsNotStringOrAccessTokenThrows() + { + $config = array_merge($this->config, [ + 'default_access_token' => 123, + ]); + $fb = new Facebook($config); + } + + public function testCreatingANewRequestWillDefaultToTheProperConfig() + { + $config = array_merge($this->config, [ + 'default_access_token' => 'foo_token', + 'enable_beta_mode' => true, + 'default_graph_version' => 'v1337', + ]); + $fb = new Facebook($config); + + $request = $fb->request('FOO_VERB', '/foo'); + $this->assertEquals('1337', $request->getApp()->getId()); + $this->assertEquals('foo_secret', $request->getApp()->getSecret()); + $this->assertEquals('foo_token', (string)$request->getAccessToken()); + $this->assertEquals('v1337', $request->getGraphVersion()); + $this->assertEquals( + FacebookClient::BASE_GRAPH_URL_BETA, + $fb->getClient()->getBaseGraphUrl() + ); + } + + public function testCanInjectCustomHandlers() + { + $config = array_merge($this->config, [ + 'http_client_handler' => new FooClientInterface(), + 'persistent_data_handler' => new FooPersistentDataInterface(), + 'url_detection_handler' => new FooUrlDetectionInterface(), + 'pseudo_random_string_generator' => new FooBarPseudoRandomStringGenerator(), + ]); + $fb = new Facebook($config); + + $this->assertInstanceOf( + 'Facebook\Tests\FooClientInterface', + $fb->getClient()->getHttpClientHandler() + ); + $this->assertInstanceOf( + 'Facebook\Tests\FooPersistentDataInterface', + $fb->getRedirectLoginHelper()->getPersistentDataHandler() + ); + $this->assertInstanceOf( + 'Facebook\Tests\FooUrlDetectionInterface', + $fb->getRedirectLoginHelper()->getUrlDetectionHandler() + ); + $this->assertInstanceOf( + 'Facebook\Tests\FooBarPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() + ); + } + + public function testPaginationReturnsProperResponse() + { + $config = array_merge($this->config, [ + 'http_client_handler' => new FooClientInterface(), + ]); + $fb = new Facebook($config); + + $request = new FacebookRequest($fb->getApp(), 'foo_token', 'GET'); + $graphEdge = new GraphEdge( + $request, + [], + [ + 'paging' => [ + 'cursors' => [ + 'after' => 'bar_after_cursor', + 'before' => 'bar_before_cursor', + ], + ] + ], + '/1337/photos', + '\Facebook\GraphNodes\GraphUser' + ); + + $nextPage = $fb->next($graphEdge); + $this->assertInstanceOf('Facebook\GraphNodes\GraphEdge', $nextPage); + $this->assertInstanceOf('Facebook\GraphNodes\GraphUser', $nextPage[0]); + $this->assertEquals('Foo', $nextPage[0]['name']); + + $lastResponse = $fb->getLastResponse(); + $this->assertInstanceOf('Facebook\FacebookResponse', $lastResponse); + $this->assertEquals(1337, $lastResponse->getHttpStatusCode()); + } +} diff --git a/lib/facebook-graph-sdk/tests/FacebookTestCredentials.php.dist b/lib/facebook-graph-sdk/tests/FacebookTestCredentials.php.dist new file mode 100644 index 0000000..e5b66f7 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/FacebookTestCredentials.php.dist @@ -0,0 +1,36 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests; + +class FacebookTestCredentials { + + /** + * These must be filled out with valid Facebook app details for the tests to + * run. + */ + public static $appId = ''; + public static $appSecret = ''; + +} + diff --git a/lib/facebook-graph-sdk/tests/FileUpload/FacebookFileTest.php b/lib/facebook-graph-sdk/tests/FileUpload/FacebookFileTest.php new file mode 100644 index 0000000..1eb5c0b --- /dev/null +++ b/lib/facebook-graph-sdk/tests/FileUpload/FacebookFileTest.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\FileUpload; + +use Facebook\FileUpload\FacebookFile; + +class FacebookFileTest extends \PHPUnit_Framework_TestCase +{ + + protected $testFile = ''; + + public function setUp() + { + $this->testFile = __DIR__ . '/../foo.txt'; + } + + public function testCanOpenAndReadAndCloseAFile() + { + $file = new FacebookFile($this->testFile); + $fileContents = $file->getContents(); + + $this->assertEquals('This is a text file used for testing. Let\'s dance.', $fileContents); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testTryingToOpenAFileThatDoesntExistsThrows() + { + new FacebookFile('does_not_exist.file'); + } +} diff --git a/lib/facebook-graph-sdk/tests/FileUpload/MimetypesTest.php b/lib/facebook-graph-sdk/tests/FileUpload/MimetypesTest.php new file mode 100644 index 0000000..c2092c1 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/FileUpload/MimetypesTest.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\FileUpload; + +use Facebook\FileUpload\Mimetypes; + +class MimetypesTest extends \PHPUnit_Framework_TestCase +{ + + /** + * Taken from Guzzle + * + * @see https://github.com/guzzle/guzzle/blob/master/tests/MimetypesTest.php + */ + public function testGetsFromExtension() + { + $this->assertEquals('text/x-php', Mimetypes::getInstance()->fromExtension('php')); + } + + public function testGetsFromFilename() + { + $this->assertEquals('text/x-php', Mimetypes::getInstance()->fromFilename(__FILE__)); + } + + public function testGetsFromCaseInsensitiveFilename() + { + $this->assertEquals('text/x-php', Mimetypes::getInstance()->fromFilename(strtoupper(__FILE__))); + } + + public function testReturnsNullWhenNoMatchFound() + { + $this->assertNull(Mimetypes::getInstance()->fromExtension('foobar')); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/AbstractGraphNode.php b/lib/facebook-graph-sdk/tests/GraphNodes/AbstractGraphNode.php new file mode 100644 index 0000000..1c4ce15 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/AbstractGraphNode.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Mockery as m; +use Facebook\GraphNodes\GraphNodeFactory; + +abstract class AbstractGraphNode extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Facebook\FacebookResponse|\Mockery\MockInterface + */ + protected $responseMock; + + public function setUp() + { + parent::setUp(); + $this->responseMock = m::mock('\Facebook\FacebookResponse'); + } + + protected function makeFactoryWithData($data) + { + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($data); + + return new GraphNodeFactory($this->responseMock); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/CollectionTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/CollectionTest.php new file mode 100755 index 0000000..af3eba8 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/CollectionTest.php @@ -0,0 +1,125 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Facebook\GraphNodes\Collection; + +class CollectionTest extends \PHPUnit_Framework_TestCase +{ + + public function testAnExistingPropertyCanBeAccessed() + { + $graphNode = new Collection(['foo' => 'bar']); + + $field = $graphNode->getField('foo'); + $this->assertEquals('bar', $field); + + // @todo v6: Remove this assertion + $property = $graphNode->getProperty('foo'); + $this->assertEquals('bar', $property); + } + + public function testAMissingPropertyWillReturnNull() + { + $graphNode = new Collection(['foo' => 'bar']); + $field = $graphNode->getField('baz'); + + $this->assertNull($field, 'Expected the property to return null.'); + } + + public function testAMissingPropertyWillReturnTheDefault() + { + $graphNode = new Collection(['foo' => 'bar']); + + $field = $graphNode->getField('baz', 'faz'); + $this->assertEquals('faz', $field); + + // @todo v6: Remove this assertion + $property = $graphNode->getProperty('baz', 'faz'); + $this->assertEquals('faz', $property); + } + + public function testTheKeysFromTheCollectionCanBeReturned() + { + $graphNode = new Collection([ + 'key1' => 'foo', + 'key2' => 'bar', + 'key3' => 'baz', + ]); + + $fieldNames = $graphNode->getFieldNames(); + $this->assertEquals(['key1', 'key2', 'key3'], $fieldNames); + + // @todo v6: Remove this assertion + $propertyNames = $graphNode->getPropertyNames(); + $this->assertEquals(['key1', 'key2', 'key3'], $propertyNames); + } + + public function testAnArrayCanBeInjectedViaTheConstructor() + { + $collection = new Collection(['foo', 'bar']); + $this->assertEquals(['foo', 'bar'], $collection->asArray()); + } + + public function testACollectionCanBeConvertedToProperJson() + { + $collection = new Collection(['foo', 'bar', 123]); + + $collectionAsString = $collection->asJson(); + + $this->assertEquals('["foo","bar",123]', $collectionAsString); + } + + public function testACollectionCanBeCounted() + { + $collection = new Collection(['foo', 'bar', 'baz']); + + $collectionCount = count($collection); + + $this->assertEquals(3, $collectionCount); + } + + public function testACollectionCanBeAccessedAsAnArray() + { + $collection = new Collection(['foo' => 'bar', 'faz' => 'baz']); + + $this->assertEquals('bar', $collection['foo']); + $this->assertEquals('baz', $collection['faz']); + } + + public function testACollectionCanBeIteratedOver() + { + $collection = new Collection(['foo' => 'bar', 'faz' => 'baz']); + + $this->assertInstanceOf('IteratorAggregate', $collection); + + $newArray = []; + + foreach ($collection as $k => $v) { + $newArray[$k] = $v; + } + + $this->assertEquals(['foo' => 'bar', 'faz' => 'baz'], $newArray); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/GraphAchievementTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/GraphAchievementTest.php new file mode 100644 index 0000000..d5e276e --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/GraphAchievementTest.php @@ -0,0 +1,117 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +class GraphAchievementTest extends AbstractGraphNode +{ + + public function testIdIsString() + { + $dataFromGraph = [ + 'id' => '1337' + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphNode = $factory->makeGraphAchievement(); + + $id = $graphNode->getId(); + + $this->assertEquals($dataFromGraph['id'], $id); + } + + public function testTypeIsAlwaysString() + { + $dataFromGraph = [ + 'id' => '1337' + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphNode = $factory->makeGraphAchievement(); + + $type = $graphNode->getType(); + + $this->assertEquals('game.achievement', $type); + } + + public function testNoFeedStoryIsBoolean() + { + $dataFromGraph = [ + 'no_feed_story' => (rand(0, 1) == 1) + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphNode = $factory->makeGraphAchievement(); + + $isNoFeedStory = $graphNode->isNoFeedStory(); + + $this->assertTrue(is_bool($isNoFeedStory)); + } + + public function testDatesGetCastToDateTime() + { + $dataFromGraph = [ + 'publish_time' => '2014-07-15T03:54:34+0000' + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphNode = $factory->makeGraphAchievement(); + + $publishTime = $graphNode->getPublishTime(); + + $this->assertInstanceOf('DateTime', $publishTime); + } + + public function testFromGetsCastAsGraphUser() + { + $dataFromGraph = [ + 'from' => [ + 'id' => '1337', + 'name' => 'Foo McBar' + ] + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphNode = $factory->makeGraphAchievement(); + + $from = $graphNode->getFrom(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphUser', $from); + } + + public function testApplicationGetsCastAsGraphApplication() + { + $dataFromGraph = [ + 'application' => [ + 'id' => '1337' + ] + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphNode = $factory->makeGraphAchievement(); + + $app = $graphNode->getApplication(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphApplication', $app); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/GraphAlbumTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/GraphAlbumTest.php new file mode 100644 index 0000000..f7a5521 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/GraphAlbumTest.php @@ -0,0 +1,109 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Mockery as m; +use Facebook\GraphNodes\GraphNodeFactory; + +class GraphAlbumTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var \Facebook\FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + } + + public function testDatesGetCastToDateTime() + { + $dataFromGraph = [ + 'created_time' => '2014-07-15T03:54:34+0000', + 'updated_time' => '2014-07-12T01:24:09+0000', + 'id' => '123', + 'name' => 'Bar', + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphAlbum(); + + $createdTime = $graphNode->getCreatedTime(); + $updatedTime = $graphNode->getUpdatedTime(); + + $this->assertInstanceOf('DateTime', $createdTime); + $this->assertInstanceOf('DateTime', $updatedTime); + } + + public function testFromGetsCastAsGraphUser() + { + $dataFromGraph = [ + 'id' => '123', + 'from' => [ + 'id' => '1337', + 'name' => 'Foo McBar', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphAlbum(); + + $from = $graphNode->getFrom(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $from); + } + + public function testPlacePropertyWillGetCastAsGraphPageObject() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo Album', + 'place' => [ + 'id' => '1', + 'name' => 'For Bar Place', + ] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphAlbum(); + + $place = $graphNode->getPlace(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $place); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/GraphEdgeTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/GraphEdgeTest.php new file mode 100644 index 0000000..4e70f52 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/GraphEdgeTest.php @@ -0,0 +1,120 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\GraphNodes\GraphEdge; + +class GraphEdgeTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var \Facebook\FacebookRequest + */ + protected $request; + + protected $basePagination = [ + 'next' => 'https://graph.facebook.com/v7.12/998899/photos?pretty=0&limit=25&after=foo_after_cursor', + 'previous' => 'https://graph.facebook.com/v7.12/998899/photos?pretty=0&limit=25&before=foo_before_cursor', + ]; + protected $cursorPagination = [ + 'cursors' => [ + 'after' => 'bar_after_cursor', + 'before' => 'bar_before_cursor', + ], + ]; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337' + ); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testNonGetRequestsWillThrow() + { + $this->request->setMethod('POST'); + $graphEdge = new GraphEdge($this->request); + $graphEdge->validateForPagination(); + } + + public function testCanReturnGraphGeneratedPaginationEndpoints() + { + $graphEdge = new GraphEdge( + $this->request, + [], + ['paging' => $this->basePagination] + ); + $nextPage = $graphEdge->getPaginationUrl('next'); + $prevPage = $graphEdge->getPaginationUrl('previous'); + + $this->assertEquals('/998899/photos?pretty=0&limit=25&after=foo_after_cursor', $nextPage); + $this->assertEquals('/998899/photos?pretty=0&limit=25&before=foo_before_cursor', $prevPage); + } + + public function testCanGeneratePaginationEndpointsFromACursor() + { + $graphEdge = new GraphEdge( + $this->request, + [], + ['paging' => $this->cursorPagination], + '/1234567890/likes' + ); + $nextPage = $graphEdge->getPaginationUrl('next'); + $prevPage = $graphEdge->getPaginationUrl('previous'); + + $this->assertEquals('/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage); + $this->assertEquals('/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage); + } + + public function testCanInstantiateNewPaginationRequest() + { + $graphEdge = new GraphEdge( + $this->request, + [], + ['paging' => $this->cursorPagination], + '/1234567890/likes' + ); + $nextPage = $graphEdge->getNextPageRequest(); + $prevPage = $graphEdge->getPreviousPageRequest(); + + $this->assertInstanceOf('Facebook\FacebookRequest', $nextPage); + $this->assertInstanceOf('Facebook\FacebookRequest', $prevPage); + $this->assertNotSame($this->request, $nextPage); + $this->assertNotSame($this->request, $prevPage); + $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage->getUrl()); + $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage->getUrl()); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/GraphEventTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/GraphEventTest.php new file mode 100644 index 0000000..98ccd85 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/GraphEventTest.php @@ -0,0 +1,109 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Facebook\FacebookResponse; +use Mockery as m; +use Facebook\GraphNodes\GraphNodeFactory; + +class GraphEventTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\Facebook\FacebookResponse'); + } + + public function testCoverGetsCastAsGraphCoverPhoto() + { + $dataFromGraph = [ + 'cover' => ['id' => '1337'] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphObject = $factory->makeGraphEvent(); + + $cover = $graphObject->getCover(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphCoverPhoto', $cover); + } + + public function testPlaceGetsCastAsGraphPage() + { + $dataFromGraph = [ + 'place' => ['id' => '1337'] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphObject = $factory->makeGraphEvent(); + + $place = $graphObject->getPlace(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphPage', $place); + } + + public function testPictureGetsCastAsGraphPicture() + { + $dataFromGraph = [ + 'picture' => ['id' => '1337'] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphObject = $factory->makeGraphEvent(); + + $picture = $graphObject->getPicture(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphPicture', $picture); + } + + public function testParentGroupGetsCastAsGraphGroup() + { + $dataFromGraph = [ + 'parent_group' => ['id' => '1337'] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphObject = $factory->makeGraphEvent(); + + $parentGroup = $graphObject->getParentGroup(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphGroup', $parentGroup); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/GraphGroupTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/GraphGroupTest.php new file mode 100644 index 0000000..21893b5 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/GraphGroupTest.php @@ -0,0 +1,75 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Facebook\FacebookResponse; +use Mockery as m; +use Facebook\GraphNodes\GraphNodeFactory; + +class GraphGroupTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\Facebook\FacebookResponse'); + } + + public function testCoverGetsCastAsGraphCoverPhoto() + { + $dataFromGraph = [ + 'cover' => ['id' => '1337'] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphGroup(); + + $cover = $graphNode->getCover(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphCoverPhoto', $cover); + } + + public function testVenueGetsCastAsGraphLocation() + { + $dataFromGraph = [ + 'venue' => ['id' => '1337'] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphGroup(); + + $venue = $graphNode->getVenue(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphLocation', $venue); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/GraphNodeFactoryTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/GraphNodeFactoryTest.php new file mode 100644 index 0000000..7d2f023 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/GraphNodeFactoryTest.php @@ -0,0 +1,437 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; +use Facebook\GraphNodes\GraphNodeFactory; +use Facebook\GraphNodes\GraphNode; + +class MyFooSubClassGraphNode extends GraphNode +{ +} + +class MyFooGraphNode extends GraphNode +{ + protected static $graphObjectMap = [ + 'foo_object' => '\Facebook\Tests\GraphNodes\MyFooSubClassGraphNode', + ]; +} + +class GraphNodeFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Facebook\FacebookRequest + */ + protected $request; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337' + ); + } + + public function testAValidGraphNodeResponseWillNotThrow() + { + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + $factory->validateResponseCastableAsGraphNode(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testANonGraphNodeResponseWillThrow() + { + $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + $factory->validateResponseCastableAsGraphNode(); + } + + public function testAValidGraphEdgeResponseWillNotThrow() + { + $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + $factory->validateResponseCastableAsGraphEdge(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testANonGraphEdgeResponseWillThrow() + { + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + $factory->validateResponseCastableAsGraphEdge(); + } + + public function testOnlyNumericArraysAreCastableAsAGraphEdge() + { + $shouldPassOne = GraphNodeFactory::isCastableAsGraphEdge([]); + $shouldPassTwo = GraphNodeFactory::isCastableAsGraphEdge(['foo', 'bar']); + $shouldFail = GraphNodeFactory::isCastableAsGraphEdge(['faz' => 'baz']); + + $this->assertTrue($shouldPassOne, 'Expected the given array to be castable as a GraphEdge.'); + $this->assertTrue($shouldPassTwo, 'Expected the given array to be castable as a GraphEdge.'); + $this->assertFalse($shouldFail, 'Expected the given array to not be castable as a GraphEdge.'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInvalidSubClassesWillThrow() + { + GraphNodeFactory::validateSubclass('FooSubClass'); + } + + public function testValidSubClassesWillNotThrow() + { + GraphNodeFactory::validateSubclass('\Facebook\GraphNodes\GraphNode'); + GraphNodeFactory::validateSubclass('\Facebook\GraphNodes\GraphAlbum'); + GraphNodeFactory::validateSubclass('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + } + + public function testCastingAsASubClassObjectWillInstantiateTheSubClass() + { + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); + } + + public function testASubClassMappingWillAutomaticallyInstantiateSubClass() + { + $data = '{"id":"123","name":"Foo Name","foo_object":{"id":"1337","name":"Should be sub classed!"}}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + $fooObject = $mySubClassObject->getField('foo_object'); + + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooSubClassGraphNode', $fooObject); + } + + public function testAnUnknownGraphNodeWillBeCastAsAGenericGraphNode() + { + $data = json_encode([ + 'id' => '123', + 'name' => 'Foo Name', + 'unknown_object' => [ + 'id' => '1337', + 'name' => 'Should be generic!', + ], + ]); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + + $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + $unknownObject = $mySubClassObject->getField('unknown_object'); + + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $unknownObject); + $this->assertNotInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $unknownObject); + } + + public function testAListFromGraphWillBeCastAsAGraphEdge() + { + $data = json_encode([ + 'data' => [ + [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + [ + 'id' => '1337', + 'name' => 'Bar McBaz', + 'link' => 'http://facebook/bar', + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', + ], + ]); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + $graphEdge = $factory->makeGraphEdge(); + $graphData = $graphEdge->asArray(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $graphEdge); + $this->assertEquals([ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], $graphData[0]); + $this->assertEquals([ + 'id' => '1337', + 'name' => 'Bar McBaz', + 'link' => 'http://facebook/bar', + ], $graphData[1]); + } + + public function testAGraphNodeWillBeCastAsAGraphNode() + { + $data = json_encode([ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ]); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + $graphNode = $factory->makeGraphNode(); + $graphData = $graphNode->asArray(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphNode); + $this->assertEquals([ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], $graphData); + } + + public function testAGraphNodeWithARootDataKeyWillBeCastAsAGraphNode() + { + $data = json_encode([ + 'data' => [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + ]); + + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + $graphNode = $factory->makeGraphNode(); + $graphData = $graphNode->asArray(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphNode); + $this->assertEquals([ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], $graphData); + } + + public function testAGraphEdgeWillBeCastRecursively() + { + $someUser = [ + 'id' => '123', + 'name' => 'Foo McBar', + ]; + $likesCollection = [ + 'data' => [ + [ + 'id' => '1', + 'name' => 'Sammy Kaye Powers', + 'is_sexy' => true, + ], + [ + 'id' => '2', + 'name' => 'Yassine Guedidi', + 'is_sexy' => true, + ], + [ + 'id' => '3', + 'name' => 'Fosco Marotto', + 'is_sexy' => true, + ], + [ + 'id' => '4', + 'name' => 'Foo McUgly', + 'is_sexy' => false, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next_likes', + 'previous' => 'http://facebook/prev_likes', + ], + ]; + $commentsCollection = [ + 'data' => [ + [ + 'id' => '42_1', + 'from' => $someUser, + 'message' => 'Foo comment.', + 'created_time' => '2014-07-15T03:54:34+0000', + 'likes' => $likesCollection, + ], + [ + 'id' => '42_2', + 'from' => $someUser, + 'message' => 'Bar comment.', + 'created_time' => '2014-07-15T04:11:24+0000', + 'likes' => $likesCollection, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next_comments', + 'previous' => 'http://facebook/prev_comments', + ], + ]; + $dataFromGraph = [ + 'data' => [ + [ + 'id' => '1337_1', + 'from' => $someUser, + 'story' => 'Some great foo story.', + 'likes' => $likesCollection, + 'comments' => $commentsCollection, + ], + [ + 'id' => '1337_2', + 'from' => $someUser, + 'to' => [ + 'data' => [$someUser], + ], + 'message' => 'Some great bar message.', + 'likes' => $likesCollection, + 'comments' => $commentsCollection, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', + ], + ]; + $data = json_encode($dataFromGraph); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + $graphNode = $factory->makeGraphEdge(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $graphNode); + + // Story + $storyObject = $graphNode[0]; + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $storyObject['from']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $storyObject['likes']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $storyObject['comments']); + + // Story Comments + $storyComments = $storyObject['comments']; + $firstStoryComment = $storyComments[0]; + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $firstStoryComment['from']); + + // Message + $messageObject = $graphNode[1]; + $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $messageObject['to']); + $toUsers = $messageObject['to']; + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $toUsers[0]); + } + + public function testAGraphEdgeWillGenerateTheProperParentGraphEdges() + { + $likesList = [ + 'data' => [ + [ + 'id' => '1', + 'name' => 'Sammy Kaye Powers', + ], + ], + 'paging' => [ + 'cursors' => [ + 'after' => 'like_after_cursor', + 'before' => 'like_before_cursor', + ], + ], + ]; + + $photosList = [ + 'data' => [ + [ + 'id' => '777', + 'name' => 'Foo Photo', + 'likes' => $likesList, + ], + ], + 'paging' => [ + 'cursors' => [ + 'after' => 'photo_after_cursor', + 'before' => 'photo_before_cursor', + ], + ], + ]; + + $data = json_encode([ + 'data' => [ + [ + 'id' => '111', + 'name' => 'Foo McBar', + 'likes' => $likesList, + 'photos' => $photosList, + ], + [ + 'id' => '222', + 'name' => 'Bar McBaz', + 'likes' => $likesList, + 'photos' => $photosList, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', + ], + ]); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphNodeFactory($res); + $graphEdge = $factory->makeGraphEdge(); + $topGraphEdge = $graphEdge->getParentGraphEdge(); + $childGraphEdgeOne = $graphEdge[0]['likes']->getParentGraphEdge(); + $childGraphEdgeTwo = $graphEdge[1]['likes']->getParentGraphEdge(); + $childGraphEdgeThree = $graphEdge[1]['photos']->getParentGraphEdge(); + $childGraphEdgeFour = $graphEdge[1]['photos'][0]['likes']->getParentGraphEdge(); + + $this->assertNull($topGraphEdge); + $this->assertEquals('/111/likes', $childGraphEdgeOne); + $this->assertEquals('/222/likes', $childGraphEdgeTwo); + $this->assertEquals('/222/photos', $childGraphEdgeThree); + $this->assertEquals('/777/likes', $childGraphEdgeFour); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/GraphNodeTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/GraphNodeTest.php new file mode 100644 index 0000000..50f58ae --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/GraphNodeTest.php @@ -0,0 +1,138 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Facebook\GraphNodes\GraphNode; + +class GraphNodeTest extends \PHPUnit_Framework_TestCase +{ + public function testAnEmptyBaseGraphNodeCanInstantiate() + { + $graphNode = new GraphNode(); + $backingData = $graphNode->asArray(); + + $this->assertEquals([], $backingData); + } + + public function testAGraphNodeCanInstantiateWithData() + { + $graphNode = new GraphNode(['foo' => 'bar']); + $backingData = $graphNode->asArray(); + + $this->assertEquals(['foo' => 'bar'], $backingData); + } + + public function testDatesThatShouldBeCastAsDateTimeObjectsAreDetected() + { + $graphNode = new GraphNode(); + + // Should pass + $shouldPass = $graphNode->isIso8601DateString('1985-10-26T01:21:00+0000'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date from Back To The Future to pass.'); + + $shouldPass = $graphNode->isIso8601DateString('1999-12-31'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to party like it\'s 1999.'); + + $shouldPass = $graphNode->isIso8601DateString('2009-05-19T14:39Z'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); + + $shouldPass = $graphNode->isIso8601DateString('2014-W36'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); + + // Should fail + $shouldFail = $graphNode->isIso8601DateString('2009-05-19T14a39r'); + $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); + + $shouldFail = $graphNode->isIso8601DateString('foo_time'); + $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); + } + + public function testATimeStampCanBeConvertedToADateTimeObject() + { + $someTimeStampFromGraph = 1405547020; + $graphNode = new GraphNode(); + $dateTime = $graphNode->castToDateTime($someTimeStampFromGraph); + $prettyDate = $dateTime->format(\DateTime::RFC1036); + $timeStamp = $dateTime->getTimestamp(); + + $this->assertInstanceOf('DateTime', $dateTime); + $this->assertEquals('Wed, 16 Jul 14 23:43:40 +0200', $prettyDate); + $this->assertEquals(1405547020, $timeStamp); + } + + public function testAGraphDateStringCanBeConvertedToADateTimeObject() + { + $someDateStringFromGraph = '2014-07-15T03:44:53+0000'; + $graphNode = new GraphNode(); + $dateTime = $graphNode->castToDateTime($someDateStringFromGraph); + $prettyDate = $dateTime->format(\DateTime::RFC1036); + $timeStamp = $dateTime->getTimestamp(); + + $this->assertInstanceOf('DateTime', $dateTime); + $this->assertEquals('Tue, 15 Jul 14 03:44:53 +0000', $prettyDate); + $this->assertEquals(1405395893, $timeStamp); + } + + public function testUncastingAGraphNodeWillUncastTheDateTimeObject() + { + $collectionOne = new GraphNode(['foo', 'bar']); + $collectionTwo = new GraphNode([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + 'some_collection' => $collectionOne, + ]); + + $uncastArray = $collectionTwo->uncastItems(); + + $this->assertEquals([ + 'id' => '123', + 'date' => '2014-07-15T03:44:53+0000', + 'some_collection' => ['foo', 'bar'], + ], $uncastArray); + } + + public function testGettingGraphNodeAsAnArrayWillNotUncastTheDateTimeObject() + { + $collection = new GraphNode([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + ]); + + $collectionAsArray = $collection->asArray(); + + $this->assertInstanceOf('DateTime', $collectionAsArray['date']); + } + + public function testReturningACollectionAsJasonWillSafelyRepresentDateTimes() + { + $collection = new GraphNode([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + ]); + + $collectionAsString = $collection->asJson(); + + $this->assertEquals('{"id":"123","date":"2014-07-15T03:44:53+0000"}', $collectionAsString); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/GraphObjectFactoryTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/GraphObjectFactoryTest.php new file mode 100644 index 0000000..764503a --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/GraphObjectFactoryTest.php @@ -0,0 +1,114 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Facebook\GraphNodes\GraphObjectFactory; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; + +/** + * @todo v6: Remove this test + */ +class GraphObjectFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Facebook\FacebookRequest + */ + protected $request; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337' + ); + } + + public function testAGraphNodeWillBeCastAsAGraphNode() + { + $data = json_encode([ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ]); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $graphObject = $factory->makeGraphObject(); + $graphData = $graphObject->asArray(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $graphObject); + $this->assertEquals([ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], $graphData); + } + + public function testAListFromGraphWillBeCastAsAGraphEdge() + { + $data = json_encode([ + 'data' => [ + [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + [ + 'id' => '1337', + 'name' => 'Bar McBaz', + 'link' => 'http://facebook/bar', + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', + ], + ]); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $graphList = $factory->makeGraphList(); + $graphData = $graphList->asArray(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphList); + $this->assertEquals([ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], $graphData[0]); + $this->assertEquals([ + 'id' => '1337', + 'name' => 'Bar McBaz', + 'link' => 'http://facebook/bar', + ], $graphData[1]); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/GraphPageTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/GraphPageTest.php new file mode 100644 index 0000000..a3a88e9 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/GraphPageTest.php @@ -0,0 +1,95 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Mockery as m; +use Facebook\GraphNodes\GraphNodeFactory; + +class GraphPageTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Facebook\FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + } + + public function testPagePropertiesReturnGraphPageObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo Page', + 'best_page' => [ + 'id' => '1', + 'name' => 'Bar Page', + ], + 'global_brand_parent_page' => [ + 'id' => '2', + 'name' => 'Faz Page', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphPage(); + + $bestPage = $graphNode->getBestPage(); + $globalBrandParentPage = $graphNode->getGlobalBrandParentPage(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $bestPage); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $globalBrandParentPage); + } + + public function testLocationPropertyWillGetCastAsGraphLocationObject() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo Page', + 'location' => [ + 'city' => 'Washington', + 'country' => 'United States', + 'latitude' => 38.881634205431, + 'longitude' => -77.029121075722, + 'state' => 'DC', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphPage(); + + $location = $graphNode->getLocation(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphLocation', $location); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/GraphSessionInfoTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/GraphSessionInfoTest.php new file mode 100644 index 0000000..2960c28 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/GraphSessionInfoTest.php @@ -0,0 +1,62 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Mockery as m; +use Facebook\GraphNodes\GraphNodeFactory; + +class GraphSessionInfoTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Facebook\FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + } + + public function testDatesGetCastToDateTime() + { + $dataFromGraph = [ + 'expires_at' => 123, + 'issued_at' => 1337, + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + + $graphNode = $factory->makeGraphSessionInfo(); + + $expires = $graphNode->getExpiresAt(); + $issuedAt = $graphNode->getIssuedAt(); + + $this->assertInstanceOf('DateTime', $expires); + $this->assertInstanceOf('DateTime', $issuedAt); + } +} diff --git a/lib/facebook-graph-sdk/tests/GraphNodes/GraphUserTest.php b/lib/facebook-graph-sdk/tests/GraphNodes/GraphUserTest.php new file mode 100644 index 0000000..ca75573 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/GraphNodes/GraphUserTest.php @@ -0,0 +1,140 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\GraphNodes; + +use Facebook\FacebookResponse; +use Mockery as m; +use Facebook\GraphNodes\GraphNodeFactory; + +class GraphUserTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + } + + public function testDatesGetCastToDateTime() + { + $dataFromGraph = [ + 'birthday' => '1984-01-01', + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphUser(); + + $birthday = $graphNode->getBirthday(); + + $this->assertInstanceOf('DateTime', $birthday); + } + + public function testPagePropertiesWillGetCastAsGraphPageObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo User', + 'hometown' => [ + 'id' => '1', + 'name' => 'Foo Place', + ], + 'location' => [ + 'id' => '2', + 'name' => 'Bar Place', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphUser(); + + $hometown = $graphNode->getHometown(); + $location = $graphNode->getLocation(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $hometown); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $location); + } + + public function testUserPropertiesWillGetCastAsGraphUserObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo User', + 'significant_other' => [ + 'id' => '1337', + 'name' => 'Bar User', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphUser(); + + $significantOther = $graphNode->getSignificantOther(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $significantOther); + } + + public function testPicturePropertiesWillGetCastAsGraphPictureObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo User', + 'picture' => [ + 'is_silhouette' => true, + 'url' => 'http://foo.bar', + 'width' => 200, + 'height' => 200, + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphUser(); + + $Picture = $graphNode->getPicture(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPicture', $Picture); + $this->assertTrue($Picture->isSilhouette()); + $this->assertEquals(200, $Picture->getWidth()); + $this->assertEquals(200, $Picture->getHeight()); + $this->assertEquals('http://foo.bar', $Picture->getUrl()); + } +} diff --git a/lib/facebook-graph-sdk/tests/Helpers/FacebookCanvasHelperTest.php b/lib/facebook-graph-sdk/tests/Helpers/FacebookCanvasHelperTest.php new file mode 100644 index 0000000..294440e --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Helpers/FacebookCanvasHelperTest.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Helpers; + +use Facebook\FacebookApp; +use Facebook\FacebookClient; +use Facebook\Helpers\FacebookCanvasHelper; + +class FacebookCanvasHelperTest extends \PHPUnit_Framework_TestCase +{ + public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + + /** + * @var FacebookCanvasHelper + */ + protected $helper; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->helper = new FacebookCanvasHelper($app, new FacebookClient()); + } + + public function testSignedRequestDataCanBeRetrievedFromPostData() + { + $_POST['signed_request'] = $this->rawSignedRequestAuthorized; + + $rawSignedRequest = $this->helper->getRawSignedRequest(); + + $this->assertEquals($this->rawSignedRequestAuthorized, $rawSignedRequest); + } +} diff --git a/lib/facebook-graph-sdk/tests/Helpers/FacebookJavaScriptHelperTest.php b/lib/facebook-graph-sdk/tests/Helpers/FacebookJavaScriptHelperTest.php new file mode 100644 index 0000000..3f9cb88 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Helpers/FacebookJavaScriptHelperTest.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Helpers; + +use Facebook\FacebookApp; +use Facebook\FacebookClient; +use Facebook\Helpers\FacebookJavaScriptHelper; + +class FacebookJavaScriptHelperTest extends \PHPUnit_Framework_TestCase +{ + public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + + public function testARawSignedRequestCanBeRetrievedFromCookieData() + { + $_COOKIE['fbsr_123'] = $this->rawSignedRequestAuthorized; + + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookJavaScriptHelper($app, new FacebookClient()); + + $rawSignedRequest = $helper->getRawSignedRequest(); + + $this->assertEquals($this->rawSignedRequestAuthorized, $rawSignedRequest); + } +} diff --git a/lib/facebook-graph-sdk/tests/Helpers/FacebookPageTabHelperTest.php b/lib/facebook-graph-sdk/tests/Helpers/FacebookPageTabHelperTest.php new file mode 100644 index 0000000..a4b06c1 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Helpers/FacebookPageTabHelperTest.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Helpers; + +use Facebook\FacebookApp; +use Facebook\FacebookClient; +use Facebook\Helpers\FacebookPageTabHelper; + +class FacebookPageTabHelperTest extends \PHPUnit_Framework_TestCase +{ + protected $rawSignedRequestAuthorized = '6Hi26ECjkj347belC0O8b8H5lwiIz5eA6V9VVjTg-HU=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MzIxLCJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsInVzZXJfaWQiOiIxMjMiLCJwYWdlIjp7ImlkIjoiNDIiLCJsaWtlZCI6dHJ1ZSwiYWRtaW4iOmZhbHNlfX0='; + + public function testPageDataCanBeAccessed() + { + $_POST['signed_request'] = $this->rawSignedRequestAuthorized; + + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookPageTabHelper($app, new FacebookClient()); + + $this->assertFalse($helper->isAdmin()); + $this->assertEquals('42', $helper->getPageId()); + $this->assertEquals('42', $helper->getPageData('id')); + $this->assertEquals('default', $helper->getPageData('foo', 'default')); + } +} diff --git a/lib/facebook-graph-sdk/tests/Helpers/FacebookRedirectLoginHelperTest.php b/lib/facebook-graph-sdk/tests/Helpers/FacebookRedirectLoginHelperTest.php new file mode 100644 index 0000000..faa4647 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -0,0 +1,140 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Helpers; + +use Facebook\Facebook; +use Facebook\FacebookApp; +use Facebook\FacebookClient; +use Facebook\Authentication\OAuth2Client; +use Facebook\Helpers\FacebookRedirectLoginHelper; +use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; +use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; + +class FooPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface +{ + public function getPseudoRandomString($length) + { + return 'csprs123'; + } +} + +class FooRedirectLoginOAuth2Client extends OAuth2Client +{ + public function getAccessTokenFromCode($code, $redirectUri = '', $machineId = null) + { + return 'foo_token_from_code|' . $code . '|' . $redirectUri; + } +} + +class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FacebookMemoryPersistentDataHandler + */ + protected $persistentDataHandler; + + /** + * @var FacebookRedirectLoginHelper + */ + protected $redirectLoginHelper; + + const REDIRECT_URL = 'http://invalid.zzz'; + + public function setUp() + { + $this->persistentDataHandler = new FacebookMemoryPersistentDataHandler(); + + $app = new FacebookApp('123', 'foo_app_secret'); + $oAuth2Client = new FooRedirectLoginOAuth2Client($app, new FacebookClient(), 'v1337'); + $this->redirectLoginHelper = new FacebookRedirectLoginHelper($oAuth2Client, $this->persistentDataHandler); + } + + public function testLoginURL() + { + $scope = ['foo', 'bar']; + $loginUrl = $this->redirectLoginHelper->getLoginUrl(self::REDIRECT_URL, $scope); + + $expectedUrl = 'https://www.facebook.com/v1337/dialog/oauth?'; + $this->assertTrue(strpos($loginUrl, $expectedUrl) === 0, 'Unexpected base login URL returned from getLoginUrl().'); + + $params = [ + 'client_id' => '123', + 'redirect_uri' => self::REDIRECT_URL, + 'state' => $this->persistentDataHandler->get('state'), + 'sdk' => 'php-sdk-' . Facebook::VERSION, + 'scope' => implode(',', $scope), + ]; + foreach ($params as $key => $value) { + $this->assertContains($key . '=' . urlencode($value), $loginUrl); + } + } + + public function testLogoutURL() + { + $logoutUrl = $this->redirectLoginHelper->getLogoutUrl('foo_token', self::REDIRECT_URL); + $expectedUrl = 'https://www.facebook.com/logout.php?'; + $this->assertTrue(strpos($logoutUrl, $expectedUrl) === 0, 'Unexpected base logout URL returned from getLogoutUrl().'); + + $params = [ + 'next' => self::REDIRECT_URL, + 'access_token' => 'foo_token', + ]; + foreach ($params as $key => $value) { + $this->assertTrue( + strpos($logoutUrl, $key . '=' . urlencode($value)) !== false + ); + } + } + + public function testAnAccessTokenCanBeObtainedFromRedirect() + { + $this->persistentDataHandler->set('state', 'foo_state'); + $_GET['state'] = 'foo_state'; + $_GET['code'] = 'foo_code'; + + $accessToken = $this->redirectLoginHelper->getAccessToken(self::REDIRECT_URL); + + $this->assertEquals('foo_token_from_code|foo_code|' . self::REDIRECT_URL, (string)$accessToken); + } + + public function testACustomCsprsgCanBeInjected() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $accessTokenClient = new FooRedirectLoginOAuth2Client($app, new FacebookClient(), 'v1337'); + $fooPrsg = new FooPseudoRandomStringGenerator(); + $helper = new FacebookRedirectLoginHelper($accessTokenClient, $this->persistentDataHandler, null, $fooPrsg); + + $loginUrl = $helper->getLoginUrl(self::REDIRECT_URL); + + $this->assertContains('state=csprs123', $loginUrl); + } + + public function testThePseudoRandomStringGeneratorWillAutoDetectCsprsg() + { + $this->assertInstanceOf( + 'Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface', + $this->redirectLoginHelper->getPseudoRandomStringGenerator() + ); + } +} diff --git a/lib/facebook-graph-sdk/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php b/lib/facebook-graph-sdk/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php new file mode 100644 index 0000000..d9bd803 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php @@ -0,0 +1,113 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Helpers; + +use Facebook\FacebookApp; +use Facebook\FacebookClient; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; +use Facebook\Helpers\FacebookSignedRequestFromInputHelper; + +class FooSignedRequestHelper extends FacebookSignedRequestFromInputHelper +{ + public function getRawSignedRequest() + { + return null; + } +} + +class FooSignedRequestHelperFacebookClient extends FacebookClient +{ + public function sendRequest(FacebookRequest $request) + { + $params = $request->getParams(); + $rawResponse = json_encode([ + 'access_token' => 'foo_access_token_from:' . $params['code'], + ]); + + return new FacebookResponse($request, $rawResponse, 200); + } +} + +class FacebookSignedRequestFromInputHelperTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FooSignedRequestHelper + */ + protected $helper; + + public $rawSignedRequestAuthorizedWithAccessToken = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + public $rawSignedRequestAuthorizedWithCode = 'oBtmZlsFguNQvGRETDYQQu1-PhwcArgbBBEK4urbpRA=.eyJjb2RlIjoiZm9vX2NvZGUiLCJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwNjMxMDc1MiwidXNlcl9pZCI6IjEyMyJ9'; + public $rawSignedRequestUnauthorized = 'KPlyhz-whtYAhHWr15N5TkbS_avz-2rUJFpFkfXKC88=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwMjU1MTA4Nn0='; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->helper = new FooSignedRequestHelper($app, new FooSignedRequestHelperFacebookClient()); + } + + public function testSignedRequestDataCanBeRetrievedFromPostData() + { + $_POST['signed_request'] = 'foo_signed_request'; + + $rawSignedRequest = $this->helper->getRawSignedRequestFromPost(); + + $this->assertEquals('foo_signed_request', $rawSignedRequest); + } + + public function testSignedRequestDataCanBeRetrievedFromCookieData() + { + $_COOKIE['fbsr_123'] = 'foo_signed_request'; + + $rawSignedRequest = $this->helper->getRawSignedRequestFromCookie(); + + $this->assertEquals('foo_signed_request', $rawSignedRequest); + } + + public function testAccessTokenWillBeNullWhenAUserHasNotYetAuthorizedTheApp() + { + $this->helper->instantiateSignedRequest($this->rawSignedRequestUnauthorized); + $accessToken = $this->helper->getAccessToken(); + + $this->assertNull($accessToken); + } + + public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsAnAccessToken() + { + $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithAccessToken); + $accessToken = $this->helper->getAccessToken(); + + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('foo_token', $accessToken->getValue()); + } + + public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsACode() + { + $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithCode); + $accessToken = $this->helper->getAccessToken(); + + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('foo_access_token_from:foo_code', $accessToken->getValue()); + } +} diff --git a/lib/facebook-graph-sdk/tests/Http/GraphRawResponseTest.php b/lib/facebook-graph-sdk/tests/Http/GraphRawResponseTest.php new file mode 100644 index 0000000..ecad26f --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Http/GraphRawResponseTest.php @@ -0,0 +1,82 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Http; + +use Facebook\Http\GraphRawResponse; + +class GraphRawResponseTest extends \PHPUnit_Framework_TestCase +{ + + protected $fakeRawProxyHeader = "HTTP/1.0 200 Connection established +Proxy-agent: Kerio Control/7.1.1 build 1971\r\n\r\n"; + protected $fakeRawHeader = <<<HEADER +HTTP/1.1 200 OK +Etag: "9d86b21aa74d74e574bbb35ba13524a52deb96e3" +Content-Type: text/javascript; charset=UTF-8 +X-FB-Rev: 9244768 +Date: Mon, 19 May 2014 18:37:17 GMT +X-FB-Debug: 02QQiffE7JG2rV6i/Agzd0gI2/OOQ2lk5UW0= +Access-Control-Allow-Origin: *\r\n\r\n +HEADER; + protected $fakeHeadersAsArray = [ + 'Etag' => '"9d86b21aa74d74e574bbb35ba13524a52deb96e3"', + 'Content-Type' => 'text/javascript; charset=UTF-8', + 'X-FB-Rev' => '9244768', + 'Date' => 'Mon, 19 May 2014 18:37:17 GMT', + 'X-FB-Debug' => '02QQiffE7JG2rV6i/Agzd0gI2/OOQ2lk5UW0=', + 'Access-Control-Allow-Origin' => '*', + ]; + + public function testCanSetTheHeadersFromAnArray() + { + $myHeaders = [ + 'foo' => 'bar', + 'baz' => 'faz', + ]; + $response = new GraphRawResponse($myHeaders, ''); + $headers = $response->getHeaders(); + + $this->assertEquals($myHeaders, $headers); + } + + public function testCanSetTheHeadersFromAString() + { + $response = new GraphRawResponse($this->fakeRawHeader, ''); + $headers = $response->getHeaders(); + $httpResponseCode = $response->getHttpResponseCode(); + + $this->assertEquals($this->fakeHeadersAsArray, $headers); + $this->assertEquals(200, $httpResponseCode); + } + + public function testWillIgnoreProxyHeaders() + { + $response = new GraphRawResponse($this->fakeRawProxyHeader . $this->fakeRawHeader, ''); + $headers = $response->getHeaders(); + $httpResponseCode = $response->getHttpResponseCode(); + + $this->assertEquals($this->fakeHeadersAsArray, $headers); + $this->assertEquals(200, $httpResponseCode); + } +} diff --git a/lib/facebook-graph-sdk/tests/Http/RequestBodyMultipartTest.php b/lib/facebook-graph-sdk/tests/Http/RequestBodyMultipartTest.php new file mode 100644 index 0000000..267cc49 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Http/RequestBodyMultipartTest.php @@ -0,0 +1,111 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Http; + +use Facebook\Http\RequestBodyMultipart; +use Facebook\FileUpload\FacebookFile; + +class RequestBodyMultipartTest extends \PHPUnit_Framework_TestCase +{ + public function testCanProperlyEncodeAnArrayOfParams() + { + $message = new RequestBodyMultipart([ + 'foo' => 'bar', + 'scawy_vawues' => '@FooBar is a real twitter handle.', + ], [], 'foo_boundary'); + $body = $message->getBody(); + + $expectedBody = "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"scawy_vawues\"\r\n\r\n@FooBar is a real twitter handle.\r\n"; + $expectedBody .= "--foo_boundary--\r\n"; + + $this->assertEquals($expectedBody, $body); + } + + public function testCanProperlyEncodeFilesAndParams() + { + $file = new FacebookFile(__DIR__ . '/../foo.txt'); + $message = new RequestBodyMultipart([ + 'foo' => 'bar', + ], [ + 'foo_file' => $file, + ], 'foo_boundary'); + $body = $message->getBody(); + + $expectedBody = "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"foo_file\"; filename=\"foo.txt\"\r\n"; + $expectedBody .= "Content-Type: text/plain\r\n\r\nThis is a text file used for testing. Let's dance.\r\n"; + $expectedBody .= "--foo_boundary--\r\n"; + + $this->assertEquals($expectedBody, $body); + } + + public function testSupportsMultidimensionalParams() + { + $message = new RequestBodyMultipart([ + 'foo' => 'bar', + 'faz' => [1,2,3], + 'targeting' => [ + 'countries' => 'US,GB', + 'age_min' => 13, + ], + 'call_to_action' => [ + 'type' => 'LEARN_MORE', + 'value' => [ + 'link' => 'http://example.com', + 'sponsorship' => [ + 'image' => 'http://example.com/bar.jpg', + ], + ], + ], + ], [], 'foo_boundary'); + $body = $message->getBody(); + + $expectedBody = "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"faz[0]\"\r\n\r\n1\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"faz[1]\"\r\n\r\n2\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"faz[2]\"\r\n\r\n3\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"targeting[countries]\"\r\n\r\nUS,GB\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"targeting[age_min]\"\r\n\r\n13\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"call_to_action[type]\"\r\n\r\nLEARN_MORE\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"call_to_action[value][link]\"\r\n\r\nhttp://example.com\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"call_to_action[value][sponsorship][image]\"\r\n\r\nhttp://example.com/bar.jpg\r\n"; + $expectedBody .= "--foo_boundary--\r\n"; + + $this->assertEquals($expectedBody, $body); + } +} diff --git a/lib/facebook-graph-sdk/tests/Http/RequestUrlEncodedTest.php b/lib/facebook-graph-sdk/tests/Http/RequestUrlEncodedTest.php new file mode 100644 index 0000000..3e22912 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Http/RequestUrlEncodedTest.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Http; + +use Facebook\Http\RequestBodyUrlEncoded; + +class RequestUrlEncodedTest extends \PHPUnit_Framework_TestCase +{ + public function testCanProperlyEncodeAnArrayOfParams() + { + $message = new RequestBodyUrlEncoded([ + 'foo' => 'bar', + 'scawy_vawues' => '@FooBar is a real twitter handle.', + ]); + $body = $message->getBody(); + + $this->assertEquals('foo=bar&scawy_vawues=%40FooBar+is+a+real+twitter+handle.', $body); + } + + public function testSupportsMultidimensionalParams() + { + $message = new RequestBodyUrlEncoded([ + 'foo' => 'bar', + 'faz' => [1,2,3], + 'targeting' => [ + 'countries' => 'US,GB', + 'age_min' => 13, + ], + 'call_to_action' => [ + 'type' => 'LEARN_MORE', + 'value' => [ + 'link' => 'http://example.com', + 'sponsorship' => [ + 'image' => 'http://example.com/bar.jpg', + ], + ], + ], + ]); + $body = $message->getBody(); + + $this->assertEquals('foo=bar&faz%5B0%5D=1&faz%5B1%5D=2&faz%5B2%5D=3&targeting%5Bcountries%5D=US%2CGB&targeting%5Bage_min%5D=13&call_to_action%5Btype%5D=LEARN_MORE&call_to_action%5Bvalue%5D%5Blink%5D=http%3A%2F%2Fexample.com&call_to_action%5Bvalue%5D%5Bsponsorship%5D%5Bimage%5D=http%3A%2F%2Fexample.com%2Fbar.jpg', $body); + } +} diff --git a/lib/facebook-graph-sdk/tests/HttpClients/AbstractTestHttpClient.php b/lib/facebook-graph-sdk/tests/HttpClients/AbstractTestHttpClient.php new file mode 100644 index 0000000..269b235 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/HttpClients/AbstractTestHttpClient.php @@ -0,0 +1,60 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\HttpClients; + +abstract class AbstractTestHttpClient extends \PHPUnit_Framework_TestCase +{ + protected $fakeRawRedirectHeader = "HTTP/1.1 302 Found +Content-Type: text/html; charset=utf-8 +Location: https://foobar.com/\r\n\r\n"; + protected $fakeRawProxyHeader = "HTTP/1.0 200 Connection established\r\n\r\n"; + protected $fakeRawProxyHeader2 = "HTTP/1.0 200 Connection established +Proxy-agent: Kerio Control/7.1.1 build 1971\r\n\r\n"; + protected $fakeRawHeader = "HTTP/1.1 200 OK +Etag: \"9d86b21aa74d74e574bbb35ba13524a52deb96e3\" +Content-Type: text/javascript; charset=UTF-8 +X-FB-Rev: 9244768 +Pragma: no-cache +Expires: Sat, 01 Jan 2000 00:00:00 GMT +Connection: close +Date: Mon, 19 May 2014 18:37:17 GMT +X-FB-Debug: 02QQiffE7JG2rV6i/Agzd0gI2/OOQ2lk5UW0= +Content-Length: 29 +Cache-Control: private, no-cache, no-store, must-revalidate +Access-Control-Allow-Origin: *\r\n\r\n"; + protected $fakeRawBody = "{\"id\":\"123\",\"name\":\"Foo Bar\"}"; + protected $fakeHeadersAsArray = [ + 'Etag' => '"9d86b21aa74d74e574bbb35ba13524a52deb96e3"', + 'Content-Type' => 'text/javascript; charset=UTF-8', + 'X-FB-Rev' => '9244768', + 'Pragma' => 'no-cache', + 'Expires' => 'Sat, 01 Jan 2000 00:00:00 GMT', + 'Connection' => 'close', + 'Date' => 'Mon, 19 May 2014 18:37:17 GMT', + 'X-FB-Debug' => '02QQiffE7JG2rV6i/Agzd0gI2/OOQ2lk5UW0=', + 'Content-Length' => '29', + 'Cache-Control' => 'private, no-cache, no-store, must-revalidate', + 'Access-Control-Allow-Origin' => '*', + ]; +} diff --git a/lib/facebook-graph-sdk/tests/HttpClients/FacebookCurlHttpClientTest.php b/lib/facebook-graph-sdk/tests/HttpClients/FacebookCurlHttpClientTest.php new file mode 100644 index 0000000..4cf31d3 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -0,0 +1,334 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\HttpClients; + +use Mockery as m; +use Facebook\HttpClients\FacebookCurlHttpClient; + +class FacebookCurlHttpClientTest extends AbstractTestHttpClient +{ + /** + * @var \Facebook\HttpClients\FacebookCurl + */ + protected $curlMock; + + /** + * @var FacebookCurlHttpClient + */ + protected $curlClient; + + const CURL_VERSION_STABLE = 0x072400; + const CURL_VERSION_BUGGY = 0x071400; + + public function setUp() + { + $this->curlMock = m::mock('Facebook\HttpClients\FacebookCurl'); + $this->curlClient = new FacebookCurlHttpClient($this->curlMock); + } + + public function testCanOpenGetCurlConnection() + { + $this->curlMock + ->shouldReceive('init') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('setoptArray') + ->with(m::on(function ($arg) { + + // array_diff() will sometimes trigger error on child-arrays + if (['X-Foo-Header: X-Bar'] !== $arg[CURLOPT_HTTPHEADER]) { + return false; + } + unset($arg[CURLOPT_HTTPHEADER]); + + $caInfo = array_diff($arg, [ + CURLOPT_CUSTOMREQUEST => 'GET', + CURLOPT_URL => 'http://foo.com', + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_TIMEOUT => 123, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => true, + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo[CURLOPT_CAINFO])) { + return false; + } + + return true; + })) + ->once() + ->andReturn(null); + + $this->curlClient->openConnection('http://foo.com', 'GET', 'foo_body', ['X-Foo-Header' => 'X-Bar'], 123); + } + + public function testCanOpenCurlConnectionWithPostBody() + { + $this->curlMock + ->shouldReceive('init') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('setoptArray') + ->with(m::on(function ($arg) { + + // array_diff() will sometimes trigger error on child-arrays + if ([] !== $arg[CURLOPT_HTTPHEADER]) { + return false; + } + unset($arg[CURLOPT_HTTPHEADER]); + + $caInfo = array_diff($arg, [ + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_URL => 'http://bar.com', + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_TIMEOUT => 60, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => true, + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_POSTFIELDS => 'baz=bar', + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo[CURLOPT_CAINFO])) { + return false; + } + + return true; + })) + ->once() + ->andReturn(null); + + $this->curlClient->openConnection('http://bar.com', 'POST', 'baz=bar', [], 60); + } + + public function testCanCloseConnection() + { + $this->curlMock + ->shouldReceive('close') + ->once() + ->andReturn(null); + + $this->curlClient->closeConnection(); + } + + public function testIsolatesTheHeaderAndBody() + { + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(strlen($this->fakeRawHeader)); + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($this->fakeRawHeader . $this->fakeRawBody); + + $this->curlClient->sendRequest(); + list($rawHeader, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); + + $this->assertEquals($rawHeader, trim($this->fakeRawHeader)); + $this->assertEquals($rawBody, $this->fakeRawBody); + } + + public function testProperlyHandlesProxyHeaders() + { + $rawHeader = $this->fakeRawProxyHeader . $this->fakeRawHeader; + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(mb_strlen($rawHeader)); + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($rawHeader . $this->fakeRawBody); + + $this->curlClient->sendRequest(); + list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); + + $this->assertEquals($rawHeaders, trim($rawHeader)); + $this->assertEquals($rawBody, $this->fakeRawBody); + } + + public function testProperlyHandlesProxyHeadersWithCurlBug() + { + $rawHeader = $this->fakeRawProxyHeader . $this->fakeRawHeader; + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(mb_strlen($this->fakeRawHeader)); // Mimic bug that doesn't count proxy header + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($rawHeader . $this->fakeRawBody); + + $this->curlClient->sendRequest(); + list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); + + $this->assertEquals($rawHeaders, trim($rawHeader)); + $this->assertEquals($rawBody, $this->fakeRawBody); + } + + public function testProperlyHandlesProxyHeadersWithCurlBug2() + { + $rawHeader = $this->fakeRawProxyHeader2 . $this->fakeRawHeader; + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(mb_strlen($this->fakeRawHeader)); // Mimic bug that doesn't count proxy header + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($rawHeader . $this->fakeRawBody); + + $this->curlClient->sendRequest(); + list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); + + $this->assertEquals($rawHeaders, trim($rawHeader)); + $this->assertEquals($rawBody, $this->fakeRawBody); + } + + public function testProperlyHandlesRedirectHeaders() + { + $rawHeader = $this->fakeRawRedirectHeader . $this->fakeRawHeader; + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(mb_strlen($rawHeader)); + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($rawHeader . $this->fakeRawBody); + + $this->curlClient->sendRequest(); + list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); + + $this->assertEquals($rawHeaders, trim($rawHeader)); + $this->assertEquals($rawBody, $this->fakeRawBody); + } + + public function testCanSendNormalRequest() + { + $this->curlMock + ->shouldReceive('init') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('setoptArray') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($this->fakeRawHeader . $this->fakeRawBody); + $this->curlMock + ->shouldReceive('errno') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(mb_strlen($this->fakeRawHeader)); + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); + $this->curlMock + ->shouldReceive('close') + ->once() + ->andReturn(null); + + $response = $this->curlClient->send('http://foo.com/', 'GET', '', [], 60); + + $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); + $this->assertEquals($this->fakeRawBody, $response->getBody()); + $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); + $this->assertEquals(200, $response->getHttpResponseCode()); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testThrowsExceptionOnClientError() + { + $this->curlMock + ->shouldReceive('init') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('setoptArray') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn(false); + $this->curlMock + ->shouldReceive('errno') + ->once() + ->andReturn(123); + $this->curlMock + ->shouldReceive('error') + ->once() + ->andReturn('Foo error'); + + $this->curlClient->send('http://foo.com/', 'GET', '', [], 60); + } +} diff --git a/lib/facebook-graph-sdk/tests/HttpClients/FacebookGuzzleHttpClientTest.php b/lib/facebook-graph-sdk/tests/HttpClients/FacebookGuzzleHttpClientTest.php new file mode 100644 index 0000000..12eb36a --- /dev/null +++ b/lib/facebook-graph-sdk/tests/HttpClients/FacebookGuzzleHttpClientTest.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\HttpClients; + +use Mockery as m; +use Facebook\HttpClients\FacebookGuzzleHttpClient; +use GuzzleHttp\Message\Request; +use GuzzleHttp\Message\Response; +use GuzzleHttp\Stream\Stream; +use GuzzleHttp\Exception\RequestException; + +class FacebookGuzzleHttpClientTest extends AbstractTestHttpClient +{ + /** + * @var \GuzzleHttp\Client + */ + protected $guzzleMock; + + /** + * @var FacebookGuzzleHttpClient + */ + protected $guzzleClient; + + public function setUp() + { + $this->guzzleMock = m::mock('GuzzleHttp\Client'); + $this->guzzleClient = new FacebookGuzzleHttpClient($this->guzzleMock); + } + + public function testCanSendNormalRequest() + { + $request = new Request('GET', 'http://foo.com'); + + $body = Stream::factory($this->fakeRawBody); + $response = new Response(200, $this->fakeHeadersAsArray, $body); + + $this->guzzleMock + ->shouldReceive('createRequest') + ->once() + ->with('GET', 'http://foo.com/', m::on(function ($arg) { + + // array_diff_assoc() will sometimes trigger error on child-arrays + if (['X-foo' => 'bar'] !== $arg['headers']) { + return false; + } + unset($arg['headers']); + + $caInfo = array_diff_assoc($arg, [ + 'body' => 'foo_body', + 'timeout' => 123, + 'connect_timeout' => 10, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['verify'])) { + return false; + } + + return true; + })) + ->andReturn($request); + $this->guzzleMock + ->shouldReceive('send') + ->once() + ->with($request) + ->andReturn($response); + + $response = $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); + + $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); + $this->assertEquals($this->fakeRawBody, $response->getBody()); + $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); + $this->assertEquals(200, $response->getHttpResponseCode()); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testThrowsExceptionOnClientError() + { + $request = new Request('GET', 'http://foo.com'); + + $this->guzzleMock + ->shouldReceive('createRequest') + ->once() + ->with('GET', 'http://foo.com/', m::on(function ($arg) { + + // array_diff_assoc() will sometimes trigger error on child-arrays + if ([] !== $arg['headers']) { + return false; + } + unset($arg['headers']); + + $caInfo = array_diff_assoc($arg, [ + 'body' => 'foo_body', + 'timeout' => 60, + 'connect_timeout' => 10, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['verify'])) { + return false; + } + + return true; + })) + ->andReturn($request); + $this->guzzleMock + ->shouldReceive('send') + ->once() + ->with($request) + ->andThrow(new RequestException('Foo', $request)); + + $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', [], 60); + } +} diff --git a/lib/facebook-graph-sdk/tests/HttpClients/FacebookStreamHttpClientTest.php b/lib/facebook-graph-sdk/tests/HttpClients/FacebookStreamHttpClientTest.php new file mode 100644 index 0000000..9102b08 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -0,0 +1,134 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\HttpClients; + +use Mockery as m; +use Facebook\HttpClients\FacebookStreamHttpClient; + +class FacebookStreamHttpClientTest extends AbstractTestHttpClient +{ + /** + * @var \Facebook\HttpClients\FacebookStream + */ + protected $streamMock; + + /** + * @var FacebookStreamHttpClient + */ + protected $streamClient; + + public function setUp() + { + $this->streamMock = m::mock('Facebook\HttpClients\FacebookStream'); + $this->streamClient = new FacebookStreamHttpClient($this->streamMock); + } + + public function testCanCompileHeader() + { + $headers = [ + 'X-foo' => 'bar', + 'X-bar' => 'faz', + ]; + $header = $this->streamClient->compileHeader($headers); + $this->assertEquals("X-foo: bar\r\nX-bar: faz", $header); + } + + public function testCanSendNormalRequest() + { + $this->streamMock + ->shouldReceive('streamContextCreate') + ->once() + ->with(m::on(function ($arg) { + if (!isset($arg['http']) || !isset($arg['ssl'])) { + return false; + } + + if ($arg['http'] !== [ + 'method' => 'GET', + 'header' => 'X-foo: bar', + 'content' => 'foo_body', + 'timeout' => 123, + 'ignore_errors' => true, + ] + ) { + return false; + } + + $caInfo = array_diff_assoc($arg['ssl'], [ + 'verify_peer' => true, + 'verify_peer_name' => true, + 'allow_self_signed' => true, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['cafile'])) { + return false; + } + + return true; + })) + ->andReturn(null); + $this->streamMock + ->shouldReceive('getResponseHeaders') + ->once() + ->andReturn(explode("\n", trim($this->fakeRawHeader))); + $this->streamMock + ->shouldReceive('fileGetContents') + ->once() + ->with('http://foo.com/') + ->andReturn($this->fakeRawBody); + + $response = $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); + + $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); + $this->assertEquals($this->fakeRawBody, $response->getBody()); + $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); + $this->assertEquals(200, $response->getHttpResponseCode()); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testThrowsExceptionOnClientError() + { + $this->streamMock + ->shouldReceive('streamContextCreate') + ->once() + ->andReturn(null); + $this->streamMock + ->shouldReceive('getResponseHeaders') + ->once() + ->andReturn(null); + $this->streamMock + ->shouldReceive('fileGetContents') + ->once() + ->with('http://foo.com/') + ->andReturn(false); + + $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', [], 60); + } +} diff --git a/lib/facebook-graph-sdk/tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php b/lib/facebook-graph-sdk/tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php new file mode 100644 index 0000000..2b09d29 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\PersistentData; + +use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; + +class FacebookMemoryPersistentDataHandlerTest extends \PHPUnit_Framework_TestCase +{ + public function testCanGetAndSetAVirtualValue() + { + $handler = new FacebookMemoryPersistentDataHandler(); + $handler->set('foo', 'bar'); + $value = $handler->get('foo'); + + $this->assertEquals('bar', $value); + } + + public function testGettingAValueThatDoesntExistWillReturnNull() + { + $handler = new FacebookMemoryPersistentDataHandler(); + $value = $handler->get('does_not_exist'); + + $this->assertNull($value); + } +} diff --git a/lib/facebook-graph-sdk/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php b/lib/facebook-graph-sdk/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php new file mode 100644 index 0000000..e21d366 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php @@ -0,0 +1,62 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\PersistentData; + +use Facebook\PersistentData\FacebookSessionPersistentDataHandler; + +class FacebookSessionPersistentDataHandlerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInactiveSessionsWillThrow() + { + $handler = new FacebookSessionPersistentDataHandler(); + } + + public function testCanSetAValue() + { + $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); + $handler->set('foo', 'bar'); + + $this->assertEquals('bar', $_SESSION['FBRLH_foo']); + } + + public function testCanGetAValue() + { + $_SESSION['FBRLH_faz'] = 'baz'; + $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); + $value = $handler->get('faz'); + + $this->assertEquals('baz', $value); + } + + public function testGettingAValueThatDoesntExistWillReturnNull() + { + $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); + $value = $handler->get('does_not_exist'); + + $this->assertNull($value); + } +} diff --git a/lib/facebook-graph-sdk/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php b/lib/facebook-graph-sdk/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php new file mode 100644 index 0000000..a45a3cf --- /dev/null +++ b/lib/facebook-graph-sdk/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\PseudoRandomString; + +use Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator; + +class McryptPseudoRandomStringGeneratorTest extends \PHPUnit_Framework_TestCase +{ + public function testCanGenerateRandomStringOfArbitraryLength() + { + if (!function_exists('mcrypt_create_iv')) { + $this->markTestSkipped( + 'Mcrypt must be installed to test mcrypt_create_iv().' + ); + } + + $prsg = new McryptPseudoRandomStringGenerator(); + $randomString = $prsg->getPseudoRandomString(10); + + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); + $this->assertEquals(10, mb_strlen($randomString)); + } +} diff --git a/lib/facebook-graph-sdk/tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php b/lib/facebook-graph-sdk/tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php new file mode 100644 index 0000000..c740d0b --- /dev/null +++ b/lib/facebook-graph-sdk/tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\PseudoRandomString; + +use Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator; + +class OpenSslPseudoRandomStringGeneratorTest extends \PHPUnit_Framework_TestCase +{ + public function testCanGenerateRandomStringOfArbitraryLength() + { + if (!function_exists('openssl_random_pseudo_bytes')) { + $this->markTestSkipped( + 'The OpenSSL extension must be enabled to test openssl_random_pseudo_bytes().' + ); + } + + $prsg = new OpenSslPseudoRandomStringGenerator(); + $randomString = $prsg->getPseudoRandomString(10); + + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); + $this->assertEquals(10, mb_strlen($randomString)); + } +} diff --git a/lib/facebook-graph-sdk/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php b/lib/facebook-graph-sdk/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php new file mode 100644 index 0000000..ea3a1f8 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\PseudoRandomString; + +use Facebook\PseudoRandomString\PseudoRandomStringGeneratorTrait; + +class MyFooBarPseudoRandomStringGenerator +{ + use PseudoRandomStringGeneratorTrait; +} + +class PseudoRandomStringGeneratorTraitTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException \InvalidArgumentException + */ + public function testAnInvalidLengthWillThrow() + { + $prsg = new MyFooBarPseudoRandomStringGenerator(); + $prsg->validateLength('foo_len'); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testALengthThatIsNotAtLeastOneCharacterWillThrow() + { + $prsg = new MyFooBarPseudoRandomStringGenerator(); + $prsg->validateLength(0); + } +} diff --git a/lib/facebook-graph-sdk/tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php b/lib/facebook-graph-sdk/tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php new file mode 100644 index 0000000..9e12a58 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\PseudoRandomString; + +use Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator; + +class UrandomPseudoRandomStringGeneratorTest extends \PHPUnit_Framework_TestCase +{ + public function testCanGenerateRandomStringOfArbitraryLength() + { + if (ini_get('open_basedir')) { + $this->markTestSkipped( + 'Cannot test /dev/urandom generator due to open_basedir constraint.' + ); + } + + if (!is_readable('/dev/urandom')) { + $this->markTestSkipped( + '/dev/urandom not found or is not readable.' + ); + } + + $prsg = new UrandomPseudoRandomStringGenerator(); + $randomString = $prsg->getPseudoRandomString(10); + + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); + $this->assertEquals(10, mb_strlen($randomString)); + } +} diff --git a/lib/facebook-graph-sdk/tests/SignedRequestTest.php b/lib/facebook-graph-sdk/tests/SignedRequestTest.php new file mode 100644 index 0000000..247600f --- /dev/null +++ b/lib/facebook-graph-sdk/tests/SignedRequestTest.php @@ -0,0 +1,139 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests; + +use Facebook\FacebookApp; +use Facebook\SignedRequest; + +class SignedRequestTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FacebookApp + */ + protected $app; + + protected $rawSignature = 'U0_O1MqqNKUt32633zAkdd2Ce-jGVgRgJeRauyx_zC8='; + protected $rawPayload = 'eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjozMjEsImNvZGUiOiJmb29fY29kZSIsInN0YXRlIjoiZm9vX3N0YXRlIiwidXNlcl9pZCI6MTIzLCJmb28iOiJiYXIifQ=='; + + protected $payloadData = [ + 'oauth_token' => 'foo_token', + 'algorithm' => 'HMAC-SHA256', + 'issued_at' => 321, + 'code' => 'foo_code', + 'state' => 'foo_state', + 'user_id' => 123, + 'foo' => 'bar', + ]; + + public function setUp() + { + $this->app = new FacebookApp('123', 'foo_app_secret'); + } + + public function testAValidSignedRequestCanBeCreated() + { + $sr = new SignedRequest($this->app); + $rawSignedRequest = $sr->make($this->payloadData); + + $srTwo = new SignedRequest($this->app, $rawSignedRequest); + $payload = $srTwo->getPayload(); + + $expectedRawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $this->assertEquals($expectedRawSignedRequest, $rawSignedRequest); + $this->assertEquals($this->payloadData, $payload); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInvalidSignedRequestsWillFailFormattingValidation() + { + new SignedRequest($this->app, 'invalid_signed_request'); + } + + public function testBase64EncodingIsUrlSafe() + { + $sr = new SignedRequest($this->app); + $encodedData = $sr->base64UrlEncode('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~'); + + $this->assertEquals('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4_Lnx-', $encodedData); + } + + public function testAUrlSafeBase64EncodedStringCanBeDecoded() + { + $sr = new SignedRequest($this->app); + $decodedData = $sr->base64UrlDecode('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4/Lnx+'); + + $this->assertEquals('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~', $decodedData); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnImproperlyEncodedSignatureWillThrowAnException() + { + new SignedRequest($this->app, 'foo_sig.' . $this->rawPayload); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnImproperlyEncodedPayloadWillThrowAnException() + { + new SignedRequest($this->app, $this->rawSignature . '.foo_payload'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testNonApprovedAlgorithmsWillThrowAnException() + { + $signedRequestData = $this->payloadData; + $signedRequestData['algorithm'] = 'FOO-ALGORITHM'; + + $sr = new SignedRequest($this->app); + $rawSignedRequest = $sr->make($signedRequestData); + + new SignedRequest($this->app, $rawSignedRequest); + } + + public function testAsRawSignedRequestCanBeValidatedAndDecoded() + { + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $sr = new SignedRequest($this->app, $rawSignedRequest); + + $this->assertEquals($this->payloadData, $sr->getPayload()); + } + + public function testARawSignedRequestCanBeValidatedAndDecoded() + { + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $sr = new SignedRequest($this->app, $rawSignedRequest); + + $this->assertEquals($sr->getPayload(), $this->payloadData); + $this->assertEquals($sr->getRawSignedRequest(), $rawSignedRequest); + $this->assertEquals(123, $sr->getUserId()); + $this->assertTrue($sr->hasOAuthData()); + } +} diff --git a/lib/facebook-graph-sdk/tests/Url/FacebookUrlDetectionHandlerTest.php b/lib/facebook-graph-sdk/tests/Url/FacebookUrlDetectionHandlerTest.php new file mode 100644 index 0000000..c3127ef --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Url/FacebookUrlDetectionHandlerTest.php @@ -0,0 +1,134 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Url; + +use Facebook\Url\FacebookUrlDetectionHandler; + +class FacebookUrlDetectionHandlerTest extends \PHPUnit_Framework_TestCase +{ + public function testProperlyGeneratesUrlFromCommonScenario() + { + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/baz?foo=123', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('http://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesSecureUrlFromCommonScenario() + { + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '443', + 'REQUEST_URI' => '/baz?foo=123', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('https://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesUrlFromProxy() + { + $_SERVER = [ + 'HTTP_X_FORWARDED_PORT' => '80', + 'HTTP_X_FORWARDED_PROTO' => 'http', + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/baz?foo=123', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('http://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesSecureUrlFromProxy() + { + $_SERVER = [ + 'HTTP_X_FORWARDED_PORT' => '443', + 'HTTP_X_FORWARDED_PROTO' => 'https', + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/baz?foo=123', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('https://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesUrlWithCustomPort() + { + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '1337', + 'REQUEST_URI' => '/foo.php', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('http://foo.bar:1337/foo.php', $currentUri); + } + + public function testProperlyGeneratesSecureUrlWithCustomPort() + { + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '1337', + 'REQUEST_URI' => '/foo.php', + 'HTTPS' => 'On', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('https://foo.bar:1337/foo.php', $currentUri); + } + + public function testProperlyGeneratesUrlWithCustomPortFromProxy() + { + $_SERVER = [ + 'HTTP_X_FORWARDED_PORT' => '8888', + 'HTTP_X_FORWARDED_PROTO' => 'http', + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/foo.php', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('http://foo.bar:8888/foo.php', $currentUri); + } +} diff --git a/lib/facebook-graph-sdk/tests/Url/FacebookUrlManipulatorTest.php b/lib/facebook-graph-sdk/tests/Url/FacebookUrlManipulatorTest.php new file mode 100644 index 0000000..c58e2b3 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/Url/FacebookUrlManipulatorTest.php @@ -0,0 +1,217 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +namespace Facebook\Tests\Url; + +use Facebook\Url\FacebookUrlManipulator; + +class FacebookUrlManipulatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider provideUris + */ + public function testParamsGetRemovedFromAUrl($dirtyUrl, $expectedCleanUrl) + { + $removeParams = [ + 'state', + 'code', + 'error', + 'error_reason', + 'error_description', + 'error_code', + ]; + $currentUri = FacebookUrlManipulator::removeParamsFromUrl($dirtyUrl, $removeParams); + $this->assertEquals($expectedCleanUrl, $currentUri); + } + + public function provideUris() + { + return [ + [ + 'http://localhost/something?state=0000&foo=bar&code=abcd', + 'http://localhost/something?foo=bar', + ], + [ + 'https://localhost/something?state=0000&foo=bar&code=abcd', + 'https://localhost/something?foo=bar', + ], + [ + 'http://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', + 'http://localhost/something?foo=bar', + ], + [ + 'https://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', + 'https://localhost/something?foo=bar', + ], + [ + 'http://localhost/something?state=0000&foo=bar&error=abcd', + 'http://localhost/something?foo=bar', + ], + [ + 'https://localhost/something?state=0000&foo=bar&error=abcd', + 'https://localhost/something?foo=bar', + ], + [ + 'https://localhost:1337/something?state=0000&foo=bar&error=abcd', + 'https://localhost:1337/something?foo=bar', + ], + [ + 'https://localhost:1337/something?state=0000&code=foo', + 'https://localhost:1337/something', + ], + [ + 'https://localhost/something/?state=0000&code=foo&foo=bar', + 'https://localhost/something/?foo=bar', + ], + [ + 'https://localhost/something/?state=0000&code=foo', + 'https://localhost/something/', + ], + ]; + } + + public function testGracefullyHandlesUrlAppending() + { + $params = []; + $url = 'https://www.foo.com/'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo', $processed_url); + + $params = [ + 'access_token' => 'foo', + 'bar' => 'baz', + ]; + $url = 'https://www.foo.com/?foo=bar'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo&bar=baz&foo=bar', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/?foo=bar&access_token=bar'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=bar&foo=bar', $processed_url); + } + + public function testSlashesAreProperlyPrepended() + { + $slashTestOne = FacebookUrlManipulator::forceSlashPrefix('foo'); + $slashTestTwo = FacebookUrlManipulator::forceSlashPrefix('/foo'); + $slashTestThree = FacebookUrlManipulator::forceSlashPrefix('foo/bar'); + $slashTestFour = FacebookUrlManipulator::forceSlashPrefix('/foo/bar'); + $slashTestFive = FacebookUrlManipulator::forceSlashPrefix(null); + $slashTestSix = FacebookUrlManipulator::forceSlashPrefix(''); + + $this->assertEquals('/foo', $slashTestOne); + $this->assertEquals('/foo', $slashTestTwo); + $this->assertEquals('/foo/bar', $slashTestThree); + $this->assertEquals('/foo/bar', $slashTestFour); + $this->assertEquals(null, $slashTestFive); + $this->assertEquals('', $slashTestSix); + } + + public function testParamsCanBeReturnedAsArray() + { + $paramsOne = FacebookUrlManipulator::getParamsAsArray('/foo'); + $paramsTwo = FacebookUrlManipulator::getParamsAsArray('/foo?one=1&two=2'); + $paramsThree = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com'); + $paramsFour = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?'); + $paramsFive = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?foo=bar'); + + $this->assertEquals([], $paramsOne); + $this->assertEquals(['one' => '1', 'two' => '2'], $paramsTwo); + $this->assertEquals([], $paramsThree); + $this->assertEquals([], $paramsFour); + $this->assertEquals(['foo' => 'bar'], $paramsFive); + } + + /** + * @dataProvider provideMergableEndpoints + */ + public function testParamsCanBeMergedOntoUrlProperly($urlOne, $urlTwo, $expected) + { + $result = FacebookUrlManipulator::mergeUrlParams($urlOne, $urlTwo); + + $this->assertEquals($result, $expected); + } + + public function provideMergableEndpoints() + { + return [ + [ + 'https://www.foo.com/?foo=ignore_foo&dance=fun', + '/me?foo=keep_foo', + '/me?dance=fun&foo=keep_foo', + ], + [ + 'https://www.bar.com?', + 'https://foo.com?foo=bar', + 'https://foo.com?foo=bar', + ], + [ + 'you', + 'me', + 'me', + ], + [ + '/1234?swing=fun', + '/1337?bar=baz&west=coast', + '/1337?bar=baz&swing=fun&west=coast', + ], + ]; + } + + public function testGraphUrlsCanBeTrimmed() + { + $fullGraphUrl = 'https://graph.facebook.com/'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/v1.0/'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.beta.facebook.com/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://whatever-they-want.facebook.com/v2.1/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/v5.301/1233?foo=bar'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/1233?foo=bar', $baseGraphUrl); + } +} diff --git a/lib/facebook-graph-sdk/tests/bootstrap.php b/lib/facebook-graph-sdk/tests/bootstrap.php new file mode 100644 index 0000000..4b04836 --- /dev/null +++ b/lib/facebook-graph-sdk/tests/bootstrap.php @@ -0,0 +1,33 @@ +<?php +/** + * Copyright 2014 Facebook, Inc. + * + * You are hereby granted a non-exclusive, worldwide, royalty-free license to + * use, copy, modify, and distribute this software in source code or binary + * form for use in connection with the web services and APIs provided by + * Facebook. + * + * As with any software that integrates with the Facebook platform, your use + * of this software is subject to the Facebook Developer Principles and + * Policies [http://developers.facebook.com/policy/]. This copyright notice + * shall be included in all copies or substantial portions of the software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +date_default_timezone_set('Europe/Paris'); + +require_once __DIR__ . '/../vendor/autoload.php'; + +use Facebook\FacebookClient; + +// Delete the temp test user after all tests have fired +register_shutdown_function(function () { + //echo "\nTotal requests made to Graph: " . FacebookClient::$requestCount . "\n\n"; +}); diff --git a/lib/facebook-graph-sdk/tests/foo.txt b/lib/facebook-graph-sdk/tests/foo.txt new file mode 100644 index 0000000..fa6541b --- /dev/null +++ b/lib/facebook-graph-sdk/tests/foo.txt @@ -0,0 +1 @@ +This is a text file used for testing. Let's dance.
\ No newline at end of file |