package game // Regression coverage for the quit refusal warning: the departure is refused // whenever a wager is committed, but only a dealt hand (or a spin in progress) // is actually forfeited on disconnect -- a stake still in the betting window is // refunded. The warning must not promise a forfeit in that case. import ( "strings" "testing" "thehouseoficarus/internal/casino" "thehouseoficarus/internal/player" ) // TestQuitRefusalWarningMatchesRefundedBet places a bet with a second seat // holding the round in the betting window (no card dealt for alice's stake), // then runs a plain quit. The message must state both outcomes, and the // refusal must still leave the player seated with no countdown running. func TestQuitRefusalWarningMatchesRefundedBet(t *testing.T) { g, sess := quitTestGame(t) sess.Account = &player.Account{Name: "alice"} cfg := casino.TableConfig{ID: "blackjack", Game: casino.GameBlackjack, MinBet: 1, MaxBet: 100} g.Casino.Join(1, cfg, "alice") g.Casino.Join(1, cfg, "bob") // bob never bets: the window stays open g.Casino.Bet(1, "blackjack", "alice", "", 10, casinoWallet{g: g, p: sess.Player}) conn := sess.Conn.(*casinoTestConn) conn.data = nil g.doQuit(sess) out := string(conn.data) if !strings.Contains(out, `"quit now"`) { t.Fatalf("expected the quit-now reminder, got %q", out) } if strings.Contains(out, "your bet will be forfeited") { t.Fatalf("warning still promises an unconditional forfeit for a betting-window stake: %q", out) } if !strings.Contains(out, "forfeit") { t.Fatalf("warning does not mention the forfeit that a dealt hand suffers: %q", out) } if !strings.Contains(out, "refund") { t.Fatalf("warning does not mention the refund a betting-window stake receives: %q", out) } // Behavior is unchanged: the refusal keeps the seat and the wager. if _, playing := g.Casino.Participation("alice"); !playing { t.Fatal("refused quit removed the player from the table") } if g.quitResting() { t.Fatal("refused quit started the rest countdown") } } // TestQuitNowBettingWindowStakeIsRefunded proves the refund half of the // warning: after "quit now" runs its countdown to the logout tick, the // betting-window stake is returned, so the old unconditional forfeit promise // would have been wrong. func TestQuitNowBettingWindowStakeIsRefunded(t *testing.T) { g, sess := quitTestGame(t) sess.Account = &player.Account{Name: "alice"} cfg := casino.TableConfig{ID: "blackjack", Game: casino.GameBlackjack, MinBet: 1, MaxBet: 100} g.Casino.Join(1, cfg, "alice") g.Casino.Join(1, cfg, "bob") g.Casino.Bet(1, "blackjack", "alice", "", 10, casinoWallet{g: g, p: sess.Player}) wallet := sess.Player g.doQuitNow(sess) for i := 0; i < 15 && sess.Player != nil; i++ { g.Ticks.Tick() } if _, playing := g.Casino.Participation("alice"); playing { t.Fatal("quit now did not free the seat at the logout tick") } if wallet.Credits != 1000 { t.Fatalf("betting-window stake was not refunded on logout: credits = %d, want 1000", wallet.Credits) } }