"""The shipped pre-baked case pool must be valid and fair: every file parses as a CaseFile, IDs are unique and stable, the solver passes, and each case reads well (human suspects with a gender mix, a real culprit). These cases are served instantly on New Case, so a broken one would reach players directly. """ from __future__ import annotations import re import pytest from case_zero.persistence.case_store import load_case from case_zero.persistence.paths import prebaked_cases_dir from case_zero.solver.checker import check _POOL = sorted(prebaked_cases_dir().glob("*.json")) if prebaked_cases_dir().is_dir() else [] _BAD_ROLE = re.compile( r"\b(detective|officer|investigator|police|inspector|sergeant|constable|cop|agent)\b", re.IGNORECASE, ) @pytest.mark.skipif(not _POOL, reason="no pre-baked pool present") def test_pool_ids_unique_and_stable() -> None: cases = [load_case(p) for p in _POOL] ids = [c.case_id for c in cases] assert len(set(ids)) == len(ids), "duplicate case IDs in the pool" # The stable scheme the player shares: CASE-0001, CASE-0002, ... for c, p in zip(cases, _POOL): assert c.case_id == p.stem, f"file {p.name} does not match its case_id {c.case_id}" @pytest.mark.skipif(not _POOL, reason="no pre-baked pool present") @pytest.mark.parametrize("path", _POOL, ids=lambda p: p.stem) def test_pool_case_is_solvable_and_well_formed(path) -> None: case = load_case(path) assert check(case).ok, f"{path.name} is not solvable" assert case.title and len(case.title.strip()) >= 4 assert case.victim.name.strip() names = [s.name.strip() for s in case.suspects] assert len(set(n.lower() for n in names)) == len(names), "duplicate suspect names" for s in case.suspects: assert not _BAD_ROLE.search(s.role), f"detective-like suspect role: {s.role}" assert not _BAD_ROLE.search(s.name), f"detective-like suspect name: {s.name}" assert any((s.visual.gender or "").lower().startswith("f") for s in case.suspects), ( "no female suspect in the cast" ) assert (case.culprit.method_narrative or "").strip(), "culprit has no method narrative"