package service import ( "testing" "time" ) func TestIsWindowExpired(t *testing.T) { now := time.Now() tests := []struct { name string start *time.Time duration time.Duration want bool }{ { name: "nil window start", start: nil, duration: RateLimitWindow5h, want: false, }, { name: "active window (started 1h ago, 5h window)", start: rateLimitTimePtr(now.Add(-1 * time.Hour)), duration: RateLimitWindow5h, want: false, }, { name: "expired window (started 6h ago, 5h window)", start: rateLimitTimePtr(now.Add(-6 * time.Hour)), duration: RateLimitWindow5h, want: true, }, { name: "exactly at boundary (started 5h ago, 5h window)", start: rateLimitTimePtr(now.Add(-5 * time.Hour)), duration: RateLimitWindow5h, want: true, }, { name: "active 1d window (started 12h ago)", start: rateLimitTimePtr(now.Add(-12 * time.Hour)), duration: RateLimitWindow1d, want: false, }, { name: "expired 1d window (started 25h ago)", start: rateLimitTimePtr(now.Add(-25 * time.Hour)), duration: RateLimitWindow1d, want: true, }, { name: "active 7d window (started 3d ago)", start: rateLimitTimePtr(now.Add(-3 * 24 * time.Hour)), duration: RateLimitWindow7d, want: false, }, { name: "expired 7d window (started 8d ago)", start: rateLimitTimePtr(now.Add(-8 * 24 * time.Hour)), duration: RateLimitWindow7d, want: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := IsWindowExpired(tt.start, tt.duration) if got != tt.want { t.Errorf("IsWindowExpired() = %v, want %v", got, tt.want) } }) } } func TestAPIKey_EffectiveUsage(t *testing.T) { now := time.Now() tests := []struct { name string key APIKey want5h float64 want1d float64 want7d float64 }{ { name: "all windows active", key: APIKey{ Usage5h: 5.0, Usage1d: 10.0, Usage7d: 50.0, Window5hStart: rateLimitTimePtr(now.Add(-1 * time.Hour)), Window1dStart: rateLimitTimePtr(now.Add(-12 * time.Hour)), Window7dStart: rateLimitTimePtr(now.Add(-3 * 24 * time.Hour)), }, want5h: 5.0, want1d: 10.0, want7d: 50.0, }, { name: "all windows expired", key: APIKey{ Usage5h: 5.0, Usage1d: 10.0, Usage7d: 50.0, Window5hStart: rateLimitTimePtr(now.Add(-6 * time.Hour)), Window1dStart: rateLimitTimePtr(now.Add(-25 * time.Hour)), Window7dStart: rateLimitTimePtr(now.Add(-8 * 24 * time.Hour)), }, want5h: 0, want1d: 0, want7d: 0, }, { name: "nil window starts return raw usage", key: APIKey{ Usage5h: 5.0, Usage1d: 10.0, Usage7d: 50.0, Window5hStart: nil, Window1dStart: nil, Window7dStart: nil, }, want5h: 5.0, want1d: 10.0, want7d: 50.0, }, { name: "mixed: 5h expired, 1d active, 7d nil", key: APIKey{ Usage5h: 5.0, Usage1d: 10.0, Usage7d: 50.0, Window5hStart: rateLimitTimePtr(now.Add(-6 * time.Hour)), Window1dStart: rateLimitTimePtr(now.Add(-12 * time.Hour)), Window7dStart: nil, }, want5h: 0, want1d: 10.0, want7d: 50.0, }, { name: "zero usage with active windows", key: APIKey{ Usage5h: 0, Usage1d: 0, Usage7d: 0, Window5hStart: rateLimitTimePtr(now.Add(-1 * time.Hour)), Window1dStart: rateLimitTimePtr(now.Add(-1 * time.Hour)), Window7dStart: rateLimitTimePtr(now.Add(-1 * time.Hour)), }, want5h: 0, want1d: 0, want7d: 0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := tt.key.EffectiveUsage5h(); got != tt.want5h { t.Errorf("EffectiveUsage5h() = %v, want %v", got, tt.want5h) } if got := tt.key.EffectiveUsage1d(); got != tt.want1d { t.Errorf("EffectiveUsage1d() = %v, want %v", got, tt.want1d) } if got := tt.key.EffectiveUsage7d(); got != tt.want7d { t.Errorf("EffectiveUsage7d() = %v, want %v", got, tt.want7d) } }) } } func TestAPIKeyRateLimitData_EffectiveUsage(t *testing.T) { now := time.Now() tests := []struct { name string data APIKeyRateLimitData want5h float64 want1d float64 want7d float64 }{ { name: "all windows active", data: APIKeyRateLimitData{ Usage5h: 3.0, Usage1d: 8.0, Usage7d: 40.0, Window5hStart: rateLimitTimePtr(now.Add(-2 * time.Hour)), Window1dStart: rateLimitTimePtr(now.Add(-10 * time.Hour)), Window7dStart: rateLimitTimePtr(now.Add(-2 * 24 * time.Hour)), }, want5h: 3.0, want1d: 8.0, want7d: 40.0, }, { name: "all windows expired", data: APIKeyRateLimitData{ Usage5h: 3.0, Usage1d: 8.0, Usage7d: 40.0, Window5hStart: rateLimitTimePtr(now.Add(-10 * time.Hour)), Window1dStart: rateLimitTimePtr(now.Add(-48 * time.Hour)), Window7dStart: rateLimitTimePtr(now.Add(-10 * 24 * time.Hour)), }, want5h: 0, want1d: 0, want7d: 0, }, { name: "nil window starts return raw usage", data: APIKeyRateLimitData{ Usage5h: 3.0, Usage1d: 8.0, Usage7d: 40.0, Window5hStart: nil, Window1dStart: nil, Window7dStart: nil, }, want5h: 3.0, want1d: 8.0, want7d: 40.0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := tt.data.EffectiveUsage5h(); got != tt.want5h { t.Errorf("EffectiveUsage5h() = %v, want %v", got, tt.want5h) } if got := tt.data.EffectiveUsage1d(); got != tt.want1d { t.Errorf("EffectiveUsage1d() = %v, want %v", got, tt.want1d) } if got := tt.data.EffectiveUsage7d(); got != tt.want7d { t.Errorf("EffectiveUsage7d() = %v, want %v", got, tt.want7d) } }) } } func rateLimitTimePtr(t time.Time) *time.Time { return &t }