aboutsummaryrefslogtreecommitdiff
path: root/internal/game/hardening_quit_bet_warning_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/hardening_quit_bet_warning_test.go')
-rw-r--r--internal/game/hardening_quit_bet_warning_test.go79
1 files changed, 79 insertions, 0 deletions
diff --git a/internal/game/hardening_quit_bet_warning_test.go b/internal/game/hardening_quit_bet_warning_test.go
new file mode 100644
index 0000000..4daef49
--- /dev/null
+++ b/internal/game/hardening_quit_bet_warning_test.go
@@ -0,0 +1,79 @@
+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)
+ }
+}