102 lines
3.6 KiB
Python
102 lines
3.6 KiB
Python
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()
|