from __future__ import annotations import os from uuid import uuid4 import pytest from sqlalchemy import create_engine, text @pytest.fixture def repository(): from app.db.repositories import PostgresSessionRepository schema = f"test_repository_{uuid4().hex}" engine = create_engine(os.environ["RESUME_AGENT_TEST_DATABASE_URL"]) with engine.begin() as connection: connection.execute(text(f'CREATE SCHEMA "{schema}"')) store = PostgresSessionRepository(engine, schema=schema) store.initialize() try: yield store finally: with engine.begin() as connection: connection.execute(text(f'DROP SCHEMA "{schema}" CASCADE')) engine.dispose() def test_turns_are_ordered_and_blocks_follow_turns(repository) -> None: repository.create_session("session-a", "PRIVACY_CONSENT", {"name": "Ada"}) first = repository.insert_turn( "session-a", role="assistant", content="first", composer_mode="ui_only", blocks=[{"type": "component", "data": {"component": "one"}}], ) second = repository.insert_turn( "session-a", role="user", content="second", composer_mode="chat", blocks=[], ) turns = repository.list_turns("session-a") assert [turn["id"] for turn in turns] == [first["id"], second["id"]] assert [turn["sequence"] for turn in turns] == [1, 2] assert turns[0]["blocks"][0]["data"] == {"component": "one"} def test_session_deletion_cascades_to_turns_blocks_and_resume(repository) -> None: repository.create_session("session-a", "PRIVACY_CONSENT", {}) repository.insert_turn( "session-a", role="assistant", content=None, composer_mode="ui_only", blocks=[{"type": "component", "data": {}}], ) repository.create_resume( "session-a", "resume-a", "create-a", {"schema_version": 3} ) assert repository.delete_session("session-a") is True assert repository.get_session("session-a") is None assert repository.list_turns("session-a") == [] assert repository.get_resume("session-a") is None def test_resume_creation_is_idempotent_for_a_session(repository) -> None: repository.create_session("session-a", "MINIMUM_READY", {}) created = repository.create_resume( "session-a", "resume-a", "first", {"schema_version": 3} ) repeated = repository.create_resume( "session-a", "resume-b", "second", {"schema_version": 3} ) assert created["id"] == "resume-a" assert repeated == created def test_resume_update_uses_expected_revision(repository) -> None: from app.db.repositories import RevisionConflict repository.create_session("session-a", "MINIMUM_READY", {}) repository.create_resume("session-a", "resume-a", None, {"schema_version": 3}) updated = repository.update_resume( "session-a", {"schema_version": 3, "basics": {"name": "Ada"}}, expected_revision=1 ) assert updated["revision"] == 2 with pytest.raises(RevisionConflict): repository.update_resume("session-a", {"schema_version": 3}, expected_revision=1) def test_resume_import_is_deduplicated_and_retains_review_payload(repository) -> None: repository.create_session("session-a", "MINIMUM_READY", {}) document = { "schema_version": 3, "basics": {"name": "Ada"}, "target": {}, "sections": [], "skill_groups": [], } reviews = [{"field_path": "basics.name", "confidence": 0.9, "evidence": []}] created = repository.create_resume_import( "session-a", import_id="import-a", file_name="resume.docx", mime_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document", size_bytes=42, sha256="a" * 64, object_key="aa/import-a.docx", document=document, field_reviews=reviews, ) repeated = repository.create_resume_import( "session-a", import_id="import-b", file_name="duplicate.docx", mime_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document", size_bytes=42, sha256="a" * 64, object_key="aa/import-b.docx", document=document, field_reviews=reviews, ) assert created["id"] == "import-a" assert repeated["id"] == "import-a" assert created["document"] == document assert created["field_reviews"] == reviews assert created["status"] == "awaiting_review" def test_resume_import_status_update_is_scoped_to_its_session(repository) -> None: repository.create_session("session-a", "MINIMUM_READY", {}) repository.create_session("session-b", "MINIMUM_READY", {}) repository.create_resume_import( "session-a", import_id="import-a", file_name="resume.pdf", mime_type="application/pdf", size_bytes=10, sha256="b" * 64, object_key="bb/import-a.pdf", document=None, field_reviews=[], ) updated = repository.update_resume_import_status("session-a", "import-a", "applied") assert updated["status"] == "applied" assert repository.get_resume_import("session-b", "import-a") is None