"""Real-Postgres test that the CHECK actually accepts 'spike' (0091). Rule 36 exists because the value and the constraint can drift apart: the code starts writing a new kind while the database still refuses it, and nothing catches it until a write fails in front of someone. A mock cannot show that — it has no CHECK — so the constraint gets its own real-DB test, the same way migration 0090's nullability did. The negative half matters as much as the positive one. A test that only proves 'spike' is accepted would also pass against a table with NO constraint at all, which is the other way this goes wrong. """ import pytest import pytest_asyncio from sqlalchemy.exc import IntegrityError from scribe.models import async_session from scribe.models.note import Note from tests.helpers import ensure_user pytestmark = [pytest.mark.integration, pytest.mark.usefixtures("_dispose_engine")] @pytest_asyncio.fixture async def owner_id(): async with async_session() as s: owner = await ensure_user(s, "spike_owner") uid = owner.id await s.commit() return uid async def _write(uid: int, kind: str) -> int: async with async_session() as s: note = Note( user_id=uid, title=f"kind {kind}", body="", is_task=True, status="todo", task_kind=kind, ) s.add(note) await s.commit() return note.id async def test_a_spike_can_be_written(owner_id): note_id = await _write(owner_id, "spike") async with async_session() as s: assert (await s.get(Note, note_id)).task_kind == "spike" async def test_the_older_kinds_still_write(owner_id): """0091 widens the whitelist; it must not narrow it by accident. 'plan' is retired — plans are milestones since 0066 — but historical plan-tasks still carry it, and a row that cannot be rewritten is a row that cannot be edited, restored, or migrated. """ for kind in ("work", "issue", "plan"): note_id = await _write(owner_id, kind) async with async_session() as s: assert (await s.get(Note, note_id)).task_kind == kind async def test_an_unknown_kind_is_still_refused(owner_id): """The half that proves a constraint is there at all. Without this, every assertion above would pass just as happily against a table whose CHECK had been dropped and never re-added — which is exactly the failure rule 36 is written against. """ with pytest.raises(IntegrityError): await _write(owner_id, "investigation")