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
88
tests/unit/host-api.test.ts
Normal file
88
tests/unit/host-api.test.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
const invokeIpcMock = vi.fn();
|
||||
|
||||
vi.mock('@/lib/api-client', () => ({
|
||||
invokeIpc: (...args: unknown[]) => invokeIpcMock(...args),
|
||||
}));
|
||||
|
||||
describe('host-api', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
|
||||
it('uses IPC proxy and returns unified envelope json', async () => {
|
||||
invokeIpcMock.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
data: {
|
||||
status: 200,
|
||||
ok: true,
|
||||
json: { success: true },
|
||||
},
|
||||
});
|
||||
|
||||
const { hostApiFetch } = await import('@/lib/host-api');
|
||||
const result = await hostApiFetch<{ success: boolean }>('/api/settings');
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(invokeIpcMock).toHaveBeenCalledWith(
|
||||
'hostapi:fetch',
|
||||
expect.objectContaining({ path: '/api/settings', method: 'GET' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('supports legacy proxy envelope response', async () => {
|
||||
invokeIpcMock.mockResolvedValueOnce({
|
||||
success: true,
|
||||
status: 200,
|
||||
ok: true,
|
||||
json: { ok: 1 },
|
||||
});
|
||||
|
||||
const { hostApiFetch } = await import('@/lib/host-api');
|
||||
const result = await hostApiFetch<{ ok: number }>('/api/settings');
|
||||
expect(result.ok).toBe(1);
|
||||
});
|
||||
|
||||
it('throws proxy error from unified envelope', async () => {
|
||||
invokeIpcMock.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
error: { message: 'No handler registered for hostapi:fetch' },
|
||||
});
|
||||
|
||||
const { hostApiFetch } = await import('@/lib/host-api');
|
||||
await expect(hostApiFetch('/api/test')).rejects.toThrow('No handler registered for hostapi:fetch');
|
||||
});
|
||||
|
||||
it('throws message from legacy non-ok envelope', async () => {
|
||||
invokeIpcMock.mockResolvedValueOnce({
|
||||
success: true,
|
||||
ok: false,
|
||||
status: 401,
|
||||
json: { error: 'Invalid Authentication' },
|
||||
});
|
||||
|
||||
const { hostApiFetch } = await import('@/lib/host-api');
|
||||
await expect(hostApiFetch('/api/test')).rejects.toThrow('Invalid Authentication');
|
||||
});
|
||||
|
||||
it('falls back to browser fetch only when IPC channel is unavailable', async () => {
|
||||
const fetchMock = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
status: 200,
|
||||
json: async () => ({ fallback: true }),
|
||||
});
|
||||
vi.stubGlobal('fetch', fetchMock);
|
||||
|
||||
invokeIpcMock.mockRejectedValueOnce(new Error('Invalid IPC channel: hostapi:fetch'));
|
||||
|
||||
const { hostApiFetch } = await import('@/lib/host-api');
|
||||
const result = await hostApiFetch<{ fallback: boolean }>('/api/test');
|
||||
|
||||
expect(result.fallback).toBe(true);
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
'http://127.0.0.1:3210/api/test',
|
||||
expect.objectContaining({ headers: expect.any(Object) }),
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user