from pathlib import Path ROOT = Path(__file__).resolve().parents[1] APP = (ROOT / "ui_builder/static/app.js").read_text(encoding="utf-8") MAPPING = (ROOT / "hockey_data/mapping_context.py").read_text(encoding="utf-8") def test_side_penalty_mapping_context_is_derived_from_active_penalties_without_overwriting_manual_selection(): start = APP.index("async function hockeySyncPenaltySideMappingContext") end = APP.index("function penaltyTargetAssignmentKey", start) snippet = APP[start:end] assert 'sortedPenaltyEntries("home")[0]' in snippet assert 'sortedPenaltyEntries("away")[0]' in snippet for key in ( "active_home_penalty_id", "active_home_penalty_player_id", "active_home_penalty_player_db_id", "active_home_penalty_team_penalty", "active_away_penalty_id", "active_away_penalty_player_id", "active_away_penalty_player_db_id", "active_away_penalty_team_penalty", ): assert f"{key}:" in snippet # BUILD84: selected_* is an explicit operator choice, so the automatic mirror # must never replace it with the first active penalty. assert "selected_home_penalty_id:" not in snippet assert "selected_away_penalty_id:" not in snippet def test_manual_side_penalty_selection_keeps_separate_mapping_identifiers(): start = APP.index("async function hockeySelectPenaltyForPreview") end = APP.index("function hockeyPenaltyCard", start) snippet = APP[start:end] for key in ( "selected_home_penalty_id", "selected_home_penalty_player_id", "selected_home_penalty_player_db_id", "selected_home_penalty_team_penalty", "selected_away_penalty_id", "selected_away_penalty_player_id", "selected_away_penalty_player_db_id", "selected_away_penalty_team_penalty", ): assert f"{key}:" in snippet assert key in MAPPING assert "const playerIds = hockeyPenaltyPlayerIdentifiers(component, event);" in snippet