170 lines
7.2 KiB
Go
170 lines
7.2 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"path/filepath"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/glebarez/sqlite"
|
|
"gorm.io/gorm"
|
|
businessbiz "kra/internal/biz/business"
|
|
"kra/internal/biz/system"
|
|
businessdata "kra/internal/data/business"
|
|
systemdata "kra/internal/data/system"
|
|
"kra/internal/server/handler"
|
|
businessservice "kra/internal/service/business"
|
|
)
|
|
|
|
func TestWorkbenchHTTP(t *testing.T) {
|
|
db, err := gorm.Open(sqlite.Open(filepath.Join(t.TempDir(), "workbench.db")), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
pool, _ := db.DB()
|
|
t.Cleanup(func() { _ = pool.Close() })
|
|
for _, step := range append(systemdata.Migrations(), businessdata.Migrations()...) {
|
|
if err := step.Migrate(db); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
for _, sql := range []string{
|
|
"INSERT INTO sys_users(id,uuid,username,level,parent_id,id_path,enable) VALUES(1,'root','root',0,0,'0',1),(7,'owner','owner',1,0,'0',1),(9,'leaf','leaf',3,7,'0,7',1),(99,'other','other',1,0,'0',1)",
|
|
"INSERT INTO sys_user_bind_platform(user_id,source_db,platform_busier_id,status) VALUES(9,'lx',14,'0'),(99,'hw',20,'0')",
|
|
"CREATE TABLE tab_promote(id INTEGER,source_db TEXT,account TEXT,promote_level INTEGER,top_promote_id INTEGER,busier_id INTEGER,create_time INTEGER,last_login_time INTEGER)",
|
|
"INSERT INTO tab_promote VALUES(100,'lx','渠道甲',1,0,14,0,0),(101,'lx','渠道甲下级',2,100,14,0,0),(200,'lx','零充值渠道',1,0,14,0,0),(100,'hw','外部商务渠道',1,0,20,0,0)",
|
|
"CREATE TABLE tab_sw_report_day(source_db TEXT,promote_id INTEGER,game_id INTEGER,dedup_mode INTEGER,stat_date DATE,total_pay DECIMAL(20,2))",
|
|
"CREATE TABLE tab_sw_report_day_key(source_db TEXT,promote_id INTEGER,game_id INTEGER,dedup_mode INTEGER,stat_date DATE,metric INTEGER,identity_key TEXT)",
|
|
} {
|
|
if err := db.Exec(sql).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
location := time.FixedZone("Asia/Shanghai", 8*3600)
|
|
now := time.Now().In(location)
|
|
today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, location)
|
|
for _, row := range []struct {
|
|
source string
|
|
promote int
|
|
amount int
|
|
}{{"lx", 100, 10}, {"lx", 101, 20}, {"hw", 100, 40}} {
|
|
if err := db.Exec("INSERT INTO tab_sw_report_day VALUES(?,?,1,0,?,?)", row.source, row.promote, today.Format("2006-01-02"), row.amount).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, metric := range []int{1, 2} {
|
|
for _, mode := range []int{0, 1} {
|
|
key := "A"
|
|
if mode == 0 {
|
|
key = strconv.Itoa(row.promote)
|
|
}
|
|
if err := db.Exec("INSERT INTO tab_sw_report_day_key VALUES(?,?,1,?,?,?,?)", row.source, row.promote, mode, today.Format("2006-01-02"), metric, key).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if err := db.Exec("UPDATE tab_promote SET create_time=?,last_login_time=? WHERE source_db='lx' AND id IN(100,101)", today.Unix(), today.AddDate(0, 0, -5).Unix()).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
provider := businessHTTPData{db}
|
|
uc := businessbiz.NewWorkbenchUsecase(businessdata.NewWorkbenchRepo(provider), businessbiz.NewAccountUsecase(businessdata.NewAccountRepo(provider)), businessbiz.NewUserPreferenceUsecase(businessdata.NewUserPreferenceRepo(provider)))
|
|
h := handler.NewWorkbench(businessservice.NewWorkbenchService(uc))
|
|
engine := gin.New()
|
|
engine.Use(func(c *gin.Context) {
|
|
id, _ := strconv.ParseUint(c.GetHeader("X-Test-User"), 10, 64)
|
|
aid := uint(901)
|
|
if id == 1 {
|
|
aid = 888
|
|
}
|
|
c.Request = c.Request.WithContext(system.NewActorContext(c.Request.Context(), system.Actor{UserID: uint(id), AuthorityID: aid}))
|
|
c.Next()
|
|
})
|
|
engine.GET("/sw/workbench/summary", h.Summary)
|
|
engine.GET("/sw/workbench/registerTop", h.RegisterTop)
|
|
engine.GET("/sw/workbench/payRank", h.PayRank)
|
|
engine.GET("/sw/workbench/unloginTop", h.UnloginTop)
|
|
srv := httptest.NewServer(engine)
|
|
defer srv.Close()
|
|
call := func(user int, endpoint, query string, code int) any {
|
|
t.Helper()
|
|
req, _ := http.NewRequest("GET", srv.URL+"/sw/workbench/"+endpoint+"?"+query, nil)
|
|
req.Header.Set("X-Test-User", strconv.Itoa(user))
|
|
res, err := srv.Client().Do(req)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer res.Body.Close()
|
|
var body map[string]any
|
|
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if res.StatusCode != 200 || body["code"] != float64(code) {
|
|
t.Fatalf("%s: %+v", endpoint, body)
|
|
}
|
|
return body["data"]
|
|
}
|
|
q := "sourceDbList=lx,hw"
|
|
card := func(data map[string]any, name, field string) any { return data[name].(map[string]any)[field] }
|
|
summary := call(7, "summary", q, 0).(map[string]any)
|
|
if card(summary, "todayRegister", "value") != "1.00" || card(summary, "todayPay", "value") != "30.00" || card(summary, "activePromote", "value") != "2.00" || card(summary, "newPromote", "value") != "2.00" || card(summary, "todayPay", "changeRate") != nil {
|
|
t.Fatalf("工作台六卡口径错误: %+v", summary)
|
|
}
|
|
summary = call(1, "summary", q, 0).(map[string]any)
|
|
if card(summary, "todayRegister", "value") != "1.00" || card(summary, "todayPay", "value") != "70.00" {
|
|
t.Fatal("超管跨平台汇总错误")
|
|
}
|
|
rows := call(7, "registerTop", q, 0).([]any)
|
|
if len(rows) != 1 || rows[0].(map[string]any)["value"] != "1.00" || rows[0].(map[string]any)["promoteName"] != "渠道甲" {
|
|
t.Fatal("注册榜应按整棵树去重")
|
|
}
|
|
rows = call(7, "payRank", q+"&period=today&order=desc", 0).([]any)
|
|
if len(rows) != 1 || rows[0].(map[string]any)["value"] != "30.00" {
|
|
t.Fatal("充值榜范围或金额错误")
|
|
}
|
|
rows = call(7, "payRank", q+"&order=asc", 0).([]any)
|
|
if len(rows) != 2 || rows[0].(map[string]any)["value"] != "0.00" || rows[0].(map[string]any)["promoteName"] != "零充值渠道" {
|
|
t.Fatal("最低榜漏掉零充值一级渠道")
|
|
}
|
|
rows = call(7, "unloginTop", q, 0).([]any)
|
|
if len(rows) != 2 || rows[0].(map[string]any)["value"] != "99999" || rows[1].(map[string]any)["value"] != "5" {
|
|
t.Fatal("未登录榜不应包含子渠道")
|
|
}
|
|
rows = call(99, "payRank", "sourceDbList=lx", 0).([]any)
|
|
if len(rows) != 0 {
|
|
t.Fatal("其他平台商务越权查询")
|
|
}
|
|
if err := db.Exec("INSERT INTO sys_user_preference(user_id,include_sub_promote,idcard_dedup) VALUES(7,1,0)").Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
summary = call(7, "summary", q, 0).(map[string]any)
|
|
if card(summary, "todayRegister", "value") != "2.00" || card(summary, "todayPay", "value") != "30.00" {
|
|
t.Fatal("偏好切换错误")
|
|
}
|
|
if err := db.Exec("UPDATE sys_user_preference SET include_sub_promote=0 WHERE user_id=7").Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
summary = call(7, "summary", q, 0).(map[string]any)
|
|
if card(summary, "todayPay", "value") != "10.00" || card(summary, "newPromote", "value") != "1.00" {
|
|
t.Fatal("渠道数和金额未排除下级")
|
|
}
|
|
for _, endpoint := range []string{"summary", "registerTop", "payRank", "unloginTop"} {
|
|
call(7, endpoint, "", 7)
|
|
}
|
|
call(7, "payRank", q+"&period=invalid", 7)
|
|
call(7, "summary", "sourceDbList=invalid", 7)
|
|
if err := db.Exec("DROP TABLE tab_sw_report_day_key").Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
summary = call(7, "summary", q, 0).(map[string]any)
|
|
if summary["available"] != false || card(summary, "todayPay", "value") != nil {
|
|
t.Fatal("缺表不能伪造零")
|
|
}
|
|
call(7, "registerTop", q, 7)
|
|
call(7, "payRank", q, 0)
|
|
call(7, "unloginTop", q, 0)
|
|
}
|