"""Tests for ScoreSheetAgent — the one-page FMS scoring sheet. No GPU/model downloads.""" import os from formscout.types import ReportResult def _report(composite=14, per_test=None, asymmetries=None): return ReportResult( per_test=per_test if per_test is not None else [], composite=composite, asymmetries=asymmetries or [], overlay_video_path=None, pdf_path=None, low_confidence_flags=[], disagreement_flags=[], ) def _pt(test_name, score, needs_human=False): return {"test_name": test_name, "score": score, "judge": None, "features": None, "needs_human": needs_human} def test_scoresheet_is_created(tmp_path): from formscout.agents.scoresheet import ScoreSheetAgent report = _report( composite=15, per_test=[ _pt("deep_squat", 2), _pt("hurdle_step", 2), _pt("trunk_stability_pushup", 3), ], asymmetries=[{"test": "hurdle_step", "left_score": 2, "right_score": 3, "delta": 1}], ) path = ScoreSheetAgent().run(report, str(tmp_path)) assert path is not None assert os.path.exists(path) assert os.path.getsize(path) > 1000 with open(path, "rb") as f: assert f.read(5) == b"%PDF-" def test_scoresheet_incomplete_composite(tmp_path): """A session with unscored/needs-human tests must still render.""" from formscout.agents.scoresheet import ScoreSheetAgent report = _report( composite=None, per_test=[_pt("deep_squat", None, needs_human=True)], ) path = ScoreSheetAgent().run(report, str(tmp_path)) assert path is not None and os.path.exists(path) def test_scoresheet_accepts_meta(tmp_path): """Optional athlete/meta fields are accepted without breaking rendering.""" from formscout.agents.scoresheet import ScoreSheetAgent path = ScoreSheetAgent().run( _report(14, per_test=[_pt("deep_squat", 2)]), str(tmp_path), meta={"name": "Test Athlete", "date": "2026-06-14"}, ) assert path is not None and os.path.exists(path)