feat: implement channel runtime connectors
This commit is contained in:
81
app-instance/frontend/lib/channel-connectors.test.ts
Normal file
81
app-instance/frontend/lib/channel-connectors.test.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
getChannelConnectorSession,
|
||||
listChannelConnectors,
|
||||
startChannelConnectorSession,
|
||||
} from '@/lib/api';
|
||||
|
||||
const originalFetch = globalThis.fetch;
|
||||
|
||||
afterEach(() => {
|
||||
globalThis.fetch = originalFetch;
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
localStorage.clear();
|
||||
}
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
function mockJsonResponse(body: unknown) {
|
||||
return Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve(body),
|
||||
} as Response);
|
||||
}
|
||||
|
||||
function firstFetchCall(fetchMock: any): [unknown, RequestInit] {
|
||||
return fetchMock.mock.calls[0] as [unknown, RequestInit];
|
||||
}
|
||||
|
||||
describe('channel connector api', () => {
|
||||
it('lists available channel connectors', async () => {
|
||||
const fetchMock = vi.fn(() => mockJsonResponse([{ kind: 'weixin', displayName: 'Weixin' }]));
|
||||
globalThis.fetch = fetchMock as typeof fetch;
|
||||
|
||||
const connectors = await listChannelConnectors();
|
||||
|
||||
expect(connectors).toEqual([{ kind: 'weixin', displayName: 'Weixin' }]);
|
||||
expect(String(firstFetchCall(fetchMock)[0])).toMatch(/\/api\/channel-connectors$/);
|
||||
});
|
||||
|
||||
it('starts a connector session with options', async () => {
|
||||
const fetchMock = vi.fn(() =>
|
||||
mockJsonResponse({
|
||||
session: { sessionId: 'cs_1', kind: 'weixin', status: 'qr_ready' },
|
||||
connection: { connection_id: 'conn_1', kind: 'weixin', status: 'pairing' },
|
||||
})
|
||||
);
|
||||
globalThis.fetch = fetchMock as typeof fetch;
|
||||
|
||||
const response = await startChannelConnectorSession({
|
||||
kind: 'weixin',
|
||||
displayName: 'Weixin Main',
|
||||
options: { mode: 'qr' },
|
||||
});
|
||||
|
||||
expect(response.session.sessionId).toBe('cs_1');
|
||||
const [, request] = firstFetchCall(fetchMock);
|
||||
expect(String(firstFetchCall(fetchMock)[0])).toMatch(/\/api\/channel-connector-sessions$/);
|
||||
expect(request).toEqual(
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ kind: 'weixin', displayName: 'Weixin Main', options: { mode: 'qr' } }),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('polls a connector session by id', async () => {
|
||||
const fetchMock = vi.fn(() =>
|
||||
mockJsonResponse({
|
||||
session: { sessionId: 'cs_1', kind: 'weixin', status: 'connected' },
|
||||
connection: { connection_id: 'conn_1', kind: 'weixin', status: 'connected' },
|
||||
})
|
||||
);
|
||||
globalThis.fetch = fetchMock as typeof fetch;
|
||||
|
||||
const response = await getChannelConnectorSession('cs_1');
|
||||
|
||||
expect(response.connection?.status).toBe('connected');
|
||||
expect(String(firstFetchCall(fetchMock)[0])).toMatch(/\/api\/channel-connector-sessions\/cs_1$/);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user