import pytest from fastapi.testclient import TestClient from main import app from unittest.mock import patch, MagicMock client = TestClient(app) def test_all_api_endpoints_return_proper_status_codes(): """Verify all API endpoints return proper status codes""" user_id = "status_test_user" # Test GET /api/tasks - should return 200 when authenticated with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.get( "/api/tasks", headers={"Authorization": "Bearer valid_token"} ) # Should return 200 OK (might be 204 No Content if no tasks exist) assert response.status_code in [200, 204, 404] # Check the response structure if response.status_code == 200: data = response.json() assert "data" in data # Should return proper response format assert isinstance(data["data"], list) # Should return list of tasks # Test POST /api/tasks - should return 200 on success with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.post( "/api/tasks", headers={"Authorization": "Bearer valid_token"}, json={ "title": "Status Code Test Task", "description": "Testing proper status codes", "priority": "medium" } ) # Should return 200 OK on success assert response.status_code == 200 # Check response structure data = response.json() assert "data" in data # Should return proper response format task_data = data["data"] assert "id" in task_data assert task_data["user_id"] == user_id assert task_data["title"] == "Status Code Test Task" assert task_data["completed"] is False task_id = task_data["id"] # Test GET /api/tasks/{id} - should return 200 for existing task with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.get( f"/api/tasks/{task_id}", headers={"Authorization": "Bearer valid_token"} ) # Should return 200 for existing task assert response.status_code == 200 # Check response structure data = response.json() assert "data" in data task_data = data["data"] assert task_data["id"] == task_id assert task_data["user_id"] == user_id # Test PUT /api/tasks/{id} - should return 200 on success with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.put( f"/api/tasks/{task_id}", headers={"Authorization": "Bearer valid_token"}, json={ "title": "Updated Status Code Test Task", "description": "Updated description for status code test", "completed": True } ) # Should return 200 OK on success assert response.status_code == 200 # Check response structure data = response.json() assert "data" in data updated_task = data["data"] assert updated_task["id"] == task_id assert updated_task["title"] == "Updated Status Code Test Task" assert updated_task["completed"] is True # Test PATCH /api/tasks/{id}/complete - should return 200 on success with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.patch( f"/api/tasks/{task_id}/complete", headers={"Authorization": "Bearer valid_token"} ) # Should return 200 OK on success assert response.status_code == 200 # Check response structure data = response.json() assert "data" in data toggled_task = data["data"] assert toggled_task["id"] == task_id assert toggled_task["completed"] is False # Toggled back to False # Test DELETE /api/tasks/{id} - should return 200 on success with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.delete( f"/api/tasks/{task_id}", headers={"Authorization": "Bearer valid_token"} ) # Should return 200 OK on success assert response.status_code == 200 # Check response structure data = response.json() assert "data" in data delete_result = data["data"] assert delete_result["ok"] is True def test_error_status_codes(): """Test that endpoints return proper error status codes""" # Test unauthenticated access - should return 401 response = client.get("/api/tasks") assert response.status_code == 401 response = client.post("/api/tasks", json={"title": "Unauthorized task"}) assert response.status_code == 401 response = client.put("/api/tasks/1", json={"title": "Unauthorized update"}) assert response.status_code == 401 response = client.delete("/api/tasks/1") assert response.status_code == 401 response = client.patch("/api/tasks/1/complete") assert response.status_code == 401 # Test authenticated access to non-existent task - should return 404 with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = "test_user" response = client.get( "/api/tasks/999999", # Non-existent task ID headers={"Authorization": "Bearer valid_token"} ) # Should return 404 for non-existent resource assert response.status_code in [404, 422] # 422 for validation errors # Test updating non-existent task response = client.put( "/api/tasks/999999", # Non-existent task ID headers={"Authorization": "Bearer valid_token"}, json={"title": "Updated non-existent task"} ) # Should return 404 for non-existent resource assert response.status_code in [404, 422] # Test deleting non-existent task response = client.delete( "/api/tasks/999999", # Non-existent task ID headers={"Authorization": "Bearer valid_token"} ) # Should return 404 for non-existent resource assert response.status_code in [404, 422] # Test completing non-existent task response = client.patch( "/api/tasks/999999/complete", # Non-existent task ID headers={"Authorization": "Bearer valid_token"} ) # Should return 404 for non-existent resource assert response.status_code in [404, 422] def test_api_endpoint_responses_structure(): """Test that all API endpoints return consistent response structures""" user_id = "response_structure_user" # Test consistent response structure for POST /api/tasks with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.post( "/api/tasks", headers={"Authorization": "Bearer valid_token"}, json={ "title": "Response Structure Test", "priority": "high" } ) assert response.status_code == 200 data = response.json() assert "data" in data # All successful responses should have data wrapper task = data["data"] required_fields = ["id", "user_id", "title", "description", "completed", "priority", "category", "tags", "created_at", "updated_at"] for field in required_fields: assert field in task # All tasks should have required fields # Test consistent response structure for GET /api/tasks task_id = data["data"]["id"] with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.get( "/api/tasks", headers={"Authorization": "Bearer valid_token"} ) assert response.status_code == 200 data = response.json() assert "data" in data # All successful responses should have data wrapper assert isinstance(data["data"], list) # Collection endpoints should return arrays # Check that each task in the list has the correct structure for task in data["data"]: required_fields = ["id", "user_id", "title", "description", "completed", "priority", "category", "tags", "created_at", "updated_at"] for field in required_fields: assert field in task # All tasks should have required fields # Test consistent response structure for GET /api/tasks/{id} with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.get( f"/api/tasks/{task_id}", headers={"Authorization": "Bearer valid_token"} ) assert response.status_code == 200 data = response.json() assert "data" in data # All successful responses should have data wrapper task = data["data"] required_fields = ["id", "user_id", "title", "description", "completed", "priority", "category", "tags", "created_at", "updated_at"] for field in required_fields: assert field in task # All tasks should have required fields # Test consistent response structure for PUT /api/tasks/{id} with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.put( f"/api/tasks/{task_id}", headers={"Authorization": "Bearer valid_token"}, json={"title": "Updated with Consistent Response Structure"} ) assert response.status_code == 200 data = response.json() assert "data" in data # All successful responses should have data wrapper task = data["data"] required_fields = ["id", "user_id", "title", "description", "completed", "priority", "category", "tags", "created_at", "updated_at"] for field in required_fields: assert field in task # All tasks should have required fields # Test consistent response structure for PATCH /api/tasks/{id}/complete with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.patch( f"/api/tasks/{task_id}/complete", headers={"Authorization": "Bearer valid_token"} ) assert response.status_code == 200 data = response.json() assert "data" in data # All successful responses should have data wrapper task = data["data"] required_fields = ["id", "user_id", "title", "description", "completed", "priority", "category", "tags", "created_at", "updated_at"] for field in required_fields: assert field in task # All tasks should have required fields # Test consistent response structure for DELETE /api/tasks/{id} with patch("auth.jwt.get_current_user_id") as mock_get_user: mock_get_user.return_value = user_id response = client.delete( f"/api/tasks/{task_id}", headers={"Authorization": "Bearer valid_token"} ) assert response.status_code == 200 data = response.json() assert "data" in data # All successful responses should have data wrapper result = data["data"] assert "ok" in result # Delete should return ok status assert result["ok"] is True