@apistudio/apim-cli
Version:
CLI for API Management Products
149 lines (122 loc) • 4.04 kB
text/typescript
/**
* Copyright IBM Corp. 2024, 2025
*/
import { ZodError, z } from 'zod';
import { transformZodErrors } from '../../src/helpers/zod-error-formatter.helper.js';
describe('zod-error-formatter.helper', () => {
describe('transformZodErrors', () => {
it('should return the original error if it is not a ZodError', () => {
// Arrange
const originalError = new Error('Original error');
// Act
const result = transformZodErrors(originalError);
// Assert
expect(result).toBe(originalError);
});
it('should transform a ZodError with a single issue into a formatted Error', () => {
// Arrange
const schema = z.object({
name: z.string(),
});
let zodError: ZodError;
try {
schema.parse({ name: 123 });
} catch (error) {
zodError = error as ZodError;
// Act
const result = transformZodErrors(zodError);
// Assert
expect(result).toBeInstanceOf(Error);
expect(result.message).toContain(
`Validation error at name: Invalid input: expected string, received number`,
);
}
});
it('should transform a ZodError with multiple issues into a formatted Error', () => {
// Arrange
const schema = z.object({
name: z.string(),
age: z.number().positive(),
});
let zodError: ZodError;
try {
schema.parse({ name: 123, age: -5 });
} catch (error) {
zodError = error as ZodError;
// Act
const result = transformZodErrors(zodError);
// Assert
expect(result).toBeInstanceOf(Error);
expect(result.message).toContain(`Validation error at name:`);
expect(result.message).toContain(`Validation error at age:`);
}
});
it('should handle nested object validation errors', () => {
// Arrange
const schema = z.object({
user: z.object({
profile: z.object({
email: z.string().email(),
}),
}),
});
let zodError: ZodError;
try {
schema.parse({ user: { profile: { email: 'not-an-email' } } });
} catch (error) {
zodError = error as ZodError;
// Act
const result = transformZodErrors(zodError);
// Assert
expect(result).toBeInstanceOf(Error);
expect(result.message).toContain(
`Validation error at user.profile.email:`,
);
expect(result.message).toContain('Invalid email');
}
});
it('should handle array validation errors with proper indexing', () => {
// Arrange
const schema = z.object({
items: z.array(z.string()),
});
let zodError: ZodError;
try {
schema.parse({ items: ['valid', 123, 'also-valid'] });
} catch (error) {
zodError = error as ZodError;
// Act
const result = transformZodErrors(zodError);
// Assert
expect(result).toBeInstanceOf(Error);
expect(result.message).toContain(
`Validation error at items.[1]: Invalid input: expected string, received number`,
);
}
});
it('should handle errors without paths', () => {
// Arrange
// Create a mock ZodError with an issue that has no path
const mockIssue = {
message: 'Generic validation error',
path: [],
};
const mockZodError = new ZodError([mockIssue as any]);
// Act
const result = transformZodErrors(mockZodError);
// Assert
expect(result).toBeInstanceOf(Error);
expect(result.message).toBe('Generic validation error');
});
it('should handle empty issues array', () => {
// Arrange
// Create a mock ZodError with no issues
const mockZodError = new ZodError([]);
// Act
const result = transformZodErrors(mockZodError);
// Assert
expect(result).toBeInstanceOf(Error);
expect(result.message).toBe('Validation error occurred');
});
});
});