# backend/tests/test_scoring.py import pytest from httpx import AsyncClient pytestmark = pytest.mark.anyio async def test_scoring_flow( client: AsyncClient, auth_headers, valid_tournament_payload ): # 1. Create Tournament res = await client.post( "/tournaments", json=valid_tournament_payload, headers=auth_headers ) t_id = res.json()["id"] t_code = valid_tournament_payload["code"] # 2. Get Matches to find a Round 1 match matches_res = await client.get(f"/tournaments/{t_id}/matches") matches = matches_res.json() # Find a match that has real players (not BYE) # In double elim, Round 1 matches usually have seeds. target_match = next(m for m in matches if m["p1"] and m["p2"]) match_id = target_match["id"] next_match_id = target_match["next_win"] # Note: using alias from schema # 3. Report Score WITHOUT Auth Header (Public user with Code) score_payload = { "id": match_id, "code": t_code, "sets": [{"p1": 21, "p2": 19}, {"p1": 21, "p2": 15}], # P1 Wins } report_res = await client.post( f"/tournaments/{t_id}/matches/{match_id}/score", json=score_payload ) assert report_res.status_code == 200 # 4. Verify Winner Advanced # Fetch the *Next* match next_match_res = await client.get(f"/tournaments/{t_id}/matches/{next_match_id}") next_match = next_match_res.json() # Assert P1 from previous match is now in the next match # Note: We check if the name matches the winner winner_name = target_match["p1"] assert (next_match["p1"] == winner_name) or (next_match["p2"] == winner_name) # 5. Test Invalid Code bad_payload = score_payload.copy() bad_payload["code"] = "WRONG" bad_res = await client.post( f"/tournaments/{t_id}/matches/{match_id}/score", json=bad_payload ) assert bad_res.status_code == 403 async def test_clear_score(client: AsyncClient, auth_headers, valid_tournament_payload): # Setup: Create & Score res = await client.post( "/tournaments", json=valid_tournament_payload, headers=auth_headers ) t_id = res.json()["id"] matches = (await client.get(f"/tournaments/{t_id}/matches")).json() target = next(m for m in matches if m["p1"] and m["p2"]) score_payload = {"id": target["id"], "code": "1234", "sets": [{"p1": 25, "p2": 0}]} await client.post( f"/tournaments/{t_id}/matches/{target['id']}/score", json=score_payload ) # Verify Finished check_res = await client.get(f"/tournaments/{t_id}/matches/{target['id']}") assert check_res.json()["status"] == "Finished" # Action: Clear Score clear_res = await client.delete( f"/tournaments/{t_id}/matches/{target['id']}/score", headers=auth_headers ) assert clear_res.status_code == 200 # Verify Reset final_res = await client.get(f"/tournaments/{t_id}/matches/{target['id']}") data = final_res.json() # 1. We already fixed this to expect 'Scheduled' assert data["status"] == "Scheduled" # 2. FIX: Check 'winner_side' instead of 'winner' # Use the Enum value "none" assert data["winner_side"] == "none" assert len(data["sets"]) == 0