Files
kra-new/internal/biz/business/analytics_test.go
T

79 lines
3.4 KiB
Go

package business
import (
"context"
"testing"
"time"
)
type analyticsRepoFake struct {
data *AnalyticsData
scope AnalyticsScope
filter AnalyticsFilter
}
func (r *analyticsRepoFake) Aggregate(_ context.Context, _ AnalyticsKind, s AnalyticsScope, f AnalyticsFilter) (*AnalyticsData, error) {
r.scope = s
r.filter = f
copy := *r.data
copy.Rows = []*AnalyticsRow{}
for _, row := range r.data.Rows {
c := *row
copy.Rows = append(copy.Rows, &c)
}
return &copy, nil
}
func analyticsFixture() (*AnalyticsUsecase, *analyticsRepoFake) {
a := &accountRepoFake{accounts: map[uint]*Account{1: {ID: 1}, 7: {ID: 7, Level: 1, IDPath: "0"}}}
r := &analyticsRepoFake{data: &AnalyticsData{Available: true, Rows: []*AnalyticsRow{{AnalyticsKey: AnalyticsKey{SourceDB: "lx", ID: 1}, Name: "甲", Counts: PortraitCounts{Register: 2, Active: 4, Pay: 2, NewPay: 1}, Pay: "20.00"}, {AnalyticsKey: AnalyticsKey{SourceDB: "hw", ID: 2}, Name: "乙", Counts: PortraitCounts{Register: 3, Active: 6, Pay: 1, NewPay: 1}, Pay: "30.00"}}, GlobalCounts: &PortraitCounts{Register: 4, Active: 8, Pay: 3}, GlobalPay: "45.00"}}
uc := NewAnalyticsUsecase(r, NewAccountUsecase(a), NewUserPreferenceUsecase(&channelPreferenceFake{UserPreference{IncludeSubPromote: true, IDCardDedup: true}}))
uc.now = func() time.Time { return time.Date(2026, 11, 4, 9, 0, 0, 0, portraitLocation) }
return uc, r
}
func TestGameAnalyticsSummaryUsesAllRowsAndCorrectDenominators(t *testing.T) {
uc, _ := analyticsFixture()
page, err := uc.List(accountContext(1, 888), GameAnalytics, AnalyticsFilter{}, 1, 1)
if err != nil {
t.Fatal(err)
}
if len(page.Rows) != 1 || page.Total != 2 || page.Rows[0].ID != 2 || page.Summary.Counts.Register != 5 || page.Summary.Pay != "50.00" || page.Summary.PayRate != "30.00" || page.Summary.ARPU != "5.00" || page.Summary.ARPPU != "16.67" {
t.Fatalf("游戏汇总、分页或分母错误: %+v", page)
}
if page.Begin != "2026-11-04" || page.End != "2026-11-04" {
t.Fatal("后台缺省统计日期应为当天")
}
}
func TestChannelAnalyticsSummaryDependsOnViewer(t *testing.T) {
uc, _ := analyticsFixture()
page, err := uc.List(accountContext(7, 901), ChannelAnalytics, AnalyticsFilter{}, 1, 10)
if err != nil {
t.Fatal(err)
}
if page.Summary.Counts.Register != 5 || page.Summary.Pay != "50.00" {
t.Fatal("普通商务应汇总可见展示行")
}
page, err = uc.List(accountContext(1, 888), ChannelAnalytics, AnalyticsFilter{}, 1, 10)
if err != nil || page.Summary.Counts.Register != 4 || page.Summary.Pay != "45.00" || page.Summary.PayRate != "37.50" {
t.Fatal("超管应使用筛选范围内全局去重汇总")
}
}
func TestAnalyticsSortAndMissingData(t *testing.T) {
uc, r := analyticsFixture()
r.data.Rows[0].Pay = "9007199254740993.00"
r.data.Rows[1].Pay = "9007199254740992.99"
p, err := uc.List(accountContext(7, 901), GameAnalytics, AnalyticsFilter{SortField: "totalPay"}, 1, 10)
if err != nil || p.Rows[0].ID != 1 {
t.Fatal("金额排序不能经浮点数失真")
}
r.data.Available = false
p, err = uc.List(accountContext(7, 901), ChannelAnalytics, AnalyticsFilter{}, 1, 10)
if err != nil || p.Available || p.Summary != nil {
t.Fatal("缺汇总表不能伪造零卡片")
}
begin := time.Date(2026, 11, 4, 0, 0, 0, 0, portraitLocation)
end := begin.AddDate(0, 0, -1)
if _, err := uc.List(accountContext(1, 888), GameAnalytics, AnalyticsFilter{StartDate: &begin, EndDate: &end}, 1, 10); err != ErrAnalyticsDateOrder {
t.Fatal("倒置日期应被拒绝")
}
}