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`, }); }); });