Skip to content

Commit a40e749

Browse files
authored
Fix django backwards compatibility (#27)
* Bring back earlier django version compatibility (fixes #26) * Make tests work with tox & pytest
1 parent 8d365ed commit a40e749

File tree

10 files changed

+108
-79
lines changed

10 files changed

+108
-79
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ dist*
66
.eggs
77
Pipfile
88
Pipfile.lock
9+
.coverage
10+
.tox/

mail_panel/utils.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1-
from django.core.cache import cache, caches
1+
from django.core.cache import caches
2+
3+
try:
4+
CACHE_SETTINGS = caches.settings
5+
except AttributeError: # < Django 3.2
6+
from django.conf import settings
7+
8+
CACHE_SETTINGS = settings.CACHES
29

310
from .conf import MAIL_TOOLBAR_CACHE_KEY, MAIL_TOOLBAR_TTL
411

512
# Use local memory cache if default cache is a DummyCache
6-
if caches.settings.get('default', {}).get('BACKEND', '').endswith('.DummyCache'):
7-
caches.settings['mail_panel'] = {
8-
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
9-
'LOCATION': 'mail-panel',
13+
if not CACHE_SETTINGS.get("default", {}).get("BACKEND", "").endswith(".DummyCache"):
14+
from django.core.cache import cache
15+
else:
16+
CACHE_SETTINGS["mail_panel"] = {
17+
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
18+
"LOCATION": "mail-panel",
1019
}
11-
cache = caches.create_connection('mail_panel')
20+
cache = caches.create_connection("mail_panel")
1221

1322

1423
def load_outbox():
@@ -17,12 +26,14 @@ def load_outbox():
1726
"""
1827
return cache.get(MAIL_TOOLBAR_CACHE_KEY, {})
1928

29+
2030
def save_outbox(outbox):
2131
"""
2232
Saves the dictionary of cached mail and sets expiry.
2333
"""
2434
cache.set(MAIL_TOOLBAR_CACHE_KEY, outbox, MAIL_TOOLBAR_TTL)
25-
35+
36+
2637
def clear_outbox():
2738
"""
2839
Utility function to clear the dictionary of cached mail. Typical use case: Starting a new real-human test session.

pyproject.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,15 @@ bump2version = "^1.0.1"
4242
[build-system]
4343
requires = ["poetry-core>=1.0.0"]
4444
build-backend = "poetry.core.masonry.api"
45+
46+
[tool.pytest.ini_options]
47+
minversion = "6.0"
48+
testpaths = [
49+
"tests",
50+
]
51+
52+
[tool.coverage.run]
53+
source = [
54+
"tests",
55+
"mail_panel",
56+
]

tests/__init__.py

Whitespace-only changes.

tests/__main__.py

Lines changed: 0 additions & 4 deletions
This file was deleted.

tests/conf.py

Lines changed: 0 additions & 3 deletions
This file was deleted.

tests/context.py

Lines changed: 0 additions & 20 deletions
This file was deleted.

tests/settings.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1-
SECRET_KEY = 'test'
1+
SECRET_KEY = "test"
22
DEBUG = True
3-
ROOT_URLCONF = 'urls'
3+
ROOT_URLCONF = "urls"
4+
5+
INSTALLED_APPS = (
6+
"debug_toolbar",
7+
"mail_panel",
8+
)
9+
DEBUG_TOOLBAR_PANELS = [
10+
"mail_panel.panels.MailToolbarPanel",
11+
]

tests/test_toolbar.py

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,58 @@
11
import io
22
import pickle
3-
4-
from .context import *
5-
3+
import sys
64
import unittest
5+
76
import debug_toolbar
87
from debug_toolbar.toolbar import DebugToolbar
98
from django.core import mail
10-
from mail_panel.backend import MailToolbarBackendEmail, MailToolbarBackend
9+
from django.test.client import RequestFactory
10+
from mail_panel.backend import MailToolbarBackend, MailToolbarBackendEmail
1111
from mail_panel.panels import MailToolbarPanel
1212
from mail_panel.utils import clear_outbox
1313

14-
from django.test.client import RequestFactory
1514
rf = RequestFactory()
16-
get_request = rf.get('/hello/')
17-
post_request = rf.post('/submit/', {'foo': 'bar'})
15+
get_request = rf.get("/hello/")
16+
post_request = rf.post("/submit/", {"foo": "bar"})
1817

1918

2019
class ToolbarSuite(unittest.TestCase):
2120
def setUp(self):
2221
debug_toolbar_version = debug_toolbar.VERSION
2322

24-
self.request = rf.post('/submit/', {'foo': 'bar'})
23+
self.request = rf.post("/submit/", {"foo": "bar"})
2524

2625
# django-debug-toolbar 1.x take 1 argument, 2.x take 2 arguments
27-
if debug_toolbar_version < '2.0':
26+
if debug_toolbar_version < "2.0":
2827
self.toolbar = DebugToolbar(self.request)
29-
self.panel_args = (self.toolbar, )
28+
self.panel_args = (self.toolbar,)
3029
else:
3130
self.toolbar = DebugToolbar(self.request, None)
3231
self.panel_args = (self.toolbar, None)
3332

3433
@staticmethod
3534
def get_fake_message(
36-
subject=None,
37-
to=None,
38-
cc=None,
39-
bcc=None,
40-
reply_to=None,
41-
from_email=None,
42-
body=None,
43-
alternatives=None,
44-
headers=None,
35+
subject=None,
36+
to=None,
37+
cc=None,
38+
bcc=None,
39+
reply_to=None,
40+
from_email=None,
41+
body=None,
42+
alternatives=None,
43+
headers=None,
4544
):
4645
# TODO Use Faker (https://github.com/joke2k/faker)
4746
return mail.EmailMultiAlternatives(
48-
subject=subject or 'fake subject',
49-
to=to or ['[email protected]'],
50-
cc=cc or ['[email protected]'],
51-
bcc=bcc or ['[email protected]'],
52-
reply_to=reply_to or ['[email protected]'],
53-
from_email=from_email or '[email protected]',
54-
body=body or 'body',
55-
alternatives=alternatives or [('<b>HTML</b> body', 'text/html')],
56-
headers=headers or {'X-MyHeader': 'myheader'}
47+
subject=subject or "fake subject",
48+
to=to or ["[email protected]"],
49+
cc=cc or ["[email protected]"],
50+
bcc=bcc or ["[email protected]"],
51+
reply_to=reply_to or ["[email protected]"],
52+
from_email=from_email or "[email protected]",
53+
body=body or "body",
54+
alternatives=alternatives or [("<b>HTML</b> body", "text/html")],
55+
headers=headers or {"X-MyHeader": "myheader"},
5756
)
5857

5958
def test_panel(self):
@@ -73,7 +72,6 @@ def test_generate_stats(self):
7372
p.generate_stats(None, None)
7473
self.assertEqual(len(p.mail_list), 0)
7574

76-
7775
# Test inbox with one message
7876
fake_message = self.get_fake_message()
7977
backend = MailToolbarBackend()
@@ -82,8 +80,6 @@ def test_generate_stats(self):
8280
p.generate_stats(None, None)
8381
self.assertEqual(len(p.mail_list), 1)
8482

85-
86-
8783
def test_process_response(self):
8884
p = MailToolbarPanel(*self.panel_args)
8985
p.process_response(None, None)
@@ -119,7 +115,9 @@ def test_backend(self):
119115

120116
# Test with not serializable message
121117
fake_message = self.get_fake_message()
122-
fake_message.not_serializable_field = io.BufferedReader(io.StringIO(u'initial text data'))
118+
fake_message.not_serializable_field = io.BufferedReader(
119+
io.StringIO(u"initial text data")
120+
)
123121

124122
# BufferedReader is serializable in Python2
125123
if sys.version_info[0] >= 3:
@@ -128,14 +126,3 @@ def test_backend(self):
128126

129127
backend = MailToolbarBackend()
130128
backend.send_messages([fake_message])
131-
132-
133-
def suite():
134-
suite = unittest.TestSuite()
135-
suite.addTest(unittest.makeSuite(ToolbarSuite))
136-
return suite
137-
138-
139-
def main():
140-
unittest.TextTestRunner().run(suite())
141-

tox.ini

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
[tox]
2+
envlist =
3+
coverage_setup
4+
latest
5+
old
6+
coverage_report
7+
skip_missing_interpreters = True
8+
isolated_build = True
9+
10+
[testenv]
11+
setenv =
12+
DJANGO_SETTINGS_MODULE = tests.settings
13+
deps =
14+
pytest-django
15+
pytest-cov
16+
Django<3.3
17+
django-debug-toolbar
18+
old: Django==2.2.*
19+
old: django-debug-toolbar==1.11.1
20+
depends = coverage_setup
21+
commands = python -m pytest --cov --cov-append --cov-report=
22+
23+
[testenv:coverage_setup]
24+
skip_install = True
25+
depends =
26+
deps = coverage[toml]
27+
commands = coverage erase
28+
29+
[testenv:coverage_report]
30+
skip_install = True
31+
parallel_show_output = True
32+
deps = {[testenv:coverage_setup]deps}
33+
depends = latest,old
34+
commands =
35+
coverage report --include="tests/*" --fail-under=100 -m
36+
coverage report --omit="tests/*" --fail-under=50 -m

0 commit comments

Comments
 (0)