"""Tests for content_loader.py: schema validation (fail loud on a malformed content/ file) and that the real glossary.yaml/pages.yaml load correctly. Ported from backend/tests/web/test_content_loader.py (repo-split Stage 4) -- content_loader.py itself moved here in Stage 3.""" import pytest import content_loader def _write(tmp_path, name, text): path = tmp_path / name path.write_text(text, encoding="utf-8") return str(path) # --- load_glossary: schema validation -------------------------------------- def test_load_glossary_rejects_non_mapping_top_level(tmp_path): path = _write(tmp_path, "g.yaml", "- just\n- a\n- list\n") with pytest.raises(ValueError, match="top-level mapping"): content_loader.load_glossary(path) def test_load_glossary_rejects_missing_terms_key(tmp_path): path = _write(tmp_path, "g.yaml", "not_terms: []\n") with pytest.raises(ValueError, match="non-empty list"): content_loader.load_glossary(path) def test_load_glossary_rejects_empty_terms(tmp_path): path = _write(tmp_path, "g.yaml", "terms: []\n") with pytest.raises(ValueError, match="non-empty list"): content_loader.load_glossary(path) def test_load_glossary_rejects_missing_required_field(tmp_path): path = _write(tmp_path, "g.yaml", """ terms: - slug: foo term: Foo short: A short definition. """) with pytest.raises(ValueError, match="foo.*body"): content_loader.load_glossary(path) def test_load_glossary_rejects_blank_required_field(tmp_path): path = _write(tmp_path, "g.yaml", """ terms: - slug: foo term: Foo short: "" body: Full body. """) with pytest.raises(ValueError, match="foo.*short"): content_loader.load_glossary(path) def test_load_glossary_rejects_duplicate_slug(tmp_path): path = _write(tmp_path, "g.yaml", """ terms: - slug: foo term: Foo short: s1 body: b1 - slug: foo term: Foo Again short: s2 body: b2 """) with pytest.raises(ValueError, match="duplicate slug"): content_loader.load_glossary(path) def test_load_glossary_accepts_well_formed_content(tmp_path): path = _write(tmp_path, "g.yaml", """ terms: - slug: foo term: Foo short: A short definition. body: A full body with markup. - slug: bar term: Bar short: Another short definition. body: Another full body. """) glossary = content_loader.load_glossary(path) assert list(glossary) == ["foo", "bar"] # file order preserved assert glossary["foo"] == { "term": "Foo", "short": "A short definition.", "body": "A full body with markup.", } # --- load_pages: schema validation ------------------------------------------ def test_load_pages_rejects_missing_pages_key(tmp_path): path = _write(tmp_path, "p.yaml", "not_pages: {}\n") with pytest.raises(ValueError, match="non-empty mapping"): content_loader.load_pages(path) def test_load_pages_rejects_missing_required_field(tmp_path): path = _write(tmp_path, "p.yaml", """ pages: about: title: About """) with pytest.raises(ValueError, match="about.*description"): content_loader.load_pages(path) def test_load_pages_accepts_well_formed_content(tmp_path): path = _write(tmp_path, "p.yaml", """ pages: about: title: About Us description: A description. """) pages = content_loader.load_pages(path) assert pages == {"about": {"title": "About Us", "description": "A description."}} # --- the real content/ files ------------------------------------------------ def test_real_glossary_loads_and_matches_the_rendered_site(): """The module-level GLOSSARY content.py loads at import IS content_loader's output — this just re-asserts the real file is well-formed and non-trivial, since a broken content/glossary.yaml would already have failed every other test at collection time (content.py loads it at import).""" glossary = content_loader.load_glossary() assert len(glossary) >= 8 assert "percentile" in glossary for slug, entry in glossary.items(): assert entry["term"] and entry["short"] and entry["body"], slug def test_real_pages_loads_the_four_static_pages(): pages = content_loader.load_pages() assert set(pages) == {"about", "privacy", "hub", "glossary_index"} for key, entry in pages.items(): assert entry["title"] and entry["description"], key