"""resolve_process precedence (id → exact title → substring) in services/notes.py. Mocks async_session — no real DB, matching the other notes-service tests. """ from unittest.mock import AsyncMock, MagicMock, patch import pytest from tests.helpers import fake_note, make_mock_session def _result(first=None, all_=None): """A SQLAlchemy-result mock exposing .scalars().first()/.all().""" r = MagicMock() r.scalars.return_value.first.return_value = first r.scalars.return_value.all.return_value = all_ or [] return r @pytest.mark.asyncio async def test_resolve_process_by_numeric_id(): note = fake_note(id=5, title="Drift Audit") session = make_mock_session() # numeric id → first execute (id lookup) hits session.execute = AsyncMock(side_effect=[_result(first=note)]) with patch("scribe.services.notes.async_session") as cls: cls.return_value = session from scribe.services.notes import resolve_process found, candidates = await resolve_process(1, "5") assert found is note assert candidates == [] assert session.execute.await_count == 1 @pytest.mark.asyncio async def test_resolve_process_exact_title_beats_substring(): note = fake_note(id=7, title="Drift Audit") session = make_mock_session() # non-digit → exact-title query (first execute) hits; substring never runs session.execute = AsyncMock(side_effect=[_result(first=note)]) with patch("scribe.services.notes.async_session") as cls: cls.return_value = session from scribe.services.notes import resolve_process found, candidates = await resolve_process(1, "Drift Audit") assert found is note assert candidates == [] assert session.execute.await_count == 1 @pytest.mark.asyncio async def test_resolve_process_substring_returns_candidates(): n1 = fake_note(id=7, title="Drift Audit Remediation") n2 = fake_note(id=9, title="Drift Audit Notes") session = make_mock_session() # exact miss, then substring returns two (most-recent first) session.execute = AsyncMock(side_effect=[_result(first=None), _result(all_=[n1, n2])]) with patch("scribe.services.notes.async_session") as cls: cls.return_value = session from scribe.services.notes import resolve_process found, candidates = await resolve_process(1, "drift") assert found is n1 assert candidates == [{"id": 9, "title": "Drift Audit Notes"}] assert session.execute.await_count == 2 @pytest.mark.asyncio async def test_resolve_process_no_match(): session = make_mock_session() session.execute = AsyncMock(side_effect=[_result(first=None), _result(all_=[])]) with patch("scribe.services.notes.async_session") as cls: cls.return_value = session from scribe.services.notes import resolve_process found, candidates = await resolve_process(1, "nope") assert found is None assert candidates == []