Add tests for event theme API functionality
All checks were successful
Build and Push Docker Images / changes (push) Successful in 5s
Build and Push Docker Images / build-backend (push) Successful in 52s
Build and Push Docker Images / build-frontend (push) Has been skipped

Introduces comprehensive tests for creating, listing, updating, and retrieving event themes. Includes scenarios with valid data, invalid data, and pagination to ensure robust API behavior. Adds necessary fixtures to support the new test cases.
This commit is contained in:
2025-03-05 12:42:06 +01:00
parent b3a4c45202
commit b384512b9c
2 changed files with 295 additions and 0 deletions

View File

@@ -0,0 +1,274 @@
import uuid
from typing import Dict
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session
from app.api.routes.event_themes import router as event_themes_router
from app.core.database import get_db
from app.main import app as main_app
# Mock the get_db dependency
@pytest.fixture
def override_get_db(db_session):
"""Override get_db dependency for testing."""
return db_session
@pytest.fixture
def app(override_get_db):
"""Create a FastAPI test application with overridden dependencies."""
app = FastAPI()
app.include_router(event_themes_router, prefix="/event_themes", tags=["event_themes"])
# Override the get_db dependency
app.dependency_overrides[get_db] = lambda: override_get_db
return app
@pytest.fixture
def client(app: FastAPI) -> TestClient:
return TestClient(app)
@pytest.fixture
def theme_data() -> Dict:
return {
"name": "Animal Safari",
"description": "A wild and fun theme with safari animals",
"preview_image_url": "https://example.com/safari.jpg",
"color_palette": {
"primary": "#f4a261",
"secondary": "#2a9d8f",
"background": "#ffffff",
"text": "#264653"
},
"fonts": {
"header": "Safari Display",
"body": "Nunito Sans"
}
}
class TestEventThemesRoutes:
def test_create_theme_success(self, client, db_session, theme_data):
# Act
response = client.post("/event_themes", json=theme_data)
# Assert
assert response.status_code == 200
data = response.json()
assert data["name"] == theme_data["name"]
assert data["description"] == theme_data["description"]
assert data["preview_image_url"] == theme_data["preview_image_url"]
assert data["color_palette"] == theme_data["color_palette"]
assert data["fonts"] == theme_data["fonts"]
assert "id" in data
def test_create_theme_invalid_data(self, client, db_session):
# Arrange
invalid_data = {
"name": "", # Empty name should not be allowed
"color_palette": {}, # Empty color palette
"fonts": {} # Empty fonts
}
# Act
response = client.post("/event_themes", json=invalid_data)
print(response.json())
# Assert
assert response.status_code == 422
def test_list_themes_empty(self, client, db_session):
# Act
response = client.get("/event_themes")
# Assert
assert response.status_code == 200
assert response.json() == []
def test_list_themes_with_data(self, client, db_session, theme_data):
# Arrange
create_response = client.post("/event_themes", json=theme_data)
assert create_response.status_code == 200
# Act
response = client.get("/event_themes")
# Assert
assert response.status_code == 200
themes = response.json()
assert len(themes) == 1
assert themes[0]["name"] == theme_data["name"]
assert "id" in themes[0]
def test_get_theme_by_id(self, client, db_session, theme_data):
# Arrange
create_response = client.post("/event_themes", json=theme_data)
assert create_response.status_code == 200
created_theme = create_response.json()
# Act
response = client.get(f"/event_themes/{created_theme['id']}")
# Assert
assert response.status_code == 200
data = response.json()
assert data["name"] == theme_data["name"]
assert data["color_palette"] == theme_data["color_palette"]
assert data["fonts"] == theme_data["fonts"]
assert data["id"] == created_theme["id"]
def test_get_theme_not_found(self, client, db_session):
# Act
random_id = str(uuid.uuid4())
response = client.get(f"/event_themes/{random_id}")
# Assert
assert response.status_code == 404
assert response.json()["detail"] == "Theme not found"
def test_update_theme_success(self, client, db_session, theme_data):
# Arrange
create_response = client.post("/event_themes", json=theme_data)
assert create_response.status_code == 200
created_theme = create_response.json()
update_data = {
"name": "Updated Safari Theme",
"color_palette": {
"primary": "#ff0000",
"secondary": "#00ff00",
"background": "#ffffff",
"text": "#000000"
}
}
# Act
response = client.patch(
f"/event_themes/{created_theme['id']}",
json=update_data
)
# Assert
assert response.status_code == 200
data = response.json()
assert data["name"] == update_data["name"]
assert data["color_palette"] == update_data["color_palette"]
assert data["id"] == created_theme["id"]
# Original fonts should remain unchanged
assert data["fonts"] == theme_data["fonts"]
def test_update_theme_not_found(self, client, db_session):
# Arrange
random_id = str(uuid.uuid4())
update_data = {
"name": "Updated Theme"
}
# Act
response = client.patch(
f"/event_themes/{random_id}",
json=update_data
)
# Assert
assert response.status_code == 404
assert response.json()["detail"] == "Theme not found"
def test_update_theme_invalid_data(self, client, db_session, theme_data):
# Act
response = client.post("/event_themes", json=theme_data)
# Assert initial creation
assert response.status_code == 200
theme = response.json()
assert "id" in theme
# Act - update with invalid data
invalid_data = {
"color_palette": "not_a_dict" # Should be a dictionary
}
response = client.patch(f"/event_themes/{theme['id']}", json=invalid_data)
# Assert
assert response.status_code == 422
def test_list_themes_pagination(self, client, db_session, theme_data):
# Arrange
# Create multiple themes
for i in range(5):
theme_data_copy = theme_data.copy()
theme_data_copy["name"] = f"Theme {i}"
response = client.post("/event_themes", json=theme_data_copy)
assert response.status_code == 200
# Act
response = client.get("/event_themes?skip=2&limit=2")
# Assert
assert response.status_code == 200
themes = response.json()
assert len(themes) == 2 # Should only return 2 themes
assert themes[0]["name"] == "Theme 2"
assert themes[1]["name"] == "Theme 3"
assert all("id" in theme for theme in themes)
def test_list_themes_default_pagination(self, client, db_session, theme_data):
# Arrange
# Create more than default limit themes
for i in range(15): # Reduced from 150 for faster testing
theme_data_copy = theme_data.copy()
theme_data_copy["name"] = f"Theme {i}"
response = client.post("/event_themes", json=theme_data_copy)
assert response.status_code == 200
# Act
response = client.get("/event_themes")
# Assert
assert response.status_code == 200
themes = response.json()
assert len(themes) <= 100 # Default limit is 100
assert all("id" in theme for theme in themes)
def test_update_theme_partial(self, client, db_session, theme_data):
# Arrange
create_response = client.post("/event_themes", json=theme_data)
assert create_response.status_code == 200
created_theme = create_response.json()
update_data = {
"name": "Partially Updated Theme"
}
# Act
response = client.patch(
f"/event_themes/{created_theme['id']}",
json=update_data
)
# Assert
assert response.status_code == 200
data = response.json()
assert data["name"] == update_data["name"]
assert data["id"] == created_theme["id"]
# Other fields should remain unchanged
assert data["color_palette"] == theme_data["color_palette"]
assert data["fonts"] == theme_data["fonts"]
def test_create_theme_missing_required_fields(self, client, db_session):
# Arrange
incomplete_data = {
"description": "Missing required name field"
}
# Act
response = client.post("/event_themes", json=incomplete_data)
# Assert
assert response.status_code == 422

View File

@@ -1,6 +1,7 @@
# tests/conftest.py
import uuid
from datetime import datetime, timezone
from typing import Dict
import pytest
@@ -326,3 +327,23 @@ def gift_category_fixture(db_session, mock_user, event_fixture):
db_session.add(gift_category)
db_session.commit()
return gift_category
@pytest.fixture
def theme_data() -> Dict:
return {
"name": "Animal Safari",
"description": "A wild and fun theme with safari animals",
"preview_image_url": "https://example.com/safari.jpg",
"color_palette": {
"primary": "#f4a261",
"secondary": "#2a9d8f",
"background": "#ffffff",
"text": "#264653"
},
"fonts": {
"header": "Safari Display",
"body": "Nunito Sans"
}
}