import React from 'react';
import { render, screen } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
const usePresetAssistantInfoMock = vi.fn();
const acpChatMock = vi.fn(() =>
);
const aionrsChatMock = vi.fn(() => );
vi.mock('react-i18next', () => ({
useTranslation: () => ({
t: (_key: string, options?: { defaultValue?: string }) => options?.defaultValue ?? _key,
}),
}));
vi.mock('@/renderer/hooks/agent/usePresetAssistantInfo', () => ({
usePresetAssistantInfo: (...args: unknown[]) => usePresetAssistantInfoMock(...args),
}));
vi.mock('@/renderer/pages/conversation/platforms/acp/AcpChat', () => ({
__esModule: true,
default: (props: unknown) => acpChatMock(props),
}));
vi.mock('@/renderer/pages/conversation/platforms/aionrs/AionrsChat', () => ({
__esModule: true,
default: (props: unknown) => aionrsChatMock(props),
}));
vi.mock('@/renderer/pages/conversation/platforms/legacy/LegacyReadOnlyConversation', () => ({
__esModule: true,
default: () => ,
}));
import TeamChatView from '@/renderer/pages/team/components/TeamChatView';
describe('TeamChatView', () => {
beforeEach(() => {
usePresetAssistantInfoMock.mockReset();
acpChatMock.mockClear();
aionrsChatMock.mockClear();
});
it('prefers preset assistant backend over legacy conversation extra backend', async () => {
usePresetAssistantInfoMock.mockReturnValue({
info: {
name: 'Planner Assistant',
logo: 'đŸ“‹',
isEmoji: true,
backend: 'codex',
},
});
render(
);
expect(await screen.findByTestId('mock-acp-chat')).toBeInTheDocument();
expect(acpChatMock).toHaveBeenCalled();
expect(acpChatMock.mock.calls[0]?.[0]).toEqual(
expect.objectContaining({
backend: 'codex',
})
);
});
it('prefers preset assistant name over legacy conversation extra agent_name', async () => {
usePresetAssistantInfoMock.mockReturnValue({
info: {
name: 'Planner Assistant',
logo: 'đŸ“‹',
isEmoji: true,
backend: 'codex',
},
});
render(
);
expect(await screen.findByTestId('mock-acp-chat')).toBeInTheDocument();
expect(acpChatMock).toHaveBeenCalled();
expect(acpChatMock.mock.calls[0]?.[0]).toEqual(
expect.objectContaining({
agent_name: 'Planner Assistant',
})
);
});
it('passes loaded skills and MCP snapshot to ACP team chat', async () => {
usePresetAssistantInfoMock.mockReturnValue({ info: null });
const mcpStatuses = [{ id: 'office', name: 'office', status: 'loaded' as const }];
render(
);
expect(await screen.findByTestId('mock-acp-chat')).toBeInTheDocument();
expect(acpChatMock.mock.calls[0]?.[0]).toEqual(
expect.objectContaining({
loadedSkills: ['excel'],
loadedMcpServers: ['office'],
loadedMcpStatuses: mcpStatuses,
})
);
});
it('passes loaded skills and MCP snapshot to AionRS team chat', async () => {
usePresetAssistantInfoMock.mockReturnValue({ info: null });
const mcpStatuses = [{ id: 'office', name: 'office', status: 'loaded' as const }];
render(
);
expect(await screen.findByTestId('mock-aionrs-chat')).toBeInTheDocument();
expect(aionrsChatMock.mock.calls[0]?.[0]).toEqual(
expect.objectContaining({
loadedSkills: ['excel'],
loadedMcpServers: ['office'],
loadedMcpStatuses: mcpStatuses,
})
);
});
it.each([
['runtime_starting', 'Waiting for this assistant to start…', true],
['runtime_failed', 'This assistant failed to start.', false],
['removing', 'Removing this assistant…', false],
['session_stopped', 'The team session has stopped.', false],
] as const)('maps %s to authoritative team runtime status', async (blockedReason, statusText, canSendMessage) => {
usePresetAssistantInfoMock.mockReturnValue({ info: null });
render(
);
expect(await screen.findByTestId('mock-acp-chat')).toBeInTheDocument();
expect(acpChatMock.mock.calls[0]?.[0]).toEqual(
expect.objectContaining({
teamRuntime: expect.objectContaining({
statusText,
queuedCount: 3,
runtimeGate: expect.objectContaining({ canSendMessage, isProcessing: false }),
}),
})
);
});
});