summaryrefslogtreecommitdiff
path: root/lib/facebook-graph-sdk/tests
diff options
context:
space:
mode:
Diffstat (limited to 'lib/facebook-graph-sdk/tests')
-rw-r--r--lib/facebook-graph-sdk/tests/Authentication/AccessTokenMetadata.php138
-rw-r--r--lib/facebook-graph-sdk/tests/Authentication/AccessTokenTest.php111
-rw-r--r--lib/facebook-graph-sdk/tests/Authentication/FooFacebookClientForOAuth2Test.php58
-rw-r--r--lib/facebook-graph-sdk/tests/Authentication/OAuth2ClientTest.php167
-rw-r--r--lib/facebook-graph-sdk/tests/Exceptions/FacebookResponseExceptionTest.php278
-rw-r--r--lib/facebook-graph-sdk/tests/FacebookAppTest.php66
-rwxr-xr-xlib/facebook-graph-sdk/tests/FacebookBatchRequestTest.php381
-rwxr-xr-xlib/facebook-graph-sdk/tests/FacebookBatchResponseTest.php138
-rw-r--r--lib/facebook-graph-sdk/tests/FacebookClientTest.php308
-rwxr-xr-xlib/facebook-graph-sdk/tests/FacebookRequestTest.php207
-rwxr-xr-xlib/facebook-graph-sdk/tests/FacebookResponseTest.php121
-rw-r--r--lib/facebook-graph-sdk/tests/FacebookTest.php381
-rw-r--r--lib/facebook-graph-sdk/tests/FacebookTestCredentials.php.dist36
-rw-r--r--lib/facebook-graph-sdk/tests/FileUpload/FacebookFileTest.php53
-rw-r--r--lib/facebook-graph-sdk/tests/FileUpload/MimetypesTest.php55
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/AbstractGraphNode.php51
-rwxr-xr-xlib/facebook-graph-sdk/tests/GraphNodes/CollectionTest.php125
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/GraphAchievementTest.php117
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/GraphAlbumTest.php109
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/GraphEdgeTest.php120
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/GraphEventTest.php109
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/GraphGroupTest.php75
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/GraphNodeFactoryTest.php437
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/GraphNodeTest.php138
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/GraphObjectFactoryTest.php114
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/GraphPageTest.php95
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/GraphSessionInfoTest.php62
-rw-r--r--lib/facebook-graph-sdk/tests/GraphNodes/GraphUserTest.php140
-rw-r--r--lib/facebook-graph-sdk/tests/Helpers/FacebookCanvasHelperTest.php53
-rw-r--r--lib/facebook-graph-sdk/tests/Helpers/FacebookJavaScriptHelperTest.php45
-rw-r--r--lib/facebook-graph-sdk/tests/Helpers/FacebookPageTabHelperTest.php46
-rw-r--r--lib/facebook-graph-sdk/tests/Helpers/FacebookRedirectLoginHelperTest.php140
-rw-r--r--lib/facebook-graph-sdk/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php113
-rw-r--r--lib/facebook-graph-sdk/tests/Http/GraphRawResponseTest.php82
-rw-r--r--lib/facebook-graph-sdk/tests/Http/RequestBodyMultipartTest.php111
-rw-r--r--lib/facebook-graph-sdk/tests/Http/RequestUrlEncodedTest.php64
-rw-r--r--lib/facebook-graph-sdk/tests/HttpClients/AbstractTestHttpClient.php60
-rw-r--r--lib/facebook-graph-sdk/tests/HttpClients/FacebookCurlHttpClientTest.php334
-rw-r--r--lib/facebook-graph-sdk/tests/HttpClients/FacebookGuzzleHttpClientTest.php143
-rw-r--r--lib/facebook-graph-sdk/tests/HttpClients/FacebookStreamHttpClientTest.php134
-rw-r--r--lib/facebook-graph-sdk/tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php46
-rw-r--r--lib/facebook-graph-sdk/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php62
-rw-r--r--lib/facebook-graph-sdk/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php44
-rw-r--r--lib/facebook-graph-sdk/tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php44
-rw-r--r--lib/facebook-graph-sdk/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php52
-rw-r--r--lib/facebook-graph-sdk/tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php50
-rw-r--r--lib/facebook-graph-sdk/tests/SignedRequestTest.php139
-rw-r--r--lib/facebook-graph-sdk/tests/Url/FacebookUrlDetectionHandlerTest.php134
-rw-r--r--lib/facebook-graph-sdk/tests/Url/FacebookUrlManipulatorTest.php217
-rw-r--r--lib/facebook-graph-sdk/tests/bootstrap.php33
-rw-r--r--lib/facebook-graph-sdk/tests/foo.txt1
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