aboutsummaryrefslogtreecommitdiff
path: root/internal/game/correct_vanished_account_reset_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/correct_vanished_account_reset_test.go')
-rw-r--r--internal/game/correct_vanished_account_reset_test.go75
1 files changed, 75 insertions, 0 deletions
diff --git a/internal/game/correct_vanished_account_reset_test.go b/internal/game/correct_vanished_account_reset_test.go
new file mode 100644
index 0000000..d40f602
--- /dev/null
+++ b/internal/game/correct_vanished_account_reset_test.go
@@ -0,0 +1,75 @@
+package game
+
+// Regression: a session whose account file has vanished (purged, or deleted
+// through the admin raw file editor) must be reset to the account-name prompt
+// with no pending registration state left behind. Clearing Account alone left
+// PendingPass set, so an already-buffered confirm-password line could still
+// reach a handler that dereferences the account; applyNewAccount now also
+// refuses to dereference a nil account.
+
+import (
+ "strings"
+ "testing"
+
+ "thehouseoficarus/internal/net"
+ "thehouseoficarus/internal/player"
+)
+
+func TestPublishAccountUpdateVanishedAccountResetsSession(t *testing.T) {
+ h := newHarness(t)
+
+ conn := newChanConn()
+ sess := &net.Session{Conn: conn, Account: &player.Account{Name: "bob"}}
+ sess.SetState(net.StateNewAccount)
+ sess.PendingPass = "pw"
+ h.hub.Add(sess)
+
+ h.g.RunOnOwner(func() { h.g.publishAccountUpdate("bob", "bob") })
+
+ if got := sess.State(); got != net.StateAccountName {
+ t.Errorf("state = %v, want StateAccountName", got)
+ }
+ if sess.Account != nil {
+ t.Errorf("account not cleared: %+v", sess.Account)
+ }
+ if sess.PendingPass != "" {
+ t.Errorf("PendingPass = %q, want it cleared with the account", sess.PendingPass)
+ }
+ out := string(conn.Bytes())
+ if !strings.Contains(out, "Your account no longer exists.") {
+ t.Errorf("missing vanished-account notice; output = %q", out)
+ }
+ if !strings.Contains(out, "Account name: ") {
+ t.Errorf("missing account-name prompt; output = %q", out)
+ }
+}
+
+func TestApplyNewAccountResetsWhenAccountVanished(t *testing.T) {
+ h := newHarness(t)
+
+ conn := newChanConn()
+ sess := &net.Session{Conn: conn}
+ sess.SetState(net.StateNewAccount)
+ sess.PendingPass = "pw"
+
+ // Direct call: the menu handlers run on the owner goroutine, so the test
+ // goroutine stands in for it and an unguarded dereference fails loudly.
+ h.g.applyNewAccount(sess, "hash", nil)
+
+ if got := sess.State(); got != net.StateAccountName {
+ t.Errorf("state = %v, want StateAccountName", got)
+ }
+ if sess.Account != nil {
+ t.Errorf("account not cleared: %+v", sess.Account)
+ }
+ if sess.PendingPass != "" {
+ t.Errorf("PendingPass = %q, want it cleared", sess.PendingPass)
+ }
+ out := string(conn.Bytes())
+ if !strings.Contains(out, "Account name: ") {
+ t.Errorf("missing account-name prompt; output = %q", out)
+ }
+ if _, err := h.g.AccountStore.LoadAccount("bob"); err == nil {
+ t.Error("an account was created for a session with no account bound")
+ }
+}