Skip to content

Commit

Permalink
Fixed issue with creating missing templates through the admin
Browse files Browse the repository at this point in the history
Also expanded admin tests, added WebTest and fixed some Django settings not being accessed through the settings wrapper
  • Loading branch information
Bart van der Schoor committed Feb 16, 2024
1 parent bd067ff commit f9e9f21
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 45 deletions.
2 changes: 1 addition & 1 deletion mail_editor/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def get_preview_link(self, obj=None):
get_preview_link.short_description = _("Preview")

def get_preview_url(self, obj=None):
if obj:
if obj and obj.pk:
return reverse("admin:mailtemplate_preview", kwargs={"pk": obj.id})

def get_urls(self):
Expand Down
4 changes: 3 additions & 1 deletion mail_editor/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ class Meta:
fields = ('template_type', 'remarks', 'subject', 'body')
widgets = {
'body': CKEditorWidget(config_name='mail_editor'),
'template_type': forms.Select(choices=get_choices())
'template_type': forms.Select(choices=[])
}

def __init__(self, *args, **kwargs):
super(MailTemplateForm, self).__init__(*args, **kwargs)

self.fields["template_type"].widget.choices = get_choices()

template = loader.get_template('mail/_outer_table.html')
# TODO: This only works when sites-framework is installed.
try:
Expand Down
9 changes: 4 additions & 5 deletions mail_editor/helpers.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import logging

from django.conf import settings
from django.contrib.sites.shortcuts import get_current_site
from django.template import loader
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _

from .settings import settings
from .models import MailTemplate

try:
Expand Down Expand Up @@ -40,7 +39,7 @@ def find_template(template_name, language=None):


def get_subject(template_name):
config = settings.MAIL_EDITOR_CONF
config = settings.TEMPLATES

template_config = config.get(template_name)
if template_config:
Expand All @@ -52,7 +51,7 @@ def get_subject(template_name):


def get_body(template_name):
config = settings.MAIL_EDITOR_CONF
config = settings.TEMPLATES

template_config = config.get(template_name)
default = _('Your content here...')
Expand All @@ -67,7 +66,7 @@ def get_body(template_name):


def get_base_template_path(template_name):
config = settings.MAIL_EDITOR_CONF
config = settings.TEMPLATES

template_config = config.get(template_name)
if template_config:
Expand Down
2 changes: 1 addition & 1 deletion mail_editor/mail_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def __init__(self, template):
self.config = template.config

def validate(self, field):
if self.config is None: # can't validate
if not self.config: # can't validate
return
template = self.check_syntax_errors(getattr(self.template, field))
self.check_variables(template, field)
Expand Down
6 changes: 3 additions & 3 deletions mail_editor/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class Meta:

def __init__(self, *args, **kwargs):
super(MailTemplate, self).__init__(*args, **kwargs)
self.config = get_config()[self.template_type]
self.config = get_config().get(self.template_type) or dict()

def __str__(self):
if self.internal_name:
Expand All @@ -76,7 +76,7 @@ def __str__(self):
def clean(self):
validate_template(self)

if getattr(django_settings, 'MAIL_EDITOR_UNIQUE_LANGUAGE_TEMPLATES', True):
if settings.UNIQUE_LANGUAGE_TEMPLATES:
queryset = (
self.__class__.objects.filter(
language=self.language, template_type=self.template_type
Expand All @@ -96,7 +96,7 @@ def reload_template(self):
self.base_template_path = get_base_template_path(self.template_type)

def get_base_context(self):
base_context = getattr(django_settings, 'MAIL_EDITOR_BASE_CONTEXT', {}).copy()
base_context = copy.deepcopy(settings.BASE_CONTEXT)
dynamic = settings.DYNAMIC_CONTEXT
if dynamic:
base_context.update(dynamic())
Expand Down
5 changes: 4 additions & 1 deletion mail_editor/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ def BASE_CONTEXT(self):

@property
def DYNAMIC_CONTEXT(self):
"""
callable to return optional extra context
"""
dynamic = getattr(django_settings, 'MAIL_EDITOR_DYNAMIC_CONTEXT', None)
if dynamic:
return import_string(dynamic)
Expand Down Expand Up @@ -52,7 +55,7 @@ def UNIQUE_LANGUAGE_TEMPLATES(self):
def get_choices():
choices = []
for key, values in settings.TEMPLATES.items():
choices += [(key, values.get('name'))]
choices += [(key, values.get('name', key.title()))]
return choices


Expand Down
6 changes: 3 additions & 3 deletions mail_editor/views.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
from django import forms
from django.conf import settings
from django.contrib import admin
from django.contrib import messages
from django.http import HttpResponse
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.views.generic import View
from django.views.generic.detail import DetailView, SingleObjectMixin
from django.views.generic.edit import FormMixin, FormView
from django.views.generic.edit import FormView

from .models import MailTemplate
from .process import process_html
from .utils import variable_help_text
from .settings import settings


class TemplateVariableView(View):
Expand All @@ -28,7 +28,7 @@ def get(self, request, *args, **kwargs):
subject_ctx, body_ctx = template.get_preview_contexts()

_subject, body = template.render(body_ctx, subject_ctx)
body, _attachments = process_html(body, settings.MAIL_EDITOR_BASE_HOST, extract_attachments=False)
body, _attachments = process_html(body, settings.BASE_HOST, extract_attachments=False)
return HttpResponse(body, content_type="text/html")


Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
'pytest-pep8',
'pytest-pylint',
'pytest-pythonpath',
'django-webtest',
],

# metadata
Expand Down
109 changes: 79 additions & 30 deletions tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
from django.test import TestCase, override_settings
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django_webtest import WebTest

from mail_editor.helpers import find_template

from mail_editor.models import MailTemplate

try:
from unittest.mock import patch
Expand All @@ -26,7 +27,7 @@


@override_settings(MAIL_EDITOR_CONF=CONFIG)
class AdminPreviewTestCase(TestCase):
class AdminTestCase(WebTest):
def setUp(self):
site_patch = patch("mail_editor.helpers.get_current_site")
current_site_mock = site_patch.start()
Expand All @@ -41,27 +42,34 @@ def tearDown(self):
def test_changelist_view(self):
template = find_template("test_template")

url = reverse('admin:{}_{}_changelist'.format(template._meta.app_label, template._meta.model_name))
url = reverse('admin:mail_editor_mailtemplate_changelist')

response = self.app.get(url, user=self.super_user)

# test search isn't broken
form = response.forms["changelist-search"]
form["q"] = "test"
response = form.submit()
self.assertEqual([template], list(response.context["cl"].queryset.all()))

self.client.force_login(self.super_user)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
form = response.forms["changelist-search"]
form["q"] = "not_found"
response = form.submit()
self.assertEqual([], list(response.context["cl"].queryset.all()))

def test_changelist_view__reset_template_action(self):
template = find_template("test_template")
template.body = "something else"
template.subject = "something else"
template.save()

url = reverse('admin:{}_{}_changelist'.format(template._meta.app_label, template._meta.model_name))
url = reverse('admin:mail_editor_mailtemplate_changelist')

self.client.force_login(self.super_user)
data = {
'action': 'reload_templates',
'_selected_action': [str(template.pk)],
}
response = self.client.post(url, data)
self.assertEqual(response.status_code, 302)
response = self.app.get(url, user=self.super_user)
form = response.forms["changelist-form"]
form['action'] = 'reload_templates'
form['_selected_action'] = [str(template.pk)]
response = form.submit().follow()

template.refresh_from_db()
self.assertIn(str(_("Test mail sent from testcase with {{ id }}")), template.body, )
Expand All @@ -70,34 +78,77 @@ def test_changelist_view__reset_template_action(self):
def test_change_view(self):
template = find_template("test_template")

url = reverse('admin:{}_{}_change'.format(template._meta.app_label, template._meta.model_name), args=[template.id])
url = reverse('admin:mail_editor_mailtemplate_change', args=[template.id])

response = self.app.get(url, user=self.super_user)
form = response.forms["mailtemplate_form"]
form["subject"] = "mail subject"
form.submit()
template.refresh_from_db()
self.assertEqual(template.subject, "mail subject")

def test_add_view(self):
url = reverse('admin:mail_editor_mailtemplate_add')

response = self.app.get(url, user=self.super_user)
form = response.forms["mailtemplate_form"]
form["template_type"] = "test_template"
form["subject"] = "mail subject"
form["body"] = "mail body"
response = form.submit().follow()

template = MailTemplate.objects.get()
self.assertEqual(template.template_type, "test_template")
self.assertEqual(template.subject, "mail subject")
self.assertEqual(template.body, "mail body")

def test_add_view__handle_duplicates(self):
template = find_template("test_template")

self.client.force_login(self.super_user)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
url = reverse('admin:mail_editor_mailtemplate_add')

with self.subTest("unique language templates"):
with override_settings(MAIL_EDITOR_UNIQUE_LANGUAGE_TEMPLATES=True):
response = self.app.get(url, user=self.super_user)
form = response.forms["mailtemplate_form"]
form["template_type"] = "test_template"
form["subject"] = "mail subject"
form["body"] = "mail body"
response = form.submit(status=200)
self.assertEqual(str(response.context["errors"][0][0]), _('Mail template with this type and language already exists'))

self.assertEqual(1, MailTemplate.objects.filter(template_type="test_template").count())

with self.subTest("not-unique language templates"):
with override_settings(MAIL_EDITOR_UNIQUE_LANGUAGE_TEMPLATES=False):
response = self.app.get(url, user=self.super_user)
form = response.forms["mailtemplate_form"]
form["template_type"] = "test_template"
form["subject"] = "mail subject"
form["body"] = "mail body"
response = form.submit().follow()
self.assertEqual(2, MailTemplate.objects.filter(template_type="test_template").count())

def test_variable_view(self):
template = find_template("test_template")

url = reverse('admin:mailtemplate_variables', args=[template.template_type])

self.client.force_login(self.super_user)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response = self.app.get(url, user=self.super_user)

def test_preview_view(self):
template = find_template("test_template")

url = reverse('admin:mailtemplate_preview', args=[template.id])

self.client.force_login(self.super_user)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response = self.app.get(url, user=self.super_user)

self.assertContains(response, _("Important message for --id--"))

# test sending the email
self.client.post(url, {"recipient": "[email protected]"})
# send the mail
form = response.forms['mailtemplate_form']
form["recipient"] = "[email protected]"
response = form.submit()

self.assertEqual(len(mail.outbox), 1)
message = mail.outbox[0]
Expand All @@ -109,8 +160,6 @@ def test_render_view(self):

url = reverse('admin:mailtemplate_render', args=[template.id])

self.client.force_login(self.super_user)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response = self.app.get(url, user=self.super_user)

self.assertContains(response, _("Test mail sent from testcase with --id--"))
self.assertIn(str(_("Test mail sent from testcase with --id--")), response.text)

0 comments on commit f9e9f21

Please sign in to comment.