generated from bisco/codex-bootstrap
234 lines
6.7 KiB
Python
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"}
|