Refactor theme creation and update for file management
Enhanced theme creation and update logic to include proper file organization by relocating and managing URLs for images and assets. Introduced roles validation to restrict access to superusers for these operations. Updated tests to align with the refactored logic and dependencies.
This commit is contained in:
@@ -1,62 +1,32 @@
|
||||
# tests/api/routes/test_event_themes.py
|
||||
import uuid
|
||||
from typing import Dict
|
||||
from fastapi import status
|
||||
|
||||
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
|
||||
from app.api.routes.event_themes import router as themes_router
|
||||
|
||||
|
||||
# Mock the get_db dependency
|
||||
@pytest.fixture
|
||||
def override_get_db(db_session):
|
||||
"""Override get_db dependency for testing."""
|
||||
return db_session
|
||||
class TestCreateEventTheme:
|
||||
"""Test scenarios for the create_theme endpoint."""
|
||||
|
||||
@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"])
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup_method(self, create_test_client, db_session, mock_superuser):
|
||||
self.client = create_test_client(
|
||||
router=themes_router,
|
||||
prefix="/themes",
|
||||
db_session=db_session,
|
||||
user=mock_superuser
|
||||
)
|
||||
self.db_session = db_session
|
||||
self.mock_superuser = mock_superuser
|
||||
|
||||
# Override the get_db dependency
|
||||
app.dependency_overrides[get_db] = lambda: override_get_db
|
||||
def test_create_theme_success(self, theme_data):
|
||||
"""Test successful theme creation."""
|
||||
# Make the request
|
||||
response = self.client.post("/themes/", json=theme_data)
|
||||
|
||||
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
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["name"] == theme_data["name"]
|
||||
@@ -64,211 +34,4 @@ class TestEventThemesRoutes:
|
||||
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
|
||||
assert "id" in data
|
||||
Reference in New Issue
Block a user