Skip to content

Commit

Permalink
Reorganize tests.
Browse files Browse the repository at this point in the history
  - Reorganize automated tests into multiple files.
  - Rename test case objects to make it clearer than they inherit from
    FacebookTestCase.
  - Remove broken `test_request` test case.
  • Loading branch information
martey committed Oct 20, 2019
1 parent 16744d6 commit e38b951
Show file tree
Hide file tree
Showing 10 changed files with 517 additions and 518 deletions.
92 changes: 92 additions & 0 deletions test/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env python
#
# Copyright 2015-2019 Mobolic
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import unittest

import facebook


class FacebookTestCase(unittest.TestCase):
"""
Sets up application ID and secret from environment and initialises an
empty list for test users.
"""

def setUp(self):
try:
self.app_id = os.environ["FACEBOOK_APP_ID"]
self.secret = os.environ["FACEBOOK_SECRET"]
except KeyError:
raise Exception(
"FACEBOOK_APP_ID and FACEBOOK_SECRET "
"must be set as environmental variables."
)

self.test_users = []

def tearDown(self):
"""Deletes the test users included in the test user list."""
token = facebook.GraphAPI().get_app_access_token(
self.app_id, self.secret, True
)
graph = facebook.GraphAPI(token)

for user in self.test_users:
graph.request(user["id"], {}, None, method="DELETE")
del self.test_users[:]

def assert_raises_multi_regex(
self,
expected_exception,
expected_regexp,
callable_obj=None,
*args,
**kwargs
):
"""
Custom function to backport assertRaisesRegexp to all supported
versions of Python.
"""
self.assertRaises(expected_exception, callable_obj, *args, **kwargs)
try:
callable_obj(*args)
except facebook.GraphAPIError as error:
self.assertEqual(error.message, expected_regexp)

def create_test_users(self, app_id, graph, amount):
"""Function for creating test users."""
for i in range(amount):
u = graph.request(
app_id + "/accounts/test-users", {}, {}, method="POST"
)
self.test_users.append(u)

def create_friend_connections(self, user, friends):
"""Function for creating friend connections for a test user."""
user_graph = facebook.GraphAPI(user["access_token"])

for friend in friends:
if user["id"] == friend["id"]:
continue
user_graph.request(
user["id"] + "/friends/" + friend["id"], {}, {}, method="POST"
)
respondent_graph = facebook.GraphAPI(friend["access_token"])
respondent_graph.request(
friend["id"] + "/friends/" + user["id"], {}, {}, method="POST"
)
88 changes: 88 additions & 0 deletions test/test_access_tokens.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import facebook
from . import FacebookTestCase


class FacebookAccessTokenTestCase(FacebookTestCase):
def test_extend_access_token(self):
"""
Test if extend_access_token requests the correct endpoint.
Note that this only tests whether extend_access_token returns the
correct error message when called without a proper user-access token.
"""
try:
facebook.GraphAPI().extend_access_token(self.app_id, self.secret)
except facebook.GraphAPIError as e:
self.assertEqual(
e.message, "fb_exchange_token parameter not specified"
)

def test_bogus_access_token(self):
graph = facebook.GraphAPI(access_token="wrong_token")
self.assertRaises(facebook.GraphAPIError, graph.get_object, "me")

def test_access_with_expired_access_token(self):
expired_token = (
"AAABrFmeaJjgBAIshbq5ZBqZBICsmveZCZBi6O4w9HSTkFI73VMtmkL9jLuWs"
"ZBZC9QMHvJFtSulZAqonZBRIByzGooCZC8DWr0t1M4BL9FARdQwPWPnIqCiFQ"
)
graph = facebook.GraphAPI(access_token=expired_token)
self.assertRaises(facebook.GraphAPIError, graph.get_object, "me")

def test_request_access_tokens_are_unique_to_instances(self):
"""Verify that access tokens are unique to each GraphAPI object."""
graph1 = facebook.GraphAPI(access_token="foo")
graph2 = facebook.GraphAPI(access_token="bar")
# We use `delete_object` so that the access_token will appear
# in request.__defaults__.
try:
graph1.delete_object("baz")
except facebook.GraphAPIError:
pass
try:
graph2.delete_object("baz")
except facebook.GraphAPIError:
pass
self.assertEqual(graph1.request.__defaults__[0], None)
self.assertEqual(graph2.request.__defaults__[0], None)


class FacebookAppAccessTokenCase(FacebookTestCase):
"""
Test if application access token is returned properly.
Note that this only tests if the returned token is a string, not
whether it is valid.
"""

def test_get_app_access_token(self):
token = facebook.GraphAPI().get_app_access_token(
self.app_id, self.secret, False
)
# Since "unicode" does not exist in Python 3, we cannot check
# the following line with flake8 (hence the noqa comment).
assert isinstance(token, str) or isinstance(token, unicode) # noqa

def test_get_offline_app_access_token(self):
"""Verify that offline generation of app access tokens works."""
token = facebook.GraphAPI().get_app_access_token(
self.app_id, self.secret, offline=True
)
self.assertEqual(token, "{0}|{1}".format(self.app_id, self.secret))

def test_get_deleted_app_access_token(self):
deleted_app_id = "174236045938435"
deleted_secret = "0073dce2d95c4a5c2922d1827ea0cca6"
deleted_error_message = (
"Error validating application. Application has been deleted."
)

self.assert_raises_multi_regex(
facebook.GraphAPIError,
deleted_error_message,
facebook.GraphAPI().get_app_access_token,
deleted_app_id,
deleted_secret,
)
119 changes: 119 additions & 0 deletions test/test_application_secret_proof.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
try:
from unittest import mock
except ImportError:
import mock

import facebook
from . import FacebookTestCase


class FacebookAppSecretProofTestCase(FacebookTestCase):
"""Tests related to application secret proofs."""

PROOF = "4dad02ff1693df832f9c183fe400fc4f601360be06514acb4a73edb783eec345"

ACCESS_TOKEN = "abc123"
APP_SECRET = "xyz789"

def test_appsecret_proof_set(self):
"""
Verify that application secret proof is set when a GraphAPI object is
initialized with an application secret and access token.
"""
api = facebook.GraphAPI(
access_token=self.ACCESS_TOKEN, app_secret=self.APP_SECRET
)
self.assertEqual(api.app_secret_hmac, self.PROOF)

def test_appsecret_proof_no_access_token(self):
"""
Verify that no application secret proof is set when
a GraphAPI object is initialized with an application secret
and no access token.
"""
api = facebook.GraphAPI(app_secret=self.APP_SECRET)
self.assertEqual(api.app_secret_hmac, None)

def test_appsecret_proof_no_app_secret(self):
"""
Verify that no application secret proof is set when
a GraphAPI object is initialized with no application secret
and no access token.
"""
api = facebook.GraphAPI(access_token=self.ACCESS_TOKEN)
self.assertEqual(api.app_secret_hmac, None)

@mock.patch("requests.request")
def test_appsecret_proof_is_set_on_get_request(self, mock_request):
"""
Verify that no application secret proof is sent with
GET requests whena GraphAPI object is initialized
with an application secret and an access token.
"""
api = facebook.GraphAPI(
access_token=self.ACCESS_TOKEN, app_secret=self.APP_SECRET
)
mock_response = mock.Mock()
mock_response.headers = {"content-type": "json"}
mock_response.json.return_value = {}
mock_request.return_value = mock_response
api.session.request = mock_request
api.request("some-path")
mock_request.assert_called_once_with(
"GET",
"https://graph.facebook.com/some-path",
data=None,
files=None,
params={"access_token": "abc123", "appsecret_proof": self.PROOF},
proxies=None,
timeout=None,
)

@mock.patch("requests.request")
def test_appsecret_proof_is_set_on_post_request(self, mock_request):
"""
Verify that no application secret proof is sent with
POST requests when a GraphAPI object is initialized
with an application secret and an access token.
"""
api = facebook.GraphAPI(
access_token=self.ACCESS_TOKEN, app_secret=self.APP_SECRET
)
mock_response = mock.Mock()
mock_response.headers = {"content-type": "json"}
mock_response.json.return_value = {}
mock_request.return_value = mock_response
api.session.request = mock_request
api.request("some-path", method="POST")
mock_request.assert_called_once_with(
"POST",
"https://graph.facebook.com/some-path",
data=None,
files=None,
params={"access_token": "abc123", "appsecret_proof": self.PROOF},
proxies=None,
timeout=None,
)

@mock.patch("requests.request")
def test_missing_appsecret_proof_is_not_set_on_request(self, mock_request):
"""
Verify that no application secret proof is set if GraphAPI
object is initialized without an application secret.
"""
api = facebook.GraphAPI(access_token=self.ACCESS_TOKEN)
mock_response = mock.Mock()
mock_response.headers = {"content-type": "json"}
mock_response.json.return_value = {}
mock_request.return_value = mock_response
api.session.request = mock_request
api.request("some-path")
mock_request.assert_called_once_with(
"GET",
"https://graph.facebook.com/some-path",
data=None,
files=None,
params={"access_token": "abc123"},
proxies=None,
timeout=None,
)
41 changes: 41 additions & 0 deletions test/test_connections.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import inspect

import facebook
from . import FacebookTestCase


class FacebookAllConnectionsMethodTestCase(FacebookTestCase):
def test_function_with_zero_connections(self):
token = facebook.GraphAPI().get_app_access_token(
self.app_id, self.secret, True
)
graph = facebook.GraphAPI(token)

self.create_test_users(self.app_id, graph, 1)
friends = graph.get_all_connections(
self.test_users[0]["id"], "friends"
)

self.assertTrue(inspect.isgenerator(friends))
self.assertTrue(len(list(friends)) == 0)

# def test_function_returns_correct_connections(self):
# token = facebook.GraphAPI().get_app_access_token(
# self.app_id, self.secret, True
# )
# graph = facebook.GraphAPI(token)

# self.create_test_users(self.app_id, graph, 3)
# self.create_friend_connections(self.test_users[0], self.test_users)

# friends = graph.get_all_connections(
# self.test_users[0]["id"], "friends"
# )
# self.assertTrue(inspect.isgenerator(friends))

# friends_list = list(friends)
# self.assertTrue(len(friends_list) == 2)
# for f in friends:
# self.assertTrue(isinstance(f, dict))
# self.assertTrue("name" in f)
# self.assertTrue("id" in f)
Loading

0 comments on commit e38b951

Please sign in to comment.