"""Unit tests: SQLAlchemy models register the pgvector schema on the metadata. Importing :mod:`app.models` is what Alembic's ``env.py`` and the runtime rely on; these tests lock the table/column contract (PLAN ยง5) without a live DB. """ from __future__ import annotations from pgvector.sqlalchemy import Vector from sqlalchemy import UniqueConstraint import app.models # noqa: F401 (import registers all tables on Base.metadata) from app.db import Base def test_all_tables_registered() -> None: tables = Base.metadata.tables assert "documents" in tables assert "chunks" in tables assert "query_log" in tables def test_chunks_embedding_is_vector_768() -> None: chunks = Base.metadata.tables["chunks"] col = chunks.c["embedding"] assert isinstance(col.type, Vector) assert col.type.dim == 768 # Embeddings are two-phase: inserted first, embedded later. assert col.nullable is True def test_chunks_reference_documents_cascade() -> None: chunks = Base.metadata.tables["chunks"] fkc = list(chunks.foreign_key_constraints)[0] assert fkc.elements[0].column.table.name == "documents" assert fkc.ondelete == "CASCADE" def test_documents_unique_source_path() -> None: documents = Base.metadata.tables["documents"] uq = [ c for c in documents.constraints if isinstance(c, UniqueConstraint) and {col.name for col in c.columns} == {"source", "path"} ] assert uq, "documents must be unique on (source, path) โ€” the upsert key" def test_doc_drafts_token_is_unique_not_null() -> None: """Phase 59: the draft's URL credential โ€” an unguessable uuid4, UNIQUE + NOT NULL (no "un-drafted" state, unlike the NULLable ``saved_chats.share_token``).""" drafts = Base.metadata.tables["doc_drafts"] token = drafts.c["token"] assert token.nullable is False, "doc_drafts.token must be NOT NULL" uq = [ c for c in drafts.constraints if isinstance(c, UniqueConstraint) and {col.name for col in c.columns} == {"token"} ] assert uq, "doc_drafts must be unique on (token) โ€” the URL credential" def test_doc_drafts_column_contract() -> None: """Phase 59: the editable triple (title/path/body) + status + timestamps are NOT NULL; ``branch`` / ``commit_sha`` are NULL until the push endpoint records them.""" drafts = Base.metadata.tables["doc_drafts"] assert set(drafts.c.keys()) == { "id", "token", "title", "path", "body", "status", "branch", "commit_sha", "created_at", "updated_at", } for name in ("title", "path", "body", "status", "created_at", "updated_at"): assert drafts.c[name].nullable is False, f"{name} must be NOT NULL" for name in ("branch", "commit_sha"): assert drafts.c[name].nullable is True, f"{name} must be NULL until pushed" assert drafts.c["status"].default is not None, "status needs an ORM default (draft)" assert drafts.c["token"].default is not None, "token needs an ORM default (uuid4)"