Merge pull request #4614 from cugxuan/codex/fix-subscription-expiry-days

fix(subscription): round remaining days up
This commit is contained in:
Wesley Liddick authored and GitHub committed 2026-07-20 10:24:14 +08:00
commit 6def36a171
3 files changed
+52 -3

No files matched your search

@@ -34,7 +34,7 @@ func TestCalculateProgress_BasicFields(t *testing.T) {
assert.Equal(t, int64(100), progress.ID) assert.Equal(t, int64(100), progress.ID)
assert.Equal(t, "Premium", progress.GroupName) assert.Equal(t, "Premium", progress.GroupName)
assert.Equal(t, sub.ExpiresAt, progress.ExpiresAt) assert.Equal(t, sub.ExpiresAt, progress.ExpiresAt)
assert.True(t, progress.ExpiresInDays == 29 || progress.ExpiresInDays == 30, "ExpiresInDays should be 29 or 30, got %d", progress.ExpiresInDays) assert.Equal(t, 30, progress.ExpiresInDays)
assert.Nil(t, progress.Daily, "无日限额时 Daily 应为 nil") assert.Nil(t, progress.Daily, "无日限额时 Daily 应为 nil")
assert.Nil(t, progress.Weekly, "无周限额时 Weekly 应为 nil") assert.Nil(t, progress.Weekly, "无周限额时 Weekly 应为 nil")
assert.Nil(t, progress.Monthly, "无月限额时 Monthly 应为 nil") assert.Nil(t, progress.Monthly, "无月限额时 Monthly 应为 nil")
+14 -2
View File
@@ -2,6 +2,8 @@ package service
import "time" import "time"
const subscriptionDayDuration = 24 * time.Hour
type UserSubscription struct { type UserSubscription struct {
ID int64 ID int64
UserID int64 UserID int64
@@ -41,10 +43,20 @@ func (s *UserSubscription) IsExpired() bool {
} }
func (s *UserSubscription) DaysRemaining() int { func (s *UserSubscription) DaysRemaining() int {
if s.IsExpired() { return s.daysRemainingAt(time.Now())
}
func (s *UserSubscription) daysRemainingAt(now time.Time) int {
remaining := s.ExpiresAt.Sub(now)
if remaining <= 0 {
return 0 return 0
} }
return int(time.Until(s.ExpiresAt).Hours() / 24)
days := int(remaining / subscriptionDayDuration)
if remaining%subscriptionDayDuration != 0 {
days++
}
return days
} }
func (s *UserSubscription) IsWindowActivated() bool { func (s *UserSubscription) IsWindowActivated() bool {
@@ -0,0 +1,37 @@
//go:build unit
package service
import (
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestUserSubscriptionDaysRemainingAt(t *testing.T) {
now := time.Date(2026, time.July, 19, 12, 0, 0, 0, time.UTC)
tests := []struct {
name string
expiresAt time.Time
want int
}{
{name: "expired", expiresAt: now.Add(-time.Nanosecond), want: 0},
{name: "expires now", expiresAt: now, want: 0},
{name: "less than one day", expiresAt: now.Add(subscriptionDayDuration - time.Nanosecond), want: 1},
{name: "exactly one day", expiresAt: now.Add(subscriptionDayDuration), want: 1},
{name: "over one day", expiresAt: now.Add(subscriptionDayDuration + time.Nanosecond), want: 2},
{name: "less than two days", expiresAt: now.Add(2*subscriptionDayDuration - time.Nanosecond), want: 2},
{name: "exactly two days", expiresAt: now.Add(2 * subscriptionDayDuration), want: 2},
{name: "over two days", expiresAt: now.Add(2*subscriptionDayDuration + time.Nanosecond), want: 3},
{name: "exactly seven days", expiresAt: now.Add(7 * subscriptionDayDuration), want: 7},
{name: "over seven days", expiresAt: now.Add(7*subscriptionDayDuration + time.Nanosecond), want: 8},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sub := &UserSubscription{ExpiresAt: tt.expiresAt}
require.Equal(t, tt.want, sub.daysRemainingAt(now))
})
}
}