Files
Genarrative/apps/ai-game-creator-shell/tests/clientHttp.test.ts
T
kdletters 8701f43f75 AGC 渲染层网络与状态下沉 Rust,并修复画布交互与失败文案
- 删除渲染层传输层:services/clientApi.ts、clientHttp 的 fetchClientHttp 与超时封装整体退场,账户、认证、素材直传、错误上报与游戏分发发布改走 Rust typed command。
- 新增宿主封装:accountHost、editorAssetHost、platformSessionRetry、agentRuntimeErrorDetail 与 features/app-shell/workspacePreferences;渲染层不再读写 access token / refresh cookie,localStorage 只剩测试态旧键迁移 shim。
- 修复 DirectProject 失败文案 v2 映射与「查看详情」按需读取,画布标签面板高度夹紧、框选每帧重算、文档预览入口与场景标题栏 key、资源筛选面板样式。
- 补齐与调整回归:accountHost、agentRuntimeErrorDetail、clientAuthHost、clientHttp、platformSession、platformSessionRetry、resourceFilterPanelStyle、directThreadChatSubscription 等定向用例,并清理测试 harness 中无调用方的残留。
2026-09-28 14:15:02 +08:00

135 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// @vitest-environment node
/**
* 客户端服务器选择的边界。
*
* 正式包只跟随构建渠道(`VITE_AGC_PLATFORM_CHANNEL`),自定义地址只在本地 Vite debug 可用;
* 归一化必须拒绝把凭据、路径、查询、哈希或明文远程地址带进登录请求——这些值随后会作为
* origin 交给 Rust 与后端,渲染层这一层只负责即时反馈与内存投影。
*/
import { beforeEach, expect, test, vi } from 'vitest';
const { invoke, resolveTauriInvoke } = vi.hoisted(() => {
const invokeMock = vi.fn();
return {
invoke: invokeMock,
resolveTauriInvoke: vi.fn(() => invokeMock),
};
});
vi.mock('../src/app/tauri', () => ({ resolveTauriInvoke }));
async function loadClientHttp() {
return import('../src/services/clientHttp');
}
beforeEach(() => {
vi.resetModules();
vi.unstubAllEnvs();
invoke.mockReset();
resolveTauriInvoke.mockReturnValue(invoke);
});
test('非法服务器地址按原因逐条拒绝', async () => {
const { normalizeClientServerBaseUrl } = await loadClientHttp();
expect(() => normalizeClientServerBaseUrl('dev.genarrative.world')).toThrow(
'服务器地址无效',
);
expect(() => normalizeClientServerBaseUrl('ftp://example.com')).toThrow(
'服务器地址必须是纯 HTTP(S) 地址',
);
expect(() =>
normalizeClientServerBaseUrl('https://user:pass@example.com'),
).toThrow('服务器地址必须是纯 HTTP(S) 地址');
expect(() => normalizeClientServerBaseUrl('https://example.com/api')).toThrow(
'服务器地址必须是纯 HTTP(S) 地址',
);
expect(() =>
normalizeClientServerBaseUrl('https://example.com/?token=1'),
).toThrow('服务器地址必须是纯 HTTP(S) 地址');
expect(() =>
normalizeClientServerBaseUrl('https://example.com/#frag'),
).toThrow('服务器地址必须是纯 HTTP(S) 地址');
expect(() => normalizeClientServerBaseUrl('http://example.com')).toThrow(
'非本机服务器必须使用 HTTPS',
);
});
test('合法地址去掉尾部斜杠并保留回环端口', async () => {
const { normalizeClientServerBaseUrl } = await loadClientHttp();
expect(normalizeClientServerBaseUrl('https://dev.genarrative.world///')).toBe(
'https://dev.genarrative.world',
);
expect(normalizeClientServerBaseUrl(' http://127.0.0.1:10001/ ')).toBe(
'http://127.0.0.1:10001',
);
expect(normalizeClientServerBaseUrl('http://localhost:8080')).toBe(
'http://localhost:8080',
);
});
test('预设映射到渠道地址,自定义走归一化', async () => {
const mod = await loadClientHttp();
expect(
mod.getClientServerBaseUrl({ preset: 'release', customBaseUrl: '' }),
).toBe(mod.AGC_RELEASE_API_BASE_URL);
expect(mod.getClientServerBaseUrl({ preset: 'dev', customBaseUrl: '' })).toBe(
mod.AGC_DEVELOPMENT_API_BASE_URL,
);
expect(
mod.getClientServerBaseUrl({
preset: 'custom',
customBaseUrl: 'https://staging.example.com/',
}),
).toBe('https://staging.example.com');
expect(mod.isClientServerPreset('custom')).toBe(true);
expect(mod.isClientServerPreset('staging')).toBe(false);
});
test('开发态切换服务器会落盘并在内存中生效', async () => {
vi.stubEnv('DEV', true);
const mod = await loadClientHttp();
expect(mod.isClientServerSelectionEnabled()).toBe(true);
expect(
mod.setClientServerSelection({
preset: 'custom',
customBaseUrl: ' https://staging.example.com/ ',
}),
).toEqual({ preset: 'custom', customBaseUrl: 'https://staging.example.com' });
await Promise.resolve();
expect(invoke).toHaveBeenCalledWith('set_client_server_selection', {
preset: 'custom',
customBaseUrl: 'https://staging.example.com',
});
expect(mod.getClientServerBaseUrl()).toBe('https://staging.example.com');
});
test('开发态从 Rust 偏好恢复服务器选择', async () => {
vi.stubEnv('DEV', true);
const mod = await loadClientHttp();
invoke.mockResolvedValue({
clientServerSelection: {
preset: 'custom',
customBaseUrl: 'https://restored.example.com',
},
});
await expect(mod.hydrateClientServerSelection()).resolves.toEqual({
preset: 'custom',
customBaseUrl: 'https://restored.example.com',
});
expect(invoke).toHaveBeenCalledWith('read_workspace_preferences');
expect(mod.getClientServerSelection()).toEqual({
preset: 'custom',
customBaseUrl: 'https://restored.example.com',
});
});
// 「打包态不开放服务器切换」这条规则这里测不了:`import.meta.env.DEV` 在测试运行下恒为
// true,`vi.stubEnv('DEV', false)` 改不动它(Vite/Vitest 把它按构建期常量处理),因此
// `isClientServerSelectionEnabled()` 与 `getClientServerSelection()` 的打包分支只能在真实
// 发布构建里核对。本文件覆盖的是地址归一化、预设映射、开发态落盘与偏好恢复。