← back to Unclaimed Property Platform
tests/test_cycle11_reconciliation.py
75 lines
"""Cycle 10 test — feed-completeness reconciliation (catches silent truncation).
Run: python -m tests.test_cycle11_reconciliation
The sample feed has 8 rows (7 accepted + 1 rejected empty-owner) => 8 records PARSED.
Reconciliation compares parsed vs the state-declared control total:
1. expected == parsed -> 'ok'
2. expected > parsed -> 'short' (SILENT-TRUNCATION signal + missing delta)
3. expected < parsed -> 'over'
4. no expected declared -> 'unknown' (not flagged)
and the result is persisted on the batch (queryable).
"""
from __future__ import annotations
import sys
import tempfile
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from services.common.sqlite_repo import FileObjectStore, SqliteRepository
from services.ingestion.ingest import FeedDefinition, ingest_authorized_feed
SAMPLE = Path(__file__).resolve().parents[1] / "data" / "sample" / "sample_state_feed.csv"
def ok(msg: str) -> None:
print(f" ✓ {msg}")
def _ingest(tmp: Path, sub: str, expected):
store = FileObjectStore(tmp / sub)
(tmp / sub).mkdir(parents=True, exist_ok=True)
store.write_bytes("incoming/s.csv", SAMPLE.read_bytes())
repo = SqliteRepository(str(tmp / sub / "p.db"))
feed = FeedDefinition("SAMPLE", "incoming/s.csv", expected_count=expected)
return repo, ingest_authorized_feed(feed, store, repo)
def main() -> int:
tmp = Path(tempfile.mkdtemp(prefix="upp-cycle11-"))
print("0) baseline parse counts")
repo, r = _ingest(tmp, "ok", expected=8)
assert r["accepted"] == 7 and r["rejected"] == 1, r
ok("8 parsed (7 accepted + 1 rejected)")
print("1) expected == parsed -> ok")
assert r["reconciliation"] == "ok" and r["reconciliation_delta"] == 0, r
stored = repo.batch_reconciliation(r["batch_id"])
assert stored["reconciliation"] == "ok" and stored["expected_count"] == 8, stored
ok("reconciliation 'ok' (persisted on batch)")
print("2) expected > parsed -> short (silent-truncation signal)")
_, r2 = _ingest(tmp, "short", expected=10)
assert r2["reconciliation"] == "short" and r2["reconciliation_delta"] == 2, r2
ok(f"expected 10, parsed 8 -> 'short', missing {r2['reconciliation_delta']} (would alert)")
print("3) expected < parsed -> over")
_, r3 = _ingest(tmp, "over", expected=5)
assert r3["reconciliation"] == "over" and r3["reconciliation_delta"] == 3, r3
ok("expected 5, parsed 8 -> 'over' (delta 3)")
print("4) no control total -> unknown (not flagged)")
_, r4 = _ingest(tmp, "unknown", expected=None)
assert r4["reconciliation"] == "unknown", r4
ok("no expected_count -> 'unknown'")
print("\nALL CYCLE-10 RECONCILIATION ASSERTIONS PASSED ✅")
return 0
if __name__ == "__main__":
raise SystemExit(main())