2026-07-03 18:49:44 +08:00

113 lines
4.4 KiB
Go

package databi
import (
"encoding/json"
"testing"
)
func TestRollupByRegionGroupsCountriesAndRecomputesDerived(t *testing.T) {
regions := []RegionInfo{
{AppCode: "aslan", RegionID: 11, RegionCode: "MENA", RegionName: "中东", Countries: []string{"SA", "AE"}},
{AppCode: "aslan", RegionID: 12, RegionCode: "SEA", RegionName: "东南亚", Countries: []string{"ID"}},
}
rows := []map[string]any{
{"country_code": "SA", "recharge_usd_minor": int64(10000), "active_users": int64(100), "paid_users": int64(10), "recharge_users": int64(10), "gift_coin_spent": nil},
{"country_code": "AE", "recharge_usd_minor": json.Number("5000"), "active_users": json.Number("50"), "paid_users": json.Number("5"), "recharge_users": json.Number("5"), "gift_coin_spent": nil},
{"country_code": "ID", "recharge_usd_minor": int64(2000), "active_users": int64(40), "paid_users": int64(2), "recharge_users": int64(2), "gift_coin_spent": int64(700)},
{"country_code": "XX", "recharge_usd_minor": int64(1), "active_users": int64(1), "paid_users": int64(0), "recharge_users": int64(0)},
}
out := rollupByRegion(rows, regionResolver(regions))
if len(out) != 3 {
t.Fatalf("expected 3 region rows (MENA/SEA/未划分), got %d", len(out))
}
mena := out[0]
if got, _ := rowInt64(mena, "region_id"); got != 11 {
t.Fatalf("expected first row to be region 11 by recharge desc, got %d", got)
}
if got, _ := rowInt64(mena, "recharge_usd_minor"); got != 15000 {
t.Fatalf("expected MENA recharge 15000, got %d", got)
}
if got, _ := rowInt64(mena, "active_users"); got != 150 {
t.Fatalf("expected MENA active users 150, got %d", got)
}
if got, ok := mena["arppu_usd_minor"].(int64); !ok || got != 1000 {
t.Fatalf("expected MENA arppu 1000, got %v", mena["arppu_usd_minor"])
}
if mena["gift_coin_spent"] != nil {
t.Fatalf("expected MENA gift_coin_spent nil when all rows nil, got %v", mena["gift_coin_spent"])
}
sea := out[1]
if got, _ := rowInt64(sea, "gift_coin_spent"); got != 700 {
t.Fatalf("expected SEA gift_coin_spent 700, got %d", got)
}
unassigned := out[2]
if got, _ := rowInt64(unassigned, "region_id"); got != 0 {
t.Fatalf("expected unassigned region id 0, got %d", got)
}
}
func TestRollupByRegionPrefersRowRegionID(t *testing.T) {
regions := []RegionInfo{{AppCode: "lalu", RegionID: 3, RegionCode: "LATAM", RegionName: "拉美", Countries: []string{"BR"}}}
rows := []map[string]any{
{"region_id": json.Number("3"), "country_id": int64(55), "recharge_usd_minor": int64(100)},
{"region_id": int64(3), "country_id": int64(56), "recharge_usd_minor": int64(200)},
}
out := rollupByRegion(rows, regionResolver(regions))
if len(out) != 1 {
t.Fatalf("expected 1 region row, got %d", len(out))
}
if got := out[0]["region_name"]; got != "拉美" {
t.Fatalf("expected region name 拉美, got %v", got)
}
if got, _ := rowInt64(out[0], "recharge_usd_minor"); got != 300 {
t.Fatalf("expected recharge 300, got %d", got)
}
}
func TestFilterRowsByRegion(t *testing.T) {
regions := []RegionInfo{
{AppCode: "yumi", RegionID: 21, Countries: []string{"SA"}},
{AppCode: "yumi", RegionID: 22, Countries: []string{"EG"}},
}
rows := []map[string]any{
{"country_code": "SA"},
{"country_code": "EG"},
{"country_code": "??"},
}
out := filterRowsByRegion(rows, regionResolver(regions), int64Set([]int64{21}))
if len(out) != 1 || out[0]["country_code"] != "SA" {
t.Fatalf("expected only SA row, got %v", out)
}
}
func TestAllowedRegions(t *testing.T) {
access := testAccess()
if all, _ := allowedRegions(access, "lalu"); !all {
t.Fatalf("expected whole-app access for lalu (region 0 scope)")
}
all, ids := allowedRegions(access, "aslan")
if all || len(ids) != 2 {
t.Fatalf("expected two region scopes for aslan, got all=%v ids=%v", all, ids)
}
if all, ids := allowedRegions(access, "yumi"); all || len(ids) != 0 {
t.Fatalf("expected no access for yumi, got all=%v ids=%v", all, ids)
}
}
func TestResolveKpiMonthClampsFuture(t *testing.T) {
location := mustLocation(t, "Asia/Shanghai")
month, start, end, err := resolveKpiMonth("2020-02", 0, location)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if month != "2020-02" {
t.Fatalf("expected month 2020-02, got %s", month)
}
if start.Format("2006-01-02") != "2020-02-01" || end.Format("2006-01-02") != "2020-03-01" {
t.Fatalf("unexpected month window %s ~ %s", start, end)
}
if _, _, _, err := resolveKpiMonth("2020/02", 0, location); err == nil {
t.Fatalf("expected format error for 2020/02")
}
}