import { afterEach, expect, test, vi } from "vitest"; import { setAccessToken } from "@/shared/api/request"; import { adminAddAgencyHost, createBDLeader, createCountry, createCoinSeller, createManager, createRegion, creditCoinSellerStock, debitCoinSellerStock, deleteAgency, disableRegion, listAgencies, listBDs, listCoinSellerSubApplications, listCoinSellerSubSellers, listCoinSellers, listCountries, listHosts, listManagers, listRegions, getJob, renameCountryCode, replaceRegionCountries, approveCoinSellerSubApplication, rejectCoinSellerSubApplication, setCoinSellerStatus, updateBDLeaderPositionAlias, updateCountry, updateManager, } from "./api"; afterEach(() => { setAccessToken(""); vi.unstubAllGlobals(); }); test("host org list APIs use generated admin paths and filters", async () => { vi.stubGlobal( "fetch", vi.fn( async () => new Response(JSON.stringify({ code: 0, data: { items: [], page: 1, pageSize: 10, total: 0 } })), ), ); await listBDs({ page: 1, page_size: 10, parent_leader_user_id: 21, region_id: 7, sort_by: "salary_wallet", sort_direction: "asc", status: "active", }); await listAgencies({ keyword: "agency", page: 2, page_size: 10, parent_bd_user_id: 31, sort_by: "salary_wallet", sort_direction: "desc", }); await listManagers({ keyword: "manager", page: 1, page_size: 10, region_id: 7, status: "active", }); await createManager({ canManageCrossRegion: false, canBlockUser: false, canGrantBadge: false, canGrantVip: true, contact: "+63", targetUserId: "1003", }); await updateManager("1003", { canManageCrossRegion: true, canBlockUser: false, canGrantVehicle: true, canGrantVip: false, canTransferUserCountry: false, contact: "+63", status: "disabled", }); await listHosts({ agency_id: 41, page: 1, page_size: 10, sort_by: "diamond", sort_direction: "desc" }); await listCoinSellers({ page: 1, page_size: 10, region_id: 7, sort_by: "merchant_balance", sort_direction: "desc", status: "active", }); await createBDLeader({ commandId: "bd-leader-test", positionAlias: "Senior Admin", targetUserId: "1002", }); await updateBDLeaderPositionAlias("1002", { commandId: "bd-leader-position-alias-test", positionAlias: "Regional Admin", }); await createCoinSeller({ commandId: "coin-seller-test", reason: "contact", targetUserId: "1001" }); await setCoinSellerStatus("1001", { commandId: "coin-seller-status-test", reason: "disable", status: "disabled" }); await creditCoinSellerStock("1001", { coinAmount: 8000000, commandId: "coin-seller-stock-test", rechargeAmount: "100.000000", type: "usdt_purchase", }); await debitCoinSellerStock("1001", { coinAmount: 1000, commandId: "coin-seller-stock-debit-test", rechargeAmount: "1.25", reason: "deduct bad stock", }); await adminAddAgencyHost(7001, { commandId: "agency-add-host-test", reason: "manual add", targetUserId: "1004", }); await deleteAgency(7001, { commandId: "agency-delete-test", reason: "cleanup" }); const [bdUrl, bdInit] = vi.mocked(fetch).mock.calls[0]; const [agencyUrl] = vi.mocked(fetch).mock.calls[1]; const [managerUrl, managerInit] = vi.mocked(fetch).mock.calls[2]; const [managerCreateUrl, managerCreateInit] = vi.mocked(fetch).mock.calls[3]; const [managerUpdateUrl, managerUpdateInit] = vi.mocked(fetch).mock.calls[4]; const [hostUrl] = vi.mocked(fetch).mock.calls[5]; const [coinSellerUrl, coinSellerInit] = vi.mocked(fetch).mock.calls[6]; const [bdLeaderCreateUrl, bdLeaderCreateInit] = vi.mocked(fetch).mock.calls[7]; const [bdLeaderAliasUrl, bdLeaderAliasInit] = vi.mocked(fetch).mock.calls[8]; const [coinSellerCreateUrl, coinSellerCreateInit] = vi.mocked(fetch).mock.calls[9]; const [coinSellerStatusUrl, coinSellerStatusInit] = vi.mocked(fetch).mock.calls[10]; const [coinSellerStockUrl, coinSellerStockInit] = vi.mocked(fetch).mock.calls[11]; const [coinSellerStockDebitUrl, coinSellerStockDebitInit] = vi.mocked(fetch).mock.calls[12]; const [agencyAddHostUrl, agencyAddHostInit] = vi.mocked(fetch).mock.calls[13]; const [agencyDeleteUrl, agencyDeleteInit] = vi.mocked(fetch).mock.calls[14]; expect(String(bdUrl)).toContain("/api/v1/admin/bds?"); expect(String(bdUrl)).toContain("parent_leader_user_id=21"); expect(String(bdUrl)).toContain("region_id=7"); expect(String(bdUrl)).toContain("sort_by=salary_wallet"); expect(String(bdUrl)).toContain("sort_direction=asc"); expect(String(bdUrl)).toContain("status=active"); expect(bdInit?.method).toBe("GET"); expect(String(agencyUrl)).toContain("/api/v1/admin/agencies?"); expect(String(agencyUrl)).toContain("parent_bd_user_id=31"); expect(String(agencyUrl)).toContain("sort_by=salary_wallet"); expect(String(agencyUrl)).toContain("sort_direction=desc"); expect(String(managerUrl)).toContain("/api/v1/admin/managers?"); expect(String(managerUrl)).toContain("keyword=manager"); expect(String(managerUrl)).toContain("region_id=7"); expect(String(managerUrl)).toContain("status=active"); expect(String(managerUrl)).not.toContain("parent_bd_user_id"); expect(managerInit?.method).toBe("GET"); expect(String(managerCreateUrl)).toContain("/api/v1/admin/managers"); expect(managerCreateInit?.method).toBe("POST"); expect(JSON.parse(String(managerCreateInit?.body))).toEqual({ canManageCrossRegion: false, canBlockUser: false, canGrantBadge: false, canGrantVip: true, contact: "+63", targetUserId: "1003", }); expect(String(managerUpdateUrl)).toContain("/api/v1/admin/managers/1003"); expect(managerUpdateInit?.method).toBe("PUT"); expect(JSON.parse(String(managerUpdateInit?.body))).toEqual({ canManageCrossRegion: true, canBlockUser: false, canGrantVehicle: true, canGrantVip: false, canTransferUserCountry: false, contact: "+63", status: "disabled", }); expect(String(hostUrl)).toContain("/api/v1/admin/hosts?"); expect(String(hostUrl)).toContain("agency_id=41"); expect(String(hostUrl)).toContain("sort_by=diamond"); expect(String(hostUrl)).toContain("sort_direction=desc"); expect(String(coinSellerUrl)).toContain("/api/v1/admin/coin-sellers?"); expect(String(coinSellerUrl)).toContain("region_id=7"); expect(String(coinSellerUrl)).toContain("sort_by=merchant_balance"); expect(String(coinSellerUrl)).toContain("sort_direction=desc"); expect(String(coinSellerUrl)).toContain("status=active"); expect(coinSellerInit?.method).toBe("GET"); expect(String(bdLeaderCreateUrl)).toContain("/api/v1/admin/bd-leaders"); expect(bdLeaderCreateInit?.method).toBe("POST"); expect(JSON.parse(String(bdLeaderCreateInit?.body))).toMatchObject({ positionAlias: "Senior Admin" }); expect(JSON.parse(String(bdLeaderCreateInit?.body))).not.toHaveProperty("regionId"); expect(String(bdLeaderAliasUrl)).toContain("/api/v1/admin/bd-leaders/1002/position-alias"); expect(bdLeaderAliasInit?.method).toBe("PATCH"); expect(JSON.parse(String(bdLeaderAliasInit?.body))).toMatchObject({ positionAlias: "Regional Admin" }); expect(String(coinSellerCreateUrl)).toContain("/api/v1/admin/coin-sellers"); expect(coinSellerCreateInit?.method).toBe("POST"); expect(String(coinSellerStatusUrl)).toContain("/api/v1/admin/coin-sellers/1001/status"); expect(coinSellerStatusInit?.method).toBe("PATCH"); expect(String(coinSellerStockUrl)).toContain("/api/v1/admin/coin-sellers/1001/stock-credits"); expect(coinSellerStockInit?.method).toBe("POST"); expect(String(coinSellerStockDebitUrl)).toContain("/api/v1/admin/coin-sellers/1001/stock-debits"); expect(coinSellerStockDebitInit?.method).toBe("POST"); expect(String(agencyAddHostUrl)).toContain("/api/v1/admin/agencies/7001/hosts"); expect(agencyAddHostInit?.method).toBe("POST"); expect(JSON.parse(String(agencyAddHostInit?.body))).toMatchObject({ commandId: "agency-add-host-test", targetUserId: "1004", }); expect(String(agencyDeleteUrl)).toContain("/api/v1/admin/agencies/7001/delete"); expect(agencyDeleteInit?.method).toBe("POST"); expect(JSON.parse(String(agencyDeleteInit?.body))).toMatchObject({ commandId: "agency-delete-test" }); }); test("coin seller sub application APIs use generated admin paths", async () => { vi.stubGlobal( "fetch", vi.fn( async () => new Response(JSON.stringify({ code: 0, data: { items: [], page: 1, pageSize: 10, total: 0 } })), ), ); await listCoinSellerSubSellers("3001", { page: 1, page_size: 10 }); await listCoinSellerSubApplications({ keyword: "163001", page: 2, page_size: 10, parent_user_id: "3001", status: "pending", target_user_id: "3002", }); await approveCoinSellerSubApplication("sub-app-1", { commandId: "approve-sub-app-test", reason: "ok", }); await rejectCoinSellerSubApplication("sub-app-2", { commandId: "reject-sub-app-test", reason: "bad", }); const [subSellerUrl, subSellerInit] = vi.mocked(fetch).mock.calls[0]; const [applicationUrl, applicationInit] = vi.mocked(fetch).mock.calls[1]; const [approveUrl, approveInit] = vi.mocked(fetch).mock.calls[2]; const [rejectUrl, rejectInit] = vi.mocked(fetch).mock.calls[3]; expect(String(subSellerUrl)).toContain("/api/v1/admin/coin-sellers/3001/sub-sellers?"); expect(String(subSellerUrl)).toContain("page=1"); expect(subSellerInit?.method).toBe("GET"); expect(String(applicationUrl)).toContain("/api/v1/admin/coin-seller-sub-applications?"); expect(String(applicationUrl)).toContain("keyword=163001"); expect(String(applicationUrl)).toContain("parent_user_id=3001"); expect(String(applicationUrl)).toContain("target_user_id=3002"); expect(String(applicationUrl)).toContain("status=pending"); expect(applicationInit?.method).toBe("GET"); expect(String(approveUrl)).toContain("/api/v1/admin/coin-seller-sub-applications/sub-app-1/approve"); expect(approveInit?.method).toBe("POST"); expect(JSON.parse(String(approveInit?.body))).toMatchObject({ commandId: "approve-sub-app-test" }); expect(String(rejectUrl)).toContain("/api/v1/admin/coin-seller-sub-applications/sub-app-2/reject"); expect(rejectInit?.method).toBe("POST"); expect(JSON.parse(String(rejectInit?.body))).toMatchObject({ commandId: "reject-sub-app-test" }); }); test("country and region APIs use generated admin paths", async () => { vi.stubGlobal( "fetch", vi.fn(async () => new Response(JSON.stringify({ code: 0, data: { items: [], total: 0 } }))), ); await listCountries({ enabled: true }); await createCountry({ countryCode: "US", countryDisplayName: "United States", countryName: "United States", enabled: true, }); await updateCountry(12, { countryDisplayName: "United States", countryName: "United States" }); await renameCountryCode(12, { countryCode: "USA", countryDisplayName: "United States", countryName: "United States", sortOrder: 10, }); await getJob(99); await listRegions({ status: "active" }); await createRegion({ countries: ["US"], name: "North America", regionCode: "NA" }); await replaceRegionCountries(7, { countries: ["US", "CA"] }); await disableRegion(7); const [countryListUrl, countryListInit] = vi.mocked(fetch).mock.calls[0]; const [countryCreateUrl, countryCreateInit] = vi.mocked(fetch).mock.calls[1]; const [countryUpdateUrl, countryUpdateInit] = vi.mocked(fetch).mock.calls[2]; const [countryRenameUrl, countryRenameInit] = vi.mocked(fetch).mock.calls[3]; const [jobUrl, jobInit] = vi.mocked(fetch).mock.calls[4]; const [regionListUrl, regionListInit] = vi.mocked(fetch).mock.calls[5]; const [regionCreateUrl, regionCreateInit] = vi.mocked(fetch).mock.calls[6]; const [regionCountriesUrl, regionCountriesInit] = vi.mocked(fetch).mock.calls[7]; const [regionDisableUrl, regionDisableInit] = vi.mocked(fetch).mock.calls[8]; expect(String(countryListUrl)).toContain("/api/v1/admin/countries?"); expect(String(countryListUrl)).toContain("enabled=true"); expect(countryListInit?.method).toBe("GET"); expect(String(countryCreateUrl)).toContain("/api/v1/admin/countries"); expect(countryCreateInit?.method).toBe("POST"); expect(String(countryUpdateUrl)).toContain("/api/v1/admin/countries/12"); expect(countryUpdateInit?.method).toBe("PATCH"); expect(JSON.parse(String(countryUpdateInit?.body))).not.toHaveProperty("countryCode"); expect(String(countryRenameUrl)).toContain("/api/v1/admin/countries/12/rename-code"); expect(countryRenameInit?.method).toBe("POST"); expect(JSON.parse(String(countryRenameInit?.body))).toMatchObject({ countryCode: "USA", sortOrder: 10 }); expect(String(jobUrl)).toContain("/api/v1/jobs/99"); expect(jobInit?.method).toBe("GET"); expect(String(regionListUrl)).toContain("/api/v1/admin/regions?"); expect(String(regionListUrl)).toContain("status=active"); expect(regionListInit?.method).toBe("GET"); expect(String(regionCreateUrl)).toContain("/api/v1/admin/regions"); expect(regionCreateInit?.method).toBe("POST"); expect(String(regionCountriesUrl)).toContain("/api/v1/admin/regions/7/countries"); expect(regionCountriesInit?.method).toBe("PUT"); expect(String(regionDisableUrl)).toContain("/api/v1/admin/regions/7"); expect(regionDisableInit?.method).toBe("DELETE"); });