diff --git a/server/store/postgres_integration_test.go b/server/store/postgres_integration_test.go index aff4eb61..aa41763d 100644 --- a/server/store/postgres_integration_test.go +++ b/server/store/postgres_integration_test.go @@ -531,14 +531,11 @@ func TestPostgreSQLProposalClaimAndResponseAreAtomic(t *testing.T) { } } -// TestPostgreSQLProposalDeclineRequeuesEveryParticipant is a real, severe -// bug this session found by reading the code, not by a failing test: no -// path anywhere transitioned a PROPOSED ticket back to QUEUED after a -// decline. A stranded ticket is invisible to the matcher (which only reads -// state='QUEUED'), still counts as the player's one active ticket (blocking -// a fresh queue_create), and is renewable forever by an ordinary heartbeat -// -- a player proposed a match with someone who declines had no way back -// into matchmaking without realising they had to manually cancel first. +// TestPostgreSQLProposalDeclineRequeuesEveryParticipant protects the durable +// decline boundary: every ticket returns to QUEUED, while the decliner's +// separate penalty prevents an immediate replacement queue ticket. Without +// the requeue, tickets are invisible to the matcher and remain trapped in +// PROPOSED despite the proposal having closed. func TestPostgreSQLProposalDeclineRequeuesEveryParticipant(t *testing.T) { db := openIntegrationPostgres(t) applyIntegrationMigrations(t, db) @@ -582,7 +579,7 @@ func TestPostgreSQLProposalDeclineRequeuesEveryParticipant(t *testing.T) { t.Fatal(err) } if stateA != "QUEUED" { - t.Fatalf("decliner's own ticket state = %s, want QUEUED (no cooldown mechanism exists yet to justify leaving it stuck)", stateA) + t.Fatalf("decliner's own ticket state = %s, want QUEUED while cooldown is recorded separately", stateA) } if stateB != "QUEUED" { t.Fatalf("uninvolved participant's ticket state = %s, want QUEUED -- they must not be stranded by someone else's decline", stateB) @@ -606,15 +603,11 @@ func TestPostgreSQLProposalDeclineRequeuesEveryParticipant(t *testing.T) { } } -// TestPostgreSQLProposalTimeoutRequeuesEveryParticipant is the timeout -// sibling of the decline test above: a proposal that simply times out (no -// explicit decline, nobody ever responds) hits the exact same -// ProposalExpireSQL/ProposalParticipantExpireSQL path with the exact same -// gap -- neither ever touched queue_tickets, so this is the same severe -// stranding bug reached a different way. Uses GetProposal (the recovery/read -// path) rather than RespondToProposal, since a real client that just missed -// the expiry event and comes back later to check on it is exactly the -// scenario this path exists for. +// TestPostgreSQLProposalTimeoutRequeuesEveryParticipant protects the timeout +// sibling of the decline path: expiry must requeue every ticket and record a +// timeout cooldown for each participant who failed to respond. It uses +// GetProposal, the recovery/read path, to exercise a client returning after +// it missed the expiry event. func TestPostgreSQLProposalTimeoutRequeuesEveryParticipant(t *testing.T) { db := openIntegrationPostgres(t) applyIntegrationMigrations(t, db)