137 lines
4.1 KiB
Go
137 lines
4.1 KiB
Go
package vip
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
"chatapp3-golang/internal/model"
|
|
)
|
|
|
|
func TestBuildPurchasePlanNewPurchase(t *testing.T) {
|
|
now := time.Date(2026, 4, 29, 10, 0, 0, 0, time.UTC)
|
|
configs := vipTestConfigs()
|
|
|
|
plan, err := buildPurchasePlan(now, nil, configs[2], configs)
|
|
if err != nil {
|
|
t.Fatalf("buildPurchasePlan returned error: %v", err)
|
|
}
|
|
|
|
if plan.OrderType != orderTypePurchase {
|
|
t.Fatalf("order type = %s, want %s", plan.OrderType, orderTypePurchase)
|
|
}
|
|
if plan.CurrentLevel != 0 || plan.TargetLevel != 2 {
|
|
t.Fatalf("levels = %d -> %d, want 0 -> 2", plan.CurrentLevel, plan.TargetLevel)
|
|
}
|
|
if plan.PayableGold != 2000 {
|
|
t.Fatalf("payable = %d, want 2000", plan.PayableGold)
|
|
}
|
|
if !plan.StartAt.Equal(now) || !plan.ExpireAt.Equal(now.AddDate(0, 0, vipDurationDay)) {
|
|
t.Fatalf("period = %s -> %s, want %s -> %s", plan.StartAt, plan.ExpireAt, now, now.AddDate(0, 0, vipDurationDay))
|
|
}
|
|
}
|
|
|
|
func TestBuildPurchasePlanUpgradePaysDifferenceAndKeepsExpireAt(t *testing.T) {
|
|
now := time.Date(2026, 4, 29, 10, 0, 0, 0, time.UTC)
|
|
startAt := now.AddDate(0, 0, -5)
|
|
expireAt := now.AddDate(0, 0, 25)
|
|
configs := vipTestConfigs()
|
|
state := &model.UserVipState{
|
|
Level: 2,
|
|
Status: statusActive,
|
|
StartAt: startAt,
|
|
ExpireAt: expireAt,
|
|
}
|
|
|
|
plan, err := buildPurchasePlan(now, state, configs[4], configs)
|
|
if err != nil {
|
|
t.Fatalf("buildPurchasePlan returned error: %v", err)
|
|
}
|
|
|
|
if plan.OrderType != orderTypeUpgrade {
|
|
t.Fatalf("order type = %s, want %s", plan.OrderType, orderTypeUpgrade)
|
|
}
|
|
if plan.PayableGold != 2000 {
|
|
t.Fatalf("payable = %d, want 2000", plan.PayableGold)
|
|
}
|
|
if !plan.StartAt.Equal(startAt) || !plan.ExpireAt.Equal(expireAt) {
|
|
t.Fatalf("upgrade period changed to %s -> %s, want %s -> %s", plan.StartAt, plan.ExpireAt, startAt, expireAt)
|
|
}
|
|
}
|
|
|
|
func TestBuildPurchasePlanRenewExtendsThirtyDays(t *testing.T) {
|
|
now := time.Date(2026, 4, 29, 10, 0, 0, 0, time.UTC)
|
|
startAt := now.AddDate(0, 0, -5)
|
|
expireAt := now.AddDate(0, 0, 25)
|
|
configs := vipTestConfigs()
|
|
state := &model.UserVipState{
|
|
Level: 3,
|
|
Status: statusActive,
|
|
StartAt: startAt,
|
|
ExpireAt: expireAt,
|
|
}
|
|
|
|
plan, err := buildPurchasePlan(now, state, configs[3], configs)
|
|
if err != nil {
|
|
t.Fatalf("buildPurchasePlan returned error: %v", err)
|
|
}
|
|
|
|
if plan.OrderType != orderTypeRenew {
|
|
t.Fatalf("order type = %s, want %s", plan.OrderType, orderTypeRenew)
|
|
}
|
|
if plan.PayableGold != 3000 {
|
|
t.Fatalf("payable = %d, want 3000", plan.PayableGold)
|
|
}
|
|
if !plan.ExpireAt.Equal(expireAt.AddDate(0, 0, vipDurationDay)) {
|
|
t.Fatalf("renew expireAt = %s, want %s", plan.ExpireAt, expireAt.AddDate(0, 0, vipDurationDay))
|
|
}
|
|
}
|
|
|
|
func TestBuildPurchasePlanRejectsDowngrade(t *testing.T) {
|
|
now := time.Date(2026, 4, 29, 10, 0, 0, 0, time.UTC)
|
|
configs := vipTestConfigs()
|
|
state := &model.UserVipState{
|
|
Level: 4,
|
|
Status: statusActive,
|
|
StartAt: now.AddDate(0, 0, -5),
|
|
ExpireAt: now.AddDate(0, 0, 25),
|
|
}
|
|
|
|
if _, err := buildPurchasePlan(now, state, configs[2], configs); err == nil {
|
|
t.Fatal("buildPurchasePlan returned nil error for downgrade")
|
|
}
|
|
}
|
|
|
|
func TestVipResourcePayloadAcceptsStringResourceID(t *testing.T) {
|
|
var payload VipResourcePayload
|
|
if err := json.Unmarshal([]byte(`{"resourceId":"2045029471274201089","name":"vip","url":"https://example.com/a.svga"}`), &payload); err != nil {
|
|
t.Fatalf("unmarshal resource payload: %v", err)
|
|
}
|
|
if payload.ResourceID.Int64() != 2045029471274201089 {
|
|
t.Fatalf("resource id = %d, want 2045029471274201089", payload.ResourceID.Int64())
|
|
}
|
|
|
|
body, err := json.Marshal(payload)
|
|
if err != nil {
|
|
t.Fatalf("marshal resource payload: %v", err)
|
|
}
|
|
if got := string(body); got != `{"resourceId":"2045029471274201089","name":"vip","url":"https://example.com/a.svga"}` {
|
|
t.Fatalf("json = %s", got)
|
|
}
|
|
}
|
|
|
|
func vipTestConfigs() map[int]model.VipLevelConfig {
|
|
configs := make(map[int]model.VipLevelConfig, levelCount)
|
|
for level := 1; level <= levelCount; level++ {
|
|
configs[level] = model.VipLevelConfig{
|
|
Level: level,
|
|
LevelCode: levelCode(level),
|
|
DisplayName: levelDisplayName(level),
|
|
Enabled: true,
|
|
DurationDays: vipDurationDay,
|
|
PriceGold: int64(level * 1000),
|
|
}
|
|
}
|
|
return configs
|
|
}
|