File size: 3,693 Bytes
aec3094 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | import type {
AiAskRequestDto,
AiApplySuggestionRequestDto,
AiChatRequestDto,
} from '@n8n/api-types';
import type { AiAssistantSDK } from '@n8n_io/ai-assistant-sdk';
import { mock } from 'jest-mock-extended';
import { InternalServerError } from '@/errors/response-errors/internal-server.error';
import type { AuthenticatedRequest } from '@/requests';
import type { WorkflowBuilderService } from '@/services/ai-workflow-builder.service';
import type { AiService } from '@/services/ai.service';
import { AiController, type FlushableResponse } from '../ai.controller';
describe('AiController', () => {
const aiService = mock<AiService>();
const workflowBuilderService = mock<WorkflowBuilderService>();
const controller = new AiController(aiService, workflowBuilderService, mock(), mock());
const request = mock<AuthenticatedRequest>({
user: { id: 'user123' },
});
const response = mock<FlushableResponse>();
beforeEach(() => {
jest.clearAllMocks();
response.header.mockReturnThis();
});
describe('chat', () => {
const payload = mock<AiChatRequestDto>();
it('should handle chat request successfully', async () => {
aiService.chat.mockResolvedValue(
mock<Response>({
body: mock({
pipeTo: jest.fn().mockImplementation(async (writableStream) => {
// Simulate stream writing
const writer = writableStream.getWriter();
await writer.write(JSON.stringify({ message: 'test response' }));
await writer.close();
}),
}),
}),
);
await controller.chat(request, response, payload);
expect(aiService.chat).toHaveBeenCalledWith(payload, request.user);
expect(response.header).toHaveBeenCalledWith('Content-type', 'application/json-lines');
expect(response.flush).toHaveBeenCalled();
expect(response.end).toHaveBeenCalled();
});
it('should throw InternalServerError if chat fails', async () => {
const mockError = new Error('Chat failed');
aiService.chat.mockRejectedValue(mockError);
await expect(controller.chat(request, response, payload)).rejects.toThrow(
InternalServerError,
);
});
});
describe('applySuggestion', () => {
const payload = mock<AiApplySuggestionRequestDto>();
it('should apply suggestion successfully', async () => {
const clientResponse = mock<AiAssistantSDK.ApplySuggestionResponse>();
aiService.applySuggestion.mockResolvedValue(clientResponse);
const result = await controller.applySuggestion(request, response, payload);
expect(aiService.applySuggestion).toHaveBeenCalledWith(payload, request.user);
expect(result).toEqual(clientResponse);
});
it('should throw InternalServerError if applying suggestion fails', async () => {
const mockError = new Error('Apply suggestion failed');
aiService.applySuggestion.mockRejectedValue(mockError);
await expect(controller.applySuggestion(request, response, payload)).rejects.toThrow(
InternalServerError,
);
});
});
describe('askAi method', () => {
const payload = mock<AiAskRequestDto>();
it('should ask AI successfully', async () => {
const clientResponse = mock<AiAssistantSDK.AskAiResponsePayload>();
aiService.askAi.mockResolvedValue(clientResponse);
const result = await controller.askAi(request, response, payload);
expect(aiService.askAi).toHaveBeenCalledWith(payload, request.user);
expect(result).toEqual(clientResponse);
});
it('should throw InternalServerError if asking AI fails', async () => {
const mockError = new Error('Ask AI failed');
aiService.askAi.mockRejectedValue(mockError);
await expect(controller.askAi(request, response, payload)).rejects.toThrow(
InternalServerError,
);
});
});
});
|