"""SLICE-1 unit tests — sidecar metadata: dual-read, unknown-key preservation, frontmatter stripping, malformed detection. Pure functions only (no DB / no Gitea). Per docs/design/2026-06-06-configurable-collection-metadata.md §7.2 (SLICE-1) and INV-6 (dual-read), INV-7 (unknown keys ride along), INV-2 (clean body). """ from __future__ import annotations import yaml from app import entry as entry_mod from app import metadata LEGACY_MD = """--- slug: view-metrics title: View today's metrics state: active owners: - ben.stull tags: - dashboard - analytics priority: P1 owner: hasan --- This is the prose body. Second paragraph. """ # ---- INV-7: unknown keys ride along ---- def test_parse_preserves_unknown_keys_in_extra(): e = entry_mod.parse(LEGACY_MD) assert e.extra == {"priority": "P1", "owner": "hasan"} def test_serialize_round_trip_preserves_unknown_keys(): e = entry_mod.parse(LEGACY_MD) text = entry_mod.serialize(e) e2 = entry_mod.parse(text) assert e2.extra == {"priority": "P1", "owner": "hasan"} assert e2.tags == ["dashboard", "analytics"] assert e2.owners == ["ben.stull"] def test_known_keys_never_leak_into_extra(): e = entry_mod.parse(LEGACY_MD) for known in ("slug", "title", "state", "owners", "tags"): assert known not in e.extra # ---- metadata_dict / sidecar_yaml ---- def test_metadata_dict_merges_known_and_extra(): e = entry_mod.parse(LEGACY_MD) d = metadata.metadata_dict(e) assert d["slug"] == "view-metrics" assert d["title"] == "View today's metrics" assert d["state"] == "active" assert d["tags"] == ["dashboard", "analytics"] # forward-compat keys present assert d["priority"] == "P1" assert d["owner"] == "hasan" def test_sidecar_yaml_is_parseable_and_has_no_frontmatter_fences(): e = entry_mod.parse(LEGACY_MD) sc = metadata.sidecar_yaml(e) assert "---" not in sc.splitlines()[0] loaded = yaml.safe_load(sc) assert loaded["slug"] == "view-metrics" assert loaded["priority"] == "P1" # ---- strip_frontmatter (INV-2) ---- def test_strip_frontmatter_removes_leading_block(): body = metadata.strip_frontmatter(LEGACY_MD) assert body.startswith("This is the prose body.") assert "slug:" not in body assert "priority:" not in body def test_strip_frontmatter_passthrough_when_no_frontmatter(): plain = "Just a body.\n\nNo frontmatter here.\n" assert metadata.strip_frontmatter(plain).strip() == plain.strip() # ---- parse_sidecar (malformed detection, INV-3) ---- def test_parse_sidecar_good(): values, malformed = metadata.parse_sidecar("slug: a\ntitle: A\npriority: P0\n") assert malformed is False assert values == {"slug": "a", "title": "A", "priority": "P0"} def test_parse_sidecar_non_mapping_is_malformed(): values, malformed = metadata.parse_sidecar("- just\n- a\n- list\n") assert malformed is True assert values == {} def test_parse_sidecar_invalid_yaml_is_malformed(): values, malformed = metadata.parse_sidecar("slug: : : not yaml\n bad: [unclosed\n") assert malformed is True assert values == {} def test_parse_sidecar_empty_is_empty_not_malformed(): values, malformed = metadata.parse_sidecar("") assert malformed is False assert values == {} # ---- read_entry dual-read equivalence (INV-6) ---- def test_dual_read_sidecar_matches_legacy(): legacy_entry, legacy_bad = metadata.read_entry(LEGACY_MD, None) # The migrated form: body-only .md + a sidecar holding the metadata. migrated_md = metadata.strip_frontmatter(LEGACY_MD) sidecar_text = metadata.sidecar_yaml(legacy_entry) sidecar_entry, sidecar_bad = metadata.read_entry(migrated_md, sidecar_text) assert legacy_bad is False assert sidecar_bad is False # Identical resulting records (INV-6). assert sidecar_entry.slug == legacy_entry.slug assert sidecar_entry.title == legacy_entry.title assert sidecar_entry.state == legacy_entry.state assert sidecar_entry.owners == legacy_entry.owners assert sidecar_entry.tags == legacy_entry.tags assert sidecar_entry.extra == legacy_entry.extra assert sidecar_entry.body.strip() == legacy_entry.body.strip() def test_read_entry_sidecar_takes_precedence_over_md_frontmatter(): # A not-yet-migrated .md still carrying frontmatter, plus a sidecar that # disagrees: the sidecar wins for metadata; the body comes from the .md. md_with_fm = "---\nslug: old\ntitle: Old Title\nstate: super-draft\n---\n\nBody.\n" sidecar = "slug: new\ntitle: New Title\nstate: active\n" e, malformed = metadata.read_entry(md_with_fm, sidecar) assert malformed is False assert e.title == "New Title" assert e.state == "active" assert e.body.strip() == "Body." def test_read_entry_malformed_sidecar_still_loads_entry(): # INV-3: a malformed sidecar never hard-fails the read. The entry loads # (from the .md frontmatter if present) and is flagged malformed. md = "---\nslug: x\ntitle: X\nstate: active\n---\n\nBody.\n" e, malformed = metadata.read_entry(md, "- not a mapping\n") assert malformed is True assert e.slug == "x" assert e.title == "X" assert e.body.strip() == "Body." # ---- dual-read robustness: degenerate sidecars never drop the entry ---- def test_empty_sidecar_falls_back_to_md_frontmatter(): # An empty sidecar has no metadata to override with — keep the .md's. md = "---\nslug: keep\ntitle: Keep Me\nstate: active\n---\n\nBody.\n" e, malformed = metadata.read_entry(md, "", fallback_slug="keep") assert malformed is False assert e.slug == "keep" assert e.title == "Keep Me" def test_malformed_sidecar_on_body_only_md_loads_with_fallback_slug(): # The .md is already body-only (migrated) and the sidecar is corrupt: # the entry must still load (INV-3), taking its slug from the filename stem. e, malformed = metadata.read_entry("Just a body.\n", "- a\n- list\n", fallback_slug="foo") assert malformed is True assert e.slug == "foo" def test_slugless_sidecar_uses_fallback_slug(): md = "Body only.\n" sidecar = "title: No Slug Here\nstate: active\n" e, malformed = metadata.read_entry(md, sidecar, fallback_slug="bar") assert malformed is False assert e.slug == "bar" assert e.title == "No Slug Here" # ---- sidecar filename helpers ---- def test_sidecar_filename_helpers(): assert metadata.sidecar_name("view-metrics") == "view-metrics.meta.yaml" assert metadata.is_sidecar("view-metrics.meta.yaml") is True assert metadata.is_sidecar("view-metrics.md") is False assert metadata.slug_of_sidecar("view-metrics.meta.yaml") == "view-metrics" # ---- SLICE-4: sidecar_path_for + apply_values ---- def test_sidecar_path_for_derives_sibling(): assert metadata.sidecar_path_for("rfcs/alpha.md") == "rfcs/alpha.meta.yaml" assert metadata.sidecar_path_for("x/y/beta.md") == "x/y/beta.meta.yaml" def test_apply_values_updates_known_and_extra_fields(): e = entry_mod.parse(LEGACY_MD) # has tags + extra priority/owner e2 = metadata.apply_values(e, {"tags": ["x"], "priority": "P0", "owner": "sam"}) assert e2.tags == ["x"] assert e2.extra["priority"] == "P0" assert e2.extra["owner"] == "sam" # body preserved unchanged assert e2.body == e.body def test_apply_values_preserves_unspecified_keys(): e = entry_mod.parse(LEGACY_MD) e2 = metadata.apply_values(e, {"priority": "P0"}) assert e2.tags == e.tags # untouched assert e2.extra["owner"] == "hasan" # untouched