import pytest from django.contrib.auth.models import User from django.urls import reverse from rest_framework.test import APIClient from scouting.models import League, Player, PlayerGameLog, PlayerSeasonStat, Season, Team @pytest.fixture def api_client(): return APIClient() @pytest.fixture def scout_user(db): user = User.objects.create_user(username="scout", password="test-password") user.profile.role = "scout" user.profile.save(update_fields=["role"]) return user @pytest.fixture def sample_data(db): lba = League.objects.create(name="Lega Basket Serie A", code="LBA", region="Europe", country="Italy") endesa = League.objects.create(name="Liga Endesa", code="ACB", region="Europe", country="Spain") nba = League.objects.create( name="National Basketball Association", code="NBA", region="North America", country="USA", ) season = Season.objects.create(label="2025-26", is_active=True) milano = Team.objects.create(name="Milano", league=lba, country="Italy") madrid = Team.objects.create(name="Madrid", league=endesa, country="Spain") boston = Team.objects.create(name="Boston", league=nba, country="USA") guard = Player.objects.create( first_name="Luca", last_name="Marini", position="PG", role="Primary ball handler", birth_year=2001, height_cm=190, weight_kg=86, nationality="Italy", current_team=milano, ) wing = Player.objects.create( first_name="Mateo", last_name="Santos", position="SF", role="3 and D wing", birth_year=1999, height_cm=201, weight_kg=96, nationality="Spain", current_team=madrid, ) nba_big = Player.objects.create( first_name="Cole", last_name="Anderson", position="C", role="Rim runner", birth_year=1998, height_cm=211, weight_kg=112, nationality="USA", current_team=boston, ) PlayerSeasonStat.objects.create( player=guard, team=milano, league=lba, season=season, games_played=28, minutes_per_game=29.4, points_per_game=16.8, assists_per_game=6.2, rebounds_per_game=3.8, steals_per_game=1.4, blocks_per_game=0.1, turnovers_per_game=2.3, field_goal_percentage=48.1, three_point_percentage=39.6, free_throw_percentage=84.2, efficiency_rating=20.5, true_shooting_percentage=59.2, usage_percentage=25.0, total_points=470, total_assists=174, total_rebounds=106, ) PlayerSeasonStat.objects.create( player=wing, team=madrid, league=endesa, season=season, games_played=25, minutes_per_game=24.1, points_per_game=11.2, assists_per_game=2.1, rebounds_per_game=5.5, steals_per_game=1.1, blocks_per_game=0.5, turnovers_per_game=1.0, field_goal_percentage=44.0, three_point_percentage=37.4, free_throw_percentage=79.3, efficiency_rating=13.7, true_shooting_percentage=55.8, usage_percentage=17.5, total_points=280, total_assists=52, total_rebounds=138, ) PlayerSeasonStat.objects.create( player=nba_big, team=boston, league=nba, season=season, games_played=30, minutes_per_game=18.2, points_per_game=8.4, assists_per_game=1.0, rebounds_per_game=7.8, steals_per_game=0.4, blocks_per_game=1.9, turnovers_per_game=1.2, field_goal_percentage=62.0, three_point_percentage=0, free_throw_percentage=68.0, efficiency_rating=12.1, true_shooting_percentage=63.4, usage_percentage=14.1, total_points=252, total_assists=30, total_rebounds=234, ) PlayerGameLog.objects.create( player=guard, team=milano, opponent="Bologna", league=lba, season=season, game_date="2026-01-10", points=28, assists=9, rebounds=5, efficiency_rating=32.0, ) PlayerGameLog.objects.create( player=guard, team=milano, opponent="Venezia", league=lba, season=season, game_date="2026-01-17", points=6, assists=3, rebounds=1, efficiency_rating=4.0, ) return {"guard": guard, "wing": wing, "nba_big": nba_big} @pytest.mark.django_db def test_players_api_requires_authentication(api_client): response = api_client.get(reverse("player-list")) assert response.status_code == 403 @pytest.mark.django_db def test_players_can_be_filtered_by_name_position_league_and_stats(api_client, scout_user, sample_data): api_client.force_authenticate(scout_user) response = api_client.get( reverse("player-list"), { "q": "luca", "position": "PG", "league": "LBA", "points_per_game__gte": "15", "assists_per_game__gte": "5", }, ) assert response.status_code == 200 payload = response.json() assert payload["count"] == 1 assert payload["results"][0]["name"] == "Luca Marini" assert payload["results"][0]["league"]["code"] == "LBA" assert payload["results"][0]["stats"]["points_per_game"] == "16.80" @pytest.mark.django_db def test_players_are_ranked_by_efficiency_then_points(api_client, scout_user, sample_data): api_client.force_authenticate(scout_user) response = api_client.get(reverse("player-list"), {"region": "Europe"}) assert response.status_code == 200 names = [player["name"] for player in response.json()["results"]] assert names == ["Luca Marini", "Mateo Santos"] @pytest.mark.django_db def test_player_detail_exposes_best_and_worst_performances(api_client, scout_user, sample_data): api_client.force_authenticate(scout_user) response = api_client.get(reverse("player-detail", args=[sample_data["guard"].id])) assert response.status_code == 200 payload = response.json() assert payload["name"] == "Luca Marini" assert payload["best_game"]["opponent"] == "Bologna" assert payload["best_game"]["efficiency_rating"] == "32.00" assert payload["worst_game"]["opponent"] == "Venezia" assert payload["worst_game"]["efficiency_rating"] == "4.00" @pytest.mark.django_db def test_me_endpoint_returns_user_role(api_client, scout_user): api_client.force_authenticate(scout_user) response = api_client.get(reverse("me")) assert response.status_code == 200 assert response.json() == {"username": "scout", "role": "scout"}