diff options
| author | historia <[not public]> | 2026-10-05 14:22:14 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-10-05 14:22:14 -0400 |
| commit | 90ad8c0c33b519d5830c69d4128bdc984b5e9de8 (patch) | |
| tree | c10bc0bebfbed6fde01a7f08cf6e2d98809b91a7 /internal/game/crypto_ux_test.go | |
| parent | c84a9944356f590d90d819d652bdf1349ebacd40 (diff) | |
| download | thehouseoficarus-90ad8c0c33b519d5830c69d4128bdc984b5e9de8.tar.gz | |
feat: cryptocurrency exchange added to casino
Diffstat (limited to 'internal/game/crypto_ux_test.go')
| -rw-r--r-- | internal/game/crypto_ux_test.go | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/internal/game/crypto_ux_test.go b/internal/game/crypto_ux_test.go new file mode 100644 index 0000000..6ac4a57 --- /dev/null +++ b/internal/game/crypto_ux_test.go @@ -0,0 +1,147 @@ +package game + +import ( + "strings" + "testing" + + "thehouseoficarus/internal/casino" + "thehouseoficarus/internal/color" +) + +func TestCryptoEntryIsBoardAndSharedHintsNotRules(t *testing.T) { + g, s, conn := cryptoFixture(t) + g.CryptoClient = cryptoMockClient(t, "100") + g.doUse(s, "crypto") + out := string(conn.data) + for _, wanted := range []string{"CRYPTO EXCHANGE", "Currency", "Buy", "Sell", "BTC", "view SYMBOL", "fund CREDITS", "stop"} { + if !strings.Contains(out, wanted) { + t.Fatalf("missing %q: %s", wanted, out) + } + } + for _, unwanted := range []string{"HOW TO TRADE", "Paper trading only", "HOUSE-MODEL", "volatility", "collateral", "Black-Scholes", "0.5%", "10-credit", "1,000,000"} { + if strings.Contains(out, unwanted) { + t.Fatalf("entry dumped rules %q: %s", unwanted, out) + } + } + for _, line := range strings.Split(out, "\n") { + if color.VisibleLen(strings.TrimSuffix(line, "\r")) > 80 { + t.Fatalf("wide entry line: %q", line) + } + } +} +func TestCryptoHintPreferencesAndExplicitWhat(t *testing.T) { + for _, mode := range []string{"off", "once", "on"} { + t.Run(mode, func(t *testing.T) { + g, s, conn := cryptoFixture(t) + g.CryptoClient = cryptoMockClient(t, "100") + s.Player.Options["casino_hints"] = mode + g.doUse(s, "crypto") + if got := strings.Contains(string(conn.data), "view SYMBOL"); got != (mode != "off") { + t.Fatalf("entry hints %s: %s", mode, conn.data) + } + conn.data = nil + g.executeCrypto(s, "refresh", nil) + if got := strings.Contains(string(conn.data), "view SYMBOL"); got != (mode == "on") { + t.Fatalf("repeat hints %s: %s", mode, conn.data) + } + conn.data = nil + // Look marks the same ShowHints flag the prediction counter uses. + s.CryptoShowHints = true + g.executeCrypto(s, "refresh", nil) + if got := strings.Contains(string(conn.data), "view SYMBOL"); got != (mode != "off") { + t.Fatalf("look hints %s: %s", mode, conn.data) + } + conn.data = nil + g.handleGameCommand(s, "what") + if !strings.Contains(string(conn.data), "view SYMBOL") || strings.Contains(string(conn.data), "HOW TO TRADE") { + t.Fatalf("what did not show command menu: %s", conn.data) + } + if g.cryptoInputOwned(s, "what") || g.cryptoInputOwned(s, "verbs") || g.cryptoInputOwned(s, "north") { + t.Fatal("counter stole a world command") + } + }) + } +} +func TestCryptoContextMenusAndRefresh(t *testing.T) { + g, s, conn := cryptoFixture(t) + g.CryptoClient = cryptoMockClient(t, "100") + s.Player.Options["casino_hints"] = "on" + g.executeCrypto(s, "view", []string{"BTC"}) + if !strings.Contains(string(conn.data), "buy BTC AMOUNT") || !strings.Contains(string(conn.data), "contracts") { + t.Fatalf("missing currency hints: %s", conn.data) + } + conn.data = nil + g.executeCrypto(s, "contracts", nil) + if !strings.Contains(string(conn.data), "option TYPE BTC") || !strings.Contains(string(conn.data), "quote TYPE BTC") { + t.Fatalf("missing option hints: %s", conn.data) + } + conn.data = nil + g.executeCrypto(s, "active", nil) + g.executeCrypto(s, "refresh", nil) + if s.CryptoScreen != "active" || strings.Contains(string(conn.data), "DAILY CANDLES") || !strings.Contains(string(conn.data), "close ID") { + t.Fatalf("refresh left portfolio: %s", conn.data) + } + conn.data = nil + g.executeCrypto(s, "closed", nil) + g.executeCrypto(s, "refresh", nil) + if s.CryptoScreen != "closed" || strings.Contains(string(conn.data), "close ID") { + t.Fatalf("closed hints or refresh wrong: %s", conn.data) + } + conn.data = nil + g.executeCrypto(s, "back", nil) + if s.CryptoScreen != "markets" || !strings.Contains(string(conn.data), "view SYMBOL") { + t.Fatalf("back failed: %s", conn.data) + } + s.CryptoBusy = true + commands := g.cryptoCommands(s) + if len(commands) != 1 || commands[0] != (casino.MenuCommand{Command: "stop", Desc: "Leave and cancel the update"}) { + t.Fatal(commands) + } +} +func TestCryptoGlobalOptionCommandsStayReachable(t *testing.T) { + g, s, _ := cryptoFixture(t) + g.CryptoClient = cryptoMockClient(t, "100") + // The settings command is not claimed by the counter... + if g.cryptoInputOwned(s, "options") { + t.Fatal("counter stole the options settings command") + } + if g.handleCryptoInput(s, "option", nil) { + t.Fatal("bare option should fall through to settings") + } + // ...but a real option trade is claimed. + if !g.cryptoInputOwned(s, "option") { + t.Fatal("option trade should be owned") + } + if !g.handleCryptoInput(s, "option", []string{"call", "BTC", "0.01", "100", "7"}) { + t.Fatal("option trade was not handled") + } +} + +func TestCryptoCommandAbbreviations(t *testing.T) { + g, s, conn := cryptoFixture(t) + g.CryptoClient = cryptoMockClient(t, "100") + // Unique prefixes resolve like every other counter command. + if got, ok := cryptoVerb("mar"); !ok || got != "markets" { + t.Fatalf("mar -> %q, %v", got, ok) + } + if got, ok := cryptoVerb("opt"); !ok || got != "option" { + t.Fatalf("opt -> %q, %v", got, ok) + } + if !g.cryptoInputOwned(s, "mar") { + t.Fatal("mar should be owned") + } + // Ambiguous shortcuts are claimed and explained instead of running. + if got, ok := cryptoVerb("b"); !ok || got != "" { + t.Fatalf("b -> %q, %v", got, ok) + } + conn.data = nil + if !g.handleCryptoInput(s, "b", nil) || !strings.Contains(string(conn.data), "ambiguous") { + t.Fatalf("ambiguous shortcut: %s", conn.data) + } + // Real world commands still win over counter prefixes. + for _, cmd := range []string{"look", "north", "score", "inventory"} { + if got, ok := cryptoVerb(cmd); ok { + t.Fatalf("%s was claimed as %q", cmd, got) + } + } +} |
