Files
MAIA/backend/tests/test_todo.py
2025-04-23 00:57:31 +02:00

209 lines
8.1 KiB
Python

from fastapi import status
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session
from datetime import date
from tests.helpers import generators
# Helper Function
def _login_user(db: Session, client: TestClient):
user, password = generators.create_user(db)
login_rsp = generators.login(db, user.username, password)
return user, login_rsp["access_token"], login_rsp["refresh_token"]
# --- Test CRUD Operations ---
def test_create_todo(client: TestClient, db: Session):
user, access_token, refresh_token = _login_user(db, client)
today_date = date.today()
# Format the date string to match the expected response format "YYYY-MM-DDTHH:MM:SS"
todo_data = {
"task": "Test TODO",
"date": f"{today_date.isoformat()}T00:00:00",
"remind": True
}
response = client.post(
"/api/todos/",
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token},
json=todo_data
)
assert response.status_code == status.HTTP_201_CREATED
data = response.json()
assert data["task"] == todo_data["task"]
assert data["date"] == todo_data["date"]
assert data["remind"] == todo_data["remind"]
assert data["complete"] is False # Default
assert "id" in data
assert data["owner_id"] == user.id
def test_read_todos(client: TestClient, db: Session):
user, access_token, refresh_token = _login_user(db, client)
# Create some todos for the user
client.post("/api/todos/", headers={"Authorization": f"Bearer {access_token}"}, cookies={"refresh_token": refresh_token}, json={"task": "Todo 1"})
client.post("/api/todos/", headers={"Authorization": f"Bearer {access_token}"}, cookies={"refresh_token": refresh_token}, json={"task": "Todo 2"})
# Create a todo for another user
other_user, other_password = generators.create_user(db)
other_login_rsp = generators.login(db, other_user.username, other_password)
other_access_token = other_login_rsp["access_token"]
other_refresh_token = other_login_rsp["refresh_token"]
client.post("/api/todos/", headers={"Authorization": f"Bearer {other_access_token}"}, cookies={"refresh_token": other_refresh_token}, json={"task": "Other User Todo"})
response = client.get(
"/api/todos/",
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token}
)
assert response.status_code == status.HTTP_200_OK
data = response.json()
assert len(data) == 2 # Should only get todos for the logged-in user
assert data[0]["task"] == "Todo 1"
assert data[1]["task"] == "Todo 2"
def test_read_single_todo(client: TestClient, db: Session):
user, access_token, refresh_token = _login_user(db, client)
create_response = client.post(
"/api/todos/",
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token},
json={"task": "Specific Todo"}
)
todo_id = create_response.json()["id"]
response = client.get(
f"/api/todos/{todo_id}",
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token}
)
assert response.status_code == status.HTTP_200_OK
data = response.json()
assert data["id"] == todo_id
assert data["task"] == "Specific Todo"
assert data["owner_id"] == user.id
def test_read_single_todo_not_found(client: TestClient, db: Session):
user, access_token, refresh_token = _login_user(db, client)
response = client.get(
"/api/todos/9999", # Non-existent ID
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token}
)
assert response.status_code == status.HTTP_404_NOT_FOUND
def test_read_single_todo_forbidden(client: TestClient, db: Session):
user, access_token, refresh_token = _login_user(db, client)
# Create a todo for another user
other_user, other_password = generators.create_user(db)
other_login_rsp = generators.login(db, other_user.username, other_password)
other_access_token = other_login_rsp["access_token"]
other_refresh_token = other_login_rsp["refresh_token"]
other_create_response = client.post("/api/todos/", headers={"Authorization": f"Bearer {other_access_token}"}, cookies={"refresh_token": other_refresh_token}, json={"task": "Other User Todo"})
other_todo_id = other_create_response.json()["id"]
# Try to access the other user's todo
response = client.get(
f"/api/todos/{other_todo_id}",
headers={"Authorization": f"Bearer {access_token}"}, # Using the first user's token
cookies={"refresh_token": refresh_token}
)
assert response.status_code == status.HTTP_404_NOT_FOUND # Service raises 404 if not found for *this* user
def test_update_todo(client: TestClient, db: Session):
user, access_token, refresh_token = _login_user(db, client)
create_response = client.post(
"/api/todos/",
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token},
json={"task": "Update Me"}
)
todo_id = create_response.json()["id"]
update_data = {"task": "Updated Task", "complete": True}
response = client.put(
f"/api/todos/{todo_id}",
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token},
json=update_data
)
assert response.status_code == status.HTTP_200_OK
data = response.json()
assert data["id"] == todo_id
assert data["task"] == update_data["task"]
assert data["complete"] == update_data["complete"]
assert data["owner_id"] == user.id
# Verify update by reading again
get_response = client.get(
f"/api/todos/{todo_id}",
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token}
)
assert get_response.json()["task"] == update_data["task"]
assert get_response.json()["complete"] == update_data["complete"]
def test_update_todo_not_found(client: TestClient, db: Session):
user, access_token, refresh_token = _login_user(db, client)
update_data = {"task": "Updated Task", "complete": True}
response = client.put(
"/api/todos/9999", # Non-existent ID
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token},
json=update_data
)
assert response.status_code == status.HTTP_404_NOT_FOUND
def test_delete_todo(client: TestClient, db: Session):
user, access_token, refresh_token = _login_user(db, client)
create_response = client.post(
"/api/todos/",
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token},
json={"task": "Delete Me"}
)
todo_id = create_response.json()["id"]
response = client.delete(
f"/api/todos/{todo_id}",
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token}
)
assert response.status_code == status.HTTP_200_OK # Delete returns the deleted item
assert response.json()["id"] == todo_id
# Verify deletion by trying to read
get_response = client.get(
f"/api/todos/{todo_id}",
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token}
)
assert get_response.status_code == status.HTTP_404_NOT_FOUND
def test_delete_todo_not_found(client: TestClient, db: Session):
user, access_token, refresh_token = _login_user(db, client)
response = client.delete(
"/api/todos/9999", # Non-existent ID
headers={"Authorization": f"Bearer {access_token}"},
cookies={"refresh_token": refresh_token}
)
assert response.status_code == status.HTTP_404_NOT_FOUND
# --- Test Authentication/Authorization ---
def test_create_todo_unauthorized(client: TestClient):
response = client.post("/api/todos/", json={"task": "No Auth"})
assert response.status_code == status.HTTP_401_UNAUTHORIZED
def test_read_todos_unauthorized(client: TestClient):
response = client.get("/api/todos/")
assert response.status_code == status.HTTP_401_UNAUTHORIZED