@appello/services
Version:
Services package with api / graphql
229 lines (228 loc) • 9.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const consts_1 = require("../../consts");
const handleApiRequestError_1 = require("./handleApiRequestError");
const createMockAxiosError = (status, data, isNetworkError = false) => {
const error = new Error('Mock axios error');
error.isAxiosError = true;
error.name = 'AxiosError';
error.code = status ? status.toString() : undefined;
if (isNetworkError) {
error.request = { status: 0 };
error.response = undefined;
}
else if (status) {
error.response = {
status,
data,
statusText: 'Error',
headers: {},
config: {},
};
}
return error;
};
describe('handleApiRequestError', () => {
describe('Non-Axios errors', () => {
it('should return unknown error for non-Axios error', () => {
const regularError = new Error('Regular error');
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: regularError,
});
expect(result).toEqual({
[consts_1.ApiErrorCodeEnum.GLOBAL_ERROR]: consts_1.ApiErrorMessagesEnum.UNKNOWN_ERROR,
});
});
});
describe('Manual error handling', () => {
it('should use onManualHandleError when provided', () => {
const mockError = createMockAxiosError(400, { detail: { field: 'error' } });
const customErrors = { customField: 'Custom error message' };
const onManualHandleError = jest.fn().mockReturnValue(customErrors);
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: mockError,
onManualHandleError,
});
expect(onManualHandleError).toHaveBeenCalledWith(mockError);
expect(result).toEqual(customErrors);
});
});
describe('Network errors', () => {
it('should return network error for status 0', () => {
const networkError = createMockAxiosError(undefined, undefined, true);
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: networkError,
});
expect(result).toEqual({
[consts_1.ApiErrorCodeEnum.GLOBAL_ERROR]: consts_1.ApiErrorMessagesEnum.NETWORK_ERROR,
});
});
});
describe('Server response errors', () => {
it('should return server error when response has no detail field', () => {
const mockError = createMockAxiosError(500, { message: 'Internal server error' });
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: mockError,
});
expect(result).toEqual({
[consts_1.ApiErrorCodeEnum.GLOBAL_ERROR]: consts_1.ApiErrorMessagesEnum.SERVER_ERROR,
});
});
it('should return server error when response data is null', () => {
const mockError = createMockAxiosError(500, null);
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: mockError,
});
expect(result).toEqual({
[consts_1.ApiErrorCodeEnum.GLOBAL_ERROR]: consts_1.ApiErrorMessagesEnum.SERVER_ERROR,
});
});
it('should use handleDetailError when provided', () => {
const mockError = createMockAxiosError(400, {
detail: { field1: 'Error 1', field2: 'Error 2' },
});
const customErrors = { customField: 'Custom processed error' };
const handleDetailError = jest.fn().mockReturnValue(customErrors);
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: mockError,
handleDetailError,
});
expect(handleDetailError).toHaveBeenCalledWith({
field1: 'Error 1',
field2: 'Error 2',
});
expect(result).toEqual(customErrors);
});
it('should process flat field errors correctly', () => {
const mockError = createMockAxiosError(400, {
detail: {
username: 'Username is required',
email: 'Invalid email format',
password: 'Password is too short',
},
});
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: mockError,
});
expect(result).toEqual({
username: 'Username is required',
email: 'Invalid email format',
password: 'Password is too short',
});
});
it('should process nested field errors correctly', () => {
const mockError = createMockAxiosError(400, {
detail: {
user: {
name: 'Name is required',
email: 'Email is invalid',
},
address: {
street: 'Street is required',
city: 'City is required',
},
},
});
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: mockError,
});
expect(result).toEqual({
'user.name': 'Name is required',
'user.email': 'Email is invalid',
'address.street': 'Street is required',
'address.city': 'City is required',
});
});
it('should handle array error messages by taking the first one', () => {
const mockError = createMockAxiosError(400, {
detail: {
username: ['Username is required', 'Username must be unique'],
email: 'Email is invalid',
},
});
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: mockError,
});
expect(result).toEqual({
username: 'Username is required',
email: 'Email is invalid',
});
});
it('should handle mixed flat and nested errors', () => {
const mockError = createMockAxiosError(400, {
detail: {
username: 'Username is required',
profile: {
firstName: 'First name is required',
lastName: ['Last name is required', 'Last name is too long'],
},
settings: {
theme: 'Invalid theme',
},
},
});
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: mockError,
});
expect(result).toEqual({
username: 'Username is required',
'profile.firstName': 'First name is required',
'profile.lastName': 'Last name is required',
'settings.theme': 'Invalid theme',
});
});
});
describe('Unauthorized errors', () => {
it('should return unknown error for 401 status', () => {
const mockError = createMockAxiosError(consts_1.ApiErrorStatusEnum.UNAUTHORIZED, {
detail: { field: 'error' },
});
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: mockError,
});
expect(result).toEqual({
[consts_1.ApiErrorCodeEnum.GLOBAL_ERROR]: consts_1.ApiErrorMessagesEnum.UNKNOWN_ERROR,
});
});
});
describe('Edge cases', () => {
it('should handle empty detail object', () => {
const mockError = createMockAxiosError(400, { detail: {} });
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: mockError,
});
expect(result).toEqual({});
});
it('should handle error without response', () => {
const error = new Error('Network error');
error.isAxiosError = true;
error.request = { status: 500 };
error.response = undefined;
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error,
});
expect(result).toEqual({
[consts_1.ApiErrorCodeEnum.GLOBAL_ERROR]: consts_1.ApiErrorMessagesEnum.UNKNOWN_ERROR,
});
});
it('should handle deeply nested objects in detail', () => {
const mockError = createMockAxiosError(400, {
detail: {
level1: {
level2: {
level3: 'Deep error message',
},
},
},
});
const result = (0, handleApiRequestError_1.handleApiRequestError)({
error: mockError,
});
expect(result).toEqual({
'level1.level2': {
level3: 'Deep error message',
},
});
});
});
});