Skip to content

Commit

Permalink
Unit tests refactoring (remove code duplication for Flask and Django …
Browse files Browse the repository at this point in the history
…test cases)
  • Loading branch information
dmitry-viskov committed Mar 24, 2020
1 parent 35a7371 commit af8ef40
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 117 deletions.
4 changes: 2 additions & 2 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .test_deep_link import TestDeepLink
from .test_deep_link import TestDjangoDeepLink, TestFlaskDeepLink
from .test_grades import TestGrades
from .test_names_roles import TestNamesRolesProvisioningService
from .test_resource_link import TestResourceLink
from .test_resource_link import TestDjangoResourceLink, TestFlaskResourceLink
38 changes: 11 additions & 27 deletions tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,22 @@
from unittest.mock import patch
except ImportError:
from mock import patch
from .django_mixin import DjangoMixin
from .flask_mixin import FlaskMixin
from .tool_config import TOOL_CONFIG


class TestLinkBase(DjangoMixin, FlaskMixin, unittest.TestCase):
class TestLinkBase(unittest.TestCase):
iss = 'replace-me'
get_login_data = {}
post_login_data = {}

def _make_oidc_login(self, adapter=None, uuid_val=None, tool_conf_cls=None, secure=False):
if adapter == 'flask':
return self._make_flask_oidc_login(uuid_val, tool_conf_cls, secure)
else:
return self._make_django_oidc_login(uuid_val, tool_conf_cls)
def _get_launch_obj(self, request, tool_conf):
raise NotImplementedError

def _get_request(self, login_request, login_response, request_is_secure=False, empty_session=False,
empty_cookies=False, post_data=None, adapter=None):
if adapter == 'flask':
return self._get_flask_request(login_request, login_response, request_is_secure, post_data,
empty_session, empty_cookies)
else:
return self._get_django_request(login_request, login_response, post_data, empty_session, empty_cookies)
def _get_launch_cls(self):
raise NotImplementedError

def _launch(self, request, tool_conf, key_set_url_response=None, force_validation=False, adapter=None):
if adapter == 'flask':
obj = self._get_flask_launch_obj(request, tool_conf)
else:
obj = self._get_django_launch_obj(request, tool_conf)
def _launch(self, request, tool_conf, key_set_url_response=None, force_validation=False):
obj = self._get_launch_obj(request, tool_conf)
obj.set_jwt_verify_options({
'verify_aud': False,
'verify_exp': False
Expand All @@ -49,14 +36,11 @@ def _launch(self, request, tool_conf, key_set_url_response=None, force_validatio
else:
return obj.get_launch_data()

def _launch_with_invalid_jwt_body(self, side_effect, request, tool_conf, adapter=None):
if adapter == 'flask':
klass = self._get_flask_launch_cls()
else:
klass = self._get_django_launch_cls()
with patch.object(klass, "_get_jwt_body", autospec=True) as get_jwt_body:
def _launch_with_invalid_jwt_body(self, side_effect, request, tool_conf):
launch_cls = self._get_launch_cls()
with patch.object(launch_cls, "_get_jwt_body", autospec=True) as get_jwt_body:
get_jwt_body.side_effect = side_effect
return self._launch(request, tool_conf, force_validation=True, adapter=adapter)
return self._launch(request, tool_conf, force_validation=True)


class TestServicesBase(unittest.TestCase):
Expand Down
29 changes: 19 additions & 10 deletions tests/django_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,28 @@

class DjangoMixin(object):

def _get_django_request(self, login_request, login_response, post_data=None,
empty_session=False, empty_cookies=False):
def _get_request(self, login_request, login_response, request_is_secure=False, post_data=None,
empty_session=False, empty_cookies=False):
session = None if empty_session else login_request.session
cookies = None if empty_cookies else login_response.get_cookies_dict()
post_launch_data = post_data if post_data else self.post_launch_data
return FakeRequest(post=post_launch_data,
cookies=cookies,
session=session)
session=session,
secure=request_is_secure)

def _make_django_oidc_login(self, uuid_val=None, tool_conf_cls=None):
def _make_oidc_login(self, uuid_val=None, tool_conf_cls=None, secure=False):
tool_conf = get_test_tool_conf(tool_conf_cls)
request = None
login_data = {}
if not uuid_val:
uuid_val = 'test-uuid-1234'

if self.get_login_data:
request = FakeRequest(get=self.get_login_data)
request = FakeRequest(get=self.get_login_data, secure=secure)
login_data = self.get_login_data.copy()
elif self.post_login_data:
request = FakeRequest(post=self.post_login_data)
request = FakeRequest(post=self.post_login_data, secure=secure)
login_data = self.post_login_data.copy()

with patch('django.shortcuts.redirect') as mock_redirect:
Expand Down Expand Up @@ -69,14 +70,22 @@ def _make_django_oidc_login(self, uuid_val=None, tool_conf_cls=None):
self.assertTrue('scope=openid' in url_params)
self.assertTrue('response_mode=form_post' in url_params)
self.assertTrue(('redirect_uri=' + quote(launch_url, '')) in url_params)
self.assertTrue(len(response.cookies), 1)
cookie_key = list(response.cookies)[0]
cookie_dict = response.cookies[cookie_key]
if secure:
self.assertTrue(cookie_dict['secure'])
self.assertEqual(cookie_dict['samesite'], 'None')
else:
self.assertFalse(cookie_dict['secure'])
self.assertTrue('samesite' not in cookie_dict)

return tool_conf, request, response

def _get_django_launch_obj(self, request, tool_conf):
def _get_launch_obj(self, request, tool_conf):
from pylti1p3.contrib.django import DjangoMessageLaunch
obj = DjangoMessageLaunch(request, tool_conf)
return obj
return DjangoMessageLaunch(request, tool_conf)

def _get_django_launch_cls(self):
def _get_launch_cls(self):
from pylti1p3.contrib.django import DjangoMessageLaunch
return DjangoMessageLaunch
17 changes: 8 additions & 9 deletions tests/flask_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def get_cookies_dict_from_response(self, response):
.split(';')[0].split('=')
return {cookie_name: cookie_value}

def _get_flask_request(self, login_request, login_response, request_is_secure=False, post_data=None,
empty_session=False, empty_cookies=False):
def _get_request(self, login_request, login_response, request_is_secure=False, post_data=None,
empty_session=False, empty_cookies=False):
session = {} if empty_session else login_request.session
cookies = {} if empty_cookies else self.get_cookies_dict_from_response(login_response)
post_launch_data = post_data if post_data else self.post_launch_data
Expand All @@ -30,7 +30,7 @@ def _get_flask_request(self, login_request, login_response, request_is_secure=Fa
session=session,
request_is_secure=request_is_secure)

def _make_flask_oidc_login(self, uuid_val=None, tool_conf_cls=None, secure=None):
def _make_oidc_login(self, uuid_val=None, tool_conf_cls=None, secure=False):
tool_conf = get_test_tool_conf(tool_conf_cls)
if not uuid_val:
uuid_val = 'test-uuid-1234'
Expand Down Expand Up @@ -101,13 +101,12 @@ def _make_flask_oidc_login(self, uuid_val=None, tool_conf_cls=None, secure=None)

return tool_conf, request, response

def _get_flask_launch_obj(self, request, tool_conf):
def _get_launch_obj(self, request, tool_conf):
from pylti1p3.contrib.flask import FlaskMessageLaunch
obj = FlaskMessageLaunch(request, tool_conf,
cookie_service=FlaskCookieService(request),
session_service=FlaskSessionService(request))
return obj
return FlaskMessageLaunch(request, tool_conf,
cookie_service=FlaskCookieService(request),
session_service=FlaskSessionService(request))

def _get_flask_launch_cls(self):
def _get_launch_cls(self):
from pylti1p3.contrib.flask import FlaskMessageLaunch
return FlaskMessageLaunch
6 changes: 4 additions & 2 deletions tests/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ class FakeRequest(object):
POST = {}
COOKIES = {}
session = None
secure = False

def __init__(self, get=None, post=None, cookies=None, session=None):
def __init__(self, get=None, post=None, cookies=None, session=None, secure=False):
self.GET = get if get else {}
self.POST = post if post else {}
self.COOKIES = cookies if cookies else {}
self.session = session if session else FakeSession()
self.secure = secure

def is_secure(self):
return False
return self.secure
19 changes: 14 additions & 5 deletions tests/test_deep_link.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from pylti1p3.deep_link_resource import DeepLinkResource
from .request import FakeRequest
from .base import TestLinkBase
from .django_mixin import DjangoMixin
from .flask_mixin import FlaskMixin


class TestDeepLink(TestLinkBase):
class DeepLinkBase(TestLinkBase):
# pylint: disable=abstract-method

iss = 'http://imsglobal.org'
jwt_canvas_keys = {
"keys": [
Expand Down Expand Up @@ -161,9 +164,7 @@ class TestDeepLink(TestLinkBase):
def test_deep_link_launch_success(self):
tool_conf, login_request, login_response = self._make_oidc_login(uuid_val='462a941bbf6a4356afa7')

launch_request = FakeRequest(post=self.post_launch_data,
cookies=login_response.get_cookies_dict(),
session=login_request.session)
launch_request = self._get_request(login_request, login_response)
validated_message_launch = self._launch(launch_request, tool_conf, force_validation=True)
message_launch_data = validated_message_launch.get_launch_data()
self.assertDictEqual(message_launch_data, self.expected_message_launch_data)
Expand All @@ -183,3 +184,11 @@ def test_deep_link_launch_success(self):
self.assertTrue(html.endswith('<script type="text/javascript">'
'document.getElementById(\'lti13_deep_link_auto_submit\').submit();'
'</script>'))


class TestDjangoDeepLink(DjangoMixin, DeepLinkBase):
pass


class TestFlaskDeepLink(FlaskMixin, DeepLinkBase):
pass
Loading

0 comments on commit af8ef40

Please sign in to comment.