mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-04-02 22:42:14 +08:00
517 lines
17 KiB
Go
517 lines
17 KiB
Go
//go:build unit
|
|
|
|
package service
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// nextFixedDailyReset
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestNextFixedDailyReset_BeforeResetHour(t *testing.T) {
|
|
tz := time.UTC
|
|
// 2026-03-14 06:00 UTC, reset hour = 9
|
|
after := time.Date(2026, 3, 14, 6, 0, 0, 0, tz)
|
|
got := nextFixedDailyReset(9, tz, after)
|
|
want := time.Date(2026, 3, 14, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestNextFixedDailyReset_AtResetHour(t *testing.T) {
|
|
tz := time.UTC
|
|
// Exactly at reset hour → should return tomorrow
|
|
after := time.Date(2026, 3, 14, 9, 0, 0, 0, tz)
|
|
got := nextFixedDailyReset(9, tz, after)
|
|
want := time.Date(2026, 3, 15, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestNextFixedDailyReset_AfterResetHour(t *testing.T) {
|
|
tz := time.UTC
|
|
// After reset hour → should return tomorrow
|
|
after := time.Date(2026, 3, 14, 15, 30, 0, 0, tz)
|
|
got := nextFixedDailyReset(9, tz, after)
|
|
want := time.Date(2026, 3, 15, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestNextFixedDailyReset_MidnightReset(t *testing.T) {
|
|
tz := time.UTC
|
|
// Reset at hour 0 (midnight), currently 23:59
|
|
after := time.Date(2026, 3, 14, 23, 59, 0, 0, tz)
|
|
got := nextFixedDailyReset(0, tz, after)
|
|
want := time.Date(2026, 3, 15, 0, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestNextFixedDailyReset_NonUTCTimezone(t *testing.T) {
|
|
tz, err := time.LoadLocation("Asia/Shanghai")
|
|
require.NoError(t, err)
|
|
|
|
// 2026-03-14 07:00 UTC = 2026-03-14 15:00 CST, reset hour = 9 (CST)
|
|
after := time.Date(2026, 3, 14, 7, 0, 0, 0, time.UTC)
|
|
got := nextFixedDailyReset(9, tz, after)
|
|
// Already past 9:00 CST today → tomorrow 9:00 CST = 2026-03-15 01:00 UTC
|
|
want := time.Date(2026, 3, 15, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// lastFixedDailyReset
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestLastFixedDailyReset_BeforeResetHour(t *testing.T) {
|
|
tz := time.UTC
|
|
now := time.Date(2026, 3, 14, 6, 0, 0, 0, tz)
|
|
got := lastFixedDailyReset(9, tz, now)
|
|
// Before today's 9:00 → yesterday 9:00
|
|
want := time.Date(2026, 3, 13, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestLastFixedDailyReset_AtResetHour(t *testing.T) {
|
|
tz := time.UTC
|
|
now := time.Date(2026, 3, 14, 9, 0, 0, 0, tz)
|
|
got := lastFixedDailyReset(9, tz, now)
|
|
// At exactly 9:00 → today 9:00
|
|
want := time.Date(2026, 3, 14, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestLastFixedDailyReset_AfterResetHour(t *testing.T) {
|
|
tz := time.UTC
|
|
now := time.Date(2026, 3, 14, 15, 0, 0, 0, tz)
|
|
got := lastFixedDailyReset(9, tz, now)
|
|
// After 9:00 → today 9:00
|
|
want := time.Date(2026, 3, 14, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// nextFixedWeeklyReset
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestNextFixedWeeklyReset_TargetDayAhead(t *testing.T) {
|
|
tz := time.UTC
|
|
// 2026-03-14 is Saturday (day=6), target = Monday (day=1), hour = 9
|
|
after := time.Date(2026, 3, 14, 10, 0, 0, 0, tz)
|
|
got := nextFixedWeeklyReset(1, 9, tz, after)
|
|
// Next Monday = 2026-03-16
|
|
want := time.Date(2026, 3, 16, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestNextFixedWeeklyReset_TargetDayToday_BeforeHour(t *testing.T) {
|
|
tz := time.UTC
|
|
// 2026-03-16 is Monday (day=1), target = Monday, hour = 9, before 9:00
|
|
after := time.Date(2026, 3, 16, 6, 0, 0, 0, tz)
|
|
got := nextFixedWeeklyReset(1, 9, tz, after)
|
|
// Today at 9:00
|
|
want := time.Date(2026, 3, 16, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestNextFixedWeeklyReset_TargetDayToday_AtHour(t *testing.T) {
|
|
tz := time.UTC
|
|
// 2026-03-16 is Monday, target = Monday, hour = 9, exactly at 9:00
|
|
after := time.Date(2026, 3, 16, 9, 0, 0, 0, tz)
|
|
got := nextFixedWeeklyReset(1, 9, tz, after)
|
|
// Next Monday at 9:00
|
|
want := time.Date(2026, 3, 23, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestNextFixedWeeklyReset_TargetDayToday_AfterHour(t *testing.T) {
|
|
tz := time.UTC
|
|
// 2026-03-16 is Monday, target = Monday, hour = 9, after 9:00
|
|
after := time.Date(2026, 3, 16, 15, 0, 0, 0, tz)
|
|
got := nextFixedWeeklyReset(1, 9, tz, after)
|
|
// Next Monday at 9:00
|
|
want := time.Date(2026, 3, 23, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestNextFixedWeeklyReset_TargetDayPast(t *testing.T) {
|
|
tz := time.UTC
|
|
// 2026-03-18 is Wednesday (day=3), target = Monday (day=1)
|
|
after := time.Date(2026, 3, 18, 10, 0, 0, 0, tz)
|
|
got := nextFixedWeeklyReset(1, 9, tz, after)
|
|
// Next Monday = 2026-03-23
|
|
want := time.Date(2026, 3, 23, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestNextFixedWeeklyReset_Sunday(t *testing.T) {
|
|
tz := time.UTC
|
|
// 2026-03-14 is Saturday (day=6), target = Sunday (day=0)
|
|
after := time.Date(2026, 3, 14, 10, 0, 0, 0, tz)
|
|
got := nextFixedWeeklyReset(0, 0, tz, after)
|
|
// Next Sunday = 2026-03-15
|
|
want := time.Date(2026, 3, 15, 0, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// lastFixedWeeklyReset
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestLastFixedWeeklyReset_SameDay_AfterHour(t *testing.T) {
|
|
tz := time.UTC
|
|
// 2026-03-16 is Monday (day=1), target = Monday, hour = 9, now = 15:00
|
|
now := time.Date(2026, 3, 16, 15, 0, 0, 0, tz)
|
|
got := lastFixedWeeklyReset(1, 9, tz, now)
|
|
// Today at 9:00
|
|
want := time.Date(2026, 3, 16, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestLastFixedWeeklyReset_SameDay_BeforeHour(t *testing.T) {
|
|
tz := time.UTC
|
|
// 2026-03-16 is Monday, target = Monday, hour = 9, now = 06:00
|
|
now := time.Date(2026, 3, 16, 6, 0, 0, 0, tz)
|
|
got := lastFixedWeeklyReset(1, 9, tz, now)
|
|
// Last Monday at 9:00 = 2026-03-09
|
|
want := time.Date(2026, 3, 9, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
func TestLastFixedWeeklyReset_DifferentDay(t *testing.T) {
|
|
tz := time.UTC
|
|
// 2026-03-18 is Wednesday (day=3), target = Monday (day=1)
|
|
now := time.Date(2026, 3, 18, 10, 0, 0, 0, tz)
|
|
got := lastFixedWeeklyReset(1, 9, tz, now)
|
|
// Last Monday = 2026-03-16
|
|
want := time.Date(2026, 3, 16, 9, 0, 0, 0, tz)
|
|
assert.Equal(t, want, got)
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// isFixedDailyPeriodExpired
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestIsFixedDailyPeriodExpired_ZeroPeriodStart(t *testing.T) {
|
|
a := &Account{Extra: map[string]any{
|
|
"quota_daily_reset_mode": "fixed",
|
|
"quota_daily_reset_hour": float64(9),
|
|
"quota_reset_timezone": "UTC",
|
|
}}
|
|
assert.True(t, a.isFixedDailyPeriodExpired(time.Time{}))
|
|
}
|
|
|
|
func TestIsFixedDailyPeriodExpired_NotExpired(t *testing.T) {
|
|
a := &Account{Extra: map[string]any{
|
|
"quota_daily_reset_mode": "fixed",
|
|
"quota_daily_reset_hour": float64(9),
|
|
"quota_reset_timezone": "UTC",
|
|
}}
|
|
// Period started after the most recent reset → not expired
|
|
// (This test uses a time very close to "now", which is after the last reset)
|
|
periodStart := time.Now().Add(-1 * time.Minute)
|
|
assert.False(t, a.isFixedDailyPeriodExpired(periodStart))
|
|
}
|
|
|
|
func TestIsFixedDailyPeriodExpired_Expired(t *testing.T) {
|
|
a := &Account{Extra: map[string]any{
|
|
"quota_daily_reset_mode": "fixed",
|
|
"quota_daily_reset_hour": float64(9),
|
|
"quota_reset_timezone": "UTC",
|
|
}}
|
|
// Period started 3 days ago → definitely expired
|
|
periodStart := time.Now().Add(-72 * time.Hour)
|
|
assert.True(t, a.isFixedDailyPeriodExpired(periodStart))
|
|
}
|
|
|
|
func TestIsFixedDailyPeriodExpired_InvalidTimezone(t *testing.T) {
|
|
a := &Account{Extra: map[string]any{
|
|
"quota_daily_reset_mode": "fixed",
|
|
"quota_daily_reset_hour": float64(9),
|
|
"quota_reset_timezone": "Invalid/Timezone",
|
|
}}
|
|
// Invalid timezone falls back to UTC
|
|
periodStart := time.Now().Add(-72 * time.Hour)
|
|
assert.True(t, a.isFixedDailyPeriodExpired(periodStart))
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// isFixedWeeklyPeriodExpired
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestIsFixedWeeklyPeriodExpired_ZeroPeriodStart(t *testing.T) {
|
|
a := &Account{Extra: map[string]any{
|
|
"quota_weekly_reset_mode": "fixed",
|
|
"quota_weekly_reset_day": float64(1),
|
|
"quota_weekly_reset_hour": float64(9),
|
|
"quota_reset_timezone": "UTC",
|
|
}}
|
|
assert.True(t, a.isFixedWeeklyPeriodExpired(time.Time{}))
|
|
}
|
|
|
|
func TestIsFixedWeeklyPeriodExpired_NotExpired(t *testing.T) {
|
|
a := &Account{Extra: map[string]any{
|
|
"quota_weekly_reset_mode": "fixed",
|
|
"quota_weekly_reset_day": float64(1),
|
|
"quota_weekly_reset_hour": float64(9),
|
|
"quota_reset_timezone": "UTC",
|
|
}}
|
|
// Period started 1 minute ago → not expired
|
|
periodStart := time.Now().Add(-1 * time.Minute)
|
|
assert.False(t, a.isFixedWeeklyPeriodExpired(periodStart))
|
|
}
|
|
|
|
func TestIsFixedWeeklyPeriodExpired_Expired(t *testing.T) {
|
|
a := &Account{Extra: map[string]any{
|
|
"quota_weekly_reset_mode": "fixed",
|
|
"quota_weekly_reset_day": float64(1),
|
|
"quota_weekly_reset_hour": float64(9),
|
|
"quota_reset_timezone": "UTC",
|
|
}}
|
|
// Period started 10 days ago → definitely expired
|
|
periodStart := time.Now().Add(-240 * time.Hour)
|
|
assert.True(t, a.isFixedWeeklyPeriodExpired(periodStart))
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ValidateQuotaResetConfig
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestValidateQuotaResetConfig_NilExtra(t *testing.T) {
|
|
assert.NoError(t, ValidateQuotaResetConfig(nil))
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_EmptyExtra(t *testing.T) {
|
|
assert.NoError(t, ValidateQuotaResetConfig(map[string]any{}))
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_ValidFixed(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_daily_reset_mode": "fixed",
|
|
"quota_daily_reset_hour": float64(9),
|
|
"quota_weekly_reset_mode": "fixed",
|
|
"quota_weekly_reset_day": float64(1),
|
|
"quota_weekly_reset_hour": float64(0),
|
|
"quota_reset_timezone": "Asia/Shanghai",
|
|
}
|
|
assert.NoError(t, ValidateQuotaResetConfig(extra))
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_ValidRolling(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_daily_reset_mode": "rolling",
|
|
"quota_weekly_reset_mode": "rolling",
|
|
}
|
|
assert.NoError(t, ValidateQuotaResetConfig(extra))
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_InvalidTimezone(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_reset_timezone": "Not/A/Timezone",
|
|
}
|
|
err := ValidateQuotaResetConfig(extra)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "quota_reset_timezone")
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_InvalidDailyMode(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_daily_reset_mode": "invalid",
|
|
}
|
|
err := ValidateQuotaResetConfig(extra)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "quota_daily_reset_mode")
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_InvalidDailyHour_TooHigh(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_daily_reset_hour": float64(24),
|
|
}
|
|
err := ValidateQuotaResetConfig(extra)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "quota_daily_reset_hour")
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_InvalidDailyHour_Negative(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_daily_reset_hour": float64(-1),
|
|
}
|
|
err := ValidateQuotaResetConfig(extra)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "quota_daily_reset_hour")
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_InvalidWeeklyMode(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_weekly_reset_mode": "unknown",
|
|
}
|
|
err := ValidateQuotaResetConfig(extra)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "quota_weekly_reset_mode")
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_InvalidWeeklyDay_TooHigh(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_weekly_reset_day": float64(7),
|
|
}
|
|
err := ValidateQuotaResetConfig(extra)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "quota_weekly_reset_day")
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_InvalidWeeklyDay_Negative(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_weekly_reset_day": float64(-1),
|
|
}
|
|
err := ValidateQuotaResetConfig(extra)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "quota_weekly_reset_day")
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_InvalidWeeklyHour(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_weekly_reset_hour": float64(25),
|
|
}
|
|
err := ValidateQuotaResetConfig(extra)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "quota_weekly_reset_hour")
|
|
}
|
|
|
|
func TestValidateQuotaResetConfig_BoundaryValues(t *testing.T) {
|
|
// All boundary values should be valid
|
|
extra := map[string]any{
|
|
"quota_daily_reset_hour": float64(23),
|
|
"quota_weekly_reset_day": float64(0), // Sunday
|
|
"quota_weekly_reset_hour": float64(0),
|
|
"quota_reset_timezone": "UTC",
|
|
}
|
|
assert.NoError(t, ValidateQuotaResetConfig(extra))
|
|
|
|
extra2 := map[string]any{
|
|
"quota_daily_reset_hour": float64(0),
|
|
"quota_weekly_reset_day": float64(6), // Saturday
|
|
"quota_weekly_reset_hour": float64(23),
|
|
}
|
|
assert.NoError(t, ValidateQuotaResetConfig(extra2))
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ComputeQuotaResetAt
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestComputeQuotaResetAt_RollingMode_NoResetAt(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_daily_reset_mode": "rolling",
|
|
"quota_weekly_reset_mode": "rolling",
|
|
}
|
|
ComputeQuotaResetAt(extra)
|
|
_, hasDailyResetAt := extra["quota_daily_reset_at"]
|
|
_, hasWeeklyResetAt := extra["quota_weekly_reset_at"]
|
|
assert.False(t, hasDailyResetAt, "rolling mode should not set quota_daily_reset_at")
|
|
assert.False(t, hasWeeklyResetAt, "rolling mode should not set quota_weekly_reset_at")
|
|
}
|
|
|
|
func TestComputeQuotaResetAt_RollingMode_ClearsExistingResetAt(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_daily_reset_mode": "rolling",
|
|
"quota_weekly_reset_mode": "rolling",
|
|
"quota_daily_reset_at": "2026-03-14T09:00:00Z",
|
|
"quota_weekly_reset_at": "2026-03-16T09:00:00Z",
|
|
}
|
|
ComputeQuotaResetAt(extra)
|
|
_, hasDailyResetAt := extra["quota_daily_reset_at"]
|
|
_, hasWeeklyResetAt := extra["quota_weekly_reset_at"]
|
|
assert.False(t, hasDailyResetAt, "rolling mode should remove quota_daily_reset_at")
|
|
assert.False(t, hasWeeklyResetAt, "rolling mode should remove quota_weekly_reset_at")
|
|
}
|
|
|
|
func TestComputeQuotaResetAt_FixedDaily_SetsResetAt(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_daily_reset_mode": "fixed",
|
|
"quota_daily_reset_hour": float64(9),
|
|
"quota_reset_timezone": "UTC",
|
|
}
|
|
ComputeQuotaResetAt(extra)
|
|
resetAtStr, ok := extra["quota_daily_reset_at"].(string)
|
|
require.True(t, ok, "quota_daily_reset_at should be set")
|
|
|
|
resetAt, err := time.Parse(time.RFC3339, resetAtStr)
|
|
require.NoError(t, err)
|
|
// Reset time should be in the future
|
|
assert.True(t, resetAt.After(time.Now()), "reset_at should be in the future")
|
|
// Reset hour should be 9 UTC
|
|
assert.Equal(t, 9, resetAt.UTC().Hour())
|
|
}
|
|
|
|
func TestComputeQuotaResetAt_FixedWeekly_SetsResetAt(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_weekly_reset_mode": "fixed",
|
|
"quota_weekly_reset_day": float64(1), // Monday
|
|
"quota_weekly_reset_hour": float64(0),
|
|
"quota_reset_timezone": "UTC",
|
|
}
|
|
ComputeQuotaResetAt(extra)
|
|
resetAtStr, ok := extra["quota_weekly_reset_at"].(string)
|
|
require.True(t, ok, "quota_weekly_reset_at should be set")
|
|
|
|
resetAt, err := time.Parse(time.RFC3339, resetAtStr)
|
|
require.NoError(t, err)
|
|
// Reset time should be in the future
|
|
assert.True(t, resetAt.After(time.Now()), "reset_at should be in the future")
|
|
// Reset day should be Monday
|
|
assert.Equal(t, time.Monday, resetAt.UTC().Weekday())
|
|
}
|
|
|
|
func TestComputeQuotaResetAt_FixedDaily_WithTimezone(t *testing.T) {
|
|
tz, err := time.LoadLocation("Asia/Shanghai")
|
|
require.NoError(t, err)
|
|
|
|
extra := map[string]any{
|
|
"quota_daily_reset_mode": "fixed",
|
|
"quota_daily_reset_hour": float64(9),
|
|
"quota_reset_timezone": "Asia/Shanghai",
|
|
}
|
|
ComputeQuotaResetAt(extra)
|
|
resetAtStr, ok := extra["quota_daily_reset_at"].(string)
|
|
require.True(t, ok)
|
|
|
|
resetAt, err := time.Parse(time.RFC3339, resetAtStr)
|
|
require.NoError(t, err)
|
|
// In Shanghai timezone, the hour should be 9
|
|
assert.Equal(t, 9, resetAt.In(tz).Hour())
|
|
}
|
|
|
|
func TestComputeQuotaResetAt_DefaultTimezone(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_daily_reset_mode": "fixed",
|
|
"quota_daily_reset_hour": float64(12),
|
|
}
|
|
ComputeQuotaResetAt(extra)
|
|
resetAtStr, ok := extra["quota_daily_reset_at"].(string)
|
|
require.True(t, ok)
|
|
|
|
resetAt, err := time.Parse(time.RFC3339, resetAtStr)
|
|
require.NoError(t, err)
|
|
// Default timezone is UTC
|
|
assert.Equal(t, 12, resetAt.UTC().Hour())
|
|
}
|
|
|
|
func TestComputeQuotaResetAt_InvalidHour_ClampedToZero(t *testing.T) {
|
|
extra := map[string]any{
|
|
"quota_daily_reset_mode": "fixed",
|
|
"quota_daily_reset_hour": float64(99),
|
|
"quota_reset_timezone": "UTC",
|
|
}
|
|
ComputeQuotaResetAt(extra)
|
|
resetAtStr, ok := extra["quota_daily_reset_at"].(string)
|
|
require.True(t, ok)
|
|
|
|
resetAt, err := time.Parse(time.RFC3339, resetAtStr)
|
|
require.NoError(t, err)
|
|
// Invalid hour → clamped to 0
|
|
assert.Equal(t, 0, resetAt.UTC().Hour())
|
|
}
|