Files
kra-new/cmd/server_analysis_http_test.go

151 lines
6.7 KiB
Go

package main
import (
"encoding/json"
"net/http"
"net/http/httptest"
"net/url"
"path/filepath"
"strconv"
"testing"
"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 TestServerAnalysisHTTP(t *testing.T) {
db, err := gorm.Open(sqlite.Open(filepath.Join(t.TempDir(), "servers.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,promote_level INTEGER,busier_id INTEGER)",
"INSERT INTO tab_promote VALUES(100,'lx',1,14),(101,'lx',2,14),(100,'hw',1,20)",
"CREATE TABLE tab_promote_apply(source_db TEXT,promote_id INTEGER,game_id INTEGER,status INTEGER)",
"INSERT INTO tab_promote_apply VALUES('lx',100,1,1),('hw',100,1,1)",
"CREATE TABLE tab_game(id INTEGER,source_db TEXT,game_name TEXT)",
"INSERT INTO tab_game VALUES(1,'lx','游戏'),(1,'hw','其他游戏')",
"CREATE TABLE tab_game_server(id INTEGER,source_db TEXT,game_id INTEGER,server_num TEXT,server_name TEXT,start_time INTEGER)",
"INSERT INTO tab_game_server VALUES(1,'lx',1,'001','一区',100),(2,'lx',1,'002','二区',200),(3,'hw',1,'001','外部一区',300)",
"CREATE TABLE tab_sw_report_server_day(source_db TEXT,game_id INTEGER,game_name TEXT,promote_id INTEGER,server_num TEXT,stat_date DATE,dedup_mode INTEGER,total_pay DECIMAL(20,2))",
"INSERT INTO tab_sw_report_server_day VALUES('lx',1,'游戏',100,'001','2026-11-04',0,10),('lx',1,'游戏',101,'001','2026-11-04',0,20),('lx',1,'游戏',100,'002','2026-11-04',0,40),('hw',1,'游戏',100,'001','2026-11-04',0,50),('lx',1,'游戏',100,'001','2026-11-04',1,9999)",
"CREATE TABLE tab_sw_report_server_day_key(source_db TEXT,game_id INTEGER,game_name TEXT,promote_id INTEGER,server_num TEXT,stat_date DATE,dedup_mode INTEGER,metric INTEGER,identity_key TEXT)",
} {
if err := db.Exec(sql).Error; err != nil {
t.Fatal(err)
}
}
for _, s := range []struct {
source, num string
promote int
}{{"lx", "001", 100}, {"lx", "001", 101}, {"lx", "002", 100}, {"hw", "001", 100}} {
for _, metric := range []int{1, 2, 3} {
for _, mode := range []int{0, 1} {
identity := "A"
if mode == 0 {
identity = strconv.Itoa(s.promote)
}
if err := db.Exec("INSERT INTO tab_sw_report_server_day_key VALUES(?,1,'游戏',?,?,'2026-11-04',?,?,?)", s.source, s.promote, s.num, mode, metric, identity).Error; err != nil {
t.Fatal(err)
}
}
}
}
provider := businessHTTPData{db}
uc := businessbiz.NewServerAnalysisUsecase(businessdata.NewServerAnalysisRepo(provider), businessbiz.NewAccountUsecase(businessdata.NewAccountRepo(provider)), businessbiz.NewUserPreferenceUsecase(businessdata.NewUserPreferenceRepo(provider)))
h := handler.NewServerAnalysis(businessservice.NewServerAnalysisService(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/serverAnalysis/list", h.List)
engine.GET("/sw/serverAnalysis/servers", h.Servers)
srv := httptest.NewServer(engine)
defer srv.Close()
call := func(user int, path, query string, code int) any {
t.Helper()
req, _ := http.NewRequest("GET", srv.URL+"/sw/serverAnalysis/"+path+"?"+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("接口响应错误: %+v", body)
}
return body["data"]
}
q := "gameName=" + url.QueryEscape("游戏") + "&sourceDb=lx,hw&beginTime=2026-11-04&endTime=2026-11-04"
p := call(7, "list", q+"&pageSize=1", 0).(map[string]any)
sum := p["summary"].(map[string]any)
if p["total"] != float64(2) || len(p["rows"].([]any)) != 1 || sum["totalPay"] != "70.00" || sum["activeCount"] != float64(2) || sum["arpu"] != "35.00" {
t.Fatalf("分页或全量汇总错误: %+v", p)
}
p = call(7, "list", q+"&serverNum=001", 0).(map[string]any)
row := p["rows"].([]any)[0].(map[string]any)
if row["serverNum"] != "001" || row["serverName"] != "一区" || row["openTime"] != float64(100) || row["newRegisterCount"] != float64(1) || row["totalPay"] != "30.00" {
t.Fatalf("区服身份、去重或金额错误: %+v", row)
}
p = call(1, "list", q, 0).(map[string]any)
if p["total"] != float64(3) || p["summary"].(map[string]any)["totalPay"] != "120.00" {
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)
}
p = call(7, "list", q, 0).(map[string]any)
if p["summary"].(map[string]any)["activeCount"] != float64(3) || p["summary"].(map[string]any)["totalPay"] != "70.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)
}
p = call(7, "list", q, 0).(map[string]any)
if p["summary"].(map[string]any)["totalPay"] != "50.00" {
t.Fatal("下级开关未生效")
}
options := call(7, "servers", "gameName="+url.QueryEscape("游戏")+"&sourceDb=lx&keyword="+url.QueryEscape("一区"), 0).([]any)
if len(options) != 1 || options[0].(map[string]any)["serverNum"] != "001" {
t.Fatal("区服选项映射错误")
}
call(7, "list", "", 7)
call(7, "servers", "", 7)
call(7, "list", q+"&pageNum=bad", 7)
call(7, "list", "gameName=x&beginTime=bad&endTime=2026-11-04", 7)
call(7, "list", "gameName=x&beginTime=2026-11-05&endTime=2026-11-04", 7)
if err := db.Exec("DROP TABLE tab_sw_report_server_day_key").Error; err != nil {
t.Fatal(err)
}
p = call(7, "list", q, 0).(map[string]any)
if p["available"] != false || p["summary"] != nil {
t.Fatal("缺表不能返回伪造零")
}
}