Files
kra-new/internal/data/business/channel_portrait_test.go
T

105 lines
4.3 KiB
Go

package business
import (
"context"
"testing"
"gorm.io/gorm"
"kra/internal/biz/business"
)
func prepareChannelTiers(t *testing.T) (*gorm.DB, business.ChannelPortraitRepo, business.ChannelGameScope) {
t.Helper()
db, _ := prepareChannels(t)
for _, sql := range []string{
"ALTER TABLE tab_spend ADD COLUMN user_id INTEGER",
"ALTER TABLE tab_spend ADD COLUMN pay_time INTEGER",
"DELETE FROM tab_spend",
"DELETE FROM tab_sw_report_day_key",
"INSERT INTO tab_user VALUES('lx',6,100,0,'subaccount'),('lx',7,100,0,'unpaid')",
"INSERT INTO tab_sw_report_day_key VALUES('lx',100,1,1,'2026-11-01',1,'abcx'),('lx',101,1,1,'2026-11-02',1,'abcx'),('lx',100,1,1,'2026-11-01',1,'subaccount'),('lx',100,1,1,'2026-11-01',1,'unpaid'),('lx',100,1,1,'2026-11-04',1,'future'),('lx',103,1,1,'2026-11-01',1,'outside-tree'),('hw',100,1,1,'2026-11-01',1,'outside-platform'),('lx',100,1,0,'2026-11-01',1,'1'),('lx',100,1,0,'2026-11-01',1,'2'),('lx',100,1,0,'2026-11-01',1,'6')",
"INSERT INTO tab_spend VALUES('lx',100,1,10.10,1,1000),('lx',101,1,20.20,2,1793577600),('lx',100,1,9969.70,1,2000000000),('lx',101,1,5000,4,1793577600),('lx',102,1,100000,3,1793577600),('lx',103,1,999999,5,1793577600),('hw',100,1,999999,1,1793577600),('lx',100,0,999999,1,1793577600)",
} {
if err := db.Exec(sql).Error; err != nil {
t.Fatal(err)
}
}
level := 1
scope := business.ChannelGameScope{Root: &business.Channel{ChannelKey: business.ChannelKey{SourceDB: "lx", ID: 100}, Level: &level}, IncludeSub: true, IDCardDedup: true, BeginDate: "2026-11-01", EndDate: "2026-11-03"}
return db, NewChannelPortraitRepo(testData{db}), scope
}
func TestChannelTierStorageUsesAllHistoricalPayAndRawPayer(t *testing.T) {
db, repo, scope := prepareChannelTiers(t)
data, err := repo.TierData(context.Background(), scope)
if err != nil {
t.Fatal(err)
}
if !data.Available || len(data.RegisterKeys) != 3 || len(data.Payments) != 3 {
t.Fatalf("分层成员或支付范围错误: %+v", data)
}
amounts := map[string]string{}
for _, pay := range data.Payments {
if pay.IDCard != nil {
amounts[*pay.IDCard] = portraitTestMoney(pay.Amount)
}
}
if amounts[" abcX "] != "9979.80" || amounts["abcx"] != "20.20" || amounts["subaccount"] != "5000.00" {
t.Fatalf("历史/未来成功支付被日期过滤、合并到错误用户或混入其他平台: %+v", amounts)
}
if err := db.Exec("DROP TABLE tab_user").Error; err != nil {
t.Fatal(err)
}
scope.IDCardDedup = false
data, err = repo.TierData(context.Background(), scope)
if err != nil || !data.Available {
t.Fatalf("模式0不应依赖身份证用户表: %v", err)
}
keys := map[string]bool{}
for _, key := range data.RegisterKeys {
keys[key] = true
}
if len(keys) != 3 || !keys["lx|1"] || !keys["lx|2"] || !keys["lx|6"] {
t.Fatalf("模式0身份前缀错误: %+v", keys)
}
payers := map[uint64]string{}
for _, pay := range data.Payments {
if pay.UserID != nil {
payers[*pay.UserID] = portraitTestMoney(pay.Amount)
}
}
if payers[2] != "20.20" || payers[4] != "5000.00" {
t.Fatal("旧分层使用实际付款账号,不能擅自把子账号金额合到父账号")
}
scope.IDCardDedup = true
data, err = repo.TierData(context.Background(), scope)
if err != nil || data.Available {
t.Fatal("身份证模式缺用户表时不能伪造分层")
}
}
func TestChannelPortraitEarliestDateAndEmptyMembership(t *testing.T) {
db, repo, scope := prepareChannelTiers(t)
date, available, err := repo.EarliestDate(context.Background(), scope)
if err != nil || !available || date != "2026-11-01" {
t.Fatalf("累计起点未遵循当前去重模式: %s %v", date, err)
}
scope.IDCardDedup = false
date, _, err = repo.EarliestDate(context.Background(), scope)
if err != nil || date != "2026-10-01" {
t.Fatal("模式0累计起点错误")
}
count, err := repo.GameCount(context.Background(), scope.Root.ChannelKey)
if err != nil || count == nil || *count != 2 {
t.Fatal("游戏数应只统计当前渠道正常申请并去重")
}
if err := db.Exec("DELETE FROM tab_sw_report_day_key").Error; err != nil {
t.Fatal(err)
}
if err := db.Exec("DROP TABLE tab_spend").Error; err != nil {
t.Fatal(err)
}
data, err := repo.TierData(context.Background(), scope)
if err != nil || !data.Available || len(data.RegisterKeys) != 0 || data.FallbackCount != 0 {
t.Fatal("无注册身份是已知零,不应继续查询支付")
}
}