Files
Genarrative/apps/ai-game-creator-shell/tests/clientHttp.test.ts
T
kdletters 9070c0760b 修复登录服务器切换与本地资源请求
- 允许 release 客户端安全访问 custom HTTPS 与本机 loopback HTTP

- 修复 Tauri WebView 请求传输与无效 URLPattern

- 按服务器 origin 隔离本机 External Editor 凭据

- 保留登录请求底层错误并补充路由与凭据隔离测试
2026-08-18 18:32:49 +08:00

148 lines
4.4 KiB
TypeScript

import { afterEach, describe, expect, it } from 'vitest';
import {
AGC_DEVELOPMENT_API_BASE_URL,
AGC_RELEASE_API_BASE_URL,
getClientServerBaseUrl,
getClientServerSelection,
normalizeClientServerBaseUrl,
resetClientServerSelectionForTests,
resolveClientHttpTarget,
setClientServerSelection,
} from '../src/services/clientHttp';
describe('AGC client HTTP transport', () => {
afterEach(() => resetClientServerSelectionForTests());
it('keeps local development requests on the Vite API proxy', () => {
expect(
resolveClientHttpTarget('/api/auth/me', {
isDevelopment: true,
isTauri: true,
pageProtocol: 'http:',
}),
).toEqual({ transport: 'web', url: '/api/auth/me' });
});
it('routes release Tauri requests through the scoped dev API transport', () => {
expect(
resolveClientHttpTarget('/api/auth/me', {
isDevelopment: false,
isTauri: true,
pageProtocol: 'tauri:',
mode: 'production',
serverBaseUrl: AGC_RELEASE_API_BASE_URL,
}),
).toEqual({
transport: 'tauri-http',
url: `${AGC_RELEASE_API_BASE_URL}/api/auth/me`,
});
});
it('keeps ordinary web releases on same-origin relative requests', () => {
expect(
resolveClientHttpTarget('/api/auth/me', {
isDevelopment: false,
isTauri: false,
pageProtocol: 'https:',
mode: 'test',
}),
).toEqual({ transport: 'web', url: '/api/auth/me' });
});
it('rejects release Tauri requests outside the fixed dev API origin', () => {
expect(() =>
resolveClientHttpTarget('https://example.com/api/auth/me', {
isDevelopment: false,
isTauri: true,
pageProtocol: 'tauri:',
mode: 'production',
serverBaseUrl: AGC_RELEASE_API_BASE_URL,
}),
).toThrow('当前选择的服务器范围');
});
it('persists release, dev, and custom server selection', () => {
const release = setClientServerSelection({
preset: 'release',
customBaseUrl: '',
});
expect(release).toEqual({
preset: 'release',
customBaseUrl: '',
});
expect(getClientServerBaseUrl(release)).toBe(AGC_RELEASE_API_BASE_URL);
const dev = setClientServerSelection({ preset: 'dev', customBaseUrl: '' });
expect(getClientServerBaseUrl(dev)).toBe(AGC_DEVELOPMENT_API_BASE_URL);
const custom = setClientServerSelection({
preset: 'custom',
customBaseUrl: 'https://staging.example.com/',
});
expect(custom).toEqual({
preset: 'custom',
customBaseUrl: 'https://staging.example.com',
});
expect(getClientServerSelection().preset).toBe('dev');
expect(getClientServerBaseUrl(custom)).toBe('https://staging.example.com');
});
it('accepts HTTPS custom servers and loopback HTTP only', () => {
expect(normalizeClientServerBaseUrl('https://example.com/')).toBe(
'https://example.com',
);
expect(normalizeClientServerBaseUrl('http://127.0.0.1:8080/')).toBe(
'http://127.0.0.1:8080',
);
expect(() => normalizeClientServerBaseUrl('http://example.com')).toThrow(
'必须使用 HTTPS',
);
expect(() =>
normalizeClientServerBaseUrl('https://example.com/api'),
).toThrow('纯 HTTP(S)');
});
it('routes selected custom servers for both web and Tauri clients', () => {
const serverBaseUrl = 'https://staging.example.com';
expect(
resolveClientHttpTarget('/api/auth/me', {
isDevelopment: true,
isTauri: false,
pageProtocol: 'http:',
mode: 'development',
serverBaseUrl,
}),
).toEqual({
transport: 'web',
url: `${serverBaseUrl}/api/auth/me`,
});
expect(
resolveClientHttpTarget('/api/auth/me', {
isDevelopment: false,
isTauri: true,
pageProtocol: 'tauri:',
mode: 'production',
serverBaseUrl,
}),
).toEqual({
transport: 'tauri-http',
url: `${serverBaseUrl}/api/auth/me`,
});
});
it('keeps Tauri HTTP transport when the WebView reports an http page protocol', () => {
expect(
resolveClientHttpTarget('/api/auth/me', {
isDevelopment: false,
isTauri: true,
pageProtocol: 'http:',
mode: 'production',
serverBaseUrl: AGC_DEVELOPMENT_API_BASE_URL,
}),
).toEqual({
transport: 'tauri-http',
url: `${AGC_DEVELOPMENT_API_BASE_URL}/api/auth/me`,
});
});
});