diff options
Diffstat (limited to 'internal/game/account_registration_regression_test.go')
| -rw-r--r-- | internal/game/account_registration_regression_test.go | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/internal/game/account_registration_regression_test.go b/internal/game/account_registration_regression_test.go new file mode 100644 index 0000000..5ecd254 --- /dev/null +++ b/internal/game/account_registration_regression_test.go @@ -0,0 +1,55 @@ +package game + +// Registration regression: a pending new-account session whose typed name +// was created in the meantime (by another concurrent registration) must be +// refused at confirm time, never overwrite the existing account's password +// or character list. + +import ( + "testing" + + "thehouseoficarus/internal/net" + "thehouseoficarus/internal/player" +) + +func TestPendingRegistrationCannotOverwriteExistingAccount(t *testing.T) { + h := newHarness(t) + h.seedAccount("alice", "pw", false) + p := h.seedCharacter("alice", "alice") + + a := &net.Session{Conn: newChanConn(), State: net.StateAccountName} + b := &net.Session{Conn: newChanConn(), State: net.StateAccountName} + h.g.RunOnOwner(func() { + // Both sessions type the same name while it does not exist yet; + // both reach the password-confirmation state. + h.g.handleAccountName(a, "wait") + h.g.handleAccountName(b, "wait") + h.g.handleNewPass(a, "firstpassword") + h.g.handleNewPass(b, "otherpassword") + // Session a wins the creation race... + h.g.handleNewAccount(a, "firstpassword") + // ...and a character is attached to the account before b confirms. + acc, err := h.g.AccountStore.LoadAccount("wait") + if err != nil { + t.Error(err) + return + } + acc.Characters = []string{p.Name} + if err := h.g.AccountStore.SaveAccount(acc); err != nil { + t.Error(err) + return + } + // Session b confirms second: this must not clobber the account. + h.g.handleNewAccount(b, "otherpassword") + }) + acc, err := h.g.AccountStore.LoadAccount("wait") + if err != nil { + t.Fatal(err) + } + if !player.CheckPassword("firstpassword", acc.PasswordHash) { + t.Errorf("winner's password was overwritten by the losing registration") + } + if len(acc.Characters) != 1 { + t.Errorf("character list destroyed by the losing registration: %v", acc.Characters) + } +} |
