Skip to content
Snippets Groups Projects
Verified Commit f144c517 authored by Andreas Ellewsen's avatar Andreas Ellewsen
Browse files

Introduce Email Templates model

Introduced to make editing of templates possible using the admin
interface. There are currently two types of templates, and there can
only be one instance of each type so that the system knows which
template to use in which situation.

Resolves: GREG-73
parent e7b064a1
No related branches found
No related tags found
1 merge request!132Greg 73 mail templates
from django.contrib import admin
from reversion.admin import VersionAdmin
from gregui.models import GregUserProfile
from gregui.models import EmailTemplate, GregUserProfile
class GregUserProfileAdmin(VersionAdmin):
pass
class EmailTemplateAdmin(VersionAdmin):
list_display = ["id", "template_key", "subject", "from_email"]
save_as = True
admin.site.register(GregUserProfile, GregUserProfileAdmin)
admin.site.register(EmailTemplate, EmailTemplateAdmin)
from typing import Union
from django.conf import settings
from django.template.loader import render_to_string
from django.template.context import Context
from django_q.tasks import async_task
from gregui.models import EmailTemplate
def registration_template(institution, sponsor) -> str:
keywords = {
"institution": institution,
"sponsor": sponsor,
"registration_link": "www.google.com",
}
return render_to_string("guest_registration.txt", keywords)
def prepare_arguments(
template: EmailTemplate, context: dict[str, str], mail_to: str
) -> dict[str, Union[str, list[str]]]:
"""Combine input to a dict ready for use as arguments ti django's send_mail"""
return {
"subject": template.get_subject(context),
"message": template.get_body(context),
"from_email": template.from_email or None,
"recipient_list": [mail_to],
}
def confirmation_template(guest) -> str:
keywords = {"guest": guest, "confirmation_link": "www.google.com"}
return render_to_string("sponsor_confirmation.txt", keywords)
def registration_template(
institution: str, sponsor: str, mail_to: str
) -> dict[str, Union[str, list[str]]]:
"""
Prepare email for registration
def send_registration_mail(mail_to, sponsor) -> str:
return async_task(
"django.core.mail.send_mail",
**{
"subject": "Subject",
"message": registration_template(settings.INSTANCE_NAME, sponsor),
"from_email": None,
"recipient_list": [mail_to],
Produces a complete set of arguments ready for use with django.core.mail.send_mail
when sending a registration email to the guest.
"""
template = EmailTemplate.objects.get(
template_key=EmailTemplate.EmailType.GUEST_REGISTRATION
)
context = Context(
{
"institution": institution,
"sponsor": sponsor,
"registration_link": "www.google.com",
}
)
return prepare_arguments(template, context, mail_to)
def send_confirmation_mail(mail_to, guest) -> str:
return async_task(
"django.core.mail.send_mail",
**{
"subject": "Subject",
"message": confirmation_template(guest),
"from_email": None,
"recipient_list": [mail_to],
}
def confirmation_template(guest: str, mail_to: str) -> dict[str, Union[str, list[str]]]:
"""
Prepare email for confirmation
Produces a complete set of arguments ready for use with django.core.mail.send_mail
when sending a confirmation email to the sponsor.
"""
template = EmailTemplate.objects.get(
template_key=EmailTemplate.EmailType.SPONSOR_CONFIRMATION
)
context = Context({"guest": guest, "confirmation_link": "www.google.com"})
return prepare_arguments(template, context, mail_to)
def send_registration_mail(mail_to: str, sponsor: str) -> str:
arguments = registration_template(settings.INSTANCE_NAME, sponsor, mail_to)
return async_task("django.core.mail.send_mail", **arguments)
def send_confirmation_mail(mail_to: str, guest: str) -> str:
arguments = confirmation_template(guest, mail_to)
return async_task("django.core.mail.send_mail", **arguments)
# Generated by Django 3.2.8 on 2021-11-02 12:49
import dirtyfields.dirtyfields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("gregui", "0001_initial"),
]
operations = [
migrations.CreateModel(
name="EmailTemplate",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created", models.DateTimeField(auto_now_add=True)),
("updated", models.DateTimeField(auto_now=True)),
(
"template_key",
models.CharField(
choices=[
("guest_registration", "Guest Registration"),
("sponsor_confirmation", "Sponsor Confirmation"),
],
max_length=64,
unique=True,
),
),
("subject", models.CharField(blank=True, max_length=255, null=True)),
("from_email", models.CharField(blank=True, max_length=255, null=True)),
("body", models.TextField(blank=True, null=True)),
],
options={
"abstract": False,
},
bases=(dirtyfields.dirtyfields.DirtyFieldsMixin, models.Model),
),
]
from django import template
from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy
......@@ -24,3 +25,34 @@ class GregUserProfile(BaseModel):
null=True,
)
userid_feide = models.CharField(gettext_lazy("userid-feide"), max_length=150)
class EmailTemplate(BaseModel):
"""
Stores templates for emails.
Only one template of each type is allowed. To introduce new ones, simply add a new
EmailType.
"""
class EmailType(models.TextChoices):
"""Types of Emails"""
GUEST_REGISTRATION = "guest_registration"
SPONSOR_CONFIRMATION = "sponsor_confirmation"
template_key = models.CharField(
max_length=64, choices=EmailType.choices, unique=True
)
subject = models.CharField(max_length=255, blank=True, null=True)
from_email = models.CharField(max_length=255, blank=True, null=True)
body = models.TextField(blank=True, null=True)
def get_rendered_template(self, tpl, context):
return template.Template(tpl).render(context)
def get_subject(self, context):
return self.get_rendered_template(self.subject, context)
def get_body(self, context):
return self.get_rendered_template(self.body, context)
......@@ -19,7 +19,7 @@ from greg.models import (
Sponsor,
)
from gregui.models import GregUserProfile
from gregui.models import EmailTemplate, GregUserProfile
# faker spams the logs with localisation warnings
# see https://github.com/joke2k/faker/issues/753
......@@ -256,3 +256,33 @@ def log_in(client):
return client
return _log_in
@pytest.fixture
def confirmation_template():
et = EmailTemplate.objects.create(
template_key=EmailTemplate.EmailType.SPONSOR_CONFIRMATION,
subject="confirmation subject",
body="""Dette er en automatisk generert melding fra gjesteregistreringstjenesten.
Din gjest, {{ guest }}, har fullført registrering, bekreft gjesten her: {{ confirmation_link }}
This message has been automatically generated by the guest registration system.
Your guest, {{ guest }}, has completed their registration, please confirm the guest here: {{ confirmation_link }}""",
)
return EmailTemplate.objects.get(id=et.id)
@pytest.fixture
def registration_template():
et = EmailTemplate.objects.create(
template_key=EmailTemplate.EmailType.GUEST_REGISTRATION,
subject="registration subject",
body="""Dette er en automatisk generert melding fra gjesteregistreringstjenesten.
Du har blitt registrert som gjest på {{ institution }} av {{ sponsor }}.
For å fullføre registreringen av gjestekontoen følg denne lenken: {{ registration_link }}
This message has been automatically generated by the guest registration system.
You have been registered as a guest at {{ institution }} by {{ sponsor }}.
To complete the registration of your guest account, please follow this link: {{ registration_link }}""",
)
return EmailTemplate.objects.get(id=et.id)
......@@ -6,33 +6,43 @@ from gregui import mailutils
@pytest.mark.django_db
def test_registration_template():
prefilled_template = """Dette er en automatisk generert melding fra gjesteregistreringstjenesten.
def test_registration_template(registration_template):
prefilled_template = {
"from_email": None,
"recipient_list": ["test@example.com"],
"subject": "registration subject",
"message": """Dette er en automatisk generert melding fra gjesteregistreringstjenesten.
Du har blitt registrert som gjest på InstanceName av Foo Bar.
For å fullføre registreringen av gjestekontoen følg denne lenken: www.google.com
This message has been automatically generated by the guest registration system.
You have been registered as a guest at InstanceName by Foo Bar.
To complete the registration of your guest account, please follow this link: www.google.com
"""
rendered_template = mailutils.registration_template("InstanceName", "Foo Bar")
To complete the registration of your guest account, please follow this link: www.google.com""",
}
rendered_template = mailutils.registration_template(
"InstanceName", "Foo Bar", "test@example.com"
)
assert rendered_template == prefilled_template
@pytest.mark.django_db
def test_confirmation_template():
prefilled_template = """Dette er en automatisk generert melding fra gjesteregistreringstjenesten.
def test_confirmation_template(confirmation_template):
prefilled_template = {
"from_email": None,
"recipient_list": ["test@example.com"],
"subject": "confirmation subject",
"message": """Dette er en automatisk generert melding fra gjesteregistreringstjenesten.
Din gjest, Foo Bar, har fullført registrering, bekreft gjesten her: www.google.com
This message has been automatically generated by the guest registration system.
Your guest, Foo Bar, has completed their registration, please confirm the guest here: www.google.com
"""
rendered_template = mailutils.confirmation_template("Foo Bar")
Your guest, Foo Bar, has completed their registration, please confirm the guest here: www.google.com""",
}
rendered_template = mailutils.confirmation_template("Foo Bar", "test@example.com")
assert rendered_template == prefilled_template
@pytest.mark.django_db
def test_registration_mail():
def test_registration_mail(registration_template):
mail.outbox = []
task_id = mailutils.send_registration_mail("test@example.no", "Foo")
assert result(task_id) == 1
......@@ -41,7 +51,7 @@ def test_registration_mail():
@pytest.mark.django_db
def test_confirmation_mail():
def test_confirmation_mail(confirmation_template):
mail.outbox = []
task_id = mailutils.send_confirmation_mail("test@example.no", "Foo")
assert result(task_id) == 1
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment