
- Set up project structure and FastAPI application - Create database models with SQLAlchemy - Set up Alembic for database migrations - Create API endpoints for todo CRUD operations - Add health check endpoint - Add unit tests for API endpoints - Configure Ruff for linting and formatting
159 lines
4.4 KiB
Python
159 lines
4.4 KiB
Python
from fastapi.testclient import TestClient
|
|
|
|
from app.db.session import Base, engine
|
|
from main import app
|
|
|
|
# Create test client
|
|
client = TestClient(app)
|
|
|
|
|
|
def test_health_check():
|
|
"""Test health check endpoint."""
|
|
response = client.get("/health")
|
|
assert response.status_code == 200
|
|
assert response.json() == {"status": "ok"}
|
|
|
|
|
|
def test_create_todo():
|
|
"""Test creating a todo item."""
|
|
# Create test database tables
|
|
Base.metadata.create_all(bind=engine)
|
|
|
|
# Define test data
|
|
test_todo = {
|
|
"title": "Test Todo",
|
|
"description": "This is a test todo",
|
|
"completed": False,
|
|
}
|
|
|
|
# Send POST request
|
|
response = client.post("/todos", json=test_todo)
|
|
|
|
# Check response
|
|
assert response.status_code == 201
|
|
data = response.json()
|
|
assert data["title"] == test_todo["title"]
|
|
assert data["description"] == test_todo["description"]
|
|
assert data["completed"] == test_todo["completed"]
|
|
assert "id" in data
|
|
assert "created_at" in data
|
|
assert "updated_at" in data
|
|
|
|
# Cleanup test data
|
|
client.delete(f"/todos/{data['id']}")
|
|
|
|
|
|
def test_read_todos():
|
|
"""Test reading all todo items."""
|
|
# Create test database tables
|
|
Base.metadata.create_all(bind=engine)
|
|
|
|
# Create a test todo item
|
|
test_todo = {
|
|
"title": "Test Todo for Reading",
|
|
"description": "This is a test todo for reading",
|
|
"completed": False,
|
|
}
|
|
create_response = client.post("/todos", json=test_todo)
|
|
created_todo = create_response.json()
|
|
|
|
# Send GET request
|
|
response = client.get("/todos")
|
|
|
|
# Check response
|
|
assert response.status_code == 200
|
|
assert isinstance(response.json(), list)
|
|
|
|
# Cleanup test data
|
|
client.delete(f"/todos/{created_todo['id']}")
|
|
|
|
|
|
def test_read_todo():
|
|
"""Test reading a specific todo item."""
|
|
# Create test database tables
|
|
Base.metadata.create_all(bind=engine)
|
|
|
|
# Create a test todo item
|
|
test_todo = {
|
|
"title": "Test Todo for Reading One",
|
|
"description": "This is a test todo for reading one",
|
|
"completed": False,
|
|
}
|
|
create_response = client.post("/todos", json=test_todo)
|
|
created_todo = create_response.json()
|
|
|
|
# Send GET request
|
|
response = client.get(f"/todos/{created_todo['id']}")
|
|
|
|
# Check response
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["id"] == created_todo["id"]
|
|
assert data["title"] == test_todo["title"]
|
|
assert data["description"] == test_todo["description"]
|
|
assert data["completed"] == test_todo["completed"]
|
|
|
|
# Cleanup test data
|
|
client.delete(f"/todos/{created_todo['id']}")
|
|
|
|
|
|
def test_update_todo():
|
|
"""Test updating a todo item."""
|
|
# Create test database tables
|
|
Base.metadata.create_all(bind=engine)
|
|
|
|
# Create a test todo item
|
|
test_todo = {
|
|
"title": "Test Todo for Updating",
|
|
"description": "This is a test todo for updating",
|
|
"completed": False,
|
|
}
|
|
create_response = client.post("/todos", json=test_todo)
|
|
created_todo = create_response.json()
|
|
|
|
# Define update data
|
|
update_data = {
|
|
"title": "Updated Test Todo",
|
|
"completed": True,
|
|
}
|
|
|
|
# Send PUT request
|
|
response = client.put(f"/todos/{created_todo['id']}", json=update_data)
|
|
|
|
# Check response
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["id"] == created_todo["id"]
|
|
assert data["title"] == update_data["title"]
|
|
assert data["description"] == test_todo["description"] # Should remain unchanged
|
|
assert data["completed"] == update_data["completed"]
|
|
|
|
# Cleanup test data
|
|
client.delete(f"/todos/{created_todo['id']}")
|
|
|
|
|
|
def test_delete_todo():
|
|
"""Test deleting a todo item."""
|
|
# Create test database tables
|
|
Base.metadata.create_all(bind=engine)
|
|
|
|
# Create a test todo item
|
|
test_todo = {
|
|
"title": "Test Todo for Deleting",
|
|
"description": "This is a test todo for deleting",
|
|
"completed": False,
|
|
}
|
|
create_response = client.post("/todos", json=test_todo)
|
|
created_todo = create_response.json()
|
|
|
|
# Send DELETE request
|
|
response = client.delete(f"/todos/{created_todo['id']}")
|
|
|
|
# Check response
|
|
assert response.status_code == 204
|
|
assert response.content == b"" # No content should be returned
|
|
|
|
# Verify the todo is deleted
|
|
get_response = client.get(f"/todos/{created_todo['id']}")
|
|
assert get_response.status_code == 404
|