Skip to content

Commit

Permalink
Merge branch 'master' into enhancement/editable-search-filters
Browse files Browse the repository at this point in the history
  • Loading branch information
metroid-samus authored Jul 24, 2024
2 parents 834c737 + c1626bf commit 57ad086
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 11 deletions.
26 changes: 15 additions & 11 deletions src/dispatch/messaging/email/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,30 @@
from datetime import datetime

import markdown
from jinja2 import (
Environment,
FileSystemLoader,
)
from jinja2 import FileSystemLoader
from jinja2.sandbox import ImmutableSandboxedEnvironment
from markupsafe import Markup
from dispatch import config

here = os.path.dirname(os.path.realpath(__file__))


autoescape = bool(config.DISPATCH_ESCAPE_HTML)
env = Environment(loader=FileSystemLoader(here), autoescape=autoescape)
env = ImmutableSandboxedEnvironment(loader=FileSystemLoader(here), autoescape=autoescape)


def format_datetime(value):
return datetime.fromisoformat(value).strftime("%A, %B %d, %Y")
def safe_format_datetime(value):
try:
return datetime.fromisoformat(value).strftime("%A, %B %d, %Y")
except (ValueError, TypeError):
return ""


def format_markdown(value):
return Markup(markdown.markdown(value))
def safe_format_markdown(value):
if not isinstance(value, str):
return ""
return Markup(markdown.markdown(value, output_format="html5", extensions=["extra"]))


env.filters["datetime"] = format_datetime
env.filters["markdown"] = format_markdown
env.filters["datetime"] = safe_format_datetime
env.filters["markdown"] = safe_format_markdown
6 changes: 6 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
DefinitionFactory,
DispatchUserFactory,
DocumentFactory,
EmailTemplateFactory,
EntityFactory,
EntityTypeFactory,
EventFactory,
Expand Down Expand Up @@ -585,6 +586,11 @@ def incident_cost_types(session):
return [IncidentCostTypeFactory(), IncidentCostTypeFactory()]


@pytest.fixture
def email_template(session):
return EmailTemplateFactory()


@pytest.fixture
def notification(session):
return NotificationFactory()
Expand Down
18 changes: 18 additions & 0 deletions tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
from dispatch.conversation.models import Conversation
from dispatch.definition.models import Definition
from dispatch.document.models import Document
from dispatch.email_templates.models import EmailTemplates
from dispatch.email_templates.enums import EmailTemplateTypes
from dispatch.entity.models import Entity
from dispatch.entity_type.models import EntityType
from dispatch.event.models import Event
Expand Down Expand Up @@ -1216,6 +1218,22 @@ class Meta:
model = IncidentCostType


class EmailTemplateFactory(BaseFactory):
"""Email Template Factory."""

# Columns
email_template_type = EmailTemplateTypes.welcome
welcome_text = "Welcome to Incident {{title}} "
welcome_body = "{{title}} Incident\n{{description}}"
components = ["title", "description"]
enabled = True

class Meta:
"""Factory Configuration."""

model = EmailTemplates


class NotificationFactory(BaseFactory):
"""Notification Factory."""

Expand Down
81 changes: 81 additions & 0 deletions tests/messaging/test_messaging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
def test_render_message_template():
"""Tests the render_message_template function.
The message template should be filled with the kwargs values, and the datetime field should be properly formatted.
"""
from dispatch.messaging.email.utils import render_message_template
from datetime import datetime, UTC

message_template = [
{
"title": "{{title}}",
"text": "{{body}}",
"datetime": "{{datetime | datetime}}",
}
]
kwargs = {
"title": "Test Title",
"body": "Test Body",
"datetime": datetime.now(UTC).isoformat(),
}

rendered = render_message_template(message_template, **kwargs)

assert rendered
assert rendered[0].get("title") == kwargs.get("title")
assert rendered[0].get("text") == kwargs.get("body")
assert rendered[0].get("datetime")


def test_render_message_template__failed_filter():
"""Tests that render_message_template fails when the input does not adhere to the datetime filter rules."""
from dispatch.messaging.email.utils import render_message_template

message_template = [
{
"datetime": "{{datetime | datetime}}",
}
]
kwargs = {"datetime": "1234"}

rendered = render_message_template(message_template, **kwargs)

assert rendered
assert not rendered[0].get("datetime")


def test_render_message_template__disable_code_execution():
"""Tests that render_message_template does not execute scripts in user input."""
from dispatch.messaging.email.utils import render_message_template

message_template = [
{
"title": "{{ title }}",
"body": "{% for i in [].append(123) %}...{% endfor %}",
}
]
kwargs = {"title": "Test Title"}

rendered = render_message_template(message_template, **kwargs)

assert rendered
assert rendered[0].get("title") == kwargs.get("title")
assert rendered[0].get("body") == message_template[0].get("body")


def test_generate_welcome_message__default():
"""Tests the generate_welcome_message function."""
from dispatch.messaging.strings import generate_welcome_message

assert generate_welcome_message(None)


def test_generate_welcome_message__email_template(email_template):
"""Tests the generate_welcome_message function with an email template."""
from dispatch.messaging.strings import generate_welcome_message

welcome_message = generate_welcome_message(email_template)

assert welcome_message
assert welcome_message[0].get("title") == email_template.welcome_text
assert welcome_message[0].get("text") == email_template.welcome_body

0 comments on commit 57ad086

Please sign in to comment.