feat(ingestion): add first real-data importer flow
This commit is contained in:
@ -11,6 +11,7 @@ from django.urls import reverse
|
||||
|
||||
from .models import (
|
||||
Competition,
|
||||
ExternalEntityMapping,
|
||||
FavoritePlayer,
|
||||
Player,
|
||||
PlayerNote,
|
||||
@ -442,6 +443,89 @@ class SeedScoutingDataCommandTests(TestCase):
|
||||
self.assertEqual(Specialty.objects.count(), first_counts["specialties"])
|
||||
|
||||
|
||||
class FirstRealIngestionFlowTests(TestCase):
|
||||
COMMAND_NAME = "import_hoopdata_demo_competition"
|
||||
SOURCE_NAME = "hoopdata_demo"
|
||||
|
||||
def test_importer_command_runs_successfully(self):
|
||||
call_command(self.COMMAND_NAME)
|
||||
self.assertGreaterEqual(Player.objects.count(), 2)
|
||||
|
||||
def test_importer_creates_expected_core_objects(self):
|
||||
call_command(self.COMMAND_NAME)
|
||||
|
||||
self.assertTrue(Competition.objects.filter(name="Italian Serie A2").exists())
|
||||
self.assertTrue(Season.objects.filter(name="2025-2026", start_year=2025, end_year=2026).exists())
|
||||
self.assertTrue(Player.objects.filter(full_name="Andrea Pulse", position="PG").exists())
|
||||
self.assertTrue(Player.objects.filter(full_name="Matteo Harbor", position="C").exists())
|
||||
self.assertTrue(PlayerSeason.objects.filter(player__full_name="Andrea Pulse").exists())
|
||||
self.assertTrue(PlayerSeasonStats.objects.filter(player_season__player__full_name="Andrea Pulse").exists())
|
||||
self.assertEqual(
|
||||
ExternalEntityMapping.objects.filter(source_name=self.SOURCE_NAME).count(),
|
||||
7,
|
||||
)
|
||||
|
||||
def test_importer_is_idempotent_for_same_input(self):
|
||||
call_command(self.COMMAND_NAME)
|
||||
first_counts = {
|
||||
"players": Player.objects.count(),
|
||||
"teams": Team.objects.count(),
|
||||
"contexts": PlayerSeason.objects.count(),
|
||||
"stats": PlayerSeasonStats.objects.count(),
|
||||
"mappings": ExternalEntityMapping.objects.count(),
|
||||
}
|
||||
|
||||
call_command(self.COMMAND_NAME)
|
||||
|
||||
self.assertEqual(Player.objects.count(), first_counts["players"])
|
||||
self.assertEqual(Team.objects.count(), first_counts["teams"])
|
||||
self.assertEqual(PlayerSeason.objects.count(), first_counts["contexts"])
|
||||
self.assertEqual(PlayerSeasonStats.objects.count(), first_counts["stats"])
|
||||
self.assertEqual(ExternalEntityMapping.objects.count(), first_counts["mappings"])
|
||||
|
||||
def test_importer_does_not_overwrite_internal_scouting_fields(self):
|
||||
role = Role.objects.create(name="internal role", slug="internal-role")
|
||||
specialty = Specialty.objects.create(name="internal specialty", slug="internal-specialty")
|
||||
call_command(self.COMMAND_NAME)
|
||||
|
||||
player = Player.objects.get(full_name="Andrea Pulse")
|
||||
player.roles.add(role)
|
||||
player.specialties.add(specialty)
|
||||
|
||||
call_command(self.COMMAND_NAME)
|
||||
player.refresh_from_db()
|
||||
|
||||
self.assertTrue(player.roles.filter(pk=role.pk).exists())
|
||||
self.assertTrue(player.specialties.filter(pk=specialty.pk).exists())
|
||||
|
||||
def test_importer_does_not_interfere_with_user_owned_data(self):
|
||||
call_command(self.COMMAND_NAME)
|
||||
user = User.objects.create_user(username="ingest_user", password="pass12345")
|
||||
player = Player.objects.get(full_name="Andrea Pulse")
|
||||
favorite = FavoritePlayer.objects.create(user=user, player=player)
|
||||
note = PlayerNote.objects.create(user=user, player=player, body="Tracked after import")
|
||||
saved = SavedSearch.objects.create(user=user, name="Imported PG", params={"name": "Andrea"})
|
||||
|
||||
call_command(self.COMMAND_NAME)
|
||||
|
||||
self.assertTrue(FavoritePlayer.objects.filter(pk=favorite.pk).exists())
|
||||
self.assertTrue(PlayerNote.objects.filter(pk=note.pk).exists())
|
||||
self.assertTrue(SavedSearch.objects.filter(pk=saved.pk).exists())
|
||||
|
||||
def test_imported_data_is_visible_in_search_and_detail_flows(self):
|
||||
call_command(self.COMMAND_NAME)
|
||||
|
||||
list_response = self.client.get(reverse("scouting:player_list"), {"name": "Andrea"})
|
||||
self.assertEqual(list_response.status_code, 200)
|
||||
self.assertContains(list_response, "Andrea Pulse")
|
||||
|
||||
player = Player.objects.get(full_name="Andrea Pulse")
|
||||
detail_response = self.client.get(reverse("scouting:player_detail", args=[player.id]))
|
||||
self.assertEqual(detail_response.status_code, 200)
|
||||
self.assertContains(detail_response, "Andrea Pulse")
|
||||
self.assertContains(detail_response, "PTS 17.2")
|
||||
|
||||
|
||||
class FavoritePlayerViewsTests(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
|
||||
Reference in New Issue
Block a user