"""IMP-33 u2 — AiFallbackProposal schema tests. Scope (Stage 2 plan, u2): - Whitelisted proposal_kind values are accepted. - Forbidden output forms are rejected: mdx_text / frame_id_change / raw_html / raw_css. - extra fields outside the declared schema are rejected (MDX read-only signal). """ from __future__ import annotations import pytest from pydantic import ValidationError from src.phase_z2_ai_fallback import AiFallbackProposal, ProposalKind @pytest.mark.parametrize( "kind_value", [ "builder_options_patch", "partial_overrides", "slot_mapping_proposal", ], ) def test_whitelisted_proposal_kinds_accepted(kind_value: str) -> None: proposal = AiFallbackProposal(proposal_kind=kind_value) assert proposal.proposal_kind == ProposalKind(kind_value) @pytest.mark.parametrize( "forbidden", ["mdx_text", "frame_id_change", "raw_html", "raw_css"], ) def test_forbidden_proposal_kinds_rejected(forbidden: str) -> None: with pytest.raises(ValidationError): AiFallbackProposal(proposal_kind=forbidden) def test_unknown_proposal_kind_rejected() -> None: with pytest.raises(ValidationError): AiFallbackProposal(proposal_kind="something_else") def test_extra_fields_rejected() -> None: """`extra=forbid` keeps the AI from smuggling raw_html/mdx_text alongside a valid kind.""" with pytest.raises(ValidationError): AiFallbackProposal(proposal_kind="partial_overrides", raw_html="
")