224 lines
8.0 KiB
Python
224 lines
8.0 KiB
Python
from datetime import date
|
|
|
|
import pytest
|
|
from django.urls import reverse
|
|
|
|
from apps.competitions.models import Competition, Season
|
|
from apps.players.models import Nationality, Player, Position, Role
|
|
from apps.stats.models import PlayerSeason, PlayerSeasonStats
|
|
from apps.teams.models import Team
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_players_api_list_and_detail(client):
|
|
nationality = Nationality.objects.create(name="Italy", iso2_code="IT", iso3_code="ITA")
|
|
position = Position.objects.create(code="PG", name="Point Guard")
|
|
role = Role.objects.create(code="playmaker", name="Playmaker")
|
|
|
|
player = Player.objects.create(
|
|
first_name="Marco",
|
|
last_name="Rossi",
|
|
full_name="Marco Rossi",
|
|
birth_date=date(2001, 1, 5),
|
|
nationality=nationality,
|
|
nominal_position=position,
|
|
inferred_role=role,
|
|
height_cm=190,
|
|
weight_kg=84,
|
|
)
|
|
|
|
list_response = client.get(reverse("api:players"), data={"q": "rossi"})
|
|
assert list_response.status_code == 200
|
|
assert list_response.json()["count"] == 1
|
|
|
|
detail_response = client.get(reverse("api:player_detail", kwargs={"pk": player.pk}))
|
|
assert detail_response.status_code == 200
|
|
assert detail_response.json()["full_name"] == "Marco Rossi"
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_lookup_list_endpoints(client):
|
|
nationality = Nationality.objects.create(name="Spain", iso2_code="ES", iso3_code="ESP")
|
|
Competition.objects.create(
|
|
name="Liga ACB",
|
|
slug="liga-acb",
|
|
competition_type=Competition.CompetitionType.LEAGUE,
|
|
gender=Competition.Gender.MEN,
|
|
country=nationality,
|
|
)
|
|
Team.objects.create(name="Madrid Flight", slug="madrid-flight", country=nationality)
|
|
Season.objects.create(label="2025-2026", start_date=date(2025, 9, 1), end_date=date(2026, 6, 30), is_current=True)
|
|
|
|
assert client.get(reverse("api:competitions")).status_code == 200
|
|
assert client.get(reverse("api:teams")).status_code == 200
|
|
assert client.get(reverse("api:seasons")).status_code == 200
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_api_is_read_only(client):
|
|
response = client.post(reverse("api:players"), data={"q": "x"})
|
|
assert response.status_code == 403
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_players_api_search_consistent_with_ui_filters(client):
|
|
nationality = Nationality.objects.create(name="Portugal", iso2_code="PT", iso3_code="PRT")
|
|
position = Position.objects.create(code="SF", name="Small Forward")
|
|
role = Role.objects.create(code="wing", name="Wing")
|
|
competition = Competition.objects.create(
|
|
name="Liga Betclic",
|
|
slug="liga-betclic",
|
|
competition_type=Competition.CompetitionType.LEAGUE,
|
|
gender=Competition.Gender.MEN,
|
|
country=nationality,
|
|
)
|
|
team = Team.objects.create(name="Porto Hoops", slug="porto-hoops", country=nationality)
|
|
season = Season.objects.create(label="2025-2026", start_date=date(2025, 9, 1), end_date=date(2026, 6, 30))
|
|
|
|
matching = Player.objects.create(
|
|
first_name="Tiago",
|
|
last_name="Silva",
|
|
full_name="Tiago Silva",
|
|
birth_date=date(2001, 3, 1),
|
|
nationality=nationality,
|
|
nominal_position=position,
|
|
inferred_role=role,
|
|
origin_competition=competition,
|
|
origin_team=team,
|
|
)
|
|
ps = PlayerSeason.objects.create(
|
|
player=matching,
|
|
season=season,
|
|
team=team,
|
|
competition=competition,
|
|
games_played=10,
|
|
minutes_played=320,
|
|
)
|
|
PlayerSeasonStats.objects.create(
|
|
player_season=ps,
|
|
points=16.5,
|
|
rebounds=5,
|
|
assists=3,
|
|
steals=1,
|
|
blocks=0.5,
|
|
turnovers=2,
|
|
)
|
|
|
|
Player.objects.create(
|
|
first_name="Pedro",
|
|
last_name="Costa",
|
|
full_name="Pedro Costa",
|
|
birth_date=date(2001, 4, 2),
|
|
nationality=nationality,
|
|
)
|
|
|
|
params = {
|
|
"origin_competition": competition.id,
|
|
"nominal_position": position.id,
|
|
"points_per_game_min": "10",
|
|
"sort": "ppg_desc",
|
|
}
|
|
ui_response = client.get(reverse("players:index"), data=params)
|
|
api_response = client.get(reverse("api:players"), data=params)
|
|
|
|
assert ui_response.status_code == 200
|
|
assert api_response.status_code == 200
|
|
assert list(ui_response.context["players"])[0].id == matching.id
|
|
assert api_response.json()["count"] == 1
|
|
assert api_response.json()["results"][0]["id"] == matching.id
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_player_detail_api_includes_origin_fields(client):
|
|
nationality = Nationality.objects.create(name="Greece", iso2_code="GR", iso3_code="GRC")
|
|
competition = Competition.objects.create(
|
|
name="HEBA A1",
|
|
slug="heba-a1",
|
|
competition_type=Competition.CompetitionType.LEAGUE,
|
|
gender=Competition.Gender.MEN,
|
|
country=nationality,
|
|
)
|
|
team = Team.objects.create(name="Athens BC", slug="athens-bc", country=nationality)
|
|
player = Player.objects.create(
|
|
first_name="Alex",
|
|
last_name="Dimitriou",
|
|
full_name="Alex Dimitriou",
|
|
birth_date=date(2000, 2, 2),
|
|
nationality=nationality,
|
|
origin_competition=competition,
|
|
origin_team=team,
|
|
)
|
|
|
|
response = client.get(reverse("api:player_detail", kwargs={"pk": player.pk}))
|
|
assert response.status_code == 200
|
|
payload = response.json()
|
|
assert payload["origin_competition"] == competition.name
|
|
assert payload["origin_team"] == team.name
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_api_combined_filters_respect_same_player_season_context(client):
|
|
nationality = Nationality.objects.create(name="Poland", iso2_code="PL", iso3_code="POL")
|
|
competition = Competition.objects.create(
|
|
name="PLK",
|
|
slug="plk",
|
|
competition_type=Competition.CompetitionType.LEAGUE,
|
|
gender=Competition.Gender.MEN,
|
|
country=nationality,
|
|
)
|
|
season = Season.objects.create(label="2024-2025", start_date=date(2024, 9, 1), end_date=date(2025, 6, 30))
|
|
team_a = Team.objects.create(name="Warsaw", slug="warsaw", country=nationality)
|
|
team_b = Team.objects.create(name="Gdansk", slug="gdansk", country=nationality)
|
|
|
|
player = Player.objects.create(first_name="Piotr", last_name="Filter", full_name="Piotr Filter", nationality=nationality)
|
|
ps_a = PlayerSeason.objects.create(
|
|
player=player,
|
|
season=season,
|
|
team=team_a,
|
|
competition=competition,
|
|
games_played=10,
|
|
minutes_played=200,
|
|
)
|
|
PlayerSeasonStats.objects.create(player_season=ps_a, points=7, rebounds=2, assists=3, steals=1, blocks=0, turnovers=1)
|
|
ps_b = PlayerSeason.objects.create(
|
|
player=player,
|
|
season=season,
|
|
team=team_b,
|
|
competition=competition,
|
|
games_played=10,
|
|
minutes_played=300,
|
|
)
|
|
PlayerSeasonStats.objects.create(player_season=ps_b, points=21, rebounds=4, assists=5, steals=1, blocks=0, turnovers=2)
|
|
|
|
response = client.get(
|
|
reverse("api:players"),
|
|
data={"team": team_a.id, "season": season.id, "competition": competition.id, "points_per_game_min": "20"},
|
|
)
|
|
assert response.status_code == 200
|
|
assert response.json()["count"] == 0
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_players_api_returns_400_for_invalid_numeric_filter(client):
|
|
response = client.get(reverse("api:players"), data={"points_per_game_min": "abc"})
|
|
assert response.status_code == 400
|
|
payload = response.json()
|
|
assert payload["detail"] == "Invalid search parameters."
|
|
assert "points_per_game_min" in payload["errors"]
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_players_api_returns_400_for_invalid_choice_filter(client):
|
|
response = client.get(reverse("api:players"), data={"sort": "not-a-sort"})
|
|
assert response.status_code == 400
|
|
payload = response.json()
|
|
assert "sort" in payload["errors"]
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_players_api_returns_400_for_invalid_range_combination(client):
|
|
response = client.get(reverse("api:players"), data={"age_min": 30, "age_max": 20})
|
|
assert response.status_code == 400
|
|
payload = response.json()
|
|
assert "age_max" in payload["errors"]
|