216 lines
6.6 KiB
Python
216 lines
6.6 KiB
Python
"""
|
|
Unit tests for Match Pydantic schemas.
|
|
"""
|
|
|
|
import pytest
|
|
from datetime import datetime, timezone
|
|
from pydantic import ValidationError
|
|
|
|
from app.schemas.match import (
|
|
MatchBase,
|
|
MatchCreate,
|
|
MatchUpdate,
|
|
MatchResponse,
|
|
MatchListResponse,
|
|
MatchStatsResponse
|
|
)
|
|
|
|
|
|
class TestMatchBase:
|
|
"""Test MatchBase schema."""
|
|
|
|
def test_match_base_valid(self):
|
|
"""Test creating a valid MatchBase."""
|
|
match_data = {
|
|
"home_team": "PSG",
|
|
"away_team": "Olympique de Marseille",
|
|
"date": datetime.now(timezone.utc),
|
|
"league": "Ligue 1",
|
|
"status": "scheduled"
|
|
}
|
|
|
|
match = MatchBase(**match_data)
|
|
|
|
assert match.home_team == "PSG"
|
|
assert match.away_team == "Olympique de Marseille"
|
|
assert match.league == "Ligue 1"
|
|
assert match.status == "scheduled"
|
|
|
|
def test_match_base_home_team_too_long(self):
|
|
"""Test that home_team exceeds max length."""
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
MatchBase(
|
|
home_team="A" * 256, # Too long
|
|
away_team="Olympique de Marseille",
|
|
date=datetime.now(timezone.utc),
|
|
league="Ligue 1",
|
|
status="scheduled"
|
|
)
|
|
|
|
assert "at most 255 characters" in str(exc_info.value).lower()
|
|
|
|
def test_match_base_away_team_empty(self):
|
|
"""Test that away_team cannot be empty."""
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
MatchBase(
|
|
home_team="PSG",
|
|
away_team="", # Empty
|
|
date=datetime.now(timezone.utc),
|
|
league="Ligue 1",
|
|
status="scheduled"
|
|
)
|
|
|
|
assert "at least 1 character" in str(exc_info.value).lower()
|
|
|
|
def test_match_base_status_too_long(self):
|
|
"""Test that status exceeds max length."""
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
MatchBase(
|
|
home_team="PSG",
|
|
away_team="Olympique de Marseille",
|
|
date=datetime.now(timezone.utc),
|
|
league="Ligue 1",
|
|
status="A" * 51 # Too long
|
|
)
|
|
|
|
assert "at most 50 characters" in str(exc_info.value).lower()
|
|
|
|
|
|
class TestMatchCreate:
|
|
"""Test MatchCreate schema."""
|
|
|
|
def test_match_create_valid(self):
|
|
"""Test creating a valid MatchCreate."""
|
|
match_data = {
|
|
"home_team": "Barcelona",
|
|
"away_team": "Real Madrid",
|
|
"date": datetime.now(timezone.utc),
|
|
"league": "La Liga",
|
|
"status": "in_progress"
|
|
}
|
|
|
|
match = MatchCreate(**match_data)
|
|
|
|
assert match.home_team == "Barcelona"
|
|
assert match.away_team == "Real Madrid"
|
|
assert match.status == "in_progress"
|
|
|
|
|
|
class TestMatchUpdate:
|
|
"""Test MatchUpdate schema."""
|
|
|
|
def test_match_update_partial(self):
|
|
"""Test updating only some fields."""
|
|
update_data = {
|
|
"status": "completed"
|
|
}
|
|
|
|
match_update = MatchUpdate(**update_data)
|
|
|
|
assert match_update.status == "completed"
|
|
assert match_update.home_team is None
|
|
assert match_update.away_team is None
|
|
|
|
def test_match_update_all_fields(self):
|
|
"""Test updating all fields."""
|
|
update_data = {
|
|
"home_team": "Manchester City",
|
|
"away_team": "Liverpool",
|
|
"date": datetime.now(timezone.utc),
|
|
"league": "Premier League",
|
|
"status": "in_progress"
|
|
}
|
|
|
|
match_update = MatchUpdate(**update_data)
|
|
|
|
assert match_update.home_team == "Manchester City"
|
|
assert match_update.away_team == "Liverpool"
|
|
assert match_update.league == "Premier League"
|
|
assert match_update.status == "in_progress"
|
|
|
|
def test_match_update_empty(self):
|
|
"""Test that MatchUpdate can be empty."""
|
|
match_update = MatchUpdate()
|
|
|
|
assert match_update.home_team is None
|
|
assert match_update.away_team is None
|
|
assert match_update.date is None
|
|
assert match_update.league is None
|
|
assert match_update.status is None
|
|
|
|
|
|
class TestMatchResponse:
|
|
"""Test MatchResponse schema."""
|
|
|
|
def test_match_response_from_dict(self):
|
|
"""Test creating MatchResponse from dictionary."""
|
|
match_dict = {
|
|
"id": 1,
|
|
"home_team": "Juventus",
|
|
"away_team": "Inter Milan",
|
|
"date": datetime.now(timezone.utc),
|
|
"league": "Serie A",
|
|
"status": "scheduled"
|
|
}
|
|
|
|
match = MatchResponse(**match_dict)
|
|
|
|
assert match.id == 1
|
|
assert match.home_team == "Juventus"
|
|
assert match.away_team == "Inter Milan"
|
|
assert match.league == "Serie A"
|
|
assert match.status == "scheduled"
|
|
|
|
|
|
class TestMatchListResponse:
|
|
"""Test MatchListResponse schema."""
|
|
|
|
def test_match_list_response(self):
|
|
"""Test creating a MatchListResponse."""
|
|
matches_data = [
|
|
{
|
|
"id": 1,
|
|
"home_team": "PSG",
|
|
"away_team": "Olympique de Marseille",
|
|
"date": datetime.now(timezone.utc),
|
|
"league": "Ligue 1",
|
|
"status": "scheduled"
|
|
},
|
|
{
|
|
"id": 2,
|
|
"home_team": "Barcelona",
|
|
"away_team": "Real Madrid",
|
|
"date": datetime.now(timezone.utc),
|
|
"league": "La Liga",
|
|
"status": "scheduled"
|
|
}
|
|
]
|
|
|
|
response = MatchListResponse(data=matches_data, count=2, meta={"page": 1})
|
|
|
|
assert response.count == 2
|
|
assert len(response.data) == 2
|
|
assert response.meta["page"] == 1
|
|
|
|
|
|
class TestMatchStatsResponse:
|
|
"""Test MatchStatsResponse schema."""
|
|
|
|
def test_match_stats_response(self):
|
|
"""Test creating a MatchStatsResponse."""
|
|
stats = {
|
|
"total_matches": 10,
|
|
"matches_by_league": {"Ligue 1": 5, "La Liga": 5},
|
|
"matches_by_status": {"scheduled": 5, "completed": 5},
|
|
"upcoming_matches": 5,
|
|
"completed_matches": 5
|
|
}
|
|
|
|
match_stats = MatchStatsResponse(**stats)
|
|
|
|
assert match_stats.total_matches == 10
|
|
assert match_stats.matches_by_league["Ligue 1"] == 5
|
|
assert match_stats.matches_by_status["scheduled"] == 5
|
|
assert match_stats.upcoming_matches == 5
|
|
assert match_stats.completed_matches == 5
|