teecup/tests/test_session_net_hunt_display.py
Erol Haagenrud bcb712810f
All checks were successful
Backend-tester / test (push) Successful in 46s
Hastecommit
2026-08-24 09:55:04 +02:00

126 lines
5.3 KiB
Python

"""
"Jakter Jesper"-visningsmodus for lagturnering-øktens individuelle
leaderboard (migrasjon 093, del 2 av ADR-106). Øktnivå, ikke turneringnivå
-- se ADR-106-tillegget for begrunnelsen. Speiler tests/test_net_hunt_
display.py sitt konvergens-bevis-mønster.
"""
from fastapi import HTTPException
import pytest
from app.auth import CurrentUser
from app.routers.scoring import HoleScoreCreate, submit_hole_score
from app.routers.tournaments import SessionUpdate, get_individual_leaderboard, update_session
from tests.conftest import (
add_membership,
create_course,
create_match,
create_match_participant,
create_org,
create_org_hole,
create_player,
create_session,
create_team,
create_team_roster,
create_tee,
create_tournament,
create_user,
)
import app.db as app_db
async def _setup_singles_session(playing_handicap=12):
org_id = await create_org()
user_id = await create_user()
await add_membership(org_id, user_id, role="owner")
tournament_id = await create_tournament(org_id)
team_a = await create_team(org_id, tournament_id)
team_b = await create_team(org_id, tournament_id)
course_id = await create_course(org_id)
for n in range(1, 19):
await create_org_hole(org_id, course_id, hole_number=n, par=4, stroke_index=n)
tee_id = await create_tee(org_id, course_id)
session_id = await create_session(org_id, tournament_id, course_id, format="singles", scoring_mode="stroke")
match_id = await create_match(org_id, session_id, team_a, team_b)
player_id = await create_player(org_id, user_id=user_id)
roster_id = await create_team_roster(org_id, team_a, player_id)
participant_id = await create_match_participant(org_id, match_id, "a", roster_id, tee_id)
async with app_db.org_connection(org_id) as conn:
await conn.execute(
"UPDATE match_participant SET playing_handicap = $1 WHERE id = $2", playing_handicap, participant_id
)
return org_id, user_id, session_id, match_id, participant_id
async def _score(match_id, participant_id, org_id, user_id, scores: list[int]) -> None:
user = CurrentUser(user_id=user_id)
for n, gross in enumerate(scores, start=1):
await submit_hole_score(
match_id,
HoleScoreCreate(
team_side="a", match_participant_id=participant_id, hole_number=n,
gross_strokes=gross, expected_version=None,
),
org_id,
user=user,
)
async def test_hunt_differs_mid_session_but_converges_at_completion(pool):
org_id, user_id, session_id, match_id, participant_id = await _setup_singles_session(playing_handicap=12)
user = CurrentUser(user_id=user_id)
# Hull 1, par -- stroke_index 1 (<=12) -> mottar 1 slag under standard.
await _score(match_id, participant_id, org_id, user_id, [4])
lb = await get_individual_leaderboard(session_id, organization_id=org_id, user=user)
assert lb.net_display_style == "standard"
# Standard: netto = 4-1=3, til par = 3-4 = -1.
assert lb.entries[0].net_to_par == -1
await update_session(session_id, SessionUpdate(net_display_style="hunt"), organization_id=org_id)
lb = await get_individual_leaderboard(session_id, organization_id=org_id, user=user)
assert lb.net_display_style == "hunt"
# Hunt: gross(4) - FULLT spillehandicap(12) = -8, til par = -8-4 = -12.
assert lb.entries[0].net_to_par == -12
assert lb.entries[0].net_score == -8
# Fullfør økten med par på alle resterende hull -- flatt hele veien
# under hunt (alltid par -> gross-til-par alltid 0).
await _score(match_id, participant_id, org_id, user_id, [4] * 17)
lb = await get_individual_leaderboard(session_id, organization_id=org_id, user=user)
assert lb.entries[0].net_to_par == -12
# Bytt tilbake til standard nå som alle 18 hull er spilt -- KONVERGERER
# til nøyaktig samme tall (selve beviset på ekvivalensen).
await update_session(session_id, SessionUpdate(net_display_style="standard"), organization_id=org_id)
lb = await get_individual_leaderboard(session_id, organization_id=org_id, user=user)
assert lb.entries[0].net_to_par == -12
async def test_hunt_rejected_for_non_singles_fourball_session(pool):
org_id = await create_org()
user_id = await create_user()
await add_membership(org_id, user_id, role="owner")
tournament_id = await create_tournament(org_id)
course_id = await create_course(org_id)
session_id = await create_session(org_id, tournament_id, course_id, format="foursome", scoring_mode="stroke")
with pytest.raises(HTTPException) as exc_info:
await update_session(session_id, SessionUpdate(net_display_style="hunt"), organization_id=org_id)
assert exc_info.value.status_code == 400
async def test_hunt_rejected_for_hole_result_scoring_mode(pool):
org_id = await create_org()
user_id = await create_user()
await add_membership(org_id, user_id, role="owner")
tournament_id = await create_tournament(org_id)
course_id = await create_course(org_id)
session_id = await create_session(org_id, tournament_id, course_id, format="singles", scoring_mode="hole_result")
with pytest.raises(HTTPException) as exc_info:
await update_session(session_id, SessionUpdate(net_display_style="hunt"), organization_id=org_id)
assert exc_info.value.status_code == 400