2026-06-14 23:42:39 +08:00

99 lines
4.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package hostorg
import (
"strings"
"testing"
)
// TestNormalizeListQueryAllowsCoinSellerComputedSorts 锁定币商余额和累充 USDT 排序字段会被后台列表查询接受。
func TestNormalizeListQueryAllowsCoinSellerComputedSorts(t *testing.T) {
for _, sortBy := range []string{sortByMerchantBalance, sortByTotalRechargeUSDT} {
query := normalizeListQuery(listQuery{Page: 1, PageSize: 50, SortBy: sortBy, SortDirection: "asc"})
if query.SortBy != sortBy || query.SortDirection != "asc" {
t.Fatalf("expected sort %s asc to be kept, got sort_by=%q direction=%q", sortBy, query.SortBy, query.SortDirection)
}
}
}
// TestBDRoleFromStatusPathUsesLeaderTableWithAPIPrefix 锁定线上真实 FullPath 带 /api/v1 前缀时BD Leader 状态仍然写独立负责人表。
func TestBDRoleFromStatusPathUsesLeaderTableWithAPIPrefix(t *testing.T) {
role, target := bdRoleFromStatusPath("/api/v1/admin/bd-leaders/:user_id/status")
if role != "bd_leader" || target != "bd_leader_profiles" {
t.Fatalf("leader status route must use bd_leader_profiles, got role=%q target=%q", role, target)
}
role, target = bdRoleFromStatusPath("/api/v1/admin/bds/:user_id/status")
if role != "bd" || target != "bd_profiles" {
t.Fatalf("bd status route must use bd_profiles, got role=%q target=%q", role, target)
}
}
// TestUserCountryRegionSQLUsesCountryMapping 锁定组织列表区域展示口径:从用户国家映射 active 区域,不从身份表区域快照取值。
func TestUserCountryRegionSQLUsesCountryMapping(t *testing.T) {
joinSQL := userCountryRegionJoin("owner", "owner_country_region", "owner_region")
for _, want := range []string{
"LEFT JOIN region_countries owner_country_region",
"owner_country_region.country_code = owner.country",
"owner_country_region.status = 'active'",
"LEFT JOIN regions owner_region",
"owner_region.region_id = owner_country_region.region_id",
"owner_region.status = 'active'",
} {
if !strings.Contains(joinSQL, want) {
t.Fatalf("country region join missing %q in %s", want, joinSQL)
}
}
if strings.Contains(joinSQL, "owner.region_id") {
t.Fatalf("country region join must not read identity or user region snapshots: %s", joinSQL)
}
if got := userCountryRegionIDSQL("owner_region"); got != "COALESCE(owner_region.region_id, 0)" {
t.Fatalf("region id projection mismatch: %s", got)
}
if got := userCountryRegionNameSQL("owner_region"); got != "COALESCE(owner_region.name, '')" {
t.Fatalf("region name projection mismatch: %s", got)
}
}
// TestSalaryWalletAssetTypeByRole 锁定四个组织身份读取各自工资钱包资产BD Leader 复用 Admin 工资资产,不能误读普通 BD 资产。
func TestSalaryWalletAssetTypeByRole(t *testing.T) {
cases := map[string]string{
"host": assetHostSalaryUSD,
"agency": assetAgencySalaryUSD,
"bd": assetBDSalaryUSD,
"bd_leader": assetAdminSalaryUSD,
"admin": assetAdminSalaryUSD,
}
for role, want := range cases {
if got := salaryWalletAssetType(role); got != want {
t.Fatalf("role %s salary wallet asset mismatch: got %q want %q", role, got, want)
}
}
}
// TestNormalizeSalaryWalletHistoryQueryCapsPageSize 避免历史抽屉一次拉太多钱包分录,同时兼容 admin 作为 BD Leader 的旧口径。
func TestNormalizeSalaryWalletHistoryQueryCapsPageSize(t *testing.T) {
query := normalizeSalaryWalletHistoryQuery(salaryWalletHistoryQuery{Page: 0, PageSize: 500, Role: "admin", UserID: 7})
if query.Page != 1 || query.PageSize != 100 || query.Role != salaryWalletRoleBDLeader || query.UserID != 7 {
t.Fatalf("salary wallet history query normalized incorrectly: %+v", query)
}
}
// TestSortCoinSellerListItemsComputedFields 验证 wallet 聚合字段排序只改变展示顺序,不改动币商身份数据。
func TestSortCoinSellerListItemsComputedFields(t *testing.T) {
items := []*CoinSellerListItem{
{UserID: 1, MerchantBalance: 100, TotalRechargeUSDTMicro: 30_000_000},
{UserID: 2, MerchantBalance: 300, TotalRechargeUSDTMicro: 10_000_000},
{UserID: 3, MerchantBalance: 200, TotalRechargeUSDTMicro: 20_000_000},
}
sortCoinSellerListItems(items, sortByMerchantBalance, "desc")
if got := []int64{items[0].UserID, items[1].UserID, items[2].UserID}; got[0] != 2 || got[1] != 3 || got[2] != 1 {
t.Fatalf("merchant balance desc order mismatch: %v", got)
}
sortCoinSellerListItems(items, sortByTotalRechargeUSDT, "asc")
if got := []int64{items[0].UserID, items[1].UserID, items[2].UserID}; got[0] != 2 || got[1] != 3 || got[2] != 1 {
t.Fatalf("total recharge usdt asc order mismatch: %v", got)
}
}