""" Massimport av spillere (`POST /orgs/{id}/players/bulk`, se FEATURE_ BACKLOG.md "Massimport av spillere til organisasjon/turnering"). Samme dedup-mønster som registration.py sin selvregistrering (ADR-017 Beslutning B), utvidet til alle PlayerCreate-felt. """ import app.db as app_db from app.routers.players import PlayerCreate, create_players_bulk from tests.conftest import create_org, create_player async def test_bulk_creates_new_players_without_email(pool): org_id = await create_org() rows = [ PlayerCreate(display_name="Ny Spiller A"), PlayerCreate(display_name="Ny Spiller B", handicap_index=12.5), ] results = await create_players_bulk(rows, organization_id=org_id) assert len(results) == 2 assert all(r.status == "created" for r in results) assert {r.player.display_name for r in results} == {"Ny Spiller A", "Ny Spiller B"} async def test_bulk_matches_existing_player_by_email_and_fills_only_empty_fields(pool): org_id = await create_org() existing_id = await create_player(org_id, display_name="Eksisterende Spiller") # Sett e-post + ett annet felt på forhånd -- importen skal IKKE # overskrive country (allerede satt), kun matche på e-posten. async with app_db.org_connection(org_id) as conn: await conn.execute( "UPDATE player SET email = 'match@example.com', country = 'Norge' WHERE id = $1", existing_id, ) rows = [ PlayerCreate( display_name="Annet Navn Fra CSV", # skal IKKE overskrive display_name email="match@example.com", country="Sverige", # skal IKKE overskrive et allerede satt felt club="Ny Klubb", # skal FYLLES INN (var tomt før) handicap_index=8.0, # skal FYLLES INN (var tomt før) ), ] results = await create_players_bulk(rows, organization_id=org_id) assert len(results) == 1 assert results[0].status == "updated" p = results[0].player assert p.id == existing_id assert p.display_name == "Eksisterende Spiller" # uendret assert p.country == "Norge" # uendret (var allerede satt) assert p.club == "Ny Klubb" # fylt inn (var tomt) assert p.handicap_index == 8.0 # fylt inn (var tomt) async def test_bulk_without_email_never_matches_existing_and_always_creates(pool): org_id = await create_org() await create_player(org_id, display_name="Har Ikke E-post") rows = [PlayerCreate(display_name="Har Ikke E-post")] results = await create_players_bulk(rows, organization_id=org_id) assert results[0].status == "created" async with app_db.org_connection(org_id) as conn: count = await conn.fetchval( "SELECT count(*) FROM player WHERE display_name = 'Har Ikke E-post'" ) assert count == 2 # den opprinnelige + den nye, ingen falsk dedup uten e-post async def test_bulk_paid_flag_never_overwritten_on_existing_match(pool): org_id = await create_org() existing_id = await create_player(org_id, display_name="Betalt Spiller") async with app_db.org_connection(org_id) as conn: await conn.execute( "UPDATE player SET email = 'paid@example.com', paid = true WHERE id = $1", existing_id ) rows = [PlayerCreate(display_name="X", email="paid@example.com", paid=False)] results = await create_players_bulk(rows, organization_id=org_id) assert results[0].player.paid is True # uendret, COALESCE mot ikke-nullbar kolonne er en no-op async def test_bulk_is_transactional_across_rows(pool): """Selve listen kjøres i org_connection sin egen transaksjon -- ingen partial-suksess-forventning her, men bekreft at flere rader i samme kall faktisk lander i samme, konsistente organisasjon.""" org_id = await create_org() rows = [PlayerCreate(display_name=f"Spiller {i}") for i in range(5)] results = await create_players_bulk(rows, organization_id=org_id) assert len(results) == 5 assert len({r.player.id for r in results}) == 5