新功能(#77): 套餐列表返回促销信息

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
2026-05-26 22:27:59 -07:00
parent d2f9289338
commit 7bc54214e2
7 changed files with 406 additions and 67 deletions
@@ -0,0 +1,75 @@
package subscribe
import (
"testing"
"time"
"github.com/perfect-panel/server/internal/model/user"
)
func TestPromoEligibilityEvaluatorMatch(t *testing.T) {
now := time.Unix(1710000000, 0)
campaignEnd := now.Add(2 * time.Hour)
campaign := subscribePromoCandidate{
RuleName: "限时活动",
RuleType: promoRuleTypeCampaign,
PromoPrice: 99,
EndTime: &campaignEnd,
}
ok, expiresAt, err := (&promoEligibilityEvaluator{}).match(campaign, now)
if err != nil {
t.Fatalf("campaign match error: %v", err)
}
if !ok {
t.Fatal("campaign promo should match without login")
}
if got, want := unixSeconds(expiresAt), campaignEnd.Unix(); got != want {
t.Fatalf("campaign expires_at = %d, want %d", got, want)
}
newUser := subscribePromoCandidate{
RuleName: "新客7天优惠",
RuleType: promoRuleTypeNewUser,
PromoPrice: 279,
Params: `{"window_hours":168}`,
}
ok, _, err = (&promoEligibilityEvaluator{}).match(newUser, now)
if err != nil {
t.Fatalf("anonymous new_user match error: %v", err)
}
if ok {
t.Fatal("new_user promo should not match without login")
}
userInfo := &user.User{Id: 1, CreatedAt: now.Add(-24 * time.Hour)}
ok, expiresAt, err = (&promoEligibilityEvaluator{userInfo: userInfo}).match(newUser, now)
if err != nil {
t.Fatalf("logged-in new_user match error: %v", err)
}
if !ok {
t.Fatal("new_user promo should match inside window")
}
if got, want := unixSeconds(expiresAt), userInfo.CreatedAt.Add(168*time.Hour).Unix(); got != want {
t.Fatalf("new_user expires_at = %d, want %d", got, want)
}
}
func TestSubscribePromoCandidateActiveWindow(t *testing.T) {
now := time.Unix(1710000000, 0)
start := now.Add(-time.Hour)
end := now.Add(time.Hour)
if !(subscribePromoCandidate{PromoPrice: 1, StartTime: &start, EndTime: &end}).isActive(now) {
t.Fatal("candidate inside active window should be active")
}
if (subscribePromoCandidate{PromoPrice: 0, StartTime: &start, EndTime: &end}).isActive(now) {
t.Fatal("candidate with zero promo price should not be active")
}
if (subscribePromoCandidate{PromoPrice: 1, StartTime: &end}).isActive(now) {
t.Fatal("candidate before start time should not be active")
}
if (subscribePromoCandidate{PromoPrice: 1, EndTime: &start}).isActive(now) {
t.Fatal("candidate after end time should not be active")
}
}