""" Automatiserer det som til nå (ADR-057) kun er verifisert manuelt i tre lag i nettleser: den optimistiske versjonssjekken på round_hole. Kaller de faktiske router-funksjonene i rounds.py direkte (samme SQL, samme feilhåndtering som produksjon) -- IKKE en gjenimplementering av logikken. """ import pytest from fastapi import HTTPException from app import db as app_db from app.auth import CurrentUser from app.routers.rounds import ( HoleUpdate, SideHoleUpdate, update_hole, update_side_hole, ) from tests.conftest import create_hole, create_participant, create_round async def _setup_round_with_hole(hole_number: int = 1): async with app_db.plain_connection() as conn: from tests.conftest import create_user owner_id = await create_user() round_id = await create_round(conn, owner_id) participant_id = await create_participant(conn, round_id, user_id=owner_id, is_owner=True) await create_hole(conn, participant_id, hole_number=hole_number, par=4, stroke_index=9) return owner_id, round_id, participant_id async def test_update_succeeds_and_increments_version(pool): owner_id, round_id, participant_id = await _setup_round_with_hole() user = CurrentUser(user_id=owner_id) out = await update_hole( round_id, participant_id, 1, HoleUpdate(score=5, expected_version=1), user=user, ) assert out.score == 5 assert out.version == 2 async def test_stale_version_is_rejected_with_409(pool): owner_id, round_id, participant_id = await _setup_round_with_hole() user = CurrentUser(user_id=owner_id) # "Enhet 1" leser versjon 1, skriver -- lykkes, hullet er nå versjon 2. await update_hole(round_id, participant_id, 1, HoleUpdate(score=4, expected_version=1), user=user) # "Enhet 2" leste OGSÅ versjon 1 (før enhet 1 sin skriving nådde den), # og prøver nå å skrive basert på den utdaterte versjonen. with pytest.raises(HTTPException) as exc_info: await update_hole(round_id, participant_id, 1, HoleUpdate(score=6, expected_version=1), user=user) assert exc_info.value.status_code == 409 assert exc_info.value.detail["code"] == "STALE_VERSION" async def test_expected_version_none_bypasses_check(pool): owner_id, round_id, participant_id = await _setup_round_with_hole() user = CurrentUser(user_id=owner_id) await update_hole(round_id, participant_id, 1, HoleUpdate(score=4, expected_version=1), user=user) # Hullet er nå versjon 2 -- men vi sender ingen forventet versjon i det # hele tatt (klient som ikke sender feltet, f.eks. eldre app-versjon). out = await update_hole(round_id, participant_id, 1, HoleUpdate(score=7, expected_version=None), user=user) assert out.score == 7 assert out.version == 3 async def test_nonexistent_hole_is_404_not_409(pool): owner_id, round_id, participant_id = await _setup_round_with_hole(hole_number=1) user = CurrentUser(user_id=owner_id) with pytest.raises(HTTPException) as exc_info: await update_hole(round_id, participant_id, 18, HoleUpdate(score=4, expected_version=1), user=user) assert exc_info.value.status_code == 404 assert exc_info.value.detail["code"] == "NOT_FOUND" # --------------------------------------------------------------------------- # round_side (delt-ball-format) -- update_side_hole har sin EGEN 404-vs-409- # logikk (egen eksistenssjekk lagt til i samme runde som versjonskolonnen), # adskilt kode fra update_hole -- verifiseres derfor separat, ikke antatt # dekket av testene over. # --------------------------------------------------------------------------- async def _setup_round_with_side_hole(hole_number: int = 1): async with app_db.plain_connection() as conn: from tests.conftest import create_user, new_id owner_id = await create_user() round_id = await create_round(conn, owner_id) side_id = new_id() await conn.execute( "INSERT INTO round_side (id, round_id, label) VALUES ($1, $2, 'Side A')", side_id, round_id, ) participant_id = await create_participant( conn, round_id, user_id=owner_id, is_owner=True, ) await conn.execute( "UPDATE round_participant SET round_side_id = $1 WHERE id = $2", side_id, participant_id ) await conn.execute( """ INSERT INTO round_hole (round_side_id, hole_number, par, stroke_index, version) VALUES ($1, $2, 4, 9, 1) """, side_id, hole_number, ) return owner_id, round_id, side_id async def test_side_hole_stale_version_is_409(pool): owner_id, round_id, side_id = await _setup_round_with_side_hole() user = CurrentUser(user_id=owner_id) await update_side_hole(round_id, side_id, 1, SideHoleUpdate(score=4, expected_version=1), user=user) with pytest.raises(HTTPException) as exc_info: await update_side_hole(round_id, side_id, 1, SideHoleUpdate(score=6, expected_version=1), user=user) assert exc_info.value.status_code == 409 assert exc_info.value.detail["code"] == "STALE_VERSION" async def test_side_hole_nonexistent_is_404_not_409(pool): owner_id, round_id, side_id = await _setup_round_with_side_hole(hole_number=1) user = CurrentUser(user_id=owner_id) with pytest.raises(HTTPException) as exc_info: await update_side_hole(round_id, side_id, 18, SideHoleUpdate(score=4, expected_version=1), user=user) assert exc_info.value.status_code == 404 assert exc_info.value.detail["code"] == "NOT_FOUND"