113 lines
4.4 KiB
Go
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")
|
|
}
|
|
}
|