Files
Prism/internal/auth/loginlimiter_test.go
T
renjue 9dfa7aa7c5
CI / docker (push) Successful in 4m28s
feat: Prism HTTP/SOCKS5 代理网关及管理台
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-23 15:37:02 +08:00

64 lines
1.3 KiB
Go

package auth
import (
"context"
"path/filepath"
"testing"
"time"
"github.com/prism/proxy/internal/store"
)
func TestLoginLimiterLockAndClear(t *testing.T) {
st, err := store.Open(filepath.Join(t.TempDir(), "data"))
if err != nil {
t.Fatal(err)
}
defer st.Close()
ctx := context.Background()
limiter := NewLoginLimiter(st)
cfg := LoginConfig{MaxAttempts: 3, Window: time.Minute, LockDuration: 2 * time.Minute}
ip := "203.0.113.1"
for i := 0; i < 2; i++ {
res, err := limiter.RecordFailure(ctx, ip, cfg)
if err != nil {
t.Fatal(err)
}
if res.Locked {
t.Fatalf("unexpected lock at attempt %d", i+1)
}
if res.Remaining != cfg.MaxAttempts-i-1 {
t.Fatalf("remaining=%d want %d", res.Remaining, cfg.MaxAttempts-i-1)
}
}
res, err := limiter.RecordFailure(ctx, ip, cfg)
if err != nil {
t.Fatal(err)
}
if !res.Locked || res.RetryAfter <= 0 {
t.Fatalf("expected lock, got %+v", res)
}
check, err := limiter.Check(ctx, ip, cfg)
if err != nil {
t.Fatal(err)
}
if check.Allowed {
t.Fatal("expected blocked while locked")
}
if err := limiter.RecordSuccess(ctx, ip); err != nil {
t.Fatal(err)
}
check, err = limiter.Check(ctx, ip, cfg)
if err != nil {
t.Fatal(err)
}
if !check.Allowed || check.Remaining != cfg.MaxAttempts {
t.Fatalf("expected reset, got %+v", check)
}
}