Files
fn_registry/functions/infra/rate_limiter_new_test.go
T
egutierrez c3d9fbd8d3 feat(infra): rate limit middlewares HTTP por IP y por key + tests
Implementa fase 2 del issue 0016:
- rate_limit_middleware: limita por IP (X-Forwarded-For > X-Real-IP > RemoteAddr)
- rate_limiter_by_key: middleware configurable con keyFunc custom (API key, user ID...)
- Cuando se rechaza responde 429 con HTTPError JSON y headers Retry-After + X-RateLimit-*
- Tests con httptest.NewRecorder cubriendo: limite, burst, IPs independientes, XFF prioritario,
  recarga temporal, JSON body, headers IETF, GC stop idempotente, key vacia salta limit
2026-04-18 17:14:25 +02:00

44 lines
1.1 KiB
Go

package infra
import "testing"
func TestRateLimiterNew(t *testing.T) {
t.Run("crea limiter con rate y burst configurados", func(t *testing.T) {
rl := RateLimiterNew(10, 20)
if rl == nil {
t.Fatal("RateLimiterNew retorno nil")
}
if rl.rate != 10 {
t.Errorf("rate=%v, want 10", rl.rate)
}
if rl.burst != 20 {
t.Errorf("burst=%d, want 20", rl.burst)
}
})
t.Run("valores cero se sustituyen por 1", func(t *testing.T) {
rl := RateLimiterNew(0, 0)
if rl.rate != 1 {
t.Errorf("rate=%v, want 1 (default)", rl.rate)
}
if rl.burst != 1 {
t.Errorf("burst=%d, want 1 (default)", rl.burst)
}
rl2 := RateLimiterNew(-5, -10)
if rl2.rate != 1 || rl2.burst != 1 {
t.Errorf("valores negativos no se normalizaron a 1: rate=%v burst=%d", rl2.rate, rl2.burst)
}
})
t.Run("el mapa de clientes empieza vacio", func(t *testing.T) {
rl := RateLimiterNew(10, 20)
if rl.clients == nil {
t.Error("clients map es nil, deberia ser inicializado")
}
if len(rl.clients) != 0 {
t.Errorf("clients len=%d, want 0", len(rl.clients))
}
})
}