Files
Genarrative/src/services/wooden-fish/woodenFishClient.test.ts

140 lines
4.1 KiB
TypeScript

import { afterEach, beforeEach, expect, test, vi } from 'vitest';
const requestJsonMock = vi.hoisted(() => vi.fn());
const { createCreationAgentClientMock } = vi.hoisted(() => ({
createCreationAgentClientMock: vi.fn(),
}));
vi.mock('../creation-agent', () => ({
createCreationAgentClient: createCreationAgentClientMock,
}));
vi.mock('../apiClient', () => ({
requestJson: requestJsonMock,
}));
beforeEach(() => {
vi.resetModules();
createCreationAgentClientMock.mockReset();
createCreationAgentClientMock.mockReturnValue({
createSession: vi.fn(),
getSession: vi.fn(),
sendMessage: vi.fn(),
streamMessage: vi.fn(),
executeAction: vi.fn(),
});
requestJsonMock.mockReset();
});
afterEach(() => {
vi.restoreAllMocks();
});
test('wooden fish creation keeps image2 generation requests alive long enough', async () => {
await import('./woodenFishClient');
expect(createCreationAgentClientMock).toHaveBeenCalledWith(
expect.objectContaining({
createSessionTimeoutMs: 20 * 60 * 1000,
executeActionTimeoutMs: 20 * 60 * 1000,
}),
);
});
test('wooden fish list works uses creation works endpoint', async () => {
const { woodenFishClient } = await import('./woodenFishClient');
requestJsonMock.mockResolvedValueOnce({ items: [] });
await woodenFishClient.listWorks();
expect(requestJsonMock).toHaveBeenCalledWith(
'/api/creation/wooden-fish/works',
{ method: 'GET' },
'读取敲木鱼作品列表失败',
);
});
test('wooden fish start run uses runtime guest json skeleton', async () => {
const { woodenFishClient } = await import('./woodenFishClient');
requestJsonMock.mockResolvedValueOnce({ run: { runId: 'run-1' } });
await woodenFishClient.startRun('profile/1', {
runtimeGuestToken: 'runtime-guest-token',
});
expect(requestJsonMock).toHaveBeenCalledWith(
'/api/runtime/wooden-fish/runs',
expect.objectContaining({
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer runtime-guest-token',
},
body: JSON.stringify({ profileId: 'profile/1' }),
}),
'启动敲木鱼运行态失败',
expect.objectContaining({
retry: expect.objectContaining({ retryUnsafeMethods: true }),
skipAuth: true,
skipRefresh: true,
}),
);
});
test('wooden fish checkpoint run keeps client event id local to the client', async () => {
const { woodenFishClient } = await import('./woodenFishClient');
vi.spyOn(Date, 'now').mockReturnValue(1780000000000);
requestJsonMock.mockResolvedValueOnce({ run: { runId: 'run-1' } });
await woodenFishClient.checkpointRun(
'run/1',
{
totalTapCount: 12,
wordCounters: [{ text: '功德', count: 3 }],
},
{ runtimeGuestToken: 'runtime-guest-token' },
);
const [, init] = requestJsonMock.mock.calls[0];
const body = JSON.parse(init.body);
expect(requestJsonMock.mock.calls[0][0]).toBe(
'/api/runtime/wooden-fish/runs/run%2F1/checkpoint',
);
expect(body).toEqual({
totalTapCount: 12,
wordCounters: [{ text: '功德', count: 3 }],
clientEventId: 'checkpoint-run/1-1780000000000',
});
expect(body).not.toHaveProperty('runId');
expect(body).not.toHaveProperty('checkpointAtMs');
});
test('wooden fish finish run keeps finish event id local to the client', async () => {
const { woodenFishClient } = await import('./woodenFishClient');
vi.spyOn(Date, 'now').mockReturnValue(1780000000001);
requestJsonMock.mockResolvedValueOnce({ run: { runId: 'run-1' } });
await woodenFishClient.finishRun(
'run/1',
{
totalTapCount: 18,
wordCounters: [{ text: '清净', count: 2 }],
},
{ runtimeGuestToken: 'runtime-guest-token' },
);
const [, init] = requestJsonMock.mock.calls[0];
const body = JSON.parse(init.body);
expect(requestJsonMock.mock.calls[0][0]).toBe(
'/api/runtime/wooden-fish/runs/run%2F1/finish',
);
expect(body).toEqual({
totalTapCount: 18,
wordCounters: [{ text: '清净', count: 2 }],
clientEventId: 'finish-run/1-1780000000001',
});
expect(body).not.toHaveProperty('runId');
expect(body).not.toHaveProperty('finishedAtMs');
});