n8n-nodes-duckduckgo-search
Version:
A powerful and comprehensive n8n community node that seamlessly integrates DuckDuckGo search capabilities into your workflows. Search the web, find images, discover news, and explore videos - all with privacy-focused, reliable results.
157 lines (156 loc) • 8.22 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = require("../errors");
const n8n_workflow_1 = require("n8n-workflow");
describe('DuckDuckGo Error Classes', () => {
describe('DuckDuckGoError', () => {
it('should create error with default values', () => {
const error = new errors_1.DuckDuckGoError('Test error');
expect(error.message).toBe('Test error');
expect(error.errorType).toBe(errors_1.DuckDuckGoErrorType.UNKNOWN_ERROR);
expect(error.severity).toBe(errors_1.ErrorSeverity.MEDIUM);
expect(error.isRetryable).toBe(false);
expect(error.userMessage).toBe('Test error');
});
it('should create error with custom values', () => {
const error = new errors_1.DuckDuckGoError('Network failed', errors_1.DuckDuckGoErrorType.NETWORK_ERROR, {
severity: errors_1.ErrorSeverity.HIGH,
isRetryable: true,
userMessage: 'Custom user message',
technicalDetails: { code: 'ECONNREFUSED' },
});
expect(error.errorType).toBe(errors_1.DuckDuckGoErrorType.NETWORK_ERROR);
expect(error.severity).toBe(errors_1.ErrorSeverity.HIGH);
expect(error.isRetryable).toBe(true);
expect(error.userMessage).toBe('Custom user message');
expect(error.technicalDetails).toEqual({ code: 'ECONNREFUSED' });
});
it('should determine retryability based on error type', () => {
const networkError = new errors_1.DuckDuckGoError('Error', errors_1.DuckDuckGoErrorType.NETWORK_ERROR);
const validationError = new errors_1.DuckDuckGoError('Error', errors_1.DuckDuckGoErrorType.INVALID_INPUT);
expect(networkError.isRetryable).toBe(true);
expect(validationError.isRetryable).toBe(false);
});
it('should generate appropriate user messages', () => {
const rateLimitError = new errors_1.DuckDuckGoError('Error', errors_1.DuckDuckGoErrorType.RATE_LIMIT_EXCEEDED);
const networkError = new errors_1.DuckDuckGoError('Error', errors_1.DuckDuckGoErrorType.NETWORK_ERROR);
expect(rateLimitError.userMessage).toContain('Too many requests');
expect(networkError.userMessage).toContain('Network connection failed');
});
it('should convert to NodeOperationError', () => {
const error = new errors_1.DuckDuckGoError('Test error', errors_1.DuckDuckGoErrorType.API_ERROR);
const mockNode = {
name: 'DuckDuckGo',
id: 'test-node-id',
typeVersion: 1,
type: 'n8n-nodes-duckduckgo.duckDuckGo',
position: [0, 0],
parameters: {}
};
const nodeError = error.toNodeOperationError(mockNode, 0);
expect(nodeError).toBeInstanceOf(n8n_workflow_1.NodeOperationError);
expect(nodeError.message).toBe('Test error');
expect(nodeError.errorType).toBe(errors_1.DuckDuckGoErrorType.API_ERROR);
});
});
describe('RateLimitError', () => {
it('should create rate limit error without retry information', () => {
const error = new errors_1.RateLimitError('Rate limit hit');
expect(error.errorType).toBe(errors_1.DuckDuckGoErrorType.RATE_LIMIT_EXCEEDED);
expect(error.isRetryable).toBe(true);
expect(error.userMessage).toBe('Too many requests. Please wait before making more requests.');
});
it('should handle missing retry after', () => {
const error = new errors_1.RateLimitError('Rate limit hit');
expect(error.userMessage).toBe('Too many requests. Please wait before making more requests.');
});
});
describe('NetworkError', () => {
it('should detect timeout errors', () => {
const timeoutError = new Error('Request timeout ETIMEDOUT');
const error = new errors_1.NetworkError('Network failed', timeoutError);
expect(error.errorType).toBe(errors_1.DuckDuckGoErrorType.TIMEOUT);
expect(error.isRetryable).toBe(true);
});
it('should detect connection refused errors', () => {
const connError = new Error('connect ECONNREFUSED');
const error = new errors_1.NetworkError('Network failed', connError);
expect(error.errorType).toBe(errors_1.DuckDuckGoErrorType.CONNECTION_REFUSED);
});
it('should detect DNS errors', () => {
const dnsError = new Error('getaddrinfo ENOTFOUND');
const error = new errors_1.NetworkError('Network failed', dnsError);
expect(error.errorType).toBe(errors_1.DuckDuckGoErrorType.DNS_ERROR);
});
});
describe('ValidationError', () => {
it('should create validation error with field information', () => {
const error = new errors_1.ValidationError('Invalid email format', {
field: 'email',
value: 'not-an-email',
validationRule: 'Must be a valid email address',
});
expect(error.errorType).toBe(errors_1.DuckDuckGoErrorType.INVALID_INPUT);
expect(error.isRetryable).toBe(false);
expect(error.field).toBe('email');
expect(error.userMessage).toContain('Invalid value for field "email"');
});
});
describe('APIError', () => {
it('should handle 429 status code as rate limit', () => {
const error = new errors_1.APIError('Too many requests', {
statusCode: 429,
responseBody: { error: 'rate_limited' },
});
expect(error.errorType).toBe(errors_1.DuckDuckGoErrorType.TOO_MANY_REQUESTS);
expect(error.isRetryable).toBe(true);
});
it('should handle 5xx errors as high severity', () => {
const error = new errors_1.APIError('Server error', {
statusCode: 503,
});
expect(error.severity).toBe(errors_1.ErrorSeverity.HIGH);
expect(error.isRetryable).toBe(true);
});
it('should handle 4xx errors as medium severity', () => {
const error = new errors_1.APIError('Bad request', {
statusCode: 400,
});
expect(error.severity).toBe(errors_1.ErrorSeverity.MEDIUM);
expect(error.isRetryable).toBe(false);
});
});
describe('handleDuckDuckGoError', () => {
const mockNode = {
name: 'DuckDuckGo',
id: 'test-node-id',
typeVersion: 1,
type: 'n8n-nodes-duckduckgo.duckDuckGo',
position: [0, 0],
parameters: {}
};
it('should pass through DuckDuckGoError', () => {
const duckError = new errors_1.DuckDuckGoError('Test', errors_1.DuckDuckGoErrorType.API_ERROR);
const result = (0, errors_1.handleDuckDuckGoError)(duckError, 'test operation', {
node: mockNode,
itemIndex: 0,
});
expect(result).toBeInstanceOf(n8n_workflow_1.NodeOperationError);
expect(result.errorType).toBe(errors_1.DuckDuckGoErrorType.API_ERROR);
});
it('should pass through NodeOperationError', () => {
const nodeError = new n8n_workflow_1.NodeOperationError(mockNode, 'Test error');
const result = (0, errors_1.handleDuckDuckGoError)(nodeError, 'test operation', {
node: mockNode,
});
expect(result).toBe(nodeError);
});
it('should handle validation errors', () => {
const error = new Error('validation failed: invalid input');
const result = (0, errors_1.handleDuckDuckGoError)(error, 'test operation', {
node: mockNode,
});
expect(result).toBeInstanceOf(n8n_workflow_1.NodeOperationError);
});
});
});