Files
hoopscout-v3/backend/scouting/tests/test_api.py
T
2026-06-03 21:37:15 +02:00

234 lines
6.7 KiB
Python

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"}