From fe5a4e8a74457f0d346fc3191856e7b0db1d59ef Mon Sep 17 00:00:00 2001 From: st4lk Date: Tue, 27 Oct 2015 18:59:54 +0300 Subject: [PATCH] test no session, refs #4, #8 --- .../templatetags/admin_affiliate_tags.py | 9 --- affiliate/tools.py | 6 +- requirements_test.txt | 1 + tests/test_affiliate_middleware.py | 50 ++++++++++++---- tests/utils.py | 58 +++++++++++++++++++ 5 files changed, 100 insertions(+), 24 deletions(-) delete mode 100644 affiliate/templatetags/admin_affiliate_tags.py create mode 100644 tests/utils.py diff --git a/affiliate/templatetags/admin_affiliate_tags.py b/affiliate/templatetags/admin_affiliate_tags.py deleted file mode 100644 index 745b898..0000000 --- a/affiliate/templatetags/admin_affiliate_tags.py +++ /dev/null @@ -1,9 +0,0 @@ -from django import template -from django.contrib.admin.templatetags.admin_modify import submit_row - -register = template.Library() - - -@register.inclusion_tag('admin/request_submit_line.html', takes_context=True) -def submit_affiliate_row(context): - return submit_row(context) diff --git a/affiliate/tools.py b/affiliate/tools.py index ab629c0..73367df 100644 --- a/affiliate/tools.py +++ b/affiliate/tools.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -import urllib +from django.utils.http import urlencode from django.utils.six.moves.urllib.parse import parse_qsl, urlparse, urlunparse from . import settings as affiliate_settings try: @@ -23,7 +23,7 @@ def add_affiliate_code(url, aid_code): query = dict(parse_qsl(parsed.query)) query.update({affiliate_settings.PARAM_NAME: str(aid_code)}) url_parts = list(parsed) - url_parts[4] = urllib.urlencode(query) + url_parts[4] = urlencode(query) return urlunparse(url_parts) @@ -32,5 +32,5 @@ def remove_affiliate_code(url): query = dict(parse_qsl(parsed.query)) query.pop(affiliate_settings.PARAM_NAME, None) url_parts = list(parsed) - url_parts[4] = urllib.urlencode(query) + url_parts[4] = urlencode(query) return urlunparse(url_parts) diff --git a/requirements_test.txt b/requirements_test.txt index 2f99089..bc8d28c 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -3,3 +3,4 @@ model-mommy freezegun coverage tox>=1.7.0 +mock diff --git a/tests/test_affiliate_middleware.py b/tests/test_affiliate_middleware.py index 072d576..41d4626 100644 --- a/tests/test_affiliate_middleware.py +++ b/tests/test_affiliate_middleware.py @@ -3,11 +3,11 @@ from django.test import TestCase from django.utils import timezone -from django.utils.http import urlencode from model_mommy import mommy from freezegun import freeze_time -from affiliate.settings import PARAM_NAME, SESSION_AGE +from affiliate.settings import SESSION_AGE +from .utils import get_aid_url, modify_settings class TestAffiliateMiddleware(TestCase): @@ -17,13 +17,13 @@ def test_no_affiliate_in_url(self): self.assertFalse(resp.context['request'].affiliate.exist()) def test_bad_affiliate_code(self): - resp = self.client.get(self.get_aid_url('/', 123)) + resp = self.client.get(get_aid_url('/', 123)) self.assertEqual(resp.status_code, 200) self.assertFalse(resp.context['request'].affiliate.exist()) def test_affiliate_assigned(self): affiliate = mommy.make('affiliate.Affiliate') - resp = self.client.get(self.get_aid_url('/', affiliate.aid)) + resp = self.client.get(get_aid_url('/', affiliate.aid)) self.assertEqual(resp.status_code, 200) affiliate_resp = resp.context['request'].affiliate self.assertTrue(affiliate_resp.exist()) @@ -31,9 +31,9 @@ def test_affiliate_assigned(self): def test_previous_affiliate_is_used(self): affiliate = mommy.make('affiliate.Affiliate') - resp = self.client.get(self.get_aid_url('/', affiliate.aid)) + resp = self.client.get(get_aid_url('/', affiliate.aid)) self.assertEqual(resp.status_code, 200) - resp = self.client.get(self.get_aid_url('/', affiliate.aid + 100)) # invalid aid code + resp = self.client.get(get_aid_url('/', affiliate.aid + 100)) # invalid aid code self.assertEqual(resp.status_code, 200) affiliate_resp = resp.context['request'].affiliate self.assertTrue(affiliate_resp.exist()) @@ -41,7 +41,7 @@ def test_previous_affiliate_is_used(self): def test_affiliate_saved_in_session(self): affiliate = mommy.make('affiliate.Affiliate') - self.client.get(self.get_aid_url('/', affiliate.aid)) + self.client.get(get_aid_url('/', affiliate.aid)) # next response without aid still contains affiliate with freeze_time(timezone.now() + timedelta(seconds=SESSION_AGE - 1)): @@ -54,7 +54,7 @@ def test_affiliate_saved_in_session(self): def test_affiliate_session_expired(self): affiliate = mommy.make('affiliate.Affiliate') - self.client.get(self.get_aid_url('/', affiliate.aid)) + self.client.get(get_aid_url('/', affiliate.aid)) # affiliate is expired with freeze_time(timezone.now() + timedelta(seconds=SESSION_AGE + 1)): @@ -65,15 +65,41 @@ def test_affiliate_session_expired(self): def test_previous_affiliate_session_expired(self): affiliate = mommy.make('affiliate.Affiliate') - resp = self.client.get(self.get_aid_url('/', affiliate.aid)) + resp = self.client.get(get_aid_url('/', affiliate.aid)) self.assertEqual(resp.status_code, 200) # affiliate is expired with freeze_time(timezone.now() + timedelta(seconds=SESSION_AGE + 1)): - resp = self.client.get(self.get_aid_url('/', affiliate.aid + 100)) # invalid aid code + resp = self.client.get(get_aid_url('/', affiliate.aid + 100)) # invalid aid code self.assertEqual(resp.status_code, 200) self.assertFalse(resp.context['request'].affiliate.exist()) - def get_aid_url(self, url, aid_code): - return '?'.join([url, urlencode({PARAM_NAME: aid_code})]) + +@modify_settings(MIDDLEWARE_CLASSES={ + 'remove': [ + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + ], +}, INSTALLED_APPS={ + 'remove': [ + 'django.contrib.sessions' + ] +}) +class TestAffiliateMiddlewareNoSession(TestCase): + def test_no_session_affiliate_in_url(self): + from affiliate import settings as affiliate_settings + affiliate_settings.SAVE_IN_SESSION = False + + affiliate = mommy.make('affiliate.Affiliate') + resp = self.client.get(get_aid_url('/', affiliate.aid)) + self.assertEqual(resp.status_code, 200) + affiliate_resp = resp.context['request'].affiliate + self.assertTrue(affiliate_resp.exist()) + self.assertEqual(affiliate.aid, affiliate_resp.aid) + + # next request can't remember previous affiliate + resp = self.client.get('/') + self.assertEqual(resp.status_code, 200) + self.assertFalse(resp.context['request'].affiliate.exist()) diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 0000000..c8ad5a9 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,58 @@ +from django.utils.http import urlencode +from affiliate.settings import PARAM_NAME + + +def get_aid_url(url, aid_code): + return '?'.join([url, urlencode({PARAM_NAME: aid_code})]) + + +try: + from django.test import modify_settings +except ImportError: + from django.test.utils import override_settings, settings, six + + class modify_settings(override_settings): + """ + Like override_settings, but makes it possible to append, prepend or remove + items instead of redefining the entire list. + """ + def __init__(self, *args, **kwargs): + if args: + # Hack used when instantiating from SimpleTestCase._pre_setup. + assert not kwargs + self.operations = args[0] + else: + assert not args + self.operations = list(kwargs.items()) + + def save_options(self, test_func): + if test_func._modified_settings is None: + test_func._modified_settings = self.operations + else: + # Duplicate list to prevent subclasses from altering their parent. + test_func._modified_settings = list( + test_func._modified_settings) + self.operations + + def enable(self): + self.options = {} + for name, operations in self.operations: + try: + # When called from SimpleTestCase._pre_setup, values may be + # overridden several times; cumulate changes. + value = self.options[name] + except KeyError: + value = list(getattr(settings, name, [])) + for action, items in operations.items(): + # items my be a single value or an iterable. + if isinstance(items, six.string_types): + items = [items] + if action == 'append': + value = value + [item for item in items if item not in value] + elif action == 'prepend': + value = [item for item in items if item not in value] + value + elif action == 'remove': + value = [item for item in value if item not in items] + else: + raise ValueError("Unsupported action: %s" % action) + self.options[name] = value + super(modify_settings, self).enable()