83 lines
1.7 KiB
Go
83 lines
1.7 KiB
Go
package auth
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestRateLimiterAllow(t *testing.T) {
|
|
r := NewRateLimiter()
|
|
if !r.Allow("user1") {
|
|
t.Error("fresh user should be allowed")
|
|
}
|
|
}
|
|
|
|
func TestRateLimiterLockAfterMaxAttempts(t *testing.T) {
|
|
r := NewRateLimiter()
|
|
id := "user2"
|
|
for i := 0; i < maxAttempts-1; i++ {
|
|
locked := r.Record(id)
|
|
if locked {
|
|
t.Fatalf("should not be locked before max attempts (attempt %d)", i+1)
|
|
}
|
|
if !r.Allow(id) {
|
|
t.Fatalf("should be allowed before lock (attempt %d)", i+1)
|
|
}
|
|
}
|
|
locked := r.Record(id)
|
|
if !locked {
|
|
t.Error("should be locked after max attempts")
|
|
}
|
|
if r.Allow(id) {
|
|
t.Error("locked user should not be allowed")
|
|
}
|
|
}
|
|
|
|
func TestRateLimiterReset(t *testing.T) {
|
|
r := NewRateLimiter()
|
|
id := "user3"
|
|
for i := 0; i < maxAttempts; i++ {
|
|
r.Record(id) //nolint
|
|
}
|
|
if r.Allow(id) {
|
|
t.Error("should be locked before reset")
|
|
}
|
|
r.Reset(id)
|
|
if !r.Allow(id) {
|
|
t.Error("should be allowed after reset")
|
|
}
|
|
}
|
|
|
|
func TestRateLimiterWindowReset(t *testing.T) {
|
|
r := NewRateLimiter()
|
|
id := "user4"
|
|
// Simulate 4 attempts within window then manually expire the window
|
|
for i := 0; i < maxAttempts-1; i++ {
|
|
r.Record(id) //nolint
|
|
}
|
|
// Manually expire the window
|
|
r.mu.Lock()
|
|
r.entries[id].firstAt = time.Now().Add(-windowMinutes*time.Minute - time.Second)
|
|
r.mu.Unlock()
|
|
|
|
// Next attempt should reset the window, not lock
|
|
locked := r.Record(id)
|
|
if locked {
|
|
t.Error("should not lock after window expired")
|
|
}
|
|
}
|
|
|
|
func TestRateLimiterRemainingLock(t *testing.T) {
|
|
r := NewRateLimiter()
|
|
id := "user5"
|
|
if r.RemainingLock(id) != 0 {
|
|
t.Error("no lock expected for fresh user")
|
|
}
|
|
for i := 0; i < maxAttempts; i++ {
|
|
r.Record(id) //nolint
|
|
}
|
|
if r.RemainingLock(id) == 0 {
|
|
t.Error("lock expected after max attempts")
|
|
}
|
|
}
|