aboutsummaryrefslogtreecommitdiff
path: root/internal/game/casino_forfeit_regression_test.go
blob: 9ad8016eb50feec19ecdff71b5d3c500fcd84b7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package game

// Disconnect-forfeit regressions: a player who disconnects mid-round
// forfeits the committed stake, so startup recovery must NOT refund it; a
// stake left outstanding by a genuine crash still is.

import (
	"testing"

	"thehouseoficarus/internal/casino"
)

// TestDisconnectForfeitsMachineStake: disconnecting mid-spin forfeits the
// stake (the machine frees the seat immediately); recovery must not refund
// it on the next startup.
func TestDisconnectForfeitsMachineStake(t *testing.T) {
	h := newHarness(t)
	h.seedAccount("alice", "pw", false)
	p := h.seedCharacter("alice", "alice")
	h.g.RunOnOwner(func() {
		p.Credits = 100
		h.g.Casino.JoinMachine(1, casino.MachineConfig{ID: "slots", Game: casino.GameSlots, SpinTicks: 50}, "alice")
		h.g.Casino.SetMachineBet(1, "slots", "alice", 10, casinoWallet{g: h.g, p: p})
		// The disconnect path forfeits the in-flight spin.
		h.g.Casino.MarkDisconnected("alice")
	})
	h.barrier()

	restarted := harnessFromDir(t, h.dir)
	loaded, err := restarted.g.AccountStore.LoadCharacter("alice")
	if err != nil {
		t.Fatal(err)
	}
	if loaded.Credits != 90 {
		t.Fatalf("credits after forfeited spin = %d, want 90 (disconnect forfeits)", loaded.Credits)
	}
}

// TestDisconnectForfeitsBlackjackStake: same policy at a table: the seat
// frees up and the stake is not refunded by recovery.
func TestDisconnectForfeitsBlackjackStake(t *testing.T) {
	h := newHarness(t)
	h.seedAccount("alice", "pw", false)
	p := h.seedCharacter("alice", "alice")
	h.g.RunOnOwner(func() {
		p.Credits = 100
		h.g.Casino.Join(1, casino.TableConfig{ID: "bj", Game: casino.GameBlackjack, MaxPlayers: 2}, "alice")
		h.g.Casino.Bet(1, "bj", "alice", "", 10, casinoWallet{g: h.g, p: p})
		h.g.Casino.MarkDisconnected("alice")
	})
	h.barrier()

	restarted := harnessFromDir(t, h.dir)
	loaded, err := restarted.g.AccountStore.LoadCharacter("alice")
	if err != nil {
		t.Fatal(err)
	}
	if loaded.Credits != 90 {
		t.Fatalf("credits after forfeited hand = %d, want 90 (disconnect forfeits)", loaded.Credits)
	}
}