feat: add scouting search sorting and pagination

This commit is contained in:
bisco
2026-04-07 17:18:36 +02:00
parent 6c53cae7a1
commit 6d8af021ce
4 changed files with 270 additions and 5 deletions

View File

@ -238,6 +238,145 @@ class ScoutingSearchViewsTests(TestCase):
self.assertContains(response, self.player_pg.full_name)
self.assertNotContains(response, self.player_wing.full_name)
def test_sorting_by_player_level_field(self):
taller_player = Player.objects.create(
full_name="Big Wing",
birth_date=date(2001, 5, 5),
position="SF",
height_cm=Decimal("208.00"),
weight_kg=Decimal("101.00"),
)
response = self.client.get(reverse("scouting:player_list"), {"sort": "height_desc"})
player_names = [player.full_name for player in response.context["players"]]
self.assertEqual(player_names[:3], [taller_player.full_name, self.player_wing.full_name, self.player_pg.full_name])
def test_sorting_by_matching_context_stat_field(self):
response = self.client.get(
reverse("scouting:player_list"),
{"competition": self.comp_a.id, "sort": "assists_desc"},
)
player_names = [player.full_name for player in response.context["players"]]
self.assertEqual(player_names[:2], [self.player_pg.full_name, self.player_wing.full_name])
def test_context_sorting_preserves_matching_context_semantics(self):
second_context = PlayerSeason.objects.create(
player=self.player_pg,
season=self.season_2024,
team=self.team_b,
competition=self.comp_a,
)
PlayerSeasonStats.objects.create(
player_season=second_context,
points=Decimal("12.00"),
assists=Decimal("9.00"),
steals=Decimal("1.00"),
turnovers=Decimal("2.80"),
blocks=Decimal("0.20"),
efg_pct=Decimal("49.00"),
ts_pct=Decimal("52.00"),
plus_minus=Decimal("1.00"),
offensive_rating=Decimal("107.00"),
defensive_rating=Decimal("109.00"),
)
response = self.client.get(
reverse("scouting:player_list"),
{"competition": self.comp_a.id, "team": self.team_a.id, "sort": "assists_desc"},
)
player = next(player for player in response.context["players"] if player.id == self.player_pg.id)
self.assertEqual(player.matching_context.id, self.ctx_pg_good.id)
self.assertContains(response, "AST 7.50")
self.assertNotContains(response, "AST 9.00")
def test_pagination_works_on_player_list(self):
for index in range(25):
Player.objects.create(
full_name=f"Depth Player {index:02d}",
birth_date=date(2000, 1, 1),
position="SG",
height_cm=Decimal("190.00"),
weight_kg=Decimal("84.00"),
)
response = self.client.get(reverse("scouting:player_list"), {"page": 2})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context["page_obj"].number, 2)
self.assertContains(response, "Page 2 of 2")
self.assertContains(response, "Depth Player 20")
self.assertContains(response, "Depth Player 24")
self.assertNotContains(response, "Depth Player 00")
def test_pagination_preserves_filters_and_sort_order(self):
for index in range(25):
Player.objects.create(
full_name=f"Guard Prospect {index:02d}",
birth_date=date(2001, 1, 1),
position="PG",
height_cm=Decimal("185.00"),
weight_kg=Decimal("80.00"),
)
response = self.client.get(
reverse("scouting:player_list"),
{"position": "PG", "sort": "name_desc"},
)
self.assertContains(response, "position=PG")
self.assertContains(response, "sort=name_desc")
self.assertContains(response, "page=2")
def test_combined_filters_sort_and_pagination(self):
for index in range(25):
player = Player.objects.create(
full_name=f"Playmaker Prospect {index:02d}",
birth_date=date(2003, 1, 1),
position="PG",
height_cm=Decimal("186.00"),
weight_kg=Decimal("79.00"),
)
context = PlayerSeason.objects.create(
player=player,
season=self.season_2025,
team=self.team_a,
competition=self.comp_a,
)
PlayerSeasonStats.objects.create(
player_season=context,
points=Decimal("10.00"),
assists=Decimal(str(30 - index)),
steals=Decimal("1.00"),
turnovers=Decimal("2.00"),
blocks=Decimal("0.10"),
efg_pct=Decimal("50.00"),
ts_pct=Decimal("56.00"),
plus_minus=Decimal("1.00"),
offensive_rating=Decimal("109.00"),
defensive_rating=Decimal("108.00"),
)
response = self.client.get(
reverse("scouting:player_list"),
{
"position": "PG",
"competition": self.comp_a.id,
"sort": "assists_desc",
"page": 2,
},
)
self.assertEqual(response.context["page_obj"].number, 2)
player_names = [player.full_name for player in response.context["players"]]
self.assertNotIn(self.player_wing.full_name, player_names)
self.assertEqual(player_names[0], "Playmaker Prospect 20")
self.assertIn("Marco Guard", player_names)
self.assertContains(response, "sort=assists_desc")
self.assertContains(response, "competition=%s" % self.comp_a.id)
class SeedScoutingDataCommandTests(TestCase):
def test_seed_command_creates_expected_core_objects(self):