"""Integration: the agent DB accessors against real Postgres (phase 37). ``list_catalog`` must order rows by ``(source, path)`` — the same order as ``GET /api/docs`` — and ``find_document`` must resolve a hit to the full document row (content included, for the never-truncated read) and return ``None`` for unknown ``source``/``path`` pairs. Requires: podman compose up -d db """ from __future__ import annotations import uuid from collections.abc import Iterator import pytest from sqlalchemy import text from sqlalchemy.orm import Session from app.models import Document from app.rag import agent def _doc(db: Session, source: str, path: str, title: str, content: str) -> Document: doc = Document( id=uuid.uuid4(), source=source, path=path, full_path=f"/tmp/{source}/{path}", title=title, content=content, content_hash="0" * 64, ) db.add(doc) return doc @pytest.fixture() def kb(db) -> Iterator[None]: """Fresh documents table (chunks first — the FK) for these accessors.""" db.execute(text("TRUNCATE chunks, documents")) db.commit() yield db.execute(text("TRUNCATE chunks, documents")) db.commit() def test_list_catalog_orders_by_source_then_path(kb, db) -> None: _doc(db, "Zeta", "b/second.md", "Zeta B", "ZB") _doc(db, "Zeta", "a/first.md", "Zeta A", "ZA") _doc(db, "Alpha", "c/third.md", "Alpha C", "AC") db.commit() assert agent.list_catalog(db) == [ ("Alpha", "c/third.md", "Alpha C"), ("Zeta", "a/first.md", "Zeta A"), ("Zeta", "b/second.md", "Zeta B"), ] def test_list_catalog_is_empty_without_rows(kb, db) -> None: assert agent.list_catalog(db) == [] def test_find_document_hit_returns_full_row(kb, db) -> None: created = _doc(db, "Alpha", "deep/nested/doc.md", "The Doc", "FULL-TEXT") db.commit() found = agent.find_document(db, "Alpha", "deep/nested/doc.md") assert found is not None assert found.id == created.id assert found.source == "Alpha" assert found.path == "deep/nested/doc.md" assert found.title == "The Doc" assert found.content == "FULL-TEXT" # the read tool feeds this, untruncated def test_find_document_none_for_unknown_pairs(kb, db) -> None: _doc(db, "Alpha", "x.md", "X", "X-CONTENT") db.commit() assert agent.find_document(db, "Alpha", "nope.md") is None # wrong path assert agent.find_document(db, "Beta", "x.md") is None # wrong source assert agent.find_document(db, "nope", "nope.md") is None # nothing at all