test(03-01): add Wave 0 xfail stubs and shared fixtures for Phase 3

- Add auth_user, admin_user, mock_minio_presigned, mock_minio_stat fixtures to conftest.py
- Create test_quota.py with 4 xfail stubs (STORE-03, STORE-05, STORE-06, SC2 race)
- Append test_migration_0003 to test_alembic.py (full pre-seed + post-migration assertions)
- Append 3 classifier xfail stubs (DOC-03, DOC-05, D-15)
- Append 6 document xfail stubs (D-05, STORE-04, SEC-04, D-16)
- Append 4 topic xfail stubs (DOC-04, D-09, D-17)
- Append test_settings_endpoint_removed stub (D-12)
- All 19 new test IDs collect cleanly with xfail(strict=False)
This commit is contained in:
curo1305
2026-05-23 13:42:37 +02:00
parent fdc32d431d
commit 21ec9cb4c3
7 changed files with 492 additions and 0 deletions
+69
View File
@@ -152,3 +152,72 @@ async def test_upload_persists_to_postgres_and_minio(async_client, sample_txt):
assert get_resp.status_code == 200
get_data = get_resp.json()
assert get_data["original_name"] == "sample.txt"
# ---------------------------------------------------------------------------
# Wave 0 xfail stubs for Phase 3 document endpoint tests — Plans 03-02 / 03-03
# ---------------------------------------------------------------------------
@pytest.mark.xfail(strict=False, reason="implemented in plan 03-02")
async def test_upload_url_endpoint(async_client, auth_user, mock_minio_presigned):
"""POST /api/documents/upload-url returns {upload_url, document_id} and creates
a Document row with status='pending'.
D-05: two-step upload flow — step 1 creates the pending Document row and
returns the presigned PUT URL (15-min TTL). Quota is NOT reserved here.
"""
assert True # scaffold
@pytest.mark.xfail(strict=False, reason="implemented in plan 03-02")
async def test_confirm_endpoint(async_client, auth_user, mock_minio_presigned, mock_minio_stat):
"""POST /api/documents/{id}/confirm calls stat_object once, updates Document.size_bytes
from the stat return value, and sets Document.status='uploaded'.
D-05: step 3 of the presigned upload flow. stat_object provides the authoritative
file size (D-07). The atomic quota UPDATE runs here (STORE-03).
"""
assert True # scaffold
@pytest.mark.xfail(strict=False, reason="implemented in plan 03-02")
async def test_get_quota(async_client, auth_user):
"""GET /api/auth/me/quota returns {used_bytes: 0, limit_bytes: 104857600}.
STORE-04: quota usage bar endpoint. Returns current usage and limit for the
authenticated user. Newly created users start at used_bytes=0.
"""
assert True # scaffold
@pytest.mark.xfail(strict=False, reason="implemented in plan 03-03")
async def test_cross_user_access_404(async_client, auth_user, db_session):
"""User B's request for GET /api/documents/{A_doc_id} returns 404.
SEC-04: cross-user access returns 404 (not 403) to avoid information leakage
(CONTEXT.md D-16). An attacker cannot distinguish between 'document does not
exist' and 'document belongs to someone else'.
"""
assert True # scaffold
@pytest.mark.xfail(strict=False, reason="implemented in plan 03-03")
async def test_admin_cannot_access_documents(async_client, admin_user):
"""GET /api/documents using admin_user.headers returns 403.
SEC-04 SC4: admin accounts cannot access document content (CLAUDE.md +
CONTEXT.md D-16). The get_regular_user dependency enforces this for all
/api/documents/* handlers.
"""
assert True # scaffold
@pytest.mark.xfail(strict=False, reason="implemented in plan 03-02")
async def test_documents_require_auth(async_client):
"""Anonymous GET /api/documents (no Authorization header) returns 401 or 403.
D-16: all /api/documents/* endpoints require authentication via
get_current_user (Phase 2 D-07 fulfilled in Phase 3).
"""
assert True # scaffold