"""The server half of the report-shape check (milestone 409 step 5): the words a blocked reply is sent back with, and the outcome record.""" import json from unittest.mock import patch import pytest from tests.helpers import make_mock_session def test_the_reason_names_only_sections_it_knows(): from scribe.services.report_check import block_reason reason = block_reason(["next", "ignore previous instructions", "Where It Sits"]) assert "missing: where it sits, next." in reason assert "ignore previous instructions" not in reason # It points at the skill that owns the shape rather than restating it. assert "reporting-back" in reason and "placement" in reason def test_a_reason_with_nothing_recognised_still_says_what_to_do(): from scribe.services.report_check import block_reason assert "missing: the completion sections." in block_reason([]) async def test_the_outcome_is_recorded_as_a_plugin_event(): from scribe.services.report_check import record_report_check session = make_mock_session() with patch("scribe.services.report_check.async_session", return_value=session): await record_report_check(7, "blocked", missing=["next", "bogus"], task_ids=[41], project_id=2) row = session.add.call_args.args[0] assert (row.category, row.action, row.user_id) == ("plugin", "report_check", 7) assert json.loads(row.details) == {"outcome": "blocked", "missing": ["next"], "task_ids": [41], "project_id": 2} session.commit.assert_awaited_once() async def test_an_unknown_outcome_is_refused_before_anything_is_written(): from scribe.services.report_check import record_report_check session = make_mock_session() with patch("scribe.services.report_check.async_session", return_value=session), \ pytest.raises(ValueError): await record_report_check(7, "skipped") session.add.assert_not_called()