2026-07-10 20:20:58 +08:00

141 lines
4.7 KiB
TypeScript

import { afterEach, expect, test, vi } from "vitest";
import { setAccessToken, setSelectedAppCode } from "@/shared/api/request";
import {
createH5Link,
createSystemMessagePushFanout,
deleteH5Link,
listH5Links,
updateH5Link,
updateH5Links,
} from "./api";
afterEach(() => {
setAccessToken("");
setSelectedAppCode("lalu");
vi.unstubAllGlobals();
});
test("H5 config API pins every request to its explicit app scope", async () => {
setSelectedAppCode("lalu");
const link = {
appCode: "huwaa",
key: "achievement",
label: "成就",
updatedAtMs: 1000,
url: "https://h5.example.com/achievement",
};
vi.stubGlobal(
"fetch",
vi.fn(async (_url, init) => {
const method = String(init?.method || "GET");
const data = method === "GET" || (method === "PUT" && !String(_url).endsWith("/achievement"))
? { items: [link], total: 1 }
: method === "DELETE"
? { deleted: true }
: link;
return new Response(JSON.stringify({ code: 0, data }), { status: method === "POST" ? 201 : 200 });
}),
);
const payload = { key: link.key, label: link.label, url: link.url };
await listH5Links(" Huwaa ");
await createH5Link("huwaa", payload);
await updateH5Links("huwaa", { items: [payload] });
await updateH5Link("huwaa", link.key, payload);
await deleteH5Link("huwaa", link.key);
const calls = vi.mocked(fetch).mock.calls;
expect(calls.map(([, init]) => init?.method)).toEqual(["GET", "POST", "PUT", "PUT", "DELETE"]);
calls.forEach(([, init]) => {
expect(init?.headers).toMatchObject({ "X-App-Code": "huwaa" });
});
expect(String(calls[0][0])).toContain("/api/v1/admin/app-config/h5-links");
expect(String(calls[3][0])).toContain("/api/v1/admin/app-config/h5-links/achievement");
expect(JSON.parse(String(calls[1][1]?.body))).toEqual(payload);
expect(JSON.parse(String(calls[2][1]?.body))).toEqual({ items: [payload] });
expect(JSON.parse(String(calls[3][1]?.body))).toEqual(payload);
});
test("system message push fanout API keeps existing operations path", async () => {
vi.stubGlobal(
"fetch",
vi.fn(
async () =>
new Response(
JSON.stringify({
code: 0,
data: {
command_id: "admin_notice_test",
created: true,
job_id: "mfan_test",
message_type: "system",
status: "pending",
target_scope: "all_registered_users",
},
}),
),
),
);
await createSystemMessagePushFanout({
action_param: "https://example.com",
action_type: "app_h5",
batch_size: 500,
message_type: "system",
producer_event_type: "admin_full_server_notice",
summary: "今晚 23:00 维护",
target_scope: "all_registered_users",
title: "维护通知",
});
const [url, init] = vi.mocked(fetch).mock.calls[0];
expect(String(url)).toContain("/api/v1/admin/operations/full-server-notices/fanout");
expect(init?.method).toBe("POST");
expect(JSON.parse(String(init?.body))).toMatchObject({
action_param: "https://example.com",
action_type: "app_h5",
message_type: "system",
producer_event_type: "admin_full_server_notice",
target_scope: "all_registered_users",
title: "维护通知",
});
});
test("system message push fanout API preserves string user IDs", async () => {
vi.stubGlobal(
"fetch",
vi.fn(
async () =>
new Response(
JSON.stringify({
code: 0,
data: {
command_id: "admin_notice_users",
created: true,
job_id: "mfan_users",
message_type: "system",
status: "pending",
target_scope: "user_ids",
},
}),
),
),
);
await createSystemMessagePushFanout({
message_type: "system",
summary: "指定用户维护",
target_scope: "user_ids",
title: "维护通知",
user_ids: ["325379237278126080", "42"],
});
const [, init] = vi.mocked(fetch).mock.calls[0];
expect(JSON.parse(String(init?.body))).toMatchObject({
target_scope: "user_ids",
user_ids: ["325379237278126080", "42"],
});
});