Files
Genarrative/apps/ai-game-creator-shell/tests/accountHost.test.ts
T
k88936 25c5ecdf6e
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m58s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 6m34s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 5m29s
Project CI / Backend tests (pull_request) Failing after 4m38s
Project CI / Frontend tests (pull_request) Successful in 3m33s
Project CI / Repository checks (pull_request) Failing after 4m4s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m13s
Project CI / Native shell tests (pull_request) Successful in 6m35s
测试:全仓测试统一 Tauri 运行时替身安装点
- 78 处内联 window.__TAURI__ 赋值改为 installTauriRuntime,覆盖 appSurface 之外的 37 个测试文件
- 31 处 delete window.__TAURI__ / window.__TAURI__ = undefined 复位改为 resetTauriRuntime
- 删除 recentProjectsHook、projectCreationDirectory、projectResourceLiveIntegration、useProjectResourceCardPreviews、resourceVersionReplacementModel、unityProjectOpen 里的本地 asTauriInvoke / asTauriListen 适配器与相关类型别名
- designProjectRestore 的 setup 参数由 ReturnType<typeof vi.fn> 收窄为具体 invoke 签名
- 迁移后仅 tests/tauriRuntimeFake.ts 直接读写 window.__TAURI__
2026-10-03 20:19:45 +08:00

108 lines
3.8 KiB
TypeScript

// @vitest-environment jsdom
/**
* 账户与钱包 typed façade 的边界。
*
* 渲染层只提交结构化业务参数;平台 origin、Bearer、envelope 与错误分类由 Rust 持有。
* 这里验证 IPC 载荷、登录失效时「续期后重试一次」,以及业务失败不重放。
*/
import { beforeEach, expect, test, vi } from 'vitest';
const invoke = vi.fn();
const platformSession = vi.hoisted(() => ({
generation: 1,
refresh: vi.fn(),
}));
// 与仓库其它 App 内调用方同口径:通过 `window.__TAURI__.core.invoke` 解析原生桥。
installTauriRuntime({
core: { invoke: (...args: unknown[]) => invoke(...args) },
});
vi.mock('../src/services/platformSession', () => ({
currentPlatformSessionGeneration: () => platformSession.generation,
requestPlatformSessionRefresh: (...args: unknown[]) =>
platformSession.refresh(...args),
}));
import {
confirmClientWechatProfileRechargeOrder,
createClientProfileRechargeOrder,
getClientProfileRechargeCenter,
getClientProfileReferralInviteCenter,
getClientProfileWalletLedger,
redeemClientProfileRewardCode,
} from '../src/services/accountHost';
import { installTauriRuntime } from './tauriRuntimeFake';
beforeEach(() => {
invoke.mockReset();
platformSession.generation = 1;
platformSession.refresh.mockReset();
platformSession.refresh.mockResolvedValue({
status: 'refreshed',
generation: 1,
user: { id: 'user-1' },
});
});
test('账户读取只提交结构化参数,不携带 token 或远端地址', async () => {
invoke.mockResolvedValue({ walletBalance: 1 });
await getClientProfileRechargeCenter();
await getClientProfileWalletLedger();
await getClientProfileReferralInviteCenter();
await createClientProfileRechargeOrder('product-1');
await confirmClientWechatProfileRechargeOrder('order-1');
await redeemClientProfileRewardCode('CODE-1');
expect(invoke.mock.calls).toEqual([
['read_profile_recharge_center', undefined],
['read_profile_wallet_ledger', undefined],
['read_profile_referral_invite_center', undefined],
['create_profile_recharge_order', { productId: 'product-1' }],
['confirm_wechat_profile_recharge_order', { orderId: 'order-1' }],
['redeem_profile_reward_code', { code: 'CODE-1' }],
]);
const serialized = JSON.stringify(invoke.mock.calls);
expect(serialized).not.toContain('token');
expect(serialized).not.toContain('Authorization');
expect(serialized).not.toContain('http');
});
test('登录失效时续期一次并重放,其它业务失败原样抛出', async () => {
invoke
.mockRejectedValueOnce(new Error('authentication-required: 请先登录'))
.mockResolvedValueOnce({ entries: [] });
await expect(getClientProfileWalletLedger()).resolves.toEqual({
entries: [],
});
expect(platformSession.refresh).toHaveBeenCalledTimes(1);
expect(invoke).toHaveBeenCalledTimes(2);
invoke.mockReset();
platformSession.refresh.mockClear();
invoke.mockRejectedValueOnce(new Error('读取泥点账单失败:余额服务不可用'));
await expect(getClientProfileWalletLedger()).rejects.toThrow(
'读取泥点账单失败:余额服务不可用',
);
expect(platformSession.refresh).not.toHaveBeenCalled();
expect(invoke).toHaveBeenCalledTimes(1);
});
test('续期期间换号时不重放旧身份的付费请求', async () => {
invoke.mockRejectedValueOnce(
new Error('authentication-required: 登录已过期'),
);
// 续期在飞期间另一个账号完成登录:代际已经推进,旧身份的续期结果不算数。
platformSession.refresh.mockImplementationOnce(async () => {
platformSession.generation = 2;
return { status: 'refreshed', generation: 1, user: { id: 'user-1' } };
});
await expect(createClientProfileRechargeOrder('product-1')).rejects.toThrow(
'登录账号已变化,原请求已停止',
);
expect(invoke).toHaveBeenCalledTimes(1);
});