mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-04-22 23:54:45 +08:00
Merge pull request #1025 from touwaeriol/fix/rate-limit-nil-window-reset
fix(billing): treat nil rate limit window as expired to prevent usage accumulation
This commit is contained in:
@@ -22,8 +22,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// IsWindowExpired returns true if the window starting at windowStart has exceeded the given duration.
|
// IsWindowExpired returns true if the window starting at windowStart has exceeded the given duration.
|
||||||
|
// A nil windowStart is treated as expired — no initialized window means any accumulated usage is stale.
|
||||||
func IsWindowExpired(windowStart *time.Time, duration time.Duration) bool {
|
func IsWindowExpired(windowStart *time.Time, duration time.Duration) bool {
|
||||||
return windowStart != nil && time.Since(*windowStart) >= duration
|
return windowStart == nil || time.Since(*windowStart) >= duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type APIKey struct {
|
type APIKey struct {
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ func TestIsWindowExpired(t *testing.T) {
|
|||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "nil window start",
|
name: "nil window start (treated as expired)",
|
||||||
start: nil,
|
start: nil,
|
||||||
duration: RateLimitWindow5h,
|
duration: RateLimitWindow5h,
|
||||||
want: false,
|
want: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "active window (started 1h ago, 5h window)",
|
name: "active window (started 1h ago, 5h window)",
|
||||||
@@ -113,7 +113,7 @@ func TestAPIKey_EffectiveUsage(t *testing.T) {
|
|||||||
want7d: 0,
|
want7d: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nil window starts return raw usage",
|
name: "nil window starts return 0 (stale usage reset)",
|
||||||
key: APIKey{
|
key: APIKey{
|
||||||
Usage5h: 5.0,
|
Usage5h: 5.0,
|
||||||
Usage1d: 10.0,
|
Usage1d: 10.0,
|
||||||
@@ -122,9 +122,9 @@ func TestAPIKey_EffectiveUsage(t *testing.T) {
|
|||||||
Window1dStart: nil,
|
Window1dStart: nil,
|
||||||
Window7dStart: nil,
|
Window7dStart: nil,
|
||||||
},
|
},
|
||||||
want5h: 5.0,
|
want5h: 0,
|
||||||
want1d: 10.0,
|
want1d: 0,
|
||||||
want7d: 50.0,
|
want7d: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mixed: 5h expired, 1d active, 7d nil",
|
name: "mixed: 5h expired, 1d active, 7d nil",
|
||||||
@@ -138,7 +138,7 @@ func TestAPIKey_EffectiveUsage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
want5h: 0,
|
want5h: 0,
|
||||||
want1d: 10.0,
|
want1d: 10.0,
|
||||||
want7d: 50.0,
|
want7d: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "zero usage with active windows",
|
name: "zero usage with active windows",
|
||||||
@@ -210,7 +210,7 @@ func TestAPIKeyRateLimitData_EffectiveUsage(t *testing.T) {
|
|||||||
want7d: 0,
|
want7d: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nil window starts return raw usage",
|
name: "nil window starts return 0 (stale usage reset)",
|
||||||
data: APIKeyRateLimitData{
|
data: APIKeyRateLimitData{
|
||||||
Usage5h: 3.0,
|
Usage5h: 3.0,
|
||||||
Usage1d: 8.0,
|
Usage1d: 8.0,
|
||||||
@@ -219,9 +219,9 @@ func TestAPIKeyRateLimitData_EffectiveUsage(t *testing.T) {
|
|||||||
Window1dStart: nil,
|
Window1dStart: nil,
|
||||||
Window7dStart: nil,
|
Window7dStart: nil,
|
||||||
},
|
},
|
||||||
want5h: 3.0,
|
want5h: 0,
|
||||||
want1d: 8.0,
|
want1d: 0,
|
||||||
want7d: 40.0,
|
want7d: 0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user