import { afterEach, expect, test, vi } from "vitest"; import { setAccessToken } from "@/shared/api/request"; import { createEmojiPack, createGift, createResource, createResourceGroup, disableResourceShopItem, disableGift, disableResource, disableResourceGroup, enableResourceShopItem, enableGift, enableResource, enableResourceGroup, grantResource, grantResourceGroup, listEmojiPackCategories, listEmojiPacks, listGiftTypes, listResourceGrants, listGifts, listResourceShopItems, listResources, lookupResourceGrantTarget, updateGift, updateGiftTypes, updateResource, updateResourceGroup, upsertResourceShopItems, } from "./api"; afterEach(() => { setAccessToken(""); vi.unstubAllGlobals(); }); test("resource 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 listResources({ page: 1, page_size: 10, resource_type: "gift", status: "active" }); await createResource({ amount: 0, assetUrl: "https://media.haiyihy.com/resource/material.png", badgeForm: "strip", badgeKind: "level", coinPrice: 10, levelTrack: "wealth", managerGrantEnabled: true, metadataJson: '{"profile_card_layout":{"content_top":117,"content_height":1550}}', name: "VIP Badge", previewUrl: "https://media.haiyihy.com/resource/cover.png", priceType: "coin", resourceCode: "badge_vip_test", resourceType: "badge", sortOrder: 0, status: "active", }); await updateResource(11, { amount: 0, assetUrl: "https://media.haiyihy.com/resource/material-updated.png", badgeForm: "tile", badgeKind: "normal", coinPrice: 20, managerGrantEnabled: false, metadataJson: '{"profile_card_layout":{"content_top":120,"content_height":1500}}', name: "VIP Badge Updated", previewUrl: "https://media.haiyihy.com/resource/cover-updated.png", priceType: "coin", resourceCode: "badge_vip_test", resourceType: "badge", sortOrder: 0, status: "active", }); await listGifts({ page: 1, page_size: 10, region_id: 1001 }); await createGift({ chargeAssetType: "COIN", coinPrice: 10, effectiveAtMs: 1777766400000, effectiveFromMs: 0, effectiveToMs: 0, effectTypes: ["animation"], giftId: "rose", giftTypeCode: "normal", name: "Rose", presentationJson: "{}", priceVersion: "default", regionIds: [0], resourceId: 11, sortOrder: 0, status: "active", }); await enableResource(11); await disableResource(11); await createResourceGroup({ description: "", groupCode: "starter_pack_test", items: [ { durationDays: 7, itemType: "resource", resourceId: 11, sortOrder: 0, }, { amount: 1000, assetType: "COIN", itemType: "wallet_asset", sortOrder: 1, }, ], name: "Starter Pack", sortOrder: 0, status: "active", }); await updateResourceGroup(22, { description: "updated", groupCode: "starter_pack_test", items: [], name: "Starter Pack Updated", sortOrder: 1, status: "disabled", }); await enableResourceGroup(22); await disableResourceGroup(22); await updateGift("rose", { chargeAssetType: "COIN", coinPrice: 10, effectiveAtMs: 1777766400000, effectiveFromMs: 0, effectiveToMs: 0, effectTypes: ["animation"], giftId: "rose", giftTypeCode: "normal", name: "Rose", presentationJson: "{}", priceVersion: "default", regionIds: [0], resourceId: 11, sortOrder: 0, status: "active", }); await enableGift("rose"); await disableGift("rose"); await listResourceGrants({ page: 1, page_size: 10, target_user_id: 1001, status: "succeeded" }); await lookupResourceGrantTarget("163000"); await grantResource({ commandId: "resource-grant-test", durationMs: 0, quantity: 1, reason: "manual", resourceId: 11, targetUserId: "318705991371722752", }); await grantResourceGroup({ commandId: "resource-group-grant-test", groupId: 22, reason: "manual", targetUserId: 1001, }); const [listUrl, listInit] = vi.mocked(fetch).mock.calls[0]; const [createUrl, createInit] = vi.mocked(fetch).mock.calls[1]; const [updateUrl, updateInit] = vi.mocked(fetch).mock.calls[2]; const [giftListUrl, giftListInit] = vi.mocked(fetch).mock.calls[3]; const [createGiftUrl, createGiftInit] = vi.mocked(fetch).mock.calls[4]; const [enableUrl, enableInit] = vi.mocked(fetch).mock.calls[5]; const [disableUrl, disableInit] = vi.mocked(fetch).mock.calls[6]; const [createGroupUrl, createGroupInit] = vi.mocked(fetch).mock.calls[7]; const [updateGroupUrl, updateGroupInit] = vi.mocked(fetch).mock.calls[8]; const [enableGroupUrl, enableGroupInit] = vi.mocked(fetch).mock.calls[9]; const [disableGroupUrl, disableGroupInit] = vi.mocked(fetch).mock.calls[10]; const [updateGiftUrl, updateGiftInit] = vi.mocked(fetch).mock.calls[11]; const [enableGiftUrl, enableGiftInit] = vi.mocked(fetch).mock.calls[12]; const [disableGiftUrl, disableGiftInit] = vi.mocked(fetch).mock.calls[13]; const [grantListUrl, grantListInit] = vi.mocked(fetch).mock.calls[14]; const [grantTargetUrl, grantTargetInit] = vi.mocked(fetch).mock.calls[15]; const [grantResourceUrl, grantResourceInit] = vi.mocked(fetch).mock.calls[16]; const [grantGroupUrl, grantGroupInit] = vi.mocked(fetch).mock.calls[17]; expect(String(listUrl)).toContain("/api/v1/admin/resources?"); expect(String(listUrl)).toContain("resource_type=gift"); expect(String(listUrl)).toContain("status=active"); expect(listInit?.method).toBe("GET"); expect(String(createUrl)).toContain("/api/v1/admin/resources"); expect(createInit?.method).toBe("POST"); expect(JSON.parse(String(createInit?.body))).toMatchObject({ badgeForm: "strip", badgeKind: "level", levelTrack: "wealth", metadataJson: '{"profile_card_layout":{"content_top":117,"content_height":1550}}', resourceCode: "badge_vip_test", resourceType: "badge", status: "active", }); expect(String(updateUrl)).toContain("/api/v1/admin/resources/11"); expect(updateInit?.method).toBe("PUT"); expect(JSON.parse(String(updateInit?.body))).toMatchObject({ badgeForm: "tile", badgeKind: "normal", metadataJson: '{"profile_card_layout":{"content_top":120,"content_height":1500}}', }); expect(String(giftListUrl)).toContain("/api/v1/admin/gifts?"); expect(String(giftListUrl)).toContain("region_id=1001"); expect(giftListInit?.method).toBe("GET"); expect(String(createGiftUrl)).toContain("/api/v1/admin/gifts"); expect(createGiftInit?.method).toBe("POST"); expect(JSON.parse(String(createGiftInit?.body))).toMatchObject({ giftId: "rose", resourceId: 11 }); expect(String(enableUrl)).toContain("/api/v1/admin/resources/11/enable"); expect(enableInit?.method).toBe("POST"); expect(String(disableUrl)).toContain("/api/v1/admin/resources/11/disable"); expect(disableInit?.method).toBe("POST"); expect(String(createGroupUrl)).toContain("/api/v1/admin/resource-groups"); expect(createGroupInit?.method).toBe("POST"); expect(JSON.parse(String(createGroupInit?.body))).toMatchObject({ groupCode: "starter_pack_test", items: [ { durationDays: 7, itemType: "resource" }, { amount: 1000, assetType: "COIN" }, ], }); expect(String(updateGroupUrl)).toContain("/api/v1/admin/resource-groups/22"); expect(updateGroupInit?.method).toBe("PUT"); expect(String(enableGroupUrl)).toContain("/api/v1/admin/resource-groups/22/enable"); expect(enableGroupInit?.method).toBe("POST"); expect(String(disableGroupUrl)).toContain("/api/v1/admin/resource-groups/22/disable"); expect(disableGroupInit?.method).toBe("POST"); expect(String(updateGiftUrl)).toContain("/api/v1/admin/gifts/rose"); expect(updateGiftInit?.method).toBe("PUT"); expect(String(enableGiftUrl)).toContain("/api/v1/admin/gifts/rose/enable"); expect(enableGiftInit?.method).toBe("POST"); expect(String(disableGiftUrl)).toContain("/api/v1/admin/gifts/rose/disable"); expect(disableGiftInit?.method).toBe("POST"); expect(String(grantListUrl)).toContain("/api/v1/admin/resource-grants?"); expect(String(grantListUrl)).toContain("target_user_id=1001"); expect(grantListInit?.method).toBe("GET"); expect(String(grantTargetUrl)).toContain("/api/v1/admin/resource-grants/target?"); expect(String(grantTargetUrl)).toContain("user_id=163000"); expect(grantTargetInit?.method).toBe("GET"); expect(String(grantResourceUrl)).toContain("/api/v1/admin/resource-grants/resource"); expect(grantResourceInit?.method).toBe("POST"); expect(JSON.parse(String(grantResourceInit?.body))).toMatchObject({ resourceId: 11, targetUserId: "318705991371722752", }); expect(String(grantGroupUrl)).toContain("/api/v1/admin/resource-grants/group"); expect(grantGroupInit?.method).toBe("POST"); expect(JSON.parse(String(grantGroupInit?.body))).toMatchObject({ groupId: 22, targetUserId: 1001 }); }); test("emoji pack APIs use generated admin paths", async () => { vi.stubGlobal( "fetch", vi.fn(async () => new Response(JSON.stringify({ code: 0, data: [] }))), ); await listEmojiPackCategories(); await listEmojiPacks({ page: 1, page_size: 10, status: "active" }); await createEmojiPack({ animationUrl: "https://media.haiyihy.com/emoji/wave.svga", category: "热门", coverUrl: "https://media.haiyihy.com/emoji/wave.png", name: "Wave", pricingType: "paid", regionIds: [0], sortOrder: 0, }); const [categoryUrl, categoryInit] = vi.mocked(fetch).mock.calls[0]; const [listUrl, listInit] = vi.mocked(fetch).mock.calls[1]; const [createUrl, createInit] = vi.mocked(fetch).mock.calls[2]; expect(String(categoryUrl)).toContain("/api/v1/admin/emoji-packs/categories"); expect(categoryInit?.method).toBe("GET"); expect(String(listUrl)).toContain("/api/v1/admin/emoji-packs?"); expect(String(listUrl)).toContain("status=active"); expect(listInit?.method).toBe("GET"); expect(String(createUrl)).toContain("/api/v1/admin/emoji-packs"); expect(createInit?.method).toBe("POST"); expect(JSON.parse(String(createInit?.body))).toMatchObject({ category: "热门", name: "Wave", pricingType: "paid", }); }); test("resource shop 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 listResourceShopItems({ page: 1, page_size: 10, resource_type: "avatar_frame", status: "active" }); await upsertResourceShopItems({ items: [ { durationDays: 3, effectiveFromMs: 0, effectiveToMs: 0, resourceId: 11, sortOrder: 0, status: "active", }, ], }); await enableResourceShopItem(99); await disableResourceShopItem(99); const [listUrl, listInit] = vi.mocked(fetch).mock.calls[0]; const [upsertUrl, upsertInit] = vi.mocked(fetch).mock.calls[1]; const [enableUrl, enableInit] = vi.mocked(fetch).mock.calls[2]; const [disableUrl, disableInit] = vi.mocked(fetch).mock.calls[3]; expect(String(listUrl)).toContain("/api/v1/admin/resource-shop/items?"); expect(String(listUrl)).toContain("resource_type=avatar_frame"); expect(String(listUrl)).toContain("status=active"); expect(listInit?.method).toBe("GET"); expect(String(upsertUrl)).toContain("/api/v1/admin/resource-shop/items"); expect(upsertInit?.method).toBe("POST"); expect(JSON.parse(String(upsertInit?.body))).toMatchObject({ items: [{ durationDays: 3, resourceId: 11, status: "active" }], }); expect(String(enableUrl)).toContain("/api/v1/admin/resource-shop/items/99/enable"); expect(enableInit?.method).toBe("POST"); expect(String(disableUrl)).toContain("/api/v1/admin/resource-shop/items/99/disable"); expect(disableInit?.method).toBe("POST"); }); test("gift type APIs save all tabs with one request", async () => { vi.stubGlobal( "fetch", vi.fn(async () => new Response(JSON.stringify({ code: 0, data: [] }))), ); await listGiftTypes(); await updateGiftTypes({ items: [ { displayName: "普通礼物", sortOrder: 10, status: "active", tabKey: "normal", tabName: "Gift", }, { displayName: "幸运礼物", sortOrder: 30, status: "active", tabKey: "lucky", tabName: "Lucky", }, ], }); const [listUrl, listInit] = vi.mocked(fetch).mock.calls[0]; const [updateUrl, updateInit] = vi.mocked(fetch).mock.calls[1]; expect(String(listUrl)).toContain("/api/v1/admin/gift-types"); expect(listInit?.method).toBe("GET"); expect(String(updateUrl)).toContain("/api/v1/admin/gift-types"); expect(String(updateUrl)).not.toContain("/api/v1/admin/gift-types/normal"); expect(updateInit?.method).toBe("PUT"); expect(JSON.parse(String(updateInit?.body))).toMatchObject({ items: [ { displayName: "普通礼物", tabKey: "normal", tabName: "Gift", }, { displayName: "幸运礼物", tabKey: "lucky", tabName: "Lucky", }, ], }); expect(vi.mocked(fetch)).toHaveBeenCalledTimes(2); });