Coverage for app/backend/src/tests/test_dump_emails.py: 100%

31 statements  

« prev     ^ index     » next       coverage.py v7.17.0, created at 2026-10-24 18:38 +0000

1""" 

2Renders sample emails for visual inspection. 

3 

4Output is written to test_artifacts/emails/ (gitignored) and picked up by CI, which 

5publishes the browsable index.html to the preview environment. 

6""" 

7 

8import base64 

9import gzip 

10import json 

11import re 

12from pathlib import Path 

13 

14from couchers.email.dump_emails import dump_all 

15 

16PAYLOADS_RE = re.compile(r"^const PAYLOADS = (.*);$", re.MULTILINE) 

17 

18 

19def read_payloads(index_html: str) -> dict[str, dict[str, dict[str, str]]]: 

20 """Unpacks the inlined bodies back out of the index, undoing the embed() escaping.""" 

21 match = PAYLOADS_RE.search(index_html) 

22 assert match, "index.html has no inlined payloads" 

23 encoded = json.loads(match.group(1).replace("<\\/", "</")) 

24 return {locale: json.loads(gzip.decompress(base64.b64decode(blob))) for locale, blob in encoded.items()} 

25 

26 

27def test_dump_email_samples(): 

28 output_path = Path(__file__).resolve().parents[2] / "test_artifacts" / "emails" 

29 rendered = dump_all(output_path) 

30 

31 assert rendered 

32 assert (output_path / "attachment_imgs" / "logo-with-couchers.org-small.png").exists() 

33 

34 payloads = read_payloads((output_path / "index.html").read_text(encoding="utf-8")) 

35 assert payloads 

36 for locale, bodies in payloads.items(): 

37 for variation in rendered: 

38 assert variation.subjects[locale] 

39 assert bodies[variation.name]["html"] 

40 assert bodies[variation.name]["txt"] 

41 

42 

43def test_dump_email_index_is_self_contained(tmp_path): 

44 rendered = dump_all(tmp_path, locales=["de", "en"]) 

45 

46 assert sorted(path.name for path in tmp_path.iterdir()) == ["attachment_imgs", "index.html"] 

47 

48 payloads = read_payloads((tmp_path / "index.html").read_text(encoding="utf-8")) 

49 assert sorted(payloads) == ["de", "en"] 

50 for bodies in payloads.values(): 

51 assert sorted(bodies) == sorted(variation.name for variation in rendered)