diff options
| author | historia <[not public]> | 2026-09-18 17:48:26 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-18 17:48:26 -0400 |
| commit | 8fe9e3c3fef0049df82281a62afe35dda516dfe2 (patch) | |
| tree | dd269f2c0710f334e19f00a191260ebc46284a90 /internal/game/login_throttle_test.go | |
| parent | 194164a77eb4f2479b94c19e6f0e1278ab608781 (diff) | |
| download | thehouseoficarus-8fe9e3c3fef0049df82281a62afe35dda516dfe2.tar.gz | |
fix: close combat ghost, admin traversal, login throttle, journal double-pay, and quality/economy gaps
Diffstat (limited to 'internal/game/login_throttle_test.go')
| -rw-r--r-- | internal/game/login_throttle_test.go | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/internal/game/login_throttle_test.go b/internal/game/login_throttle_test.go new file mode 100644 index 0000000..b2565c4 --- /dev/null +++ b/internal/game/login_throttle_test.go @@ -0,0 +1,35 @@ +package game + +import ( + "testing" + "time" +) + +// TestLoginThrottleEscalatesAndResets pins the telnet login throttle: the +// first wrong password is free, then the delay escalates to a cap, and a +// successful login clears the state. +func TestLoginThrottleEscalatesAndResets(t *testing.T) { + th := newLoginThrottle() + key := loginThrottleKey("alice", "203.0.113.7") + + if d := th.delayFor(key); d != 0 { + t.Fatalf("first failure delay = %v, want 0", d) + } + if d := th.delayFor(key); d != 250*time.Millisecond { + t.Fatalf("second failure delay = %v, want 250ms", d) + } + if d := th.delayFor(key); d != 500*time.Millisecond { + t.Fatalf("third failure delay = %v, want 500ms", d) + } + for i := 0; i < 10; i++ { + th.delayFor(key) + } + if d := th.delayFor(key); d != loginThrottleMaxDelay { + t.Fatalf("capped delay = %v, want %v", d, loginThrottleMaxDelay) + } + + th.clear(key) + if d := th.delayFor(key); d != 0 { + t.Fatalf("delay after clear = %v, want 0", d) + } +} |
