diff options
Diffstat (limited to 'internal/game/quit_casino_test.go')
| -rw-r--r-- | internal/game/quit_casino_test.go | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/internal/game/quit_casino_test.go b/internal/game/quit_casino_test.go index a62e9cf..f055e07 100644 --- a/internal/game/quit_casino_test.go +++ b/internal/game/quit_casino_test.go @@ -150,6 +150,118 @@ func TestStopCancelsQuit(t *testing.T) { } } +// Plain quit mid-round points the player at "quit now" and its forfeit. +func TestQuitMidRoundMentionsQuitNow(t *testing.T) { + g, sess := quitTestGame(t) + 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}) + conn := sess.Conn.(*casinoTestConn) + + conn.data = nil + g.doQuit(sess) + + if !strings.Contains(string(conn.data), `"quit now"`) || !strings.Contains(string(conn.data), "forfeit") { + t.Fatalf("expected a quit-now reminder with the forfeit warning, got %q", string(conn.data)) + } +} + +// "quit now" starts the logout countdown while the player keeps their seat +// and wager; the stake is forfeited and the seat freed only on the final +// tick, immediately before the disconnect. +func TestQuitNowForfeitsOnlyAtLogout(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) + + // Still seated, still committed, countdown running. + if _, playing := g.Casino.Participation("alice"); !playing { + t.Fatal("quit now freed the seat before the logout tick") + } + if !g.quitResting("alice") { + t.Fatal("quit now did not start the rest countdown") + } + + // Drive the countdown to its final tick (fires on the 11th engine tick). + 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") + } + // Alice's stake was debited when she bet and never refunded or paid: the + // forfeit. Bob remains seated with his round untouched. + if wallet.Credits != 990 { + t.Fatalf("alice's credits were disturbed by the forfeit: %d", wallet.Credits) + } + if _, playing := g.Casino.Participation("bob"); !playing { + t.Fatal("quit now removed the wrong player") + } + if sess.Player != nil || sess.State != net.StateMenu { + t.Fatal("quit now did not log the player out") + } + if _, stillLoggedIn := g.loggedInChars["alice"]; stillLoggedIn { + t.Fatal("quit now did not remove the session from the logged-in map") + } + if g.quitResting("alice") { + t.Fatal("countdown timer was not cleared after logout") + } +} + +// Until the logout tick, "stop" cancels a pending quit-now and leaves the +// wager intact: the player keeps their seat mid-round. +func TestQuitNowCancelledByStopMidRound(t *testing.T) { + g, sess := quitTestGame(t) + 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}) + + g.doQuitNow(sess) + g.executeStop(sess, nil, "stop") + + if g.quitResting("alice") { + t.Fatal("stop did not cancel the pending quit-now countdown") + } + if _, playing := g.Casino.Participation("alice"); !playing { + t.Fatal("cancelled quit-now still freed the seat") + } + // The wager is still committed after the cancellation. + if events := g.Casino.Leave(1, "blackjack", "alice"); len(events) == 0 || !strings.Contains(events[0].Message, "middle of a blackjack round") { + t.Fatalf("wager was not still committed after the cancelled quit-now: %+v", events) + } +} + +// A quit-now at a machine also holds the machine until the logout tick. +func TestQuitNowAtMachineHoldsUntilLogout(t *testing.T) { + g, sess := quitTestGame(t) + sess.Account = &player.Account{Name: "alice"} + cfg := casino.MachineConfig{ID: "slots", Game: casino.GameSlots, MinBet: 1, MaxBet: 100} + g.Casino.JoinMachine(1, cfg, "alice") + + g.doQuitNow(sess) + + if _, playing := g.Casino.Participation("alice"); !playing { + t.Fatal("quit now freed the machine before the logout tick") + } + 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 machine at the logout tick") + } + if sess.Player != nil || sess.State != net.StateMenu { + t.Fatal("quit now did not log the player out") + } +} + // Stop and quit share one departure path: both refuse mid-round and both // leave gracefully between rounds. func TestStopMatchesQuitCasinoPolicy(t *testing.T) { |
