package chat import ( "testing" "time" "github.com/google/uuid" "github.com/stretchr/testify/assert" "go.uber.org/zap/zaptest" ) func TestRateLimiter_InMemoryFallback_AllowsWithinLimit(t *testing.T) { logger := zaptest.NewLogger(t) rl := NewRateLimiter(nil, logger) userID := uuid.New() for i := 0; i < 10; i++ { assert.True(t, rl.Allow(userID, "send_message"), "request %d should be allowed", i+1) } assert.False(t, rl.Allow(userID, "send_message"), "11th request should be denied") } func TestRateLimiter_InMemoryFallback_WindowReset(t *testing.T) { logger := zaptest.NewLogger(t) rl := NewRateLimiter(nil, logger) rl.limits["test_action"] = rateConfig{maxRequests: 2, window: 50 * time.Millisecond} userID := uuid.New() assert.True(t, rl.Allow(userID, "test_action")) assert.True(t, rl.Allow(userID, "test_action")) assert.False(t, rl.Allow(userID, "test_action")) time.Sleep(60 * time.Millisecond) assert.True(t, rl.Allow(userID, "test_action"), "should allow after window reset") } func TestRateLimiter_UnknownAction_AlwaysAllowed(t *testing.T) { logger := zaptest.NewLogger(t) rl := NewRateLimiter(nil, logger) userID := uuid.New() for i := 0; i < 100; i++ { assert.True(t, rl.Allow(userID, "unknown_action")) } } func TestRateLimiter_DifferentUsers_IndependentLimits(t *testing.T) { logger := zaptest.NewLogger(t) rl := NewRateLimiter(nil, logger) user1 := uuid.New() user2 := uuid.New() for i := 0; i < 10; i++ { assert.True(t, rl.Allow(user1, "send_message")) } assert.False(t, rl.Allow(user1, "send_message")) assert.True(t, rl.Allow(user2, "send_message"), "user2 should be independent of user1") } func TestRateLimiter_DifferentActions_IndependentLimits(t *testing.T) { logger := zaptest.NewLogger(t) rl := NewRateLimiter(nil, logger) userID := uuid.New() for i := 0; i < 10; i++ { assert.True(t, rl.Allow(userID, "send_message")) } assert.False(t, rl.Allow(userID, "send_message")) assert.True(t, rl.Allow(userID, "typing"), "typing should be independent of send_message") }