')) class NewsExtraction(unittest.TestCase): def setUp(self): slug = "proof-of-means-updated-2026" html = _read(f"en/news/{slug}/index.html") self.rec, self.err = mig.parse_page(html, "news", slug, "en") def test_parses(self): self.assertIsNone(self.err) def test_news_has_no_subtitle(self): # News pages have no .article-subtitle; the field must be omitted, not empty. self.assertNotIn("subtitle", self.rec) self.assertEqual(self.rec["type"], "news") def test_hero_present(self): self.assertIn("hero", self.rec) class EventExtraction(unittest.TestCase): def setUp(self): slug = "paint-and-wine-at-sunset" html = _read(f"en/projects/{slug}/index.html") self.rec, self.err = mig.parse_page(html, "projects", slug, "en") def test_type_and_folder_mapping(self): self.assertIsNone(self.err) self.assertEqual(self.rec["type"], "event") self.assertEqual(self.rec["source_folder"], "projects") # URL/date key unchanged def test_gallery_and_lightbox_preserved(self): body = self.rec["_body"] self.assertIn("event-gallery", body) # sibling section after .article-body self.assertIn("eg-thumb", body) # lightbox thumbnails self.assertIn("data-full", body) class CyrillicRoundTrip(unittest.TestCase): def test_mk_serialises_and_parses_without_mojibake(self): slug = "proof-of-means-updated-2026" html = _read(f"mk/news/{slug}/index.html") rec, err = mig.parse_page(html, "news", slug, "mk") self.assertIsNone(err) # Title is Macedonian Cyrillic. self.assertTrue(any("Ѐ" <= ch <= "ӿ" for ch in rec["title"])) text = mig.to_file_text(rec) meta, body = _split_front_matter(text) self.assertEqual(meta["title"], rec["title"]) # exact UTF-8 round-trip self.assertEqual(meta["lang"], "mk") self.assertTrue(body.strip()) class FrontMatterRoundTrip(unittest.TestCase): def test_metadata_survives_serialise_parse(self): slug = "how-to-open-slovenian-bank-account" html = _read(f"en/blog/{slug}/index.html") rec, _ = mig.parse_page(html, "blog", slug, "en") meta, _body = _split_front_matter(mig.to_file_text(rec)) for key in ("type", "slug", "lang", "source_folder", "title", "date", "body_format"): self.assertEqual(meta[key], rec[key], f"{key} changed across round-trip") class EveryPageParses(unittest.TestCase): def test_no_page_is_skipped(self): """Every current blog/news/event page must parse (a skip is a regression).""" en_cache = {} for lang, folder, slug, page in mig.iter_pages(): if lang == "en": with open(page, encoding="utf-8") as f: en_cache[(folder, slug)] = f.read() failures = [] for lang, folder, slug, page in mig.iter_pages(): with open(page, encoding="utf-8") as f: html = f.read() rec, err = mig.parse_page(html, folder, slug, lang, en_html=en_cache.get((folder, slug))) if rec is None: failures.append(f"{lang}/{folder}/{slug}: {err}") self.assertEqual(failures, [], f"unparseable pages: {failures}") if __name__ == "__main__": unittest.main(verbosity=2)