Files
FabledGrimoire/tests/test_integration_inception.py
T
bvandeusenandClaude Opus 5.5 79de8938b9 docs(6209): forty test files — design cascade and stylesheet, embeddings, family canon, forge, backup round trips, inception, placement, platforms, moments, rule move and verification, search scope, facets
Module and test docstrings state what is pinned without the record number
or step that introduced it. Incident accounts become the failure shape in
the present tense: the pipefail head, the code_shapes import, the export
order, the facet dialects, the cross-kind repeat, the write-once kind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 21:40:25 -04:00

99 lines
4.2 KiB
Python

"""Real-Postgres integration tests for project inception.
What mocks can't prove: a decision's effects land through the real services
(the design system points, the standard Systems seed once), the record is
written last, a bad target applies nothing.
Rules are not part of inception: a rule in a rulebook is
global and applies to every project, so there is nothing to subscribe to.
"""
import pytest
import pytest_asyncio
from scribe.models import async_session
from scribe.models.project import Project
from scribe.services import inception as inception_svc
from scribe.services import canonical_systems as canonical_svc
from scribe.services import systems as systems_svc
from tests.helpers import ensure_user
pytestmark = [pytest.mark.integration, pytest.mark.usefixtures("_dispose_engine")]
@pytest_asyncio.fixture
async def seeded():
"""Owner and a fresh, undecided project."""
async with async_session() as s:
owner = await ensure_user(s, "inception_owner")
project = Project(user_id=owner.id, title="Inception target")
s.add(project)
await s.flush()
ids = {"owner": owner.id, "pid": project.id}
await s.commit()
return ids
@pytest.mark.integration
async def test_decide_applies_every_effect_and_records_last(seeded):
owner, pid = seeded["owner"], seeded["pid"]
defaults = await inception_svc.current_defaults(owner, pid)
assert set(defaults) == {
"design_system_id", "design_systems", "systems", "platforms", "project_platforms",
}
assert defaults["systems"] == 0 and defaults["design_system_id"] is None
out = await inception_svc.decide(owner, pid, via="mcp", choices={
"design_system_id": None,
"seed_systems": True,
})
assert set(out["effects"]) == {"design_system_id", "systems_seeded", "platforms"}
catalog = await canonical_svc.list_canonical_systems()
assert len(out["effects"]["systems_seeded"]) == len(catalog)
# Seeded Systems come out mapped, not needing a later reconciliation.
seeded_systems = await systems_svc.list_systems(owner, pid)
assert all(s.canonical_id is not None for s in seeded_systems)
# The record, written last, says why.
async with async_session() as s:
project = await s.get(Project, pid)
assert inception_svc.is_decided(project)
assert project.inception["via"] == "mcp" and project.inception["decided_by"] == owner
assert project.inception["choices"] == {
"design_system_id": None, "seed_systems": True, "platforms": None,
}
# Re-deciding with seed again mints nothing twice.
again = await inception_svc.decide(owner, pid, via="ui", choices={"seed_systems": True})
assert again["effects"]["systems_seeded"] == []
assert len(await systems_svc.list_systems(owner, pid)) == len(catalog)
@pytest.mark.integration
async def test_a_bad_decision_applies_nothing(seeded):
owner, pid = seeded["owner"], seeded["pid"]
# A design system that is not readable is refused BEFORE any effect
# lands — the seed must not happen on a decision that fails.
with pytest.raises(ValueError, match="not found"):
await inception_svc.decide(owner, pid, via="mcp", choices={
"design_system_id": 999999, "seed_systems": True,
})
assert await systems_svc.list_systems(owner, pid) == []
# The retired rulebook choice is an unknown key, refused whole: a caller
# still passing it must not believe a rulebook was subscribed.
with pytest.raises(ValueError, match="unknown inception choice"):
await inception_svc.decide(owner, pid, via="mcp", choices={
"subscribe_rulebooks": [1], "seed_systems": True,
})
assert await systems_svc.list_systems(owner, pid) == []
with pytest.raises(ValueError, match="legacy"):
await inception_svc.decide(owner, pid, via="legacy", choices={})
async with async_session() as s:
project = await s.get(Project, pid)
assert not inception_svc.is_decided(project)
# An outsider cannot decide someone else's project.
async with async_session() as s:
other = await ensure_user(s, "inception_other")
other_id = other.id
await s.commit()
with pytest.raises(ValueError, match="not found"):
await inception_svc.decide(other_id, pid, via="mcp", choices={})