-
Notifications
You must be signed in to change notification settings - Fork 121
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enable knox tests and split tests (#83)
Enable knox tests and split tests
- Loading branch information
Showing
10 changed files
with
593 additions
and
531 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import json | ||
|
||
from httpretty import HTTPretty | ||
from social_core.backends.utils import load_backends | ||
from social_core.tests.backends.test_facebook import FacebookOAuth2Test | ||
from social_core.tests.backends.test_twitter import TwitterOAuth1Test | ||
from social_core.utils import module_member | ||
|
||
from rest_social_auth import views | ||
|
||
|
||
# don't run third party tests | ||
for attr in (attr for attr in dir(FacebookOAuth2Test) if attr.startswith('test_')): | ||
delattr(FacebookOAuth2Test, attr) | ||
for attr in (attr for attr in dir(TwitterOAuth1Test) if attr.startswith('test_')): | ||
delattr(TwitterOAuth1Test, attr) | ||
|
||
|
||
class RestSocialMixin(object): | ||
def setUp(self): | ||
HTTPretty.enable() | ||
Backend = module_member(self.backend_path) | ||
self.strategy = views.load_strategy() | ||
self.backend = Backend(self.strategy, redirect_uri=self.complete_url) | ||
self.name = self.backend.name.upper().replace('-', '_') | ||
self.complete_url = self.strategy.build_absolute_uri( | ||
self.raw_complete_url.format(self.backend.name) | ||
) | ||
backends = (self.backend_path, ) | ||
load_backends(backends, force_load=True) | ||
|
||
user_data_body = json.loads(self.user_data_body) | ||
self.email = 'example@mail.com' | ||
user_data_body['email'] = self.email | ||
self.user_data_body = json.dumps(user_data_body) | ||
|
||
self.do_rest_login() | ||
|
||
def tearDown(self): | ||
HTTPretty.disable() | ||
HTTPretty.reset() | ||
self.backend = None | ||
self.strategy = None | ||
self.name = None | ||
self.complete_url = None | ||
|
||
|
||
class BaseFacebookAPITestCase(RestSocialMixin, FacebookOAuth2Test): | ||
|
||
def do_rest_login(self): | ||
start_url = self.backend.start().url | ||
self.auth_handlers(start_url) | ||
|
||
|
||
class BaseTwitterApiTestCase(RestSocialMixin, TwitterOAuth1Test): | ||
|
||
def do_rest_login(self): | ||
self.request_token_handler() | ||
start_url = self.backend.start().url | ||
self.auth_handlers(start_url) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
from django.test import modify_settings | ||
from django.urls import reverse | ||
from rest_framework.test import APITestCase | ||
from rest_framework_jwt.settings import api_settings as jwt_api_settings | ||
from social_core.utils import parse_qs | ||
|
||
from .base import BaseFacebookAPITestCase, BaseTwitterApiTestCase | ||
|
||
|
||
jwt_modify_settings = dict( | ||
INSTALLED_APPS={ | ||
'remove': [ | ||
'django.contrib.sessions', | ||
'rest_framework.authtoken', | ||
'knox', | ||
] | ||
}, | ||
MIDDLEWARE_CLASSES={ | ||
'remove': [ | ||
'django.contrib.sessions.middleware.SessionMiddleware', | ||
'django.contrib.auth.middleware.AuthenticationMiddleware', | ||
'django.contrib.messages.middleware.MessageMiddleware', | ||
], | ||
} | ||
) | ||
|
||
|
||
class TestSocialAuth1JWT(APITestCase, BaseTwitterApiTestCase): | ||
|
||
@modify_settings(INSTALLED_APPS={'remove': ['rest_framework.authtoken', ]}) | ||
def test_login_social_oauth1_jwt(self): | ||
""" | ||
Currently oauth1 works only if session is enabled. | ||
Probably it is possible to make it work without session, but | ||
it will be needed to change the logic in python-social-auth. | ||
""" | ||
resp = self.client.post( | ||
reverse('login_social_jwt_user'), data={'provider': 'twitter'}) | ||
self.assertEqual(resp.status_code, 200) | ||
self.assertEqual(resp.data, parse_qs(self.request_token_body)) | ||
resp = self.client.post(reverse('login_social_jwt_user'), data={ | ||
'provider': 'twitter', | ||
'oauth_token': 'foobar', | ||
'oauth_verifier': 'overifier' | ||
}) | ||
self.assertEqual(resp.status_code, 200) | ||
|
||
|
||
class TestSocialAuth2JWT(APITestCase, BaseFacebookAPITestCase): | ||
|
||
@modify_settings(**jwt_modify_settings) | ||
def _check_login_social_jwt_only(self, url, data): | ||
jwt_decode_handler = jwt_api_settings.JWT_DECODE_HANDLER | ||
resp = self.client.post(url, data) | ||
self.assertEqual(resp.status_code, 200) | ||
# check token valid | ||
jwt_data = jwt_decode_handler(resp.data['token']) | ||
self.assertEqual(jwt_data['email'], self.email) | ||
|
||
@modify_settings(**jwt_modify_settings) | ||
def _check_login_social_jwt_user(self, url, data): | ||
jwt_decode_handler = jwt_api_settings.JWT_DECODE_HANDLER | ||
resp = self.client.post(url, data) | ||
self.assertEqual(resp.status_code, 200) | ||
self.assertEqual(resp.data['email'], self.email) | ||
# check token valid | ||
jwt_data = jwt_decode_handler(resp.data['token']) | ||
self.assertEqual(jwt_data['email'], self.email) | ||
|
||
def test_login_social_jwt_only(self): | ||
self._check_login_social_jwt_only( | ||
reverse('login_social_jwt'), | ||
data={'provider': 'facebook', 'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
|
||
def test_login_social_jwt_only_provider_in_url(self): | ||
self._check_login_social_jwt_only( | ||
reverse('login_social_jwt', kwargs={'provider': 'facebook'}), | ||
data={'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
|
||
def test_login_social_jwt_user(self): | ||
self._check_login_social_jwt_user( | ||
reverse('login_social_jwt_user'), | ||
data={'provider': 'facebook', 'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
|
||
def test_login_social_jwt_user_provider_in_url(self): | ||
self._check_login_social_jwt_user( | ||
reverse('login_social_jwt_user', kwargs={'provider': 'facebook'}), | ||
data={'code': '3D52VoM1uiw94a1ETnGvYlCw'}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
from django.urls import reverse | ||
from knox.auth import TokenAuthentication as KnoxTokenAuthentication | ||
from rest_framework.test import APITestCase | ||
from social_core.utils import parse_qs | ||
|
||
from .base import BaseFacebookAPITestCase, BaseTwitterApiTestCase | ||
|
||
|
||
class TestSocialAuth1Knox(APITestCase, BaseTwitterApiTestCase): | ||
|
||
def test_login_social_oauth1_knox(self): | ||
""" | ||
Currently oauth1 works only if session is enabled. | ||
Probably it is possible to make it work without session, but | ||
it will be needed to change the logic in python-social-auth. | ||
""" | ||
resp = self.client.post( | ||
reverse('login_social_knox_user'), data={'provider': 'twitter'}) | ||
self.assertEqual(resp.status_code, 200) | ||
self.assertEqual(resp.data, parse_qs(self.request_token_body)) | ||
resp = self.client.post(reverse('login_social_knox_user'), data={ | ||
'provider': 'twitter', | ||
'oauth_token': 'foobar', | ||
'oauth_verifier': 'overifier' | ||
}) | ||
self.assertEqual(resp.status_code, 200) | ||
|
||
|
||
class TestSocialAuth2Knox(APITestCase, BaseFacebookAPITestCase): | ||
|
||
def _check_login_social_knox_only(self, url, data): | ||
resp = self.client.post(url, data) | ||
self.assertEqual(resp.status_code, 200) | ||
# check token valid | ||
knox_auth = KnoxTokenAuthentication() | ||
user, auth_data = knox_auth.authenticate_credentials(resp.data['token'].encode('utf8')) | ||
self.assertEqual(user.email, self.email) | ||
|
||
def _check_login_social_knox_user(self, url, data): | ||
resp = self.client.post(url, data) | ||
self.assertEqual(resp.status_code, 200) | ||
self.assertEqual(resp.data['email'], self.email) | ||
# check token valid | ||
knox_auth = KnoxTokenAuthentication() | ||
user, auth_data = knox_auth.authenticate_credentials(resp.data['token'].encode('utf8')) | ||
self.assertEqual(user.email, self.email) | ||
|
||
def test_login_social_knox_only(self): | ||
self._check_login_social_knox_only( | ||
reverse('login_social_knox'), | ||
data={'provider': 'facebook', 'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
|
||
def test_login_social_knox_only_provider_in_url(self): | ||
self._check_login_social_knox_only( | ||
reverse('login_social_knox', kwargs={'provider': 'facebook'}), | ||
data={'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
|
||
def test_login_social_knox_user(self): | ||
self._check_login_social_knox_user( | ||
reverse('login_social_knox_user'), | ||
data={'provider': 'facebook', 'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
|
||
def test_login_social_knox_user_provider_in_url(self): | ||
self._check_login_social_knox_user( | ||
reverse('login_social_knox_user', kwargs={'provider': 'facebook'}), | ||
data={'code': '3D52VoM1uiw94a1ETnGvYlCw'}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
try: | ||
from urlparse import parse_qsl, urlparse | ||
except ImportError: | ||
# python 3 | ||
from urllib.parse import parse_qsl, urlparse | ||
|
||
from mock import patch | ||
from django.urls import reverse | ||
from django.contrib.auth import get_user_model | ||
from django.test import modify_settings | ||
from django.test.utils import override_settings | ||
from rest_framework.test import APITestCase | ||
from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly | ||
from httpretty import HTTPretty | ||
from social_core.utils import parse_qs | ||
|
||
from .base import BaseFacebookAPITestCase, BaseTwitterApiTestCase | ||
|
||
|
||
session_modify_settings = dict( | ||
INSTALLED_APPS={ | ||
'remove': [ | ||
'rest_framework.authtoken', | ||
'knox', | ||
] | ||
}, | ||
) | ||
|
||
|
||
class TestSocialAuth1(APITestCase, BaseTwitterApiTestCase): | ||
|
||
@modify_settings(**session_modify_settings) | ||
def test_login_social_oauth1_session(self): | ||
resp = self.client.post( | ||
reverse('login_social_session'), data={'provider': 'twitter'}) | ||
self.assertEqual(resp.status_code, 200) | ||
self.assertEqual(resp.data, parse_qs(self.request_token_body)) | ||
resp = self.client.post(reverse('login_social_session'), data={ | ||
'provider': 'twitter', | ||
'oauth_token': 'foobar', | ||
'oauth_verifier': 'overifier' | ||
}) | ||
self.assertEqual(resp.status_code, 200) | ||
|
||
|
||
class TestSocialAuth2(APITestCase, BaseFacebookAPITestCase): | ||
|
||
@modify_settings(**session_modify_settings) | ||
def _check_login_social_session(self, url, data): | ||
resp = self.client.post(url, data) | ||
self.assertEqual(resp.status_code, 200) | ||
self.assertEqual(resp.data['email'], self.email) | ||
# check cookies are set | ||
self.assertTrue('sessionid' in resp.cookies) | ||
# check user is created | ||
self.assertTrue( | ||
get_user_model().objects.filter(email=self.email).exists()) | ||
|
||
def test_login_social_session(self): | ||
self._check_login_social_session( | ||
reverse('login_social_session'), | ||
{'provider': 'facebook', 'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
|
||
def test_login_social_session_provider_in_url(self): | ||
self._check_login_social_session( | ||
reverse('login_social_session', kwargs={'provider': 'facebook'}), | ||
{'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
|
||
def test_no_provider_session(self): | ||
resp = self.client.post( | ||
reverse('login_social_session'), | ||
{'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
self.assertEqual(resp.status_code, 400) | ||
|
||
def test_unknown_provider_session(self): | ||
resp = self.client.post( | ||
reverse('login_social_session', kwargs={'provider': 'unknown'}), | ||
{'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
self.assertEqual(resp.status_code, 404) | ||
|
||
def test_login_social_http_origin(self): | ||
resp = self.client.post( | ||
reverse('login_social_session'), | ||
data={'provider': 'facebook', 'code': '3D52VoM1uiw94a1ETnGvYlCw'}, | ||
HTTP_ORIGIN="http://frontend.com") | ||
self.assertEqual(resp.status_code, 200) | ||
url_params = dict(parse_qsl(urlparse(HTTPretty.latest_requests[0].path).query)) | ||
self.assertEqual(url_params['redirect_uri'], "http://frontend.com/") | ||
|
||
@override_settings(REST_SOCIAL_OAUTH_ABSOLUTE_REDIRECT_URI='http://myproject.com/') | ||
def test_login_absolute_redirect(self): | ||
resp = self.client.post( | ||
reverse('login_social_session'), | ||
data={'provider': 'facebook', 'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
self.assertEqual(resp.status_code, 200) | ||
url_params = dict(parse_qsl(urlparse(HTTPretty.latest_requests[0].path).query)) | ||
self.assertEqual('http://myproject.com/', url_params['redirect_uri']) | ||
|
||
@override_settings(REST_SOCIAL_OAUTH_ABSOLUTE_REDIRECT_URI='http://myproject.com/') | ||
def test_login_manual_redirect(self): | ||
resp = self.client.post( | ||
reverse('login_social_session'), | ||
data={'provider': 'facebook', 'code': '3D52VoM1uiw94a1ETnGvYlCw', | ||
'redirect_uri': 'http://manualdomain.com/'}) | ||
self.assertEqual(resp.status_code, 200) | ||
url_params = dict(parse_qsl(urlparse(HTTPretty.latest_requests[0].path).query)) | ||
self.assertEqual('http://manualdomain.com/', url_params['redirect_uri']) | ||
|
||
@patch('rest_framework.views.APIView.permission_classes') | ||
def test_login_social_session_model_permission(self, m_permission_classes): | ||
setattr(m_permission_classes, '__get__', lambda *args, **kwargs: (DjangoModelPermissionsOrAnonReadOnly, )) | ||
self._check_login_social_session( | ||
reverse('login_social_session'), | ||
{'provider': 'facebook', 'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
|
||
|
||
class TestSocialAuth2Error(APITestCase, BaseFacebookAPITestCase): | ||
access_token_status = 400 | ||
|
||
def test_login_oauth_provider_error(self): | ||
resp = self.client.post( | ||
reverse('login_social_session'), | ||
data={'provider': 'facebook', 'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
self.assertEqual(resp.status_code, 400) | ||
|
||
|
||
class TestSocialAuth2HTTPError(APITestCase, BaseFacebookAPITestCase): | ||
access_token_status = 401 | ||
|
||
def test_login_oauth_provider_http_error(self): | ||
resp = self.client.post( | ||
reverse('login_social_session'), | ||
data={'provider': 'facebook', 'code': '3D52VoM1uiw94a1ETnGvYlCw'}) | ||
self.assertEqual(resp.status_code, 400) |
Oops, something went wrong.