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