mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-03-26 08:01:08 -04:00
* rename js files to ts * start migrating ajax * finish migrating ajax * migrate algolia-locale-setup * migrate format * migrate format.test * migrate get-words * install axios for types in handled-error * migrate handled-error * migrate handled-error.test * migrate report-error * migrate script-loaders * migrate to-learn-path * correct renamed imports * remove unnecessary type assertions in searchBar * remove unnecessary global comment * remove unnecessary max-len enable/disable * change axios imports to type imports * revert to .then() from await * use UserType from redux/prop-types * replace assertion with generic type * revert format to JS * remove unused getArticleById() * update putUpdateUserFlag() to use Record * remove unnecessary envData cast * update algolia-locale-setup types * remove invalid key property
152 lines
4.5 KiB
TypeScript
152 lines
4.5 KiB
TypeScript
import { isObject } from 'lodash-es';
|
|
import type { AxiosError } from 'axios';
|
|
|
|
import {
|
|
isHandledError,
|
|
wrapHandledError,
|
|
unwrapHandledError,
|
|
handledErrorSymbol,
|
|
handleAPIError
|
|
} from './handled-error';
|
|
import type { HandledError } from './handled-error';
|
|
|
|
import reportedErrorMessage from './reported-error-message';
|
|
|
|
describe('client/src utilities', () => {
|
|
describe('handled-error.js', () => {
|
|
const mockHandledErrorData = {
|
|
type: 'info',
|
|
message: 'something helpful',
|
|
redirectTo: '/a-path-we-choose'
|
|
};
|
|
|
|
describe('isHandledError', () => {
|
|
it('returns a boolean', () => {
|
|
expect(typeof isHandledError({} as Error)).toEqual('boolean');
|
|
});
|
|
|
|
it('returns false for an unhandled error', () => {
|
|
expect(isHandledError(new Error())).toEqual(false);
|
|
});
|
|
|
|
it('returns true for a handled error', () => {
|
|
const handledError = new Error() as HandledError;
|
|
handledError[handledErrorSymbol] = {};
|
|
|
|
expect(isHandledError(handledError)).toEqual(true);
|
|
});
|
|
});
|
|
|
|
describe('wrapHandledError', () => {
|
|
// this is testing implementation details 👎
|
|
// we need to make these tests more robust 💪
|
|
it('returns an error with a handledError property', () => {
|
|
const handledError = wrapHandledError(
|
|
new Error() as HandledError,
|
|
mockHandledErrorData
|
|
);
|
|
expect(handledErrorSymbol in handledError).toEqual(true);
|
|
});
|
|
it('assigns error handling details to the handledError property', () => {
|
|
const handledError = wrapHandledError(
|
|
new Error() as HandledError,
|
|
mockHandledErrorData
|
|
);
|
|
expect(handledError[handledErrorSymbol]).toEqual(mockHandledErrorData);
|
|
});
|
|
});
|
|
|
|
describe('unwrapHandledError', () => {
|
|
// this is testing implementation details 👎
|
|
// we need to make these tests more robust 💪
|
|
it('returns an object by default', () => {
|
|
const error = new Error() as HandledError;
|
|
const unwrappedError = unwrapHandledError(error);
|
|
expect(isObject(unwrappedError)).toBe(true);
|
|
});
|
|
|
|
it('returns the data that was wrapped in the error', () => {
|
|
const handledError = new Error() as HandledError;
|
|
handledError[handledErrorSymbol] = mockHandledErrorData;
|
|
const unwrapped = unwrapHandledError(handledError);
|
|
expect(unwrapped).toEqual(mockHandledErrorData);
|
|
});
|
|
});
|
|
|
|
describe('handleAPIError', () => {
|
|
let reportMock: () => void;
|
|
beforeEach(() => {
|
|
reportMock = jest.fn();
|
|
});
|
|
|
|
it('returns handled error data', () => {
|
|
expect.assertions(3);
|
|
const axiosErrorMock = {
|
|
response: {
|
|
status: 400
|
|
}
|
|
} as AxiosError;
|
|
const result = handleAPIError(
|
|
axiosErrorMock,
|
|
{ redirectTo: '/' },
|
|
reportMock
|
|
);
|
|
expect(result).toHaveProperty('type');
|
|
expect(result).toHaveProperty('message');
|
|
expect(result).toHaveProperty('redirectTo');
|
|
});
|
|
|
|
it('does not report 4** errors', () => {
|
|
expect.assertions(1);
|
|
for (let i = 400; i < 500; i++) {
|
|
const axiosErrorMock = {
|
|
response: {
|
|
status: i
|
|
}
|
|
} as AxiosError;
|
|
handleAPIError(axiosErrorMock, { redirectTo: '/' }, reportMock);
|
|
}
|
|
expect(reportMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('reports on 5** errors', () => {
|
|
const axiosErrorMock = {
|
|
response: {
|
|
status: 502
|
|
}
|
|
} as AxiosError;
|
|
handleAPIError(axiosErrorMock, { redirectTo: '/' }, reportMock);
|
|
expect(reportMock).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('returns a `reportedErrorMessage` for a 5** error', () => {
|
|
const axiosErrorMock = {
|
|
response: {
|
|
status: 502
|
|
}
|
|
} as AxiosError;
|
|
const result = handleAPIError(
|
|
axiosErrorMock,
|
|
{ redirectTo: '/' },
|
|
reportMock
|
|
);
|
|
expect(result).toEqual({ ...reportedErrorMessage, redirectTo: '/' });
|
|
});
|
|
|
|
it('respects a `null` redirectTo', () => {
|
|
const axiosErrorMock = {
|
|
response: {
|
|
status: 400
|
|
}
|
|
} as AxiosError;
|
|
const result = handleAPIError(
|
|
axiosErrorMock,
|
|
{ redirectTo: null },
|
|
reportMock
|
|
);
|
|
expect(result.redirectTo).toBe(null);
|
|
});
|
|
});
|
|
});
|
|
});
|