refactor/channel & ipc (#349)
Co-authored-by: paisley <8197966+su8su@users.noreply.github.com> Co-authored-by: zuolingxuan <zuolingxuan@bytedance.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
8b45960662
commit
e28eba01e1
@@ -8,11 +8,17 @@ import {
|
||||
registerTransportInvoker,
|
||||
unregisterTransportInvoker,
|
||||
clearTransportBackoff,
|
||||
getApiClientConfig,
|
||||
applyGatewayTransportPreference,
|
||||
createGatewayHttpTransportInvoker,
|
||||
getGatewayWsDiagnosticEnabled,
|
||||
setGatewayWsDiagnosticEnabled,
|
||||
} from '@/lib/api-client';
|
||||
|
||||
describe('api-client', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
window.localStorage.removeItem('clawx:gateway-ws-diagnostic');
|
||||
configureApiClient({
|
||||
enabled: { ws: false, http: false },
|
||||
rules: [{ matcher: /.*/, order: ['ipc'] }],
|
||||
@@ -150,4 +156,82 @@ describe('api-client', () => {
|
||||
expect(wsInvoker).toHaveBeenCalledTimes(2);
|
||||
expect(invoke).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('defaults transport preference to ipc-only', () => {
|
||||
applyGatewayTransportPreference();
|
||||
const config = getApiClientConfig();
|
||||
expect(config.enabled.ws).toBe(false);
|
||||
expect(config.enabled.http).toBe(false);
|
||||
expect(config.rules[0]).toEqual({ matcher: /^gateway:rpc$/, order: ['ipc'] });
|
||||
});
|
||||
|
||||
it('enables ws->http->ipc order when ws diagnostic is on', () => {
|
||||
setGatewayWsDiagnosticEnabled(true);
|
||||
expect(getGatewayWsDiagnosticEnabled()).toBe(true);
|
||||
|
||||
const config = getApiClientConfig();
|
||||
expect(config.enabled.ws).toBe(true);
|
||||
expect(config.enabled.http).toBe(true);
|
||||
expect(config.rules[0]).toEqual({ matcher: /^gateway:rpc$/, order: ['ws', 'http', 'ipc'] });
|
||||
});
|
||||
|
||||
it('parses gateway:httpProxy unified envelope response', async () => {
|
||||
const invoke = vi.mocked(window.electron.ipcRenderer.invoke);
|
||||
invoke.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
data: {
|
||||
status: 200,
|
||||
ok: true,
|
||||
json: { type: 'res', ok: true, payload: { rows: [1, 2] } },
|
||||
},
|
||||
});
|
||||
|
||||
const invoker = createGatewayHttpTransportInvoker();
|
||||
const result = await invoker<{ success: boolean; result: { rows: number[] } }>(
|
||||
'gateway:rpc',
|
||||
['chat.history', { sessionKey: 's1' }],
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.result.rows).toEqual([1, 2]);
|
||||
expect(invoke).toHaveBeenCalledWith(
|
||||
'gateway:httpProxy',
|
||||
expect.objectContaining({
|
||||
path: '/rpc',
|
||||
method: 'POST',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('throws meaningful error when gateway:httpProxy unified envelope fails', async () => {
|
||||
const invoke = vi.mocked(window.electron.ipcRenderer.invoke);
|
||||
invoke.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
error: { message: 'proxy unavailable' },
|
||||
});
|
||||
|
||||
const invoker = createGatewayHttpTransportInvoker();
|
||||
await expect(invoker('gateway:rpc', ['chat.history', {}])).rejects.toThrow('proxy unavailable');
|
||||
});
|
||||
|
||||
it('normalizes raw gateway:httpProxy payload into ipc-style envelope', async () => {
|
||||
const invoke = vi.mocked(window.electron.ipcRenderer.invoke);
|
||||
invoke.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
data: {
|
||||
status: 200,
|
||||
ok: true,
|
||||
json: { channels: [{ id: 'telegram-default' }] },
|
||||
},
|
||||
});
|
||||
|
||||
const invoker = createGatewayHttpTransportInvoker();
|
||||
const result = await invoker<{ success: boolean; result: { channels: Array<{ id: string }> } }>(
|
||||
'gateway:rpc',
|
||||
['channels.status', { probe: false }],
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.result.channels[0].id).toBe('telegram-default');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user