Add tests and validation for EventTheme schema

Introduced extensive test cases to validate `EventTheme` schemas, ensuring proper handling of valid and invalid inputs, optional fields, and partial updates. Enhanced schema validation by adding constraints for `name`, `color_palette`, and `fonts` fields, as well as updating `id` to use `UUID` type for consistency. These changes improve data integrity and increase confidence in schema-related functionality.
This commit is contained in:
2025-03-05 12:41:31 +01:00
parent c5478e45b6
commit d65d1f3164
2 changed files with 139 additions and 5 deletions

View File

@@ -1,13 +1,27 @@
# app/schemas/event_theme.py
from typing import Dict, Optional from typing import Dict, Optional
from pydantic import BaseModel from uuid import UUID # Add this import
from pydantic import BaseModel, Field, validator, field_validator
class EventThemeBase(BaseModel): class EventThemeBase(BaseModel):
name: str name: str = Field(..., min_length=1) # Ensures name is not empty
description: Optional[str] = None description: Optional[str] = None
preview_image_url: Optional[str] = None preview_image_url: Optional[str] = None
color_palette: Dict[str, str] color_palette: Dict[str, str] = Field(..., min_items=1) # Ensures at least one color
fonts: Dict[str, str] fonts: Dict[str, str] = Field(..., min_items=1) # Ensures at least one font
@field_validator('color_palette')
def validate_color_palette(cls, v):
if not v:
raise ValueError("color_palette cannot be empty")
return v
@field_validator('fonts')
def validate_fonts(cls, v):
if not v:
raise ValueError("fonts cannot be empty")
return v
class EventThemeCreate(EventThemeBase): class EventThemeCreate(EventThemeBase):
@@ -20,12 +34,18 @@ class EventThemeUpdate(EventThemeBase):
fonts: Optional[Dict[str, str]] = None fonts: Optional[Dict[str, str]] = None
# Move EventThemeInDBBase before EventThemeResponse
class EventThemeInDBBase(EventThemeBase): class EventThemeInDBBase(EventThemeBase):
id: str id: UUID # Changed from str to UUID to match the model
class Config: class Config:
from_attributes = True from_attributes = True
# Now EventThemeResponse can properly inherit from EventThemeInDBBase
class EventThemeResponse(EventThemeInDBBase):
pass
class EventTheme(EventThemeInDBBase): class EventTheme(EventThemeInDBBase):
pass pass

View File

@@ -0,0 +1,114 @@
import pytest
from uuid import UUID
from pydantic import ValidationError
from app.schemas.event_theme import (
EventThemeCreate,
EventThemeUpdate,
EventThemeResponse,
EventTheme
)
class TestEventThemeSchemas:
def test_valid_theme_create(self, theme_data):
"""Test creating a valid theme with all required fields"""
theme = EventThemeCreate(**theme_data)
assert theme.name == theme_data["name"]
assert theme.description == theme_data["description"]
assert theme.preview_image_url == theme_data["preview_image_url"]
assert theme.color_palette == theme_data["color_palette"]
assert theme.fonts == theme_data["fonts"]
@pytest.mark.parametrize("invalid_data,expected_error", [
(
{"name": "", "color_palette": {"primary": "#000"}, "fonts": {"main": "Arial"}},
"name"
),
(
{"name": "Theme", "color_palette": {}, "fonts": {"main": "Arial"}},
"color_palette"
),
(
{"name": "Theme", "color_palette": {"primary": "#000"}, "fonts": {}},
"fonts"
),
(
{},
"name"
),
])
def test_invalid_theme_create(self, invalid_data, expected_error):
"""Test validation errors for invalid theme data"""
with pytest.raises(ValidationError) as exc_info:
EventThemeCreate(**invalid_data)
assert expected_error in str(exc_info.value)
def test_theme_update_partial(self):
"""Test updating theme with partial data"""
update_data = {
"name": "Updated Theme"
}
theme = EventThemeUpdate(**update_data)
assert theme.name == "Updated Theme"
assert theme.color_palette is None
assert theme.fonts is None
def test_theme_response(self, theme_data):
"""Test theme response schema with ID"""
response_data = {
**theme_data,
"id": "123e4567-e89b-12d3-a456-426614174000"
}
theme = EventThemeResponse(**response_data)
assert isinstance(theme.id, UUID)
assert str(theme.id) == "123e4567-e89b-12d3-a456-426614174000"
assert theme.name == theme_data["name"]
def test_color_palette_validation(self):
"""Test color palette validation"""
valid_data = {
"name": "Test Theme",
"color_palette": {"primary": "#000000", "secondary": "#FFFFFF"},
"fonts": {"main": "Arial"}
}
theme = EventThemeCreate(**valid_data)
assert theme.color_palette == valid_data["color_palette"]
def test_fonts_validation(self):
"""Test fonts validation"""
valid_data = {
"name": "Test Theme",
"color_palette": {"primary": "#000000"},
"fonts": {"main": "Arial", "secondary": "Helvetica"}
}
theme = EventThemeCreate(**valid_data)
assert theme.fonts == valid_data["fonts"]
def test_optional_fields(self):
"""Test optional fields handling"""
minimal_data = {
"name": "Minimal Theme",
"color_palette": {"primary": "#000000"},
"fonts": {"main": "Arial"}
}
theme = EventThemeCreate(**minimal_data)
assert theme.description is None
assert theme.preview_image_url is None
@pytest.mark.parametrize("field,value", [
("name", "Updated Name"),
("color_palette", {"new": "#123456"}),
("fonts", {"new": "Times New Roman"}),
("description", "New description"),
("preview_image_url", "https://new-image.jpg"),
])
def test_update_individual_fields(self, field, value):
"""Test updating individual fields"""
update_data = {field: value}
theme = EventThemeUpdate(**update_data)
assert getattr(theme, field) == value
def test_theme_model_config(self):
"""Test model configuration"""
assert hasattr(EventThemeResponse.Config, 'from_attributes')
assert EventThemeResponse.Config.from_attributes is True