"""Tests for the prune logic — both rolling (pin_kind IS NULL) and the auto-pin bucket (pin_kind='auto'). Design: docs/superpowers/specs/2026-05-13-note-version-pinning-design.md """ from unittest.mock import AsyncMock, MagicMock, patch async def test_create_version_prune_sql_filters_to_unpinned(): """The DELETE statement issued by create_version's prune step must include `pin_kind IS NULL` in the inner SELECT so pinned versions aren't counted toward MAX_VERSIONS and can't be pruned by it.""" mock_session = AsyncMock() select_result = MagicMock() # No prior version → skips the throttle/dedupe early-return paths and # proceeds straight to insert + prune. select_result.scalars.return_value.first.return_value = None mock_session.add = MagicMock() mock_session.commit = AsyncMock() mock_session.refresh = AsyncMock() mock_session.__aenter__ = AsyncMock(return_value=mock_session) mock_session.__aexit__ = AsyncMock(return_value=False) captured_sql: list[str] = [] async def execute_capture(stmt, *args, **kwargs): captured_sql.append(str(stmt)) if len(captured_sql) == 1: return select_result return MagicMock() mock_session.execute = AsyncMock(side_effect=execute_capture) with patch( "fabledassistant.services.note_versions.async_session", return_value=mock_session, ): from fabledassistant.services.note_versions import create_version await create_version( user_id=1, note_id=42, body="content", title="t", tags=["a"], ) assert any("pin_kind IS NULL" in s for s in captured_sql), ( f"Expected prune SQL to filter pin_kind IS NULL; got: {captured_sql!r}" )