From e0075989dff823fe20dd9ca4bc1a40c765749859 Mon Sep 17 00:00:00 2001 From: curo1305 Date: Mon, 25 May 2026 18:23:40 +0200 Subject: [PATCH] feat(04-01): add Wave 0 xfail stubs for FOLD and SHARE requirements - test_folders.py: 13 stubs for FOLD-01..05 (create, rename, delete, move, breadcrumb, sort, FTS) - test_shares.py: 7 stubs for SHARE-01..05 (share, received list, quota isolation, revoke, duplicate) - FTS tests carry both xfail and skipif(INTEGRATION) decorators - All stubs: xfail(strict=False), body is pytest.xfail("not implemented yet") --- backend/tests/test_folders.py | 123 ++++++++++++++++++++++++++++++++++ backend/tests/test_shares.py | 79 ++++++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 backend/tests/test_folders.py create mode 100644 backend/tests/test_shares.py diff --git a/backend/tests/test_folders.py b/backend/tests/test_folders.py new file mode 100644 index 0000000..044679d --- /dev/null +++ b/backend/tests/test_folders.py @@ -0,0 +1,123 @@ +""" +Folder API tests — Wave 0 xfail stubs for Phase 4. + +All tests in this file are xfail stubs. They will be implemented in Plans 04-02 +through 04-04. The stubs ensure pytest collects them and keeps CI green before +implementation code exists. +""" +from __future__ import annotations + +import os + +import pytest + + +# --------------------------------------------------------------------------- +# FOLD-01: Create folder +# --------------------------------------------------------------------------- + + +@pytest.mark.xfail(strict=False) +async def test_create_folder(async_client, auth_user): + """POST /api/folders creates a folder, returns 201.""" + pytest.xfail("not implemented yet") + + +@pytest.mark.xfail(strict=False) +async def test_create_folder_duplicate_name(async_client, auth_user): + """POST /api/folders with same name under same parent returns 409.""" + pytest.xfail("not implemented yet") + + +# --------------------------------------------------------------------------- +# FOLD-02: Rename folder +# --------------------------------------------------------------------------- + + +@pytest.mark.xfail(strict=False) +async def test_rename_folder(async_client, auth_user): + """PATCH /api/folders/{id} changes name, returns 200.""" + pytest.xfail("not implemented yet") + + +@pytest.mark.xfail(strict=False) +async def test_rename_folder_wrong_owner(async_client, auth_user): + """PATCH /api/folders/{id} by non-owner returns 404.""" + pytest.xfail("not implemented yet") + + +# --------------------------------------------------------------------------- +# FOLD-03: Delete folder +# --------------------------------------------------------------------------- + + +@pytest.mark.xfail(strict=False) +async def test_delete_empty_folder(async_client, auth_user): + """DELETE /api/folders/{id} on empty folder returns 204.""" + pytest.xfail("not implemented yet") + + +@pytest.mark.xfail(strict=False) +async def test_delete_folder_cascade(async_client, auth_user): + """DELETE /api/folders/{id} on non-empty folder deletes all docs + decrements quota.""" + pytest.xfail("not implemented yet") + + +@pytest.mark.xfail(strict=False) +async def test_delete_folder_wrong_owner(async_client, auth_user): + """DELETE /api/folders/{id} by non-owner returns 404.""" + pytest.xfail("not implemented yet") + + +# --------------------------------------------------------------------------- +# FOLD-04: Move document +# --------------------------------------------------------------------------- + + +@pytest.mark.xfail(strict=False) +async def test_move_document(async_client, auth_user): + """PATCH /api/documents/{id}/folder moves doc to target folder, returns 200.""" + pytest.xfail("not implemented yet") + + +@pytest.mark.xfail(strict=False) +async def test_move_wrong_owner_404(async_client, auth_user): + """PATCH /api/documents/{id}/folder where doc or target folder belongs to other user returns 404.""" + pytest.xfail("not implemented yet") + + +# --------------------------------------------------------------------------- +# FOLD-05: Breadcrumb, sort, FTS +# --------------------------------------------------------------------------- + + +@pytest.mark.xfail(strict=False) +async def test_breadcrumb_path(async_client, auth_user): + """GET /api/folders/{id} returns breadcrumb array of {id, name} from root to current.""" + pytest.xfail("not implemented yet") + + +@pytest.mark.xfail(strict=False) +async def test_document_sort(async_client, auth_user): + """GET /api/documents?sort=name|date|size returns correctly ordered results.""" + pytest.xfail("not implemented yet") + + +@pytest.mark.xfail(strict=False) +@pytest.mark.skipif( + not os.environ.get("INTEGRATION"), + reason="requires PostgreSQL", +) +async def test_fts_search(async_client, auth_user): + """GET /api/documents?q=term returns matching docs only; requires PostgreSQL FTS.""" + pytest.xfail("not implemented yet") + + +@pytest.mark.xfail(strict=False) +@pytest.mark.skipif( + not os.environ.get("INTEGRATION"), + reason="requires PostgreSQL", +) +async def test_fts_search_scoped_to_owner(async_client, auth_user): + """GET /api/documents?q=term does not return other user's matching docs.""" + pytest.xfail("not implemented yet") diff --git a/backend/tests/test_shares.py b/backend/tests/test_shares.py new file mode 100644 index 0000000..6dc41c7 --- /dev/null +++ b/backend/tests/test_shares.py @@ -0,0 +1,79 @@ +""" +Share API tests — Wave 0 xfail stubs for Phase 4. + +All tests in this file are xfail stubs. They will be implemented in Plan 04-05. +The stubs ensure pytest collects them and keeps CI green before implementation +code exists. +""" +from __future__ import annotations + +import os + +import pytest + + +# --------------------------------------------------------------------------- +# SHARE-01: Share a document +# --------------------------------------------------------------------------- + + +@pytest.mark.xfail(strict=False) +async def test_share_success(async_client, auth_user): + """POST /api/shares grants share; recipient can see doc via GET /api/shares/received.""" + pytest.xfail("not implemented yet") + + +@pytest.mark.xfail(strict=False) +async def test_share_handle_not_found(async_client, auth_user): + """POST /api/shares with unknown handle returns 404.""" + pytest.xfail("not implemented yet") + + +# --------------------------------------------------------------------------- +# SHARE-02: List shared-with-me +# --------------------------------------------------------------------------- + + +@pytest.mark.xfail(strict=False) +async def test_shared_with_me(async_client, auth_user): + """GET /api/shares/received lists docs shared with current user.""" + pytest.xfail("not implemented yet") + + +# --------------------------------------------------------------------------- +# SHARE-03: Quota isolation +# --------------------------------------------------------------------------- + + +@pytest.mark.xfail(strict=False) +async def test_share_no_quota_impact(async_client, auth_user): + """Share does not increment recipient's quota used_bytes.""" + pytest.xfail("not implemented yet") + + +# --------------------------------------------------------------------------- +# SHARE-04: Revoke share +# --------------------------------------------------------------------------- + + +@pytest.mark.xfail(strict=False) +async def test_revoke_share(async_client, auth_user): + """DELETE /api/shares/{id} removes share; GET /api/shares/received no longer lists the doc.""" + pytest.xfail("not implemented yet") + + +@pytest.mark.xfail(strict=False) +async def test_share_revoke_wrong_owner_404(async_client, auth_user): + """DELETE /api/shares/{id} by non-owner returns 404.""" + pytest.xfail("not implemented yet") + + +# --------------------------------------------------------------------------- +# SHARE-05: Duplicate share +# --------------------------------------------------------------------------- + + +@pytest.mark.xfail(strict=False) +async def test_share_duplicate(async_client, auth_user): + """POST /api/shares same doc+recipient twice returns 409.""" + pytest.xfail("not implemented yet")