mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-02-18 00:17:39 +01:00
test: add X-RateLimit-Limit header regression test (#578)
test: add X-RateLimit-Limit header regression test
This commit is contained in:
55
internal/api/rate_limit_config_test.go
Normal file
55
internal/api/rate_limit_config_test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUniversalRateLimitMiddleware_HeaderFormat(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
middleware := UniversalRateLimitMiddleware(handler)
|
||||
|
||||
limiter := GetRateLimiterForEndpoint("/api/login", http.MethodPost)
|
||||
testIP := "203.0.113.55"
|
||||
t.Cleanup(func() {
|
||||
ResetRateLimitForIP(testIP)
|
||||
})
|
||||
|
||||
makeRequest := func() *http.Request {
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/login", nil)
|
||||
req.RemoteAddr = testIP + ":12345"
|
||||
return req
|
||||
}
|
||||
|
||||
// Make requests up to the limit - all should succeed
|
||||
for i := 0; i < limiter.limit; i++ {
|
||||
rr := httptest.NewRecorder()
|
||||
middleware.ServeHTTP(rr, makeRequest())
|
||||
if rr.Code != http.StatusOK {
|
||||
t.Fatalf("expected OK while under limit, got %d on request %d", rr.Code, i+1)
|
||||
}
|
||||
}
|
||||
|
||||
// Next request should trigger rate limit
|
||||
rr := httptest.NewRecorder()
|
||||
middleware.ServeHTTP(rr, makeRequest())
|
||||
if rr.Code != http.StatusTooManyRequests {
|
||||
t.Fatalf("expected rate-limit status, got %d", rr.Code)
|
||||
}
|
||||
|
||||
// Verify X-RateLimit-Limit header is a proper decimal string
|
||||
limitHeader := rr.Result().Header.Get("X-RateLimit-Limit")
|
||||
expected := strconv.Itoa(limiter.limit)
|
||||
if limitHeader != expected {
|
||||
t.Fatalf("expected X-RateLimit-Limit %q, got %q", expected, limitHeader)
|
||||
}
|
||||
|
||||
// Verify the header parses as a valid integer (not a control character)
|
||||
if _, err := strconv.Atoi(limitHeader); err != nil {
|
||||
t.Fatalf("header %q should parse as decimal: %v", limitHeader, err)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -24,7 +25,7 @@ func TestHubConcurrentClients(t *testing.T) {
|
||||
client := &Client{
|
||||
hub: hub,
|
||||
send: make(chan []byte, 10),
|
||||
id: "client-register-" + string(rune(i)),
|
||||
id: "client-register-" + strconv.Itoa(i),
|
||||
}
|
||||
hub.register <- client
|
||||
time.Sleep(time.Microsecond)
|
||||
|
||||
Reference in New Issue
Block a user