File size: 2,468 Bytes
414dc55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
"""Golden-case conformance + anti-leak for the PUBLIC wire view.

The PUBLIC case the client receives must (a) match the prototype shape and (b) never
carry the sealed solution or any per-question/per-evidence suspicion delta (the deltas
alone would reveal the killer).
"""

from __future__ import annotations

import json

import pytest

from case_zero.api.public_view import PublicCase, golden_to_public
from case_zero.persistence.golden import load_golden

GOLDEN_ID = "GRAYMOOR-3107"

# Quoted JSON keys (not bare substrings): "iris"/"kill" appear in public prose, the KEYS must not.
SEALED_KEY_TOKENS = ('"sealed"', '"killer"', '"correctMotive"', '"keyEvidence"', '"present"', '"default"')


@pytest.fixture(scope="module")
def public_dump() -> tuple[PublicCase, dict]:
    pub = golden_to_public(load_golden(GOLDEN_ID))
    return pub, pub.model_dump(by_alias=True)


def test_golden_loads_and_validates(public_dump: tuple[PublicCase, dict]) -> None:
    pub, _ = public_dump
    assert isinstance(pub, PublicCase)
    assert pub.id == GOLDEN_ID
    assert len(pub.suspects) == 4
    assert len(pub.evidence) == 6
    assert len(pub.motives) == 4
    assert len(pub.timeline) == 9
    assert pub.flashback.title


def test_camel_case_wire_keys(public_dump: tuple[PublicCase, dict]) -> None:
    _, d = public_dump
    assert "bootLines" in d
    s0 = d["suspects"][0]
    assert "baselineSuspicion" in s0
    assert "suggestedQuestions" in s0
    thread_ev = next(e for e in d["evidence"] if e["type"] == "PHONE")
    assert thread_ev["thread"][0]["from"] in ("me", "them")  # JS "from" alias preserved


def test_no_sealed_fields_leak(public_dump: tuple[PublicCase, dict]) -> None:
    _, d = public_dump
    blob = json.dumps(d)
    for token in SEALED_KEY_TOKENS:
        assert token not in blob, f"sealed token leaked into public view: {token}"


def test_suggested_questions_expose_only_text(public_dump: tuple[PublicCase, dict]) -> None:
    _, d = public_dump
    for s in d["suspects"]:
        for q in s["suggestedQuestions"]:
            assert set(q.keys()) == {"id", "q"}, "scripted answer/delta must not be exposed"


def test_no_suspicion_delta_survives(public_dump: tuple[PublicCase, dict]) -> None:
    # The sealed golden carries "d": <delta> on each scripted answer (Iris/keycard is +26).
    # No "d" key exists in the public model, so none must appear in the serialized output.
    _, d = public_dump
    assert '"d":' not in json.dumps(d)