Files
Genarrative/apps/admin-web/src/api/adminApiClient.test.ts
T
kdletters 0baa8cf8cc 修复退款复核与发布安全边界
补齐退款人工复核、刷新恢复、会话隔离和旧冷备导入兼容
强化真实微信退款对账开关、重复环境变量和生产发布门禁
优化公开作品资产授权查询并保持实时撤销语义
统一后台微信渠道、退款追回流水和画布正式资源测试契约
补齐生成与素材侧栏回归测试
2026-07-14 16:31:22 +08:00

118 lines
3.4 KiB
TypeScript

import {afterEach, expect, test, vi} from 'vitest';
import {
executeAdminRechargeRefund,
getAdminUserDetail,
listAdminRechargeOrders,
resolveAdminRechargeRefundManualReview,
} from './adminApiClient';
afterEach(() => {
vi.unstubAllGlobals();
});
test('充值订单查询按后台契约序列化筛选参数', async () => {
const fetchMock = vi.fn().mockResolvedValue(
new Response(JSON.stringify({entries: []}), {
status: 200,
headers: {'content-type': 'application/json'},
}),
);
vi.stubGlobal('fetch', fetchMock);
await listAdminRechargeOrders('token-1', {
orderId: 'order 1',
userId: 'user-1',
providerTransactionId: 'wx-1',
paymentChannel: 'wechat_native',
status: 'paid',
createdAfter: '2026-07-01T00:00:00.000Z',
createdBefore: '2026-07-13T23:59:00.000Z',
limit: 50,
});
const requestUrl = String(fetchMock.mock.calls[0]?.[0]);
const parsed = new URL(requestUrl, 'http://admin.local');
expect(parsed.pathname).toBe('/admin/api/profile/recharge-orders');
expect(Object.fromEntries(parsed.searchParams)).toEqual({
orderId: 'order 1',
providerTransactionId: 'wx-1',
userId: 'user-1',
paymentChannel: 'wechat_native',
status: 'paid',
createdAfter: '2026-07-01T00:00:00.000Z',
createdBefore: '2026-07-13T23:59:00.000Z',
limit: '50',
});
});
test('用户详情只发送实际提供的用户定位字段', async () => {
const fetchMock = vi.fn().mockResolvedValue(
new Response(JSON.stringify({userId: 'user-1'}), {status: 200}),
);
vi.stubGlobal('fetch', fetchMock);
await getAdminUserDetail('token-1', {publicUserCode: 'TN1001'});
const requestUrl = String(fetchMock.mock.calls[0]?.[0]);
const parsed = new URL(requestUrl, 'http://admin.local');
expect(parsed.pathname).toBe('/admin/api/profile/users/detail');
expect(Object.fromEntries(parsed.searchParams)).toEqual({
publicUserCode: 'TN1001',
});
});
test('退款执行使用独立 execute 管理员路由', async () => {
const fetchMock = vi.fn().mockResolvedValue(
new Response(JSON.stringify({outRefundNo: 'refund-1'}), {status: 200}),
);
vi.stubGlobal('fetch', fetchMock);
await executeAdminRechargeRefund('token-1', {
orderId: 'order-1',
refundAmountCents: 300,
requestId: 'request-1',
reason: '用户申请',
});
expect(String(fetchMock.mock.calls[0]?.[0])).toBe(
'/admin/api/profile/recharge-refunds/execute',
);
expect(fetchMock.mock.calls[0]?.[1]).toEqual(
expect.objectContaining({
method: 'POST',
body: JSON.stringify({
orderId: 'order-1',
refundAmountCents: 300,
requestId: 'request-1',
reason: '用户申请',
}),
}),
);
});
test('退款人工复核使用独立 resolve 管理员路由', async () => {
const fetchMock = vi.fn().mockResolvedValue(
new Response(JSON.stringify({outRefundNo: 'refund-1'}), {status: 200}),
);
vi.stubGlobal('fetch', fetchMock);
await resolveAdminRechargeRefundManualReview('token-1', {
outRefundNo: 'refund-1',
reason: '已核对微信商户平台原始账单',
});
expect(String(fetchMock.mock.calls[0]?.[0])).toBe(
'/admin/api/profile/recharge-refunds/manual-review/resolve',
);
expect(fetchMock.mock.calls[0]?.[1]).toEqual(
expect.objectContaining({
method: 'POST',
body: JSON.stringify({
outRefundNo: 'refund-1',
reason: '已核对微信商户平台原始账单',
}),
}),
);
});