Files
cmroubao/backend-api/internal/transport/authcommon/attempt_limiter_test.go
T

76 lines
2.0 KiB
Go

package authcommon
import (
"testing"
"time"
)
func TestAttemptLimiterBlocksUntilWindowExpiresAndCanReset(t *testing.T) {
now := time.Date(2026, 7, 26, 1, 2, 3, 0, time.UTC)
limiter, err := newAttemptLimiter(
2,
time.Minute,
10,
func() time.Time { return now },
)
if err != nil {
t.Fatalf("newAttemptLimiter() error = %v", err)
}
if allowed, _ := limiter.Allow("admin:127.0.0.1"); !allowed {
t.Fatal("first attempt was blocked")
}
if allowed, _ := limiter.Allow("admin:127.0.0.1"); !allowed {
t.Fatal("second attempt was blocked")
}
if allowed, wait := limiter.Allow("admin:127.0.0.1"); allowed ||
wait != time.Minute {
t.Fatalf("third attempt = %v, wait = %v", allowed, wait)
}
limiter.Reset("admin:127.0.0.1")
if allowed, _ := limiter.Allow("admin:127.0.0.1"); !allowed {
t.Fatal("attempt after reset was blocked")
}
now = now.Add(time.Minute)
if allowed, _ := limiter.Allow("admin:127.0.0.1"); !allowed {
t.Fatal("attempt after window expiry was blocked")
}
}
func TestAttemptLimiterBoundsTrackedKeys(t *testing.T) {
now := time.Date(2026, 7, 26, 1, 2, 3, 0, time.UTC)
limiter, err := newAttemptLimiter(
1,
time.Minute,
1,
func() time.Time { return now },
)
if err != nil {
t.Fatalf("newAttemptLimiter() error = %v", err)
}
if allowed, _ := limiter.Allow("one"); !allowed {
t.Fatal("first key was blocked")
}
if allowed, wait := limiter.Allow("two"); allowed ||
wait != time.Minute {
t.Fatalf("second key = %v, wait = %v", allowed, wait)
}
now = now.Add(time.Minute)
if allowed, _ := limiter.Allow("two"); !allowed {
t.Fatal("expired key was not evicted")
}
}
func TestLoginAttemptKeyUsesRemoteAddressOnly(t *testing.T) {
if got := LoginAttemptKey("buyer", "127.0.0.1:1234"); got != "buyer:127.0.0.1" {
t.Fatalf("IPv4 key = %q", got)
}
if got := LoginAttemptKey("admin", "[2001:db8::1]:443"); got != "admin:2001:db8::1" {
t.Fatalf("IPv6 key = %q", got)
}
if got := RetryAfterSeconds(time.Millisecond); got != 1 {
t.Fatalf("RetryAfterSeconds() = %d", got)
}
}