error-response-utils.test.tsβ’10.6 kB
/**
* Unit tests for enhanced error response utilities
*/
import { describe, it, expect } from 'vitest';
import {
createFieldValidationError,
createSelectOptionError,
createMultiSelectOptionError,
createReadOnlyFieldError,
createUnknownFieldError,
createFieldTypeMismatchError,
createRequiredFieldError,
formatEnhancedErrorResponse,
createErrorResponse,
ValidationErrorCode,
} from '../../../src/utils/error-response-utils.js';
describe('error-response-utils', () => {
describe('createFieldValidationError', () => {
it('should create a field validation error with suggestions', () => {
const error = createFieldValidationError(
'name',
'companies',
'Field is required',
['Provide a name value', 'Name should not be empty']
);
expect(error.error).toContain(
"Field validation failed for 'name' in companies"
);
expect(error.error_code).toBe(ValidationErrorCode.FIELD_VALIDATION_ERROR);
expect(error.field).toBe('name');
expect(error.suggestions).toEqual([
'Provide a name value',
'Name should not be empty',
]);
expect(error.help_url).toBe(
'https://docs.attio.com/api-reference/companies'
);
expect(error.context).toEqual({
resource_type: 'companies',
field_name: 'name',
});
});
it('should create a field validation error without suggestions', () => {
const error = createFieldValidationError(
'email',
'people',
'Invalid email format'
);
expect(error.suggestions).toEqual([
'Use get-attributes to see valid fields for people',
]);
});
});
describe('createSelectOptionError', () => {
it('should create a select option error with valid options', () => {
const error = createSelectOptionError('company_type', 'invalid_option', [
'startup',
'enterprise',
'small_business',
'non_profit',
]);
expect(error.error).toContain(
"Invalid value 'invalid_option' for select field 'company_type'"
);
expect(error.error).toContain(
"Valid options are: ['startup', 'enterprise', 'small_business', 'non_profit']"
);
expect(error.error_code).toBe(ValidationErrorCode.INVALID_SELECT_OPTION);
expect(error.field).toBe('company_type');
expect(error.suggestions).toContain(
'Choose one of: startup, enterprise, small_business...'
);
expect(error.context).toEqual({
field_name: 'company_type',
provided_value: 'invalid_option',
valid_options: [
'startup',
'enterprise',
'small_business',
'non_profit',
],
});
});
it('should handle few options without truncation', () => {
const error = createSelectOptionError('status', 'invalid', [
'active',
'inactive',
]);
expect(error.suggestions[0]).toBe('Choose one of: active, inactive');
});
});
describe('createMultiSelectOptionError', () => {
it('should create a multi-select option error', () => {
const error = createMultiSelectOptionError(
'tags',
['invalid_tag1', 'invalid_tag2'],
['important', 'urgent', 'follow_up', 'completed', 'archived']
);
expect(error.error).toContain(
"Invalid values ['invalid_tag1', 'invalid_tag2'] for multi-select field 'tags'"
);
expect(error.error_code).toBe(
ValidationErrorCode.INVALID_MULTI_SELECT_OPTION
);
expect(error.field).toBe('tags');
expect(error.suggestions[0]).toContain(
'Valid options include: important, urgent, follow_up, completed, archived'
);
expect(error.context).toEqual({
field_name: 'tags',
invalid_values: ['invalid_tag1', 'invalid_tag2'],
valid_options: [
'important',
'urgent',
'follow_up',
'completed',
'archived',
],
});
});
});
describe('createReadOnlyFieldError', () => {
it('should create a read-only field error for single field', () => {
const error = createReadOnlyFieldError(['created_at'], 'companies');
expect(error.error).toContain(
"Cannot update read-only field 'created_at'"
);
expect(error.error).toContain(
'This field is automatically managed by the system'
);
expect(error.error_code).toBe(ValidationErrorCode.READ_ONLY_FIELD_UPDATE);
expect(error.field).toBe('created_at');
expect(error.suggestions).toContain(
'Remove this field from your update request'
);
expect(error.context).toEqual({
resource_type: 'companies',
read_only_fields: ['created_at'],
});
});
it('should create a read-only field error for multiple fields', () => {
const error = createReadOnlyFieldError(
['created_at', 'updated_at'],
'people'
);
expect(error.error).toContain(
"Cannot update read-only fields 'created_at', 'updated_at'"
);
expect(error.error).toContain(
'These fields are automatically managed by the system'
);
expect(error.field).toBeUndefined();
expect(error.suggestions).toContain(
'Remove these fields from your update request'
);
});
});
describe('createUnknownFieldError', () => {
it('should create an unknown field error with suggestions', () => {
const error = createUnknownFieldError(
'company_description',
'companies',
['description', 'notes']
);
expect(error.error).toContain(
"Unknown field 'company_description' for resource type 'companies'"
);
expect(error.error).toContain("Did you mean: 'description', 'notes'?");
expect(error.error_code).toBe(ValidationErrorCode.UNKNOWN_FIELD);
expect(error.field).toBe('company_description');
expect(error.suggestions).toContain('Try using: description');
expect(error.context).toEqual({
resource_type: 'companies',
invalid_field: 'company_description',
suggested_fields: ['description', 'notes'],
});
});
it('should create an unknown field error without suggestions', () => {
const error = createUnknownFieldError('invalid_field', 'people');
expect(error.error).not.toContain('Did you mean');
expect(error.suggestions).toEqual([
'Use get-attributes to see all available fields for people',
]);
});
});
describe('createFieldTypeMismatchError', () => {
it('should create a field type mismatch error', () => {
const error = createFieldTypeMismatchError(
'age',
'number',
'string',
'people'
);
expect(error.error).toContain(
"Field 'age' expects type 'number' but received 'string'"
);
expect(error.error_code).toBe(ValidationErrorCode.FIELD_TYPE_MISMATCH);
expect(error.field).toBe('age');
expect(error.suggestions).toContain('Convert the value to number format');
expect(error.context).toEqual({
resource_type: 'people',
field_name: 'age',
expected_type: 'number',
actual_type: 'string',
});
});
});
describe('createRequiredFieldError', () => {
it('should create a required field error for single field', () => {
const error = createRequiredFieldError(['name'], 'companies');
expect(error.error).toContain("Required field 'name' is missing");
expect(error.error_code).toBe(ValidationErrorCode.REQUIRED_FIELD_MISSING);
expect(error.field).toBe('name');
expect(error.suggestions).toContain(
'Add this required field to your request'
);
});
it('should create a required field error for multiple fields', () => {
const error = createRequiredFieldError(['name', 'email'], 'people');
expect(error.error).toContain(
"Required fields 'name', 'email' are missing"
);
expect(error.field).toBeUndefined();
expect(error.suggestions).toContain(
'Add these required fields to your request'
);
});
});
describe('formatEnhancedErrorResponse', () => {
it('should format an enhanced error response with all components', () => {
const errorResponse = createSelectOptionError('status', 'invalid', [
'active',
'inactive',
]);
const formatted = formatEnhancedErrorResponse(errorResponse);
expect(formatted.content[0].type).toBe('text');
expect(formatted.content[0].text).toContain(
"Invalid value 'invalid' for select field 'status'"
);
expect(formatted.content[0].text).toContain('π‘ Suggestions:');
expect(formatted.content[0].text).toContain(
'β’ Choose one of: active, inactive'
);
expect(formatted.content[0].text).toContain(
'β’ Use get-attributes to see all available options'
);
expect(formatted.isError).toBe(true);
expect(formatted.error.code).toBe(
ValidationErrorCode.INVALID_SELECT_OPTION
);
expect(formatted.error.field).toBe('status');
expect(formatted.error.suggestions).toEqual([
'Choose one of: active, inactive',
'Use get-attributes to see all available options',
]);
expect(formatted.error.context).toBeDefined();
});
it('should format an error response without suggestions', () => {
const errorResponse = {
error: 'Simple error message',
error_code: 'SIMPLE_ERROR',
};
const formatted = formatEnhancedErrorResponse(errorResponse);
expect(formatted.content[0].text).toBe('Simple error message');
expect(formatted.content[0].text).not.toContain('π‘ Suggestions:');
});
it('should include help URL when provided', () => {
const errorResponse = createUnknownFieldError('test_field', 'companies');
const formatted = formatEnhancedErrorResponse(errorResponse);
expect(formatted.content[0].text).toContain(
'π Documentation: https://docs.attio.com/api-reference/companies'
);
});
});
describe('createErrorResponse', () => {
it('should create a simple error response', () => {
const error = createErrorResponse('Something went wrong');
expect(error.content[0].type).toBe('text');
expect(error.content[0].text).toBe('Something went wrong');
expect(error.isError).toBe(true);
expect(error.error.message).toBe('Something went wrong');
});
});
});