diff --git a/backend/tests/test_admin_ai_config.py b/backend/tests/test_admin_ai_config.py new file mode 100644 index 0000000..2a99647 --- /dev/null +++ b/backend/tests/test_admin_ai_config.py @@ -0,0 +1,25 @@ +""" +Wave 0 xfail stubs for Phase 7 admin AI config endpoint tests. + +Covers: + - T-07-01: GET /api/admin/ai-config never returns api_key_enc (D-05/D-08) + - D-08: PUT /api/admin/ai-config writes active provider (admin AI Providers panel) + +Each function is a placeholder to be promoted in Plan 07-05 once the admin +AI config endpoints exist. + +Stub policy (STATE.md decision: xfail(strict=False) for Wave 0): + - Body is a single pytest.xfail() call — no assertion code. + - strict=False so unexpected passes (xpass) never break CI. +""" +import pytest + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-05") +async def test_get_never_returns_key(): + pytest.xfail("not implemented yet — Plan 07-05") + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-05") +async def test_put_writes_active_provider(): + pytest.xfail("not implemented yet — Plan 07-05") diff --git a/backend/tests/test_ai_config.py b/backend/tests/test_ai_config.py new file mode 100644 index 0000000..819a64e --- /dev/null +++ b/backend/tests/test_ai_config.py @@ -0,0 +1,25 @@ +""" +Wave 0 xfail stubs for Phase 7 AI config service tests. + +Covers: + - D-04: load_provider_config() reads from system_settings table + - D-05: API key HKDF encryption round-trip + +Each function is a placeholder to be promoted in Plan 07-01 (green gate) once +the services/ai_config.py module and system_settings table exist. + +Stub policy (STATE.md decision: xfail(strict=False) for Wave 0): + - Body is a single pytest.xfail() call — no assertion code. + - strict=False so unexpected passes (xpass) never break CI. +""" +import pytest + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-01") +async def test_load_provider_config(): + pytest.xfail("not implemented yet — Plan 07-01") + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-01") +async def test_api_key_encrypt_decrypt(): + pytest.xfail("not implemented yet — Plan 07-01") diff --git a/backend/tests/test_ai_providers.py b/backend/tests/test_ai_providers.py new file mode 100644 index 0000000..9775c2a --- /dev/null +++ b/backend/tests/test_ai_providers.py @@ -0,0 +1,46 @@ +""" +Wave 0 xfail stubs for Phase 7 AI provider tests. + +Each function is a placeholder for a test that will be promoted to green +in a later plan wave (per 07-VALIDATION.md per-task-verification map). + +Stub policy (STATE.md decision: xfail(strict=False) for Wave 0): + - Body is a single pytest.xfail() call — no assertion code. + - strict=False so unexpected passes (xpass) never break CI. +""" +import pytest + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-02") +async def test_generic_openai_json_mode(): + pytest.xfail("not implemented yet — Plan 07-02") + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-03") +async def test_anthropic_structured_output(): + pytest.xfail("not implemented yet — Plan 07-03") + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-02") +async def test_get_provider_typed(): + pytest.xfail("not implemented yet — Plan 07-02") + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-02") +async def test_client_singleton(): + pytest.xfail("not implemented yet — Plan 07-02") + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-03") +async def test_context_chars_truncation(): + pytest.xfail("not implemented yet — Plan 07-03") + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-03") +async def test_smart_truncation(): + pytest.xfail("not implemented yet — Plan 07-03") + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-02 Task 4 (D-02 Gemini fallback path)") +async def test_gemini_fallback_to_parse_classification(): + pytest.xfail("not implemented yet — Plan 07-02") diff --git a/backend/tests/test_document_tasks.py b/backend/tests/test_document_tasks.py new file mode 100644 index 0000000..3b5d632 --- /dev/null +++ b/backend/tests/test_document_tasks.py @@ -0,0 +1,25 @@ +""" +Wave 0 xfail stubs for Phase 7 Celery document task tests. + +Covers: + - D-09: Celery retry with 30s/90s/270s exponential backoff + - D-10: After 3 retries doc.status = "classification_failed" + +Each function is a placeholder to be promoted in Plan 07-04 once the +bind=True retry harness is implemented in document_tasks.py. + +Stub policy (STATE.md decision: xfail(strict=False) for Wave 0): + - Body is a single pytest.xfail() call — no assertion code. + - strict=False so unexpected passes (xpass) never break CI. +""" +import pytest + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-04") +async def test_retry_backoff(): + pytest.xfail("not implemented yet — Plan 07-04") + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-04") +async def test_exhaustion_sets_failed_status(): + pytest.xfail("not implemented yet — Plan 07-04") diff --git a/backend/tests/test_documents.py b/backend/tests/test_documents.py index 57c891a..6a76fee 100644 --- a/backend/tests/test_documents.py +++ b/backend/tests/test_documents.py @@ -923,3 +923,13 @@ async def test_delete_cloud_remove_only(async_client, auth_user, db_session): # DB row removed deleted = await db_session.get(Document, doc_id) assert deleted is None + + +# --------------------------------------------------------------------------- +# Phase 7 Wave 0 xfail stub — D-11 re-classify endpoint +# --------------------------------------------------------------------------- + + +@pytest.mark.xfail(strict=False, reason="Wave 0 stub — promoted in Plan 07-04") +async def test_reclassify_requeues_celery(): + pytest.xfail("not implemented yet — Plan 07-04")