Files
huangguo_server/web/service/paymentguideser/payment_guide_test.go
T
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

259 lines
8.3 KiB
Go

package paymentguideser
import (
"encoding/json"
"strings"
"testing"
"time"
"91porn-server/models/v/paymentguidemod"
"go.mongodb.org/mongo-driver/bson/primitive"
)
func TestPaymentGuideListResponseUsesLegacyVideoLimitDefault(t *testing.T) {
list := []paymentguidemod.PaymentGuide{
{Scene: paymentguidemod.SceneVIPContentUpdate},
{Scene: paymentguidemod.SceneVIPContentUpdate, VideoLimit: 12},
{Scene: paymentguidemod.SceneVIPCenter},
}
normalizeVideoLimits(list)
if list[0].VideoLimit != paymentguidemod.DefaultVIPContentVideoLimit {
t.Fatalf("legacy videoLimit = %d, want %d", list[0].VideoLimit, paymentguidemod.DefaultVIPContentVideoLimit)
}
if list[1].VideoLimit != 12 {
t.Fatalf("configured videoLimit = %d, want 12", list[1].VideoLimit)
}
if list[2].VideoLimit != 0 {
t.Fatalf("unrelated scene videoLimit = %d, want 0", list[2].VideoLimit)
}
}
func TestSceneOptionsUseConfiguredFreeTrialCountAndHideLegacyScene(t *testing.T) {
options := sceneOptions(5)
if len(options) != paymentguidemod.MaxBatchSceneCount {
t.Fatalf("len(options) = %d, want %d", len(options), paymentguidemod.MaxBatchSceneCount)
}
if options[0].Value != paymentguidemod.SceneHomeNewUserFreeTrial ||
options[0].Label != "首页新用户免费5次试看" ||
options[0].TotalWatchCount == nil || *options[0].TotalWatchCount != 5 {
t.Fatalf("unexpected free-trial option: %+v", options[0])
}
for _, option := range options {
if option.Value == paymentguidemod.SceneHomeNewUser {
t.Fatalf("legacy HOME_NEW_USER must not be returned: %+v", options)
}
}
}
func TestWebConfigurationRejectsLegacyHomeNewUserScene(t *testing.T) {
listReq := ListReq{Scene: paymentguidemod.SceneHomeNewUser, PageNumber: 1, PageSize: 20}
if _, err := listReq.List(); err == nil || !strings.Contains(err.Error(), "unsupported scene") {
t.Fatalf("List() error = %v, want unsupported scene", err)
}
config := validBatchConfig()
config.Scene = paymentguidemod.SceneHomeNewUser
if err := Add(&config); err == nil || !strings.Contains(err.Error(), "unsupported scene") {
t.Fatalf("Add() error = %v, want unsupported scene", err)
}
}
func validBatchConfig() paymentguidemod.PaymentGuide {
return paymentguidemod.PaymentGuide{
Segments: []string{paymentguidemod.SegmentNormal},
Style: "BOTTOM_SHEET",
Title: "会员内容更新",
VideoIDs: []string{"video-a"},
Action: paymentguidemod.Action{Type: "NONE"},
Enable: true,
Sort: 100,
}
}
func TestBatchAddReqConfigsNormalizesScenesAndDefaultsVideoLimit(t *testing.T) {
req := BatchAddReq{
Scenes: []string{" home_new_user_free_trial ", "vip_content_update"},
Config: validBatchConfig(),
}
configs, err := req.Configs()
if err != nil {
t.Fatal(err)
}
if len(configs) != 2 {
t.Fatalf("len(configs) = %d, want 2", len(configs))
}
if configs[0].Scene != paymentguidemod.SceneHomeNewUserFreeTrial || configs[1].Scene != paymentguidemod.SceneVIPContentUpdate {
t.Fatalf("unexpected scenes: %#v", []string{configs[0].Scene, configs[1].Scene})
}
for i := range configs {
if configs[i].VideoLimit != paymentguidemod.DefaultVIPContentVideoLimit {
t.Fatalf("configs[%d].VideoLimit = %d, want %d", i, configs[i].VideoLimit, paymentguidemod.DefaultVIPContentVideoLimit)
}
}
configs[0].Segments[0] = paymentguidemod.SegmentMaxVIP
configs[0].VideoIDs[0] = "changed"
if configs[1].Segments[0] != paymentguidemod.SegmentNormal || configs[1].VideoIDs[0] != "video-a" {
t.Fatal("batch configs must not share slice storage")
}
if req.Config.Segments[0] != paymentguidemod.SegmentNormal || req.Config.VideoIDs[0] != "video-a" {
t.Fatal("building configs must not mutate the request template")
}
}
func TestBatchAddReqConfigsPreservesExplicitVideoLimit(t *testing.T) {
config := validBatchConfig()
config.VideoLimit = 12
configs, err := (BatchAddReq{
Scenes: []string{paymentguidemod.SceneVIPContentUpdate},
Config: config,
}).Configs()
if err != nil {
t.Fatal(err)
}
if configs[0].VideoLimit != 12 {
t.Fatalf("VideoLimit = %d, want 12", configs[0].VideoLimit)
}
}
func TestBatchAddReqConfigsSupportsEveryScene(t *testing.T) {
configs, err := (BatchAddReq{
Scenes: []string{
paymentguidemod.SceneHomeNewUserFreeTrial,
paymentguidemod.SceneHomeOldUser,
paymentguidemod.SceneVideoPreviewEnd,
paymentguidemod.SceneDiscountCountdown,
paymentguidemod.SceneVideoBack,
paymentguidemod.SceneVIPCenter,
paymentguidemod.SceneVIPContentUpdate,
},
Config: validBatchConfig(),
}).Configs()
if err != nil {
t.Fatal(err)
}
if len(configs) != paymentguidemod.MaxBatchSceneCount {
t.Fatalf("len(configs) = %d, want %d", len(configs), paymentguidemod.MaxBatchSceneCount)
}
}
func TestBatchAddReqConfigsDiscardsTemplateIdentityAndTimestamps(t *testing.T) {
config := validBatchConfig()
config.ID = primitive.NewObjectID()
config.Scene = paymentguidemod.SceneVIPCenter
config.CreatedAt = time.Now().Add(-2 * time.Hour)
config.UpdatedAt = time.Now().Add(-time.Hour)
configs, err := (BatchAddReq{
Scenes: []string{paymentguidemod.SceneHomeNewUserFreeTrial},
Config: config,
}).Configs()
if err != nil {
t.Fatal(err)
}
if !configs[0].ID.IsZero() {
t.Fatalf("ID = %s, want zero before insertion", configs[0].ID.Hex())
}
if configs[0].Scene != paymentguidemod.SceneHomeNewUserFreeTrial {
t.Fatalf("Scene = %s, want %s", configs[0].Scene, paymentguidemod.SceneHomeNewUserFreeTrial)
}
if !configs[0].CreatedAt.IsZero() || !configs[0].UpdatedAt.IsZero() {
t.Fatalf("timestamps must be zero before insertion: %+v", configs[0])
}
}
func TestBatchAddReqConfigsRejectsInvalidScenes(t *testing.T) {
tests := []struct {
name string
scenes []string
match string
}{
{name: "empty", scenes: nil, match: "scenes are required"},
{name: "unsupported", scenes: []string{"UNKNOWN"}, match: "unsupported scene"},
{name: "duplicate after normalization", scenes: []string{"VIP_CENTER", " vip_center "}, match: "duplicate scene"},
{name: "too many inputs", scenes: []string{"a", "b", "c", "d", "e", "f", "g", "h"}, match: "more than 7"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := (BatchAddReq{Scenes: tt.scenes, Config: validBatchConfig()}).Configs()
if err == nil || !strings.Contains(err.Error(), tt.match) {
t.Fatalf("Configs() error = %v, want match %q", err, tt.match)
}
})
}
}
func TestBatchAddReqConfigsValidatesTemplateForEveryScene(t *testing.T) {
config := validBatchConfig()
config.Title = ""
_, err := (BatchAddReq{
Scenes: []string{paymentguidemod.SceneVIPCenter},
Config: config,
}).Configs()
if err == nil || !strings.Contains(err.Error(), "title is required") {
t.Fatalf("Configs() error = %v, want title validation error", err)
}
}
func TestAddReqSupportsExistingSingleSceneJSON(t *testing.T) {
body := []byte(`{
"scene":"VIP_CONTENT_UPDATE",
"style":"BOTTOM_SHEET",
"title":"会员内容更新",
"action":{"type":"NONE","value":""}
}`)
var req AddReq
if err := json.Unmarshal(body, &req); err != nil {
t.Fatal(err)
}
if req.IsBatch() {
t.Fatal("existing flat add request must remain single-scene")
}
if req.Scene != paymentguidemod.SceneVIPContentUpdate || req.Title != "会员内容更新" {
t.Fatalf("unexpected single add request: %+v", req.PaymentGuide)
}
}
func TestAddReqSupportsBatchJSONShape(t *testing.T) {
body := []byte(`{
"scenes":["HOME_NEW_USER_FREE_TRIAL","VIP_CONTENT_UPDATE"],
"config":{
"style":"BOTTOM_SHEET",
"title":"会员内容更新",
"videoLimit":20,
"action":{"type":"NONE","value":""},
"enable":true,
"sort":100
}
}`)
var req AddReq
if err := json.Unmarshal(body, &req); err != nil {
t.Fatal(err)
}
if !req.IsBatch() || req.Config == nil {
t.Fatalf("unexpected batch add request: %+v", req)
}
configs, err := (BatchAddReq{Scenes: req.Scenes, Config: *req.Config}).Configs()
if err != nil {
t.Fatal(err)
}
if len(configs) != 2 || configs[1].VideoLimit != 20 {
t.Fatalf("unexpected configs: %+v", configs)
}
}
func TestAddReqTreatsPresentEmptyScenesAsBatch(t *testing.T) {
var req AddReq
if err := json.Unmarshal([]byte(`{"scenes":[]}`), &req); err != nil {
t.Fatal(err)
}
if !req.IsBatch() {
t.Fatal("a present scenes field must use batch validation")
}
_, err := (BatchAddReq{Scenes: req.Scenes, Config: paymentguidemod.PaymentGuide{}}).Configs()
if err == nil || !strings.Contains(err.Error(), "scenes are required") {
t.Fatalf("Configs() error = %v, want scenes validation error", err)
}
}