79 lines
3.4 KiB
Go
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 ©, 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("倒置日期应被拒绝")
|
|
}
|
|
}
|