package game import ( "strings" "testing" "thehouseoficarus/internal/casino" ) // Quitting at a slot machine must take one command: a machine between spins // has no committed stake, so "quit" stops autobet AND frees the seat instead // of reporting the player as still playing (the old flow needed a second // quit and warned about a forfeit that could not happen). func TestQuitAtMachineStopsAutobetAndLeavesInOneAttempt(t *testing.T) { g, sess := quitTestGame(t) cfg := casino.MachineConfig{ID: "slots", Game: casino.GameSlots, MinBet: 1, MaxBet: 100, SpinTicks: 1} g.Casino.JoinMachine(1, cfg, "alice") wallet := casinoWallet{g: g, p: sess.Player} if events := g.Casino.SetMachineBet(1, "slots", "alice", 10, wallet); len(events) == 0 { t.Fatal("bet produced no events") } // Let the bet's spin finish: the machine is now between spins. for i := 0; i < 30 && g.Casino.MachineBusy("alice"); i++ { g.Casino.Tick() } if events := g.Casino.EnableMachineAutoBet(1, "slots", "alice", wallet); len(events) != 0 { t.Fatalf("enabling autobet emitted events: %+v", events) } conn := sess.Conn.(*casinoTestConn) conn.data = nil g.doQuit(sess) out := string(conn.data) if !g.quitResting() { t.Fatalf("quit between spins did not start the rest countdown: %q", out) } if _, playing := g.Casino.Participation("alice"); playing { t.Fatalf("quit left the player at the machine, requiring a second quit: %q", out) } if !strings.Contains(out, "Autobet stopped") { t.Fatalf("quit did not stop autobet: %q", out) } if strings.Contains(out, "WARNING") || strings.Contains(out, "forfeit") { t.Fatalf("quit warned about a stake that does not exist: %q", out) } } // A machine mid-spin really does hold a committed stake, so quit must still // refuse it (with the forfeit warning) rather than silently discard the spin. func TestQuitMidSpinStillWarnsAboutTheCommittedStake(t *testing.T) { g, sess := quitTestGame(t) cfg := casino.MachineConfig{ID: "slots", Game: casino.GameSlots, MinBet: 1, MaxBet: 100, SpinTicks: 50} g.Casino.JoinMachine(1, cfg, "alice") wallet := casinoWallet{g: g, p: sess.Player} if events := g.Casino.SetMachineBet(1, "slots", "alice", 10, wallet); len(events) == 0 { t.Fatal("bet produced no events") } conn := sess.Conn.(*casinoTestConn) conn.data = nil g.doQuit(sess) out := string(conn.data) if g.quitResting() { t.Fatal("quit started the countdown with a spin in flight") } if _, playing := g.Casino.Participation("alice"); !playing { t.Fatal("quit freed the machine mid-spin") } if !strings.Contains(out, "forfeit") { t.Fatalf("expected the forfeit warning for a committed stake, got %q", out) } }