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") } }