from __future__ import annotations from fastapi.testclient import TestClient def test_items_crud_and_completion(test_client: TestClient): # 1. List existing seed items list_res = test_client.get("/api/v1/items") assert list_res.status_code == 200 items = list_res.json() assert len(items) > 0 # 2. Create item res = test_client.post( "/api/v1/items", json={ "name": "Passport Renewal", "lifecycleType": "renewal", "dueDate": "2026-11-20", }, ) assert res.status_code == 201 item = res.json() item_id = item["id"] assert item["name"] == "Passport Renewal" assert item["lifecycleType"] == "renewal" assert item["status"] == "active" assert item["ownerEmail"] == "alex@example.com" # 3. Get item by ID get_res = test_client.get(f"/api/v1/items/{item_id}") assert get_res.status_code == 200 assert get_res.json()["id"] == item_id # 4. Update item patch_res = test_client.patch( f"/api/v1/items/{item_id}", json={"name": "Updated Passport Renewal", "dueDate": "2026-12-01"}, ) assert patch_res.status_code == 200 assert patch_res.json()["name"] == "Updated Passport Renewal" assert patch_res.json()["dueDate"] == "2026-12-01" # 5. Toggle complete complete_res = test_client.post(f"/api/v1/items/{item_id}/complete") assert complete_res.status_code == 200 assert complete_res.json()["status"] == "completed" # Toggle back to active active_res = test_client.post(f"/api/v1/items/{item_id}/complete") assert active_res.status_code == 200 assert active_res.json()["status"] == "active" # 6. Delete item del_res = test_client.delete(f"/api/v1/items/{item_id}") assert del_res.status_code == 204 # 7. Verify deletion not_found_res = test_client.get(f"/api/v1/items/{item_id}") assert not_found_res.status_code == 404 def test_items_filtering(test_client: TestClient): # Filter by type renewals_res = test_client.get("/api/v1/items?type=renewal") assert renewals_res.status_code == 200 for itm in renewals_res.json(): assert itm["lifecycleType"] == "renewal" # Filter personal only (groupId=null) personal_res = test_client.get("/api/v1/items?groupId=null") assert personal_res.status_code == 200 for itm in personal_res.json(): assert itm["groupId"] is None # Filter specific group group_res = test_client.get("/api/v1/items?groupId=group_home") assert group_res.status_code == 200 for itm in group_res.json(): assert itm["groupId"] == "group_home" # Search query search_res = test_client.get("/api/v1/items?searchQuery=Auto") assert search_res.status_code == 200 assert any("Auto" in itm["name"] for itm in search_res.json()) def test_create_item_with_auth_bearer(test_client: TestClient): # Signup a distinct user signup_res = test_client.post( "/api/v1/auth/signup", json={"email": "beareruser@example.com", "name": "Bearer User", "password": "password123"}, ) token = signup_res.json()["token"] headers = {"Authorization": f"Bearer {token}"} # Create item with Bearer header res = test_client.post( "/api/v1/items", json={"name": "Bicycle Service", "lifecycleType": "maintenance"}, headers=headers, ) assert res.status_code == 201 item = res.json() assert item["ownerEmail"] == "beareruser@example.com" assert item["name"] == "Bicycle Service" def test_items_not_found_errors(test_client: TestClient): assert test_client.get("/api/v1/items/non-existent-id").status_code == 404 assert test_client.patch("/api/v1/items/non-existent-id", json={"name": "X"}).status_code == 404 assert test_client.delete("/api/v1/items/non-existent-id").status_code == 404 assert test_client.post("/api/v1/items/non-existent-id/complete").status_code == 404