django-cms-qe 3.4.2__py3-none-any.whl → 3.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cms_qe/tests/__init__.py +0 -0
- cms_qe/tests/test_errors.py +61 -0
- cms_qe/tests/test_export.py +108 -0
- cms_qe/tests/test_monitoring.py +15 -0
- cms_qe/tests/test_utils.py +77 -0
- cms_qe/tests/test_views_security.py +18 -0
- cms_qe/views/maintenance.py +6 -0
- cms_qe_analytical/tests/__init__.py +0 -0
- cms_qe_analytical/tests/settings.py +24 -0
- cms_qe_analytical/tests/templatetags/__init__.py +0 -0
- cms_qe_analytical/tests/templatetags/dummy.py +37 -0
- cms_qe_analytical/tests/test_tag_google_analytics.py +178 -0
- cms_qe_analytical/tests/test_tag_piwik.py +152 -0
- cms_qe_analytical/tests/test_utils.py +112 -0
- cms_qe_analytical/tests/utils.py +56 -0
- cms_qe_auth/tests/__init__.py +0 -0
- cms_qe_auth/tests/test_models.py +70 -0
- cms_qe_auth/tests/test_utils.py +36 -0
- cms_qe_auth/tests/test_view.py +72 -0
- cms_qe_auth/tests/utils.py +22 -0
- cms_qe_newsletter/tests/__init__.py +0 -0
- cms_qe_newsletter/tests/test_mailchimp.py +38 -0
- cms_qe_newsletter/tests/test_managment.py +22 -0
- cms_qe_newsletter/tests/test_models.py +43 -0
- cms_qe_newsletter/tests/test_plugin.py +21 -0
- cms_qe_newsletter/tests/test_sync.py +71 -0
- cms_qe_newsletter/tests/test_views.py +13 -0
- cms_qe_plugins/cms_plugins.py +10 -0
- cms_qe_plugins/templates/cms_qe_plugins/published_or_draft_content.html +6 -0
- cms_qe_table/tests/__init__.py +0 -0
- cms_qe_table/tests/test_models.py +23 -0
- cms_qe_table/tests/test_plugin.py +18 -0
- cms_qe_table/tests/test_utils.py +90 -0
- cms_qe_video/tests/__init__.py +0 -0
- cms_qe_video/tests/test_models.py +96 -0
- cms_qe_video/tests/test_plugin.py +24 -0
- cms_qe_video/tests/test_templatetags.py +20 -0
- {django_cms_qe-3.4.2.dist-info → django_cms_qe-3.5.0.dist-info}/METADATA +12 -11
- {django_cms_qe-3.4.2.dist-info → django_cms_qe-3.5.0.dist-info}/RECORD +42 -7
- {django_cms_qe-3.4.2.dist-info → django_cms_qe-3.5.0.dist-info}/WHEEL +1 -1
- {django_cms_qe-3.4.2.dist-info → django_cms_qe-3.5.0.dist-info}/LICENSE +0 -0
- {django_cms_qe-3.4.2.dist-info → django_cms_qe-3.5.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for the Piwik template tags and filters.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from constance.test import override_config
|
|
6
|
+
from django.contrib.auth import get_user_model
|
|
7
|
+
from django.http import HttpRequest
|
|
8
|
+
from django.template import Context
|
|
9
|
+
from django.test.utils import override_settings
|
|
10
|
+
|
|
11
|
+
from ..templatetags.piwik import PiwikNode
|
|
12
|
+
from ..tests.utils import TagTestCase
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@override_config(PIWIK_DOMAIN_PATH='example.com', PIWIK_SITE_ID='345')
|
|
16
|
+
class PiwikTagTestCase(TagTestCase):
|
|
17
|
+
"""
|
|
18
|
+
Tests for the ``piwik`` template tag.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def test_tag(self):
|
|
22
|
+
r = self.render_tag('piwik', 'piwik')
|
|
23
|
+
self.assertTrue(' ? "https" : "http") + "://example.com/";' in r, r)
|
|
24
|
+
self.assertTrue("_paq.push(['setSiteId', 345]);" in r, r)
|
|
25
|
+
self.assertTrue('img src="http://example.com/matomo.php?idsite=345"'
|
|
26
|
+
in r, r)
|
|
27
|
+
|
|
28
|
+
def test_node(self):
|
|
29
|
+
r = PiwikNode().render(Context({}))
|
|
30
|
+
self.assertTrue(' ? "https" : "http") + "://example.com/";' in r, r)
|
|
31
|
+
self.assertTrue("_paq.push(['setSiteId', 345]);" in r, r)
|
|
32
|
+
self.assertTrue('img src="http://example.com/matomo.php?idsite=345"'
|
|
33
|
+
in r, r)
|
|
34
|
+
|
|
35
|
+
@override_config(PIWIK_DOMAIN_PATH='example.com/piwik',
|
|
36
|
+
PIWIK_SITE_ID='345')
|
|
37
|
+
def test_domain_path_valid(self):
|
|
38
|
+
r = self.render_tag('piwik', 'piwik')
|
|
39
|
+
self.assertTrue(' ? "https" : "http") + "://example.com/piwik/";' in r,
|
|
40
|
+
r)
|
|
41
|
+
|
|
42
|
+
@override_config(PIWIK_DOMAIN_PATH='example.com:1234',
|
|
43
|
+
PIWIK_SITE_ID='345')
|
|
44
|
+
def test_domain_port_valid(self):
|
|
45
|
+
r = self.render_tag('piwik', 'piwik')
|
|
46
|
+
self.assertTrue(' ? "https" : "http") + "://example.com:1234/";' in r,
|
|
47
|
+
r)
|
|
48
|
+
|
|
49
|
+
@override_config(PIWIK_DOMAIN_PATH='example.com:1234/piwik',
|
|
50
|
+
PIWIK_SITE_ID='345')
|
|
51
|
+
def test_domain_port_path_valid(self):
|
|
52
|
+
r = self.render_tag('piwik', 'piwik')
|
|
53
|
+
self.assertTrue(' ? "https" : "http") + "://example.com:1234/piwik/";' in r,
|
|
54
|
+
r)
|
|
55
|
+
|
|
56
|
+
@override_config(PIWIK_DOMAIN_PATH='')
|
|
57
|
+
def test_no_domain(self):
|
|
58
|
+
self.assertEqual(PiwikNode().render({}), '')
|
|
59
|
+
|
|
60
|
+
@override_config(PIWIK_SITE_ID='')
|
|
61
|
+
def test_no_siteid(self):
|
|
62
|
+
self.assertEqual(PiwikNode().render({}), '')
|
|
63
|
+
|
|
64
|
+
@override_config(PIWIK_SITE_ID='x')
|
|
65
|
+
def test_siteid_not_a_number(self):
|
|
66
|
+
self.assertEqual(PiwikNode().render({}), '')
|
|
67
|
+
|
|
68
|
+
@override_config(PIWIK_DOMAIN_PATH='http://www.example.com')
|
|
69
|
+
def test_domain_protocol_invalid(self):
|
|
70
|
+
self.assertEqual(PiwikNode().render({}), '')
|
|
71
|
+
|
|
72
|
+
@override_config(PIWIK_DOMAIN_PATH='example.com/')
|
|
73
|
+
def test_domain_slash_invalid(self):
|
|
74
|
+
self.assertEqual(PiwikNode().render({}), '')
|
|
75
|
+
|
|
76
|
+
@override_config(PIWIK_DOMAIN_PATH='example.com:123:456')
|
|
77
|
+
def test_domain_multi_port(self):
|
|
78
|
+
self.assertEqual(PiwikNode().render({}), '')
|
|
79
|
+
|
|
80
|
+
@override_config(PIWIK_DOMAIN_PATH='example.com:')
|
|
81
|
+
def test_domain_incomplete_port(self):
|
|
82
|
+
self.assertEqual(PiwikNode().render({}), '')
|
|
83
|
+
|
|
84
|
+
@override_config(PIWIK_DOMAIN_PATH='example.com:/piwik')
|
|
85
|
+
def test_domain_uri_incomplete_port(self):
|
|
86
|
+
self.assertEqual(PiwikNode().render({}), '')
|
|
87
|
+
|
|
88
|
+
@override_config(PIWIK_DOMAIN_PATH='example.com:12df')
|
|
89
|
+
def test_domain_port_invalid(self):
|
|
90
|
+
self.assertEqual(PiwikNode().render({}), '')
|
|
91
|
+
|
|
92
|
+
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
|
93
|
+
def test_render_internal_ip(self):
|
|
94
|
+
req = HttpRequest()
|
|
95
|
+
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
|
96
|
+
context = Context({'request': req})
|
|
97
|
+
r = PiwikNode().render(context)
|
|
98
|
+
self.assertTrue(r.startswith(
|
|
99
|
+
'<!-- Piwik disabled on internal IP address'), r)
|
|
100
|
+
self.assertTrue(r.endswith('-->'), r)
|
|
101
|
+
|
|
102
|
+
def test_uservars(self):
|
|
103
|
+
context = Context({'piwik_vars': [(1, 'foo', 'foo_val'),
|
|
104
|
+
(2, 'bar', 'bar_val', 'page'),
|
|
105
|
+
(3, 'spam', 'spam_val', 'visit')]})
|
|
106
|
+
r = PiwikNode().render(context)
|
|
107
|
+
msg = 'Incorrect Piwik custom variable rendering. Expected:\n%s\nIn:\n%s'
|
|
108
|
+
for var_code in ['_paq.push(["setCustomVariable", 1, "foo", "foo_val", "page"]);',
|
|
109
|
+
'_paq.push(["setCustomVariable", 2, "bar", "bar_val", "page"]);',
|
|
110
|
+
'_paq.push(["setCustomVariable", 3, "spam", "spam_val", "visit"]);']:
|
|
111
|
+
self.assertIn(var_code, r, msg % (var_code, r))
|
|
112
|
+
|
|
113
|
+
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
|
114
|
+
def test_default_usertrack(self):
|
|
115
|
+
User = get_user_model()
|
|
116
|
+
context = Context({
|
|
117
|
+
'user': User(username='BDFL', first_name='Guido', last_name='van Rossum')
|
|
118
|
+
})
|
|
119
|
+
r = PiwikNode().render(context)
|
|
120
|
+
msg = 'Incorrect Piwik user tracking rendering.\nNot found:\n%s\nIn:\n%s'
|
|
121
|
+
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
|
122
|
+
self.assertIn(var_code, r, msg % (var_code, r))
|
|
123
|
+
|
|
124
|
+
def test_piwik_usertrack(self):
|
|
125
|
+
context = Context({
|
|
126
|
+
'piwik_identity': 'BDFL'
|
|
127
|
+
})
|
|
128
|
+
r = PiwikNode().render(context)
|
|
129
|
+
msg = 'Incorrect Piwik user tracking rendering.\nNot found:\n%s\nIn:\n%s'
|
|
130
|
+
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
|
131
|
+
self.assertIn(var_code, r, msg % (var_code, r))
|
|
132
|
+
|
|
133
|
+
def test_analytical_usertrack(self):
|
|
134
|
+
context = Context({
|
|
135
|
+
'analytical_identity': 'BDFL'
|
|
136
|
+
})
|
|
137
|
+
r = PiwikNode().render(context)
|
|
138
|
+
msg = 'Incorrect Piwik user tracking rendering.\nNot found:\n%s\nIn:\n%s'
|
|
139
|
+
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
|
140
|
+
self.assertIn(var_code, r, msg % (var_code, r))
|
|
141
|
+
|
|
142
|
+
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
|
143
|
+
def test_disable_usertrack(self):
|
|
144
|
+
User = get_user_model()
|
|
145
|
+
context = Context({
|
|
146
|
+
'user': User(username='BDFL', first_name='Guido', last_name='van Rossum'),
|
|
147
|
+
'piwik_identity': None
|
|
148
|
+
})
|
|
149
|
+
r = PiwikNode().render(context)
|
|
150
|
+
msg = 'Incorrect Piwik user tracking rendering.\nFound:\n%s\nIn:\n%s'
|
|
151
|
+
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
|
152
|
+
self.assertNotIn(var_code, r, msg % (var_code, r))
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for the analytical.utils module.
|
|
3
|
+
"""
|
|
4
|
+
# import django
|
|
5
|
+
|
|
6
|
+
from django.contrib.auth.models import AbstractBaseUser
|
|
7
|
+
from django.db import models
|
|
8
|
+
from django.http import HttpRequest
|
|
9
|
+
from django.template import Context
|
|
10
|
+
from django.test.utils import override_settings
|
|
11
|
+
|
|
12
|
+
from ..tests.utils import TestCase
|
|
13
|
+
from ..utils import AnalyticalException, get_domain, get_identity, get_required_setting, is_internal_ip
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SettingDeletedTestCase(TestCase):
|
|
17
|
+
|
|
18
|
+
@override_settings(USER_ID=None)
|
|
19
|
+
def test_get_required_setting(self):
|
|
20
|
+
"""
|
|
21
|
+
Make sure using get_required_setting fails in the right place.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
# available in python >= 3.2
|
|
25
|
+
if hasattr(self, 'assertRaisesRegex'):
|
|
26
|
+
with self.assertRaisesRegex(AnalyticalException, "USER_ID"):
|
|
27
|
+
get_required_setting("USER_ID", r"\d+", "invalid USER_ID")
|
|
28
|
+
else:
|
|
29
|
+
self.assertRaises(AnalyticalException,
|
|
30
|
+
get_required_setting, "USER_ID", r"\d+", "invalid USER_ID")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class MyUser(AbstractBaseUser):
|
|
34
|
+
identity = models.CharField(max_length=50)
|
|
35
|
+
USERNAME_FIELD = 'identity'
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class GetIdentityTestCase(TestCase):
|
|
39
|
+
def test_custom_username_field(self):
|
|
40
|
+
get_id = get_identity(Context({}), user=MyUser(identity='fake_id'))
|
|
41
|
+
self.assertEqual(get_id, 'fake_id')
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@override_settings(ANALYTICAL_DOMAIN="example.org")
|
|
45
|
+
class GetDomainTestCase(TestCase):
|
|
46
|
+
def test_get_service_domain_from_context(self):
|
|
47
|
+
context = Context({'test_domain': 'example.com'})
|
|
48
|
+
self.assertEqual(get_domain(context, 'test'), 'example.com')
|
|
49
|
+
|
|
50
|
+
def test_get_analytical_domain_from_context(self):
|
|
51
|
+
context = Context({'analytical_domain': 'example.com'})
|
|
52
|
+
self.assertEqual(get_domain(context, 'test'), 'example.com')
|
|
53
|
+
|
|
54
|
+
@override_settings(TEST_DOMAIN="example.net")
|
|
55
|
+
def test_get_service_domain_from_settings(self):
|
|
56
|
+
context = Context()
|
|
57
|
+
self.assertEqual(get_domain(context, 'test'), 'example.net')
|
|
58
|
+
|
|
59
|
+
def test_get_analytical_domain_from_settings(self):
|
|
60
|
+
context = Context()
|
|
61
|
+
self.assertEqual(get_domain(context, 'test'), 'example.org')
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class InternalIpTestCase(TestCase):
|
|
65
|
+
|
|
66
|
+
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
|
67
|
+
def test_render_no_internal_ip(self):
|
|
68
|
+
context = Context()
|
|
69
|
+
self.assertFalse(is_internal_ip(context))
|
|
70
|
+
|
|
71
|
+
@override_settings(INTERNAL_IPS=['1.1.1.1'])
|
|
72
|
+
@override_settings(ANALYTICAL_INTERNAL_IPS=[])
|
|
73
|
+
def test_render_analytical_internal_ips_override_when_empty(self):
|
|
74
|
+
req = HttpRequest()
|
|
75
|
+
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
|
76
|
+
context = Context({'request': req})
|
|
77
|
+
self.assertFalse(is_internal_ip(context))
|
|
78
|
+
|
|
79
|
+
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
|
80
|
+
def test_render_internal_ip(self):
|
|
81
|
+
req = HttpRequest()
|
|
82
|
+
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
|
83
|
+
context = Context({'request': req})
|
|
84
|
+
self.assertTrue(is_internal_ip(context))
|
|
85
|
+
|
|
86
|
+
@override_settings(TEST_INTERNAL_IPS=['1.1.1.1'])
|
|
87
|
+
def test_render_prefix_internal_ip(self):
|
|
88
|
+
req = HttpRequest()
|
|
89
|
+
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
|
90
|
+
context = Context({'request': req})
|
|
91
|
+
self.assertTrue(is_internal_ip(context, 'TEST'))
|
|
92
|
+
|
|
93
|
+
@override_settings(INTERNAL_IPS=['1.1.1.1'])
|
|
94
|
+
def test_render_internal_ip_fallback(self):
|
|
95
|
+
req = HttpRequest()
|
|
96
|
+
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
|
97
|
+
context = Context({'request': req})
|
|
98
|
+
self.assertTrue(is_internal_ip(context))
|
|
99
|
+
|
|
100
|
+
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
|
101
|
+
def test_render_internal_ip_forwarded_for(self):
|
|
102
|
+
req = HttpRequest()
|
|
103
|
+
req.META['HTTP_X_FORWARDED_FOR'] = '1.1.1.1'
|
|
104
|
+
context = Context({'request': req})
|
|
105
|
+
self.assertTrue(is_internal_ip(context))
|
|
106
|
+
|
|
107
|
+
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
|
108
|
+
def test_render_different_internal_ip(self):
|
|
109
|
+
req = HttpRequest()
|
|
110
|
+
req.META['REMOTE_ADDR'] = '2.2.2.2'
|
|
111
|
+
context = Context({'request': req})
|
|
112
|
+
self.assertFalse(is_internal_ip(context))
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Testing utilities.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from django.template import Context, RequestContext, Template
|
|
7
|
+
from django.test.testcases import TestCase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def run_tests():
|
|
11
|
+
"""
|
|
12
|
+
Use the Django test runner to run the tests.
|
|
13
|
+
|
|
14
|
+
Sets the return code to the number of failed tests.
|
|
15
|
+
"""
|
|
16
|
+
import sys
|
|
17
|
+
|
|
18
|
+
import django
|
|
19
|
+
try:
|
|
20
|
+
django.setup()
|
|
21
|
+
except AttributeError:
|
|
22
|
+
pass
|
|
23
|
+
try:
|
|
24
|
+
from django.test.runner import DiscoverRunner as TestRunner
|
|
25
|
+
except ImportError:
|
|
26
|
+
from django.test.simple import DjangoTestSuiteRunner as TestRunner
|
|
27
|
+
runner = TestRunner()
|
|
28
|
+
sys.exit(runner.run_tests(["analytical"]))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class TagTestCase(TestCase):
|
|
32
|
+
"""
|
|
33
|
+
Tests for a template tag.
|
|
34
|
+
|
|
35
|
+
Adds support methods for testing template tags.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def render_tag(self, library, tag, vars=None, request=None):
|
|
39
|
+
if vars is None:
|
|
40
|
+
vars = {}
|
|
41
|
+
t = Template(f"{{% load {library} %}}{{% {tag} %}}")
|
|
42
|
+
if request is not None:
|
|
43
|
+
context = RequestContext(request, vars)
|
|
44
|
+
else:
|
|
45
|
+
context = Context(vars)
|
|
46
|
+
return t.render(context)
|
|
47
|
+
|
|
48
|
+
def render_template(self, template, vars=None, request=None):
|
|
49
|
+
if vars is None:
|
|
50
|
+
vars = {}
|
|
51
|
+
t = Template(template)
|
|
52
|
+
if request is not None:
|
|
53
|
+
context = RequestContext(request, vars)
|
|
54
|
+
else:
|
|
55
|
+
context = Context(vars)
|
|
56
|
+
return t.render(context)
|
|
File without changes
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from django.test import override_settings
|
|
4
|
+
from django.urls.converters import SlugConverter
|
|
5
|
+
from pytest_data import use_data
|
|
6
|
+
|
|
7
|
+
from cms_qe_auth.models import User
|
|
8
|
+
from cms_qe_auth.tests.utils import reset_urls
|
|
9
|
+
from cms_qe_auth.utils import pk_to_uidb64
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_set_username_by_email():
|
|
13
|
+
user = User(email='user@example.com')
|
|
14
|
+
assert not user.username
|
|
15
|
+
user.save()
|
|
16
|
+
assert user.username == user.email
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@use_data(user_data={'username': 'user@example.com', 'email': 'user@example.com'})
|
|
20
|
+
def test_set_username_by_changing_email(user):
|
|
21
|
+
assert user.username == 'user@example.com'
|
|
22
|
+
user.email = 'another@example.com'
|
|
23
|
+
assert user.username == 'user@example.com'
|
|
24
|
+
user.save()
|
|
25
|
+
assert user.username == 'another@example.com'
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@use_data(user_data={'email': 'user@example.com'})
|
|
29
|
+
def test_unset_is_active_by_changing_email(user):
|
|
30
|
+
assert user.is_active
|
|
31
|
+
user.email = 'another@example.com'
|
|
32
|
+
assert user.is_active
|
|
33
|
+
user.save()
|
|
34
|
+
assert not user.is_active
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test_simple_token_generation_and_checking(user):
|
|
38
|
+
token = user._generate_activation_token()
|
|
39
|
+
assert user._check_activation_token(token)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@use_data(user_data={'is_active': False})
|
|
43
|
+
def test_simple_token_generation_and_activate_is_active(user):
|
|
44
|
+
assert not user.is_active
|
|
45
|
+
token = user._generate_activation_token()
|
|
46
|
+
user.activate(token)
|
|
47
|
+
assert user.is_active
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@use_data(user_data={'is_active': False})
|
|
51
|
+
def test_simple_token_generation_and_activate_invalid(user):
|
|
52
|
+
user._generate_activation_token()
|
|
53
|
+
assert not user.activate("123456789ABZ-987654321abcdefg")
|
|
54
|
+
assert not user.is_active
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@override_settings(CMS_QE_AUTH_ENABLED=True)
|
|
58
|
+
def test_activation_email_sending(mailoutbox):
|
|
59
|
+
reset_urls()
|
|
60
|
+
user = User(username='testuser', email='testuser@example.com', is_active=False)
|
|
61
|
+
user.save(base_url="http://example.com")
|
|
62
|
+
assert len(mailoutbox) == 1
|
|
63
|
+
email = mailoutbox[0]
|
|
64
|
+
assert user.email == email.to[0]
|
|
65
|
+
assert 'activate' in email.subject.lower()
|
|
66
|
+
token_re = f'(?P<token>{SlugConverter.regex})'
|
|
67
|
+
url_re = fr'//example.com/en/auth/activate/{pk_to_uidb64(user.pk)}/{token_re}'
|
|
68
|
+
match = re.findall(url_re, email.body)
|
|
69
|
+
assert match
|
|
70
|
+
assert user._check_activation_token(match[0])
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from pytest_data import use_data
|
|
3
|
+
|
|
4
|
+
from ..utils import get_user_by_uidb64, pk_to_uidb64, uidb64_to_pk
|
|
5
|
+
|
|
6
|
+
UIDB64_TEST_DATA = (
|
|
7
|
+
'pk, uid',
|
|
8
|
+
[
|
|
9
|
+
('1', 'MQ'),
|
|
10
|
+
('99', 'OTk'),
|
|
11
|
+
('100', 'MTAw'),
|
|
12
|
+
('123456', 'MTIzNDU2')
|
|
13
|
+
]
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@pytest.mark.parametrize(*UIDB64_TEST_DATA)
|
|
18
|
+
def test_uidb64_to_pk(pk, uid):
|
|
19
|
+
assert uidb64_to_pk(uid) == pk
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@pytest.mark.parametrize(*UIDB64_TEST_DATA)
|
|
23
|
+
def test_pk_to_uidb64(pk, uid):
|
|
24
|
+
assert pk_to_uidb64(pk) == uid
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@use_data(user_data={'id': 1})
|
|
28
|
+
def test_get_user_by_uidb64(user):
|
|
29
|
+
assert user.pk == 1
|
|
30
|
+
assert user == get_user_by_uidb64("MQ")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@use_data(user_data={'id': 1})
|
|
34
|
+
def test_get_user_by_uidb64_user_not_exits(user):
|
|
35
|
+
user = get_user_by_uidb64("Mg")
|
|
36
|
+
assert not user
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from django.contrib.auth import get_user_model
|
|
4
|
+
from django.test import override_settings
|
|
5
|
+
from pytest_data import use_data
|
|
6
|
+
|
|
7
|
+
from cms_qe_auth.tests.utils import reset_urls
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@override_settings(CMS_QE_AUTH_ENABLED=True)
|
|
11
|
+
@use_data(user_data={'username': 'testuser', 'password': 'testpass'})
|
|
12
|
+
def test_login(client, user):
|
|
13
|
+
reset_urls()
|
|
14
|
+
res = client.post('/en/auth/login/', {'username': 'testuser', 'password': 'testpass'})
|
|
15
|
+
assert res.status_code == 302
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@override_settings(CMS_QE_AUTH_ENABLED=True)
|
|
19
|
+
def test_register(mailoutbox, client):
|
|
20
|
+
assert len(mailoutbox) == 0
|
|
21
|
+
assert not get_user_model().objects.filter(username='testuser')
|
|
22
|
+
|
|
23
|
+
reset_urls()
|
|
24
|
+
user = _register_user(client)
|
|
25
|
+
|
|
26
|
+
assert user.email == 'testuser@example.com'
|
|
27
|
+
assert len(mailoutbox) == 1
|
|
28
|
+
activation_mail = mailoutbox[0]
|
|
29
|
+
assert 'activate' in activation_mail.body
|
|
30
|
+
assert 'http' in activation_mail.body
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@override_settings(AUTHENTICATION_BACKENDS=[
|
|
34
|
+
'django.contrib.auth.backends.ModelBackend',
|
|
35
|
+
'cms_qe_auth.tests.utils.TestAuthBackend',
|
|
36
|
+
], CMS_QE_AUTH_ENABLED=True)
|
|
37
|
+
def test_activation_multiple_authentication_backends(client, mailoutbox):
|
|
38
|
+
_test_activation(client, mailoutbox)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@override_settings(CMS_QE_AUTH_ENABLED=True)
|
|
42
|
+
def test_activation(client, mailoutbox):
|
|
43
|
+
_test_activation(client, mailoutbox)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _test_activation(client, mailoutbox):
|
|
47
|
+
reset_urls()
|
|
48
|
+
user = get_user_model()(username='testuser', email='testuser@example.com', is_active=False)
|
|
49
|
+
user.save(base_url="http://example.com")
|
|
50
|
+
|
|
51
|
+
# Get activation link from email
|
|
52
|
+
activation_mail = mailoutbox[0]
|
|
53
|
+
activate_url_pattern = r'(?P<url>https?://[^\s]+/activate/[^\s]+)'
|
|
54
|
+
url = re.search(activate_url_pattern, activation_mail.body).group('url')
|
|
55
|
+
|
|
56
|
+
response = client.get(url)
|
|
57
|
+
user.refresh_from_db()
|
|
58
|
+
|
|
59
|
+
assert user.is_active
|
|
60
|
+
# Test automatic login
|
|
61
|
+
assert response.context['user'].is_authenticated
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _register_user(client):
|
|
65
|
+
res = client.post('/en/auth/register/', {
|
|
66
|
+
'username': 'testuser',
|
|
67
|
+
'password1': '179ad45c6ce2cb97cf1029e212046e81',
|
|
68
|
+
'password2': '179ad45c6ce2cb97cf1029e212046e81',
|
|
69
|
+
'email': 'testuser@example.com',
|
|
70
|
+
})
|
|
71
|
+
assert res.status_code == 302
|
|
72
|
+
return get_user_model().objects.get(username='testuser')
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
from django.conf import settings
|
|
4
|
+
from django.contrib.auth import get_user_model
|
|
5
|
+
from django.contrib.auth.backends import ModelBackend
|
|
6
|
+
from django.urls import clear_url_caches
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestAuthBackend(ModelBackend):
|
|
10
|
+
def authenticate(self, username=None, password=None):
|
|
11
|
+
User = get_user_model()
|
|
12
|
+
try:
|
|
13
|
+
user = User.objects.get(username=username)
|
|
14
|
+
return user
|
|
15
|
+
except User.DoesNotExist:
|
|
16
|
+
return
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def reset_urls():
|
|
20
|
+
"""Reset Django site urls."""
|
|
21
|
+
del sys.modules[settings.ROOT_URLCONF]
|
|
22
|
+
clear_url_caches()
|
|
File without changes
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from constance.test import override_config
|
|
3
|
+
from django.conf import settings
|
|
4
|
+
from mailchimp3.mailchimpclient import MailChimpError
|
|
5
|
+
from pytest_data import use_data
|
|
6
|
+
|
|
7
|
+
from ..external_services.mailchimp import sync_mailing_lists, sync_subscribe, sync_unsubscribe
|
|
8
|
+
from ..models import MailingList
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@override_config(
|
|
12
|
+
MAILCHIMP_USERNAME=settings.TEST_MAILCHIMP_USERNAME,
|
|
13
|
+
MAILCHIMP_API_KEY=settings.TEST_MAILCHIMP_API_KEY,
|
|
14
|
+
)
|
|
15
|
+
def test_sync_mailing_lists_integrate():
|
|
16
|
+
with pytest.raises(MailChimpError) as exc_info:
|
|
17
|
+
_test_sync_mailing_lists()
|
|
18
|
+
assert exc_info.value.args[0]['title'] == 'API Key Invalid'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_sync_mailing_lists(mock_mailchimp):
|
|
22
|
+
_test_sync_mailing_lists()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _test_sync_mailing_lists():
|
|
26
|
+
assert MailingList.objects.count() == 0
|
|
27
|
+
sync_mailing_lists()
|
|
28
|
+
assert MailingList.objects.count() == 2
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@use_data(cms_qe_mailchimp_subscribe_data={'id': 'subid'})
|
|
32
|
+
def test_sync_subscribe(mock_mailchimp):
|
|
33
|
+
assert 'subid' == sync_subscribe('listid', 'test@example.com', 'first', 'last')
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_sync_unsubscribe(mock_mailchimp):
|
|
37
|
+
# No exception.
|
|
38
|
+
sync_unsubscribe('listid', 'test@example.com')
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from unittest import mock
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_not_set_mailchimp():
|
|
5
|
+
with mock.patch('cms_qe_newsletter.external_services.sync.sync_tasks', return_value=[
|
|
6
|
+
(True, 'ok'),
|
|
7
|
+
(None, 'warning'),
|
|
8
|
+
(False, 'error'),
|
|
9
|
+
]):
|
|
10
|
+
# Import here so mock works correctly.
|
|
11
|
+
from ..management.commands.cms_qe_newsletter_sync import Command
|
|
12
|
+
|
|
13
|
+
with mock.patch('cms_qe_newsletter.management.commands.cms_qe_newsletter_sync.logger') as log_mock:
|
|
14
|
+
command = Command()
|
|
15
|
+
command.handle()
|
|
16
|
+
assert log_mock.info.call_args_list == [
|
|
17
|
+
mock.call('Newsletter sync started...'),
|
|
18
|
+
mock.call('ok'),
|
|
19
|
+
mock.call('Newsletter sync finished...'),
|
|
20
|
+
]
|
|
21
|
+
assert log_mock.warning.call_args_list == [mock.call('warning')]
|
|
22
|
+
assert log_mock.error.call_args_list == [mock.call('error')]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from django.core.exceptions import ValidationError
|
|
3
|
+
from pytest_data import use_data
|
|
4
|
+
|
|
5
|
+
from ..models import SERVICE_MAILCHIMP, Subscriber, SubscribeTask
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_clean_newsletter_plugin(cms_qe_newsletter_plugin):
|
|
9
|
+
cms_qe_newsletter_plugin.fullname_show = False
|
|
10
|
+
cms_qe_newsletter_plugin.fullname_require = True
|
|
11
|
+
with pytest.raises(ValidationError):
|
|
12
|
+
cms_qe_newsletter_plugin.clean()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_validate_mailing_list(cms_qe_mailing_list):
|
|
16
|
+
cms_qe_mailing_list.external_service = SERVICE_MAILCHIMP
|
|
17
|
+
cms_qe_mailing_list.external_id = None
|
|
18
|
+
with pytest.raises(ValidationError):
|
|
19
|
+
cms_qe_mailing_list.clean()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_save_will_create_task(cms_qe_mailing_list):
|
|
23
|
+
sub = Subscriber(
|
|
24
|
+
mailing_list=cms_qe_mailing_list,
|
|
25
|
+
email='test@example.com',
|
|
26
|
+
)
|
|
27
|
+
assert SubscribeTask.objects.all().count() == 0
|
|
28
|
+
sub.save()
|
|
29
|
+
assert SubscribeTask.objects.all().count() == 1
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@use_data(cms_qe_subscriber_data={'external_id': 'test_id'})
|
|
33
|
+
def test_delete_will_create_task(cms_qe_subscriber):
|
|
34
|
+
assert SubscribeTask.objects.all().count() == 0
|
|
35
|
+
cms_qe_subscriber.delete()
|
|
36
|
+
assert SubscribeTask.objects.all().count() == 1
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@use_data(cms_qe_subscriber_data={'external_id': None})
|
|
40
|
+
def test_delete_will_remove_pending_task(cms_qe_subscriber):
|
|
41
|
+
assert SubscribeTask.objects.all().count() == 1
|
|
42
|
+
cms_qe_subscriber.delete()
|
|
43
|
+
assert SubscribeTask.objects.all().count() == 0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from cms_qe_test import render_plugin
|
|
2
|
+
|
|
3
|
+
from ..cms_plugins import NewsletterPlugin
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_render():
|
|
7
|
+
html = render_plugin(NewsletterPlugin)
|
|
8
|
+
assert '<form' in html
|
|
9
|
+
assert '<input' in html
|
|
10
|
+
assert 'email' in html
|
|
11
|
+
assert 'first' not in html
|
|
12
|
+
assert 'last' not in html
|
|
13
|
+
assert 'submit' in html
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_render_fullname_show():
|
|
17
|
+
html = render_plugin(NewsletterPlugin, fullname_show=True)
|
|
18
|
+
assert 'email' in html
|
|
19
|
+
assert 'first' in html
|
|
20
|
+
assert 'last' in html
|
|
21
|
+
assert 'submit' in html
|