117 lines
6.3 KiB
Go
117 lines
6.3 KiB
Go
package business
|
|
|
|
import (
|
|
"context"
|
|
"kra/internal/biz/business"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestWorkbenchStorageSummaryAndRankRules(t *testing.T) {
|
|
db, _ := prepareChannels(t)
|
|
ctx := context.Background()
|
|
day := time.Date(2026, 11, 4, 0, 0, 0, 0, time.FixedZone("Asia/Shanghai", 8*3600))
|
|
for _, sql := range []string{
|
|
"ALTER TABLE tab_promote ADD COLUMN last_login_time INTEGER",
|
|
"INSERT INTO tab_promote(id,source_db,account,promote_level,parent_id,top_promote_id,busier_id,create_time) VALUES(105,'lx','zero-channel',1,0,0,14,1000)",
|
|
"DELETE FROM tab_sw_report_day",
|
|
"DELETE FROM tab_sw_report_day_key",
|
|
"INSERT INTO tab_sw_report_day VALUES('lx',100,1,0,'2026-11-04',10),('lx',101,1,0,'2026-11-04',20),('hw',100,1,0,'2026-11-04',40),('lx',103,1,0,'2026-11-04',-5),('lx',0,1,0,'2026-11-04',5),('lx',999,1,0,'2026-11-04',7),('lx',100,1,1,'2026-11-04',9999),('lx',100,1,0,'2026-11-03',5),('hw',100,1,0,'2026-11-03',5),('lx',100,1,0,'2026-11-01',1),('lx',100,1,0,'2026-10-01',8),('lx',100,1,0,'2026-10-04',12),('lx',100,1,0,'2026-10-05',999)",
|
|
"INSERT INTO tab_sw_report_day_key VALUES('lx',100,1,1,'2026-11-04',1,'A'),('lx',101,1,1,'2026-11-04',1,'A'),('hw',100,1,1,'2026-11-04',1,'A'),('lx',100,1,1,'2026-11-04',2,'A'),('lx',101,1,1,'2026-11-04',2,'B'),('hw',100,1,1,'2026-11-04',2,'A'),('lx',100,1,0,'2026-11-04',1,'1'),('lx',101,1,0,'2026-11-04',1,'2'),('hw',100,1,0,'2026-11-04',1,'1'),('lx',0,1,1,'2026-11-04',1,'official'),('lx',999,1,1,'2026-11-04',1,'orphan')",
|
|
} {
|
|
if err := db.Exec(sql).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if err := db.Exec("UPDATE tab_promote SET create_time=? WHERE source_db='lx' AND id IN(100,101)", day.Unix()).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
w := business.WorkbenchWindow{Today: day, Yesterday: day.AddDate(0, 0, -1), MonthStart: day.AddDate(0, 0, -3), PreviousMonthStart: day.AddDate(0, -1, -3), PreviousMonthEnd: day.AddDate(0, -1, 0)}
|
|
r := NewWorkbenchRepo(testData{db})
|
|
scope := business.AnalyticsScope{Viewer: channelTestScope(), IncludeSub: true, IDCardDedup: true}
|
|
sources := []string{"lx", "hw"}
|
|
out, err := r.Summary(ctx, scope, sources, w)
|
|
if err != nil || out.Today.Counts.Register != 1 || out.Today.Counts.Active != 2 || portraitTestMoney(out.Today.Pay) != "65.00" || out.Today.ActiveChannels != 3 || out.Today.NewChannels != 2 || portraitTestMoney(out.MonthPay) != "76.00" || portraitTestMoney(out.PreviousMonthPay) != "20.00" {
|
|
t.Fatalf("工作台统计口径错误: %+v %v", out, err)
|
|
}
|
|
scope.IDCardDedup = false
|
|
out, err = r.Summary(ctx, scope, sources, w)
|
|
if err != nil || out.Today.Counts.Register != 3 || portraitTestMoney(out.Today.Pay) != "65.00" {
|
|
t.Fatal("模式0应按平台前缀去重,金额不变")
|
|
}
|
|
scope.IncludeSub = false
|
|
out, err = r.Summary(ctx, scope, sources, w)
|
|
if err != nil || out.Today.Counts.Register != 2 || out.Today.NewChannels != 1 || out.Today.ActiveChannels != 2 || portraitTestMoney(out.Today.Pay) != "50.00" {
|
|
t.Fatal("下级偏好未作用到渠道数和金额")
|
|
}
|
|
scope = business.AnalyticsScope{Viewer: business.UserScope{All: true}, IncludeSub: true, IDCardDedup: true}
|
|
f := business.AnalyticsFilter{Sources: sources, Begin: "2026-11-04", End: "2026-11-04"}
|
|
rows, err := r.Ranks(ctx, scope, f, business.WorkbenchRegister)
|
|
if err != nil || len(rows.Rows) != 2 {
|
|
t.Fatalf("注册榜含下级时应排除无渠道实体的官方/孤立记录: %+v %v", rows, err)
|
|
}
|
|
for _, row := range rows.Rows {
|
|
if row.ID != 100 || row.Value != "1" {
|
|
t.Fatal("注册榜应整棵树去重")
|
|
}
|
|
}
|
|
rows, err = r.Ranks(ctx, scope, f, business.WorkbenchPayLow)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
values := map[business.AnalyticsKey]string{}
|
|
for _, row := range rows.Rows {
|
|
values[row.AnalyticsKey] = portraitTestMoney(row.Value)
|
|
}
|
|
for id, want := range map[int64]string{0: "5.00", 100: "30.00", 103: "-5.00", 105: "0.00", 999: "7.00"} {
|
|
if values[business.AnalyticsKey{SourceDB: "lx", ID: id}] != want {
|
|
t.Fatalf("最低榜漏掉零实体或汇总错误: %+v", values)
|
|
}
|
|
}
|
|
scope.Viewer = channelTestScope()
|
|
rows, err = r.Ranks(ctx, scope, f, business.WorkbenchUnlogin)
|
|
if err != nil || len(rows.Rows) != 3 {
|
|
t.Fatal("未登录榜只取可见一级实体")
|
|
}
|
|
if err := db.Exec("DROP TABLE tab_sw_report_day").Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rows, err = r.Ranks(ctx, scope, f, business.WorkbenchRegister)
|
|
if err != nil || !rows.Available {
|
|
t.Fatal("注册榜不应依赖金额汇总表")
|
|
}
|
|
out, err = r.Summary(ctx, scope, sources, w)
|
|
if err != nil || out.Available {
|
|
t.Fatal("六卡缺表应明确未接入")
|
|
}
|
|
}
|
|
|
|
func TestWorkbenchSummaryMonthStartAndNullableRegistrationKeys(t *testing.T) {
|
|
db, _ := prepareChannels(t)
|
|
for _, statement := range []string{
|
|
"DELETE FROM tab_sw_report_day",
|
|
"DELETE FROM tab_sw_report_day_key",
|
|
"INSERT INTO tab_sw_report_day VALUES('lx',100,1,0,'2026-10-01',10),('lx',100,1,0,'2026-10-02',999),('lx',100,1,0,'2026-10-31',30),('lx',100,1,0,'2026-11-01',20),('lx',103,1,0,'2026-11-01',-1)",
|
|
"INSERT INTO tab_sw_report_day_key VALUES('lx',103,1,1,'2026-11-01',1,NULL),('lx',999,1,1,'2026-11-01',1,''),('lx',100,1,1,'2026-10-31',1,'A')",
|
|
} {
|
|
if err := db.Exec(statement).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
day := time.Date(2026, 11, 1, 0, 0, 0, 0, time.FixedZone("Asia/Shanghai", 8*3600))
|
|
if err := db.Exec("UPDATE tab_promote SET create_time=CASE WHEN id=100 THEN ? ELSE ? END WHERE source_db='lx' AND id IN(100,101)", day.Unix(), day.AddDate(0, 0, -1).Unix()).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
window := business.WorkbenchWindow{Today: day, Yesterday: day.AddDate(0, 0, -1), MonthStart: day, PreviousMonthStart: day.AddDate(0, -1, 0), PreviousMonthEnd: day.AddDate(0, -1, 0)}
|
|
out, err := NewWorkbenchRepo(testData{db}).Summary(context.Background(), business.AnalyticsScope{Viewer: business.UserScope{All: true}, IncludeSub: true, IDCardDedup: true}, []string{"lx"}, window)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if portraitTestMoney(out.Today.Pay) != "19.00" || portraitTestMoney(out.Yesterday.Pay) != "30.00" || portraitTestMoney(out.MonthPay) != "19.00" || portraitTestMoney(out.PreviousMonthPay) != "10.00" {
|
|
t.Fatalf("month-first comparison mixed yesterday with the previous-month window: %+v", out)
|
|
}
|
|
if out.Today.ActiveChannels != 2 || out.Today.Counts.Register != 1 || out.Yesterday.ActiveChannels != 1 || out.Today.NewChannels != 1 || out.Yesterday.NewChannels != 1 {
|
|
t.Fatalf("daily groups or NULL/empty registration-key behavior changed: %+v", out)
|
|
}
|
|
}
|