Files
iofficeai--aionui/tests/unit/team-config-options.test.ts
2026-07-13 13:20:22 +08:00

120 lines
3.8 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest';
import { BackendHttpError } from '@/common/adapter/httpBridge';
import { createTeamConfigOptionsLoader } from '@/renderer/pages/team/hooks/teamConfigOptions';
describe('createTeamConfigOptionsLoader', () => {
const configOptionsResponse = {
config_options: [
{
id: 'model',
category: 'model',
type: 'select',
current_value: 'gpt-5.5',
options: [{ value: 'gpt-5.5', label: 'GPT 5.5' }],
},
],
};
it('loads a conversation config snapshot without warming the whole team', async () => {
const calls: string[] = [];
const warmupSession = vi.fn(() => {
calls.push('warmup');
return Promise.resolve();
});
const getConfigOptions = vi.fn(async (team_id: string, conversation_id: string) => {
calls.push(`get:${team_id}:${conversation_id}`);
return configOptionsResponse;
});
const loader = createTeamConfigOptionsLoader({
team_id: 'team-1',
warmupSession,
getConfigOptions,
});
const result = await loader('conversation-1');
expect(calls).toEqual(['get:team-1:conversation-1']);
expect(warmupSession).not.toHaveBeenCalled();
expect(result?.[0]?.current_value).toBe('gpt-5.5');
});
it('can await warmup explicitly when callers need the whole team ready', async () => {
const calls: string[] = [];
const warmupSession = vi.fn(async () => {
calls.push('warmup');
});
const getConfigOptions = vi.fn(async (team_id: string, conversation_id: string) => {
calls.push(`get:${team_id}:${conversation_id}`);
return configOptionsResponse;
});
const loader = createTeamConfigOptionsLoader({
team_id: 'team-1',
warmupSession,
getConfigOptions,
});
await loader.warmup();
const result = await loader.load('conversation-1');
expect(calls).toEqual(['warmup', 'get:team-1:conversation-1']);
expect(result?.[0]?.current_value).toBe('gpt-5.5');
});
it('surfaces team runtime-not-ready without retrying config loads', async () => {
vi.useFakeTimers();
try {
const runtimeNotReady = new BackendHttpError({
method: 'GET',
path: '/api/teams/team-1/conversations/conversation-1/config-options',
status: 409,
body: {
success: false,
error: 'Team agent runtime is not ready for conversation: conversation-1',
code: 'TEAM_RUNTIME_NOT_READY',
details: { conversation_id: 'conversation-1' },
},
});
const warmupSession = vi.fn(async () => {});
const getConfigOptions = vi.fn().mockRejectedValue(runtimeNotReady);
const loader = createTeamConfigOptionsLoader({
team_id: 'team-1',
warmupSession,
getConfigOptions,
});
const resultPromise = loader.load('conversation-1');
const expectation = expect(resultPromise).rejects.toBe(runtimeNotReady);
await vi.advanceTimersByTimeAsync(31_000);
await expectation;
expect(getConfigOptions).toHaveBeenCalledTimes(1);
expect(warmupSession).not.toHaveBeenCalled();
} finally {
vi.useRealTimers();
}
});
it('does not retry ordinary config load failures', async () => {
const error = new BackendHttpError({
method: 'GET',
path: '/api/teams/team-1/conversations/conversation-1/config-options',
status: 400,
body: {
success: false,
error: 'bad request',
code: 'BAD_REQUEST',
},
});
const getConfigOptions = vi.fn().mockRejectedValue(error);
const loader = createTeamConfigOptionsLoader({
team_id: 'team-1',
warmupSession: vi.fn(async () => {}),
getConfigOptions,
});
await expect(loader.load('conversation-1')).rejects.toBe(error);
expect(getConfigOptions).toHaveBeenCalledTimes(1);
});
});