forked from Shared/esg
Implement normalized error handling with Persian translations across all exception types, replace legacy NestJS exceptions with AppException, and add unit, integration, and smoke tests. - Add error catalog with gateway-owned codes and Persian messages - Introduce AppException wrapping normalized error envelopes - Add translateError helper for automatic messageFa population - Remove claims module and update provider error normalization - Add unit tests for error contracts and helper functions - Add integration tests for admin and inquiry endpoints - Add smoke tests for real provider connectivity - Add test support utilities (auth mocks, assertions, app factory)
95 lines
3.2 KiB
TypeScript
95 lines
3.2 KiB
TypeScript
import { HttpStatus } from '@nestjs/common';
|
|
import { AppException } from './app-exception';
|
|
import {
|
|
buildNormalizedError,
|
|
resolveProviderPublicMessage,
|
|
resolveErrorCodeFromMessage,
|
|
} from '../constants/error-messages';
|
|
import { translateError } from '../helpers/translate-error.helper';
|
|
|
|
describe('application error contract', () => {
|
|
it('builds normalized errors from stable catalog codes', () => {
|
|
const error = buildNormalizedError('INVALID_CREDENTIALS');
|
|
|
|
expect(error).toEqual({
|
|
code: 'INVALID_CREDENTIALS',
|
|
message: 'Invalid credentials',
|
|
messageFa: 'نام کاربری یا رمز عبور صحیح نیست',
|
|
providerMessage: undefined,
|
|
providerCode: undefined,
|
|
providerTrackingCode: undefined,
|
|
details: undefined,
|
|
conflict: undefined,
|
|
});
|
|
});
|
|
|
|
it('serializes AppException with the catalog status and normalized error', () => {
|
|
const exception = new AppException('RATE_LIMIT_EXCEEDED');
|
|
|
|
expect(exception.getStatus()).toBe(HttpStatus.TOO_MANY_REQUESTS);
|
|
expect(exception.normalizedError.code).toBe('RATE_LIMIT_EXCEEDED');
|
|
expect(exception.normalizedError.messageFa).toBe(
|
|
'تعداد درخواستهای مجاز کاربر به پایان رسیده است',
|
|
);
|
|
});
|
|
|
|
it('bridges known legacy English messages to catalog codes', () => {
|
|
expect(resolveErrorCodeFromMessage('Invalid credentials')).toBe('INVALID_CREDENTIALS');
|
|
expect(
|
|
translateError({
|
|
code: 'HTTP_ERROR',
|
|
message: 'Invalid credentials',
|
|
}),
|
|
).toMatchObject({
|
|
code: 'INVALID_CREDENTIALS',
|
|
messageFa: 'نام کاربری یا رمز عبور صحیح نیست',
|
|
});
|
|
});
|
|
|
|
it('keeps raw provider diagnostics separate from public provider messages', () => {
|
|
expect(
|
|
translateError({
|
|
code: 'PROVIDER_ERROR',
|
|
message: 'Invalid national code',
|
|
messageFa: 'کد ملی اشتباه است',
|
|
providerMessage: 'کد ملی اشتباه است',
|
|
providerCode: 'PROVIDER_ERROR',
|
|
providerTrackingCode: 'provider-tracking',
|
|
}),
|
|
).toEqual({
|
|
code: 'PROVIDER_ERROR',
|
|
message: 'Invalid national code',
|
|
messageFa: 'کد ملی اشتباه است',
|
|
providerMessage: 'کد ملی اشتباه است',
|
|
providerCode: 'PROVIDER_ERROR',
|
|
providerTrackingCode: 'provider-tracking',
|
|
details: undefined,
|
|
conflict: undefined,
|
|
});
|
|
});
|
|
|
|
it('maps known Persian provider text to stable public English and Persian messages', () => {
|
|
expect(resolveProviderPublicMessage('کد ملی اشتباه است')).toEqual({
|
|
message: 'Invalid national code',
|
|
messageFa: 'کد ملی اشتباه است',
|
|
});
|
|
});
|
|
|
|
it('uses the generic public message for unknown provider errors', () => {
|
|
expect(
|
|
translateError({
|
|
code: 'UNKNOWN_ERROR',
|
|
message: 'Unknown provider error',
|
|
providerMessage: 'No policy record found',
|
|
providerCode: 'POLICY_NOT_FOUND',
|
|
}),
|
|
).toMatchObject({
|
|
code: 'UNKNOWN_ERROR',
|
|
message: 'Unknown provider error',
|
|
messageFa: 'خطای ناشناخته در سرویسدهنده',
|
|
providerMessage: 'No policy record found',
|
|
providerCode: 'POLICY_NOT_FOUND',
|
|
});
|
|
});
|
|
});
|