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.
274 lines
8.6 KiB
Python
274 lines
8.6 KiB
Python
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 |