Files
web-core/tests/errors/createErrorResolver.test.ts
Beatrice Dellacà d7e144620e
All checks were successful
continuous-integration/drone/push Build is passing
add unit tests
2026-02-24 11:14:24 +01:00

144 lines
5.2 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { createErrorResolver } from '../../src/errors/createErrorResolver';
const CATALOG = {
AUTH_UNAUTHORIZED: 'Unauthorized access. Please sign in again.',
FORBIDDEN: 'You do not have permission to perform this action.',
USER_NOT_FOUND: 'User not found.',
INTERNAL_ERROR: 'Unexpected request error.',
REQUEST_FAILED: 'Request failed. Please try again.',
};
const resolver = createErrorResolver({
catalog: CATALOG,
fallbackCode: 'REQUEST_FAILED',
defaultContext: 'default',
contextOverrides: {
session: {
AUTH_UNAUTHORIZED: 'Session expired. Please sign in again.',
},
},
inferCodeFromStatus: (status?: number | null) => {
switch (status) {
case 401:
return 'AUTH_UNAUTHORIZED';
case 403:
return 'FORBIDDEN';
case 404:
return 'USER_NOT_FOUND';
default:
if (status != null && status >= 500) {
return 'INTERNAL_ERROR';
}
return undefined;
}
},
inferCodeFromLegacyMessage: (message?: string | null) => {
if (message?.toLowerCase() === 'unauthorized') {
return 'AUTH_UNAUTHORIZED';
}
return undefined;
},
});
describe('createErrorResolver', () => {
it('recognizes known error codes', () => {
expect(resolver.isKnownErrorCode('AUTH_UNAUTHORIZED')).toBe(true);
expect(resolver.isKnownErrorCode('NOPE')).toBe(false);
});
it('returns context override for known code', () => {
expect(
resolver.resolveErrorMessage({
code: 'AUTH_UNAUTHORIZED',
context: 'session',
}),
).toBe('Session expired. Please sign in again.');
});
it('falls back from unknown code to legacy message inference', () => {
expect(
resolver.resolveErrorMessage({
code: 'UNKNOWN_CODE',
fallbackMessage: 'unauthorized',
}),
).toBe('Unauthorized access. Please sign in again.');
});
it('falls back to status mapping when code is missing', () => {
expect(resolver.resolveErrorMessage({ status: 404 })).toBe('User not found.');
});
it('falls back to status mapping when legacy inference returns an unmapped code', () => {
const resolverWithUnmappedLegacyCode = createErrorResolver({
catalog: CATALOG,
inferCodeFromStatus: resolver.inferErrorCodeFromStatus,
inferCodeFromLegacyMessage: () => 'LEGACY_ONLY_CODE',
});
expect(
resolverWithUnmappedLegacyCode.resolveErrorMessage({
status: 403,
fallbackMessage: 'legacy message',
}),
).toBe('You do not have permission to perform this action.');
});
it('uses fallbackCode when no code/status resolve and fallback message is missing', () => {
expect(resolver.resolveErrorMessage({ status: 418 })).toBe('Request failed. Please try again.');
});
it('uses fallback message when no mapping exists and fallback code is unavailable', () => {
const noFallbackCodeResolver = createErrorResolver({
catalog: CATALOG,
inferCodeFromStatus: () => undefined,
});
expect(
noFallbackCodeResolver.resolveErrorMessage({
code: 'UNKNOWN',
fallbackMessage: 'raw backend message',
}),
).toBe('raw backend message');
});
it('returns default request failure message when no signal is available', () => {
const emptyResolver = createErrorResolver({
catalog: {},
});
expect(emptyResolver.resolveErrorMessage({})).toBe('Request failed. Please try again.');
});
it('resolveOptionalErrorMessage returns undefined for empty inputs', () => {
expect(resolver.resolveOptionalErrorMessage(undefined)).toBeUndefined();
expect(resolver.resolveOptionalErrorMessage(null)).toBeUndefined();
});
it('resolveOptionalErrorMessage resolves known codes', () => {
expect(resolver.resolveOptionalErrorMessage('FORBIDDEN')).toBe(
'You do not have permission to perform this action.',
);
});
it('toErrorMessage prefers rawMessage over message and handles unknown values', () => {
expect(
resolver.toErrorMessage({
status: 403,
rawMessage: 'unauthorized',
message: 'ignored message',
}),
).toBe('Unauthorized access. Please sign in again.');
expect(resolver.toErrorMessage('boom')).toBe('Request failed. Please try again.');
expect(resolver.toErrorMessage(null)).toBe('Request failed. Please try again.');
});
it('exposes inferErrorCodeFromStatus', () => {
expect(resolver.inferErrorCodeFromStatus(401)).toBe('AUTH_UNAUTHORIZED');
expect(resolver.inferErrorCodeFromStatus(500)).toBe('INTERNAL_ERROR');
expect(resolver.inferErrorCodeFromStatus(418)).toBeUndefined();
expect(resolver.inferErrorCodeFromStatus(null)).toBeUndefined();
});
});