Files
hoopscout-v2/app/scouting/tests.py

170 lines
6.3 KiB
Python

from datetime import date
from decimal import Decimal
from django.test import TestCase
from django.urls import reverse
from .models import Competition, Player, PlayerSeason, PlayerSeasonStats, Role, Season, Specialty, Team
class ScoutingSearchViewsTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.role_playmaker = Role.objects.create(name="playmaker", slug="playmaker")
cls.role_3d = Role.objects.create(name="3-and-D", slug="3-and-d")
cls.specialty_defense = Specialty.objects.create(name="defense", slug="defense")
cls.specialty_offball = Specialty.objects.create(name="off ball", slug="off-ball")
cls.comp_a = Competition.objects.create(name="League A")
cls.comp_b = Competition.objects.create(name="League B")
cls.team_a = Team.objects.create(name="Team A", country="IT")
cls.team_b = Team.objects.create(name="Team B", country="IT")
cls.season_2025 = Season.objects.create(name="2025-2026", start_year=2025, end_year=2026)
cls.season_2024 = Season.objects.create(name="2024-2025", start_year=2024, end_year=2025)
cls.player_pg = Player.objects.create(
full_name="Marco Guard",
birth_date=date(2002, 1, 1),
position="PG",
height_cm=Decimal("188.00"),
weight_kg=Decimal("82.00"),
nationality="IT",
)
cls.player_pg.roles.add(cls.role_playmaker)
cls.player_pg.specialties.add(cls.specialty_defense)
cls.player_wing = Player.objects.create(
full_name="Luca Wing",
birth_date=date(1998, 2, 2),
position="SF",
height_cm=Decimal("201.00"),
weight_kg=Decimal("95.00"),
)
cls.player_wing.roles.add(cls.role_3d)
cls.player_wing.specialties.add(cls.specialty_offball)
cls.ctx_pg_good = PlayerSeason.objects.create(
player=cls.player_pg,
season=cls.season_2025,
team=cls.team_a,
competition=cls.comp_a,
)
PlayerSeasonStats.objects.create(
player_season=cls.ctx_pg_good,
points=Decimal("16.00"),
assists=Decimal("7.50"),
steals=Decimal("1.80"),
turnovers=Decimal("2.10"),
blocks=Decimal("0.30"),
efg_pct=Decimal("53.20"),
ts_pct=Decimal("58.10"),
plus_minus=Decimal("4.20"),
offensive_rating=Decimal("112.00"),
defensive_rating=Decimal("104.00"),
)
cls.ctx_pg_other = PlayerSeason.objects.create(
player=cls.player_pg,
season=cls.season_2024,
team=cls.team_b,
competition=cls.comp_b,
)
PlayerSeasonStats.objects.create(
player_season=cls.ctx_pg_other,
points=Decimal("10.00"),
assists=Decimal("4.00"),
steals=Decimal("1.00"),
turnovers=Decimal("3.50"),
blocks=Decimal("0.20"),
efg_pct=Decimal("48.00"),
ts_pct=Decimal("50.00"),
plus_minus=Decimal("-2.00"),
offensive_rating=Decimal("101.00"),
defensive_rating=Decimal("112.00"),
)
cls.ctx_wing = PlayerSeason.objects.create(
player=cls.player_wing,
season=cls.season_2025,
team=cls.team_b,
competition=cls.comp_a,
)
PlayerSeasonStats.objects.create(
player_season=cls.ctx_wing,
points=Decimal("14.00"),
assists=Decimal("2.00"),
steals=Decimal("1.20"),
turnovers=Decimal("1.90"),
blocks=Decimal("0.70"),
efg_pct=Decimal("55.00"),
ts_pct=Decimal("60.00"),
plus_minus=Decimal("1.50"),
offensive_rating=Decimal("108.00"),
defensive_rating=Decimal("106.00"),
)
def test_player_list_page_loads(self):
response = self.client.get(reverse("scouting:player_list"))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Scout Search")
def test_player_detail_page_loads(self):
response = self.client.get(reverse("scouting:player_detail", args=[self.player_pg.id]))
self.assertEqual(response.status_code, 200)
self.assertContains(response, self.player_pg.full_name)
def test_filter_by_player_level_fields(self):
response = self.client.get(
reverse("scouting:player_list"),
{"position": "PG", "role": self.role_playmaker.id, "specialty": self.specialty_defense.id},
)
self.assertContains(response, self.player_pg.full_name)
self.assertNotContains(response, self.player_wing.full_name)
def test_filter_by_context_fields_and_stats(self):
response = self.client.get(
reverse("scouting:player_list"),
{
"competition": self.comp_a.id,
"season": self.season_2025.id,
"team": self.team_a.id,
"min_ts_pct": "57",
},
)
self.assertContains(response, self.player_pg.full_name)
self.assertNotContains(response, self.player_wing.full_name)
def test_no_false_positive_from_different_context_rows(self):
response = self.client.get(
reverse("scouting:player_list"),
{
"team": self.team_b.id,
"season": self.season_2024.id,
"min_ts_pct": "57",
},
)
self.assertNotContains(response, self.player_pg.full_name)
def test_combined_pg_under_age_with_assists(self):
response = self.client.get(
reverse("scouting:player_list"),
{
"position": "PG",
"max_age": "25",
"min_assists": "7",
},
)
self.assertContains(response, self.player_pg.full_name)
self.assertNotContains(response, self.player_wing.full_name)
def test_combined_team_and_defensive_rating_quality_filter(self):
response = self.client.get(
reverse("scouting:player_list"),
{
"team": self.team_a.id,
"max_defensive_rating": "105",
},
)
self.assertContains(response, self.player_pg.full_name)
self.assertNotContains(response, self.player_wing.full_name)