128 lines
6.9 KiB
Go
128 lines
6.9 KiB
Go
package business
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"testing"
|
||
|
||
"gorm.io/gorm"
|
||
"kra/internal/biz/business"
|
||
)
|
||
|
||
func prepareLedgerData(t *testing.T) (*gorm.DB, business.LedgerRepo, business.LedgerScope, business.LedgerFilter) {
|
||
t.Helper()
|
||
db, _ := prepareChannels(t)
|
||
for _, sql := range []string{
|
||
"DROP TABLE tab_user", "DROP TABLE tab_spend",
|
||
"CREATE TABLE tab_user(id INTEGER,source_db TEXT,register_time TEXT,fgame_id INTEGER,fgame_name TEXT,register_ip TEXT,device_name TEXT,promote_id INTEGER,puid INTEGER)",
|
||
"INSERT INTO tab_user VALUES(1,'lx','1500',1,'历史游戏名','192.0.2.1','机型甲',100,0),(2,'lx','1500',1,'历史游戏名','','',101,NULL),(3,'lx','1500',1,'历史游戏名','','',102,0),(4,'lx','1500',1,'历史游戏名','','',101,1),(5,'lx','1500',1,'历史游戏名','','',103,0),(6,'lx','1500',1,'历史游戏名','','',0,0),(7,'lx','1500',1,'历史游戏名','','',999,0),(1,'hw','1500',1,'其他平台','','',100,0)",
|
||
"CREATE TABLE tab_spend(id INTEGER,source_db TEXT,user_id INTEGER,pay_order_number TEXT,game_id INTEGER,game_name TEXT,server_id TEXT,server_name TEXT,game_player_name TEXT,pay_amount DECIMAL(20,2),pay_time INTEGER,pay_way INTEGER,pay_status INTEGER,spend_ip TEXT,promote_id INTEGER,promote_account TEXT)",
|
||
"INSERT INTO tab_spend VALUES(901,'lx',1,'00001',1,'游戏甲','s1','区服甲','角色甲',10.10,1500,3,1,'192.0.2.2',100,''),(902,'lx',3,'00002',1,'游戏甲','s1','区服甲','角色乙',30.30,1501,4,1,'',102,''),(903,'lx',5,'00003',1,'游戏甲','s1','区服甲','角色丙',40.40,1502,3,1,'',103,''),(904,'lx',1,'failed',1,'游戏甲','s1','区服甲','角色甲',999,1503,3,0,'',100,''),(905,'lx',1,'outside',1,'游戏甲','s1','区服甲','角色甲',700,500,3,1,'',999,'历史渠道'),(906,'hw',1,'other',1,'同号其他游戏','s1','其他','角色甲',9999,1500,3,1,'',100,''),(907,'lx',6,'official',1,'游戏甲','s1','官方','角色甲',5,1500,3,1,'',0,''),(908,'lx',7,'orphan',1,'游戏甲','s1','未知','角色甲',6,1500,3,1,'',999,''),(909,'lx',1,'pending',1,'游戏甲','s1','区服甲','角色甲',8,1504,3,2,'',100,'旧渠道名')",
|
||
} {
|
||
if err := db.Exec(sql).Error; err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
}
|
||
scope := business.LedgerScope{Viewer: channelTestScope(), IncludeSub: true}
|
||
filter := business.LedgerFilter{Sources: []string{"lx"}, BeginUnix: 1000, EndUnix: 2000, SortField: "registerTime"}
|
||
return db, NewLedgerRepo(testData{db}), scope, filter
|
||
}
|
||
func TestRegistrationScopePuidAndUnboundedPlayerPay(t *testing.T) {
|
||
_, repo, scope, filter := prepareLedgerData(t)
|
||
ctx := context.Background()
|
||
page, err := repo.Registrations(ctx, scope, filter, business.LedgerListOptions{Limit: 20})
|
||
if err != nil || page.Total != 3 {
|
||
t.Fatalf("注册范围或 puid=0 规则错误: %+v %v", page, err)
|
||
}
|
||
var first *business.Registration
|
||
for _, row := range page.Rows {
|
||
if row.ID == 1 {
|
||
first = row
|
||
}
|
||
}
|
||
if first == nil || first.TotalPayAmount == nil || portraitTestMoney(*first.TotalPayAmount) != "710.10" || first.FirstGameName != "历史游戏名" || first.DisplayBusiness() != "lx-business(leaf)" {
|
||
t.Fatalf("累计充值不能受本次时间/渠道限制,且需保留游戏快照: %+v", first)
|
||
}
|
||
filter.SortField = "totalPayAmount"
|
||
page, err = repo.Registrations(ctx, scope, filter, business.LedgerListOptions{Limit: 2})
|
||
if err != nil || page.Rows[0].ID != 1 || page.Rows[1].ID != 5 {
|
||
t.Fatal("累计金额排序关联到了错误的支付 ID 或平台")
|
||
}
|
||
filter.GameNames = []string{"同号其他游戏"}
|
||
page, err = repo.Registrations(ctx, scope, filter, business.LedgerListOptions{Limit: 20})
|
||
if err != nil || page.Total != 0 {
|
||
t.Fatal("游戏名称筛选串到了另一个平台")
|
||
}
|
||
filter.GameNames = []string{"游戏甲"}
|
||
filter.PromoteAccount = "child-channel"
|
||
page, err = repo.Registrations(ctx, scope, filter, business.LedgerListOptions{Limit: 20})
|
||
if err != nil || page.Total != 2 {
|
||
t.Fatal("精确子渠道账号应扩到同一一级树内的可见渠道")
|
||
}
|
||
filter.PromoteAccount = "CHILD-channel"
|
||
page, err = repo.Registrations(ctx, scope, filter, business.LedgerListOptions{Limit: 20})
|
||
if err != nil || page.Total != 0 {
|
||
t.Fatal("渠道账号应保持区分大小写的精确匹配")
|
||
}
|
||
}
|
||
func TestSpendSummaryIgnoresSelectedFailureStatusAndKeepsSnapshot(t *testing.T) {
|
||
_, repo, scope, filter := prepareLedgerData(t)
|
||
status := 0
|
||
filter.PayStatus = &status
|
||
page, err := repo.Spends(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20})
|
||
if err != nil || page.Total != 1 || page.Rows[0].ID != 904 || portraitTestMoney(*page.TotalPayAmount) != "80.80" {
|
||
t.Fatalf("失败列表与成功支付合计不能使用同一个状态条件: %+v %v", page, err)
|
||
}
|
||
status = 2
|
||
page, err = repo.Spends(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20})
|
||
if err != nil || page.Rows[0].PromoteAccount != "旧渠道名" {
|
||
t.Fatal("支付明细不应覆盖历史渠道账号")
|
||
}
|
||
filter.PayStatus = nil
|
||
scope.Unrestricted = true
|
||
scope.Viewer = business.UserScope{All: true}
|
||
page, err = repo.Spends(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20})
|
||
if err != nil || page.Total != 7 || portraitTestMoney(*page.TotalPayAmount) != "91.80" {
|
||
t.Fatalf("超管应包含官方和失去当前渠道资料的历史订单: %+v %v", page, err)
|
||
}
|
||
unknown := map[uint64]string{}
|
||
for _, row := range page.Rows {
|
||
unknown[row.ID] = row.DisplayPromote()
|
||
}
|
||
if unknown[907] != "官方渠道" || unknown[908] != "未知渠道(ID:999)" {
|
||
t.Fatal("渠道资料缺失时显示不明确")
|
||
}
|
||
scope.IncludeSub = false
|
||
page, err = repo.Spends(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20})
|
||
if err != nil || page.Total != 3 {
|
||
t.Fatal("不含下级时超管只保留真实一级渠道")
|
||
}
|
||
}
|
||
func TestLedgerLargeTreeFilterDoesNotFallBackToAll(t *testing.T) {
|
||
db, repo, scope, filter := prepareLedgerData(t)
|
||
for i := 0; i < 205; i++ {
|
||
if err := db.Exec("INSERT INTO tab_promote(id,source_db,account,promote_level,parent_id,top_promote_id,busier_id) VALUES(?,'lx',?,3,100,100,14)", 1000+i, fmt.Sprintf("child-%d", i)).Error; err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
}
|
||
scope.Unrestricted = true
|
||
scope.Viewer = business.UserScope{All: true}
|
||
filter.PromoteAccount = "root-channel"
|
||
page, err := repo.Registrations(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20})
|
||
if err != nil || page.Total != 2 {
|
||
t.Fatalf("超过200渠道后筛选被放宽到全平台: %+v %v", page, err)
|
||
}
|
||
filter.PromoteAccount = ""
|
||
page, err = repo.Registrations(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20, RejectAbove: 1})
|
||
if err != nil || page.Total != 5 || len(page.Rows) != 0 {
|
||
t.Fatal("导出超过上限应在读取完整结果前停止")
|
||
}
|
||
if err := db.Exec("DROP TABLE tab_promote").Error; err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
page, err = repo.Registrations(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20})
|
||
if err != nil || page.Available {
|
||
t.Fatal("缺渠道范围表不能把限制解释为全量")
|
||
}
|
||
}
|