Deduplicate campaign template rendering
This commit is contained in:
101
tests/test_template_rendering.py
Normal file
101
tests/test_template_rendering.py
Normal file
@@ -0,0 +1,101 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from govoplan_campaign.backend.campaign.models import CampaignConfig
|
||||
from govoplan_campaign.backend.attachments.resolver import resolve_entry_attachments
|
||||
from govoplan_campaign.backend.template_rendering import (
|
||||
find_unresolved_placeholders,
|
||||
normalize_template_key,
|
||||
render_template,
|
||||
)
|
||||
|
||||
|
||||
class CampaignTemplateRenderingTests(unittest.TestCase):
|
||||
def test_template_key_aliases_have_shared_normalization(self) -> None:
|
||||
cases = {
|
||||
" name ": "name",
|
||||
"fields.name": "name",
|
||||
"local.name": "local::name",
|
||||
"local:name": "local::name",
|
||||
"local::name": "local::name",
|
||||
"global.name": "global::name",
|
||||
"global:name": "global::name",
|
||||
"global::name": "global::name",
|
||||
}
|
||||
|
||||
for raw, expected in cases.items():
|
||||
with self.subTest(raw=raw):
|
||||
self.assertEqual(normalize_template_key(raw), expected)
|
||||
|
||||
def test_rendering_preserves_both_syntaxes_none_and_missing_values(self) -> None:
|
||||
values = {
|
||||
"name": "Ada",
|
||||
"local::reference": 42,
|
||||
"global::empty": None,
|
||||
}
|
||||
template = "${fields.name}|{{ local.reference }}|${global:empty}|${missing}|{{ global.absent }}"
|
||||
|
||||
self.assertEqual(
|
||||
render_template(template, values),
|
||||
"Ada|42||${missing}|{{ global.absent }}",
|
||||
)
|
||||
self.assertEqual(render_template(template, values, keep_missing=False), "Ada|42|||")
|
||||
|
||||
def test_rendering_unescapes_literal_dollar_placeholders(self) -> None:
|
||||
self.assertEqual(
|
||||
render_template(r"\${literal\}|${known}", {"known": "resolved"}, keep_missing=False),
|
||||
"${literal}|resolved",
|
||||
)
|
||||
|
||||
def test_unresolved_placeholders_are_normalized_and_deduplicated(self) -> None:
|
||||
unresolved = find_unresolved_placeholders(
|
||||
r"${fields.missing} {{ local:name }} ${global.other} {{local::name}} \${escaped\}"
|
||||
)
|
||||
|
||||
self.assertEqual(unresolved, {"missing", "local::name", "global::other"})
|
||||
self.assertEqual(find_unresolved_placeholders(None), set())
|
||||
|
||||
def test_attachment_resolution_keeps_missing_placeholders(self) -> None:
|
||||
config = CampaignConfig.model_validate(
|
||||
{
|
||||
"version": "1.0",
|
||||
"campaign": {"id": "template-parity", "name": "Template parity", "mode": "test"},
|
||||
"template": {"subject": "Subject", "text": "Body"},
|
||||
"attachments": {
|
||||
"base_path": ".",
|
||||
"global": [
|
||||
{
|
||||
"base_dir": ".",
|
||||
"file_filter": "${missing}.pdf",
|
||||
"required": False,
|
||||
"missing_behavior": "continue",
|
||||
}
|
||||
],
|
||||
},
|
||||
"entries": {
|
||||
"inline": [
|
||||
{
|
||||
"id": "recipient-1",
|
||||
"to": [{"email": "recipient@example.test", "type": "to"}],
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
resolution = resolve_entry_attachments(
|
||||
config=config,
|
||||
campaign_file=Path(temp_dir) / "campaign.json",
|
||||
entry=config.entries.inline[0], # type: ignore[index]
|
||||
entry_index=1,
|
||||
)
|
||||
|
||||
self.assertEqual(resolution.attachments[0].file_filter, "${missing}.pdf")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user