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:
@@ -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
|
||||||
114
backend/tests/schemas/test_event_theme_schema.py
Normal file
114
backend/tests/schemas/test_event_theme_schema.py
Normal 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
|
||||||
Reference in New Issue
Block a user