@axinom/mosaic-transactional-inbox-outbox
Version:
This library encapsulates the Mosaic based transactional inbox and outbox pattern
174 lines (153 loc) • 5.35 kB
text/typescript
/* eslint-disable no-console */
import 'jest-extended';
import { InboxOutboxLogger } from '../common';
import { TransactionalInboxMessageHandler } from './transactional-inbox-message-handler';
class TestTransactionalInboxMessageHandler extends TransactionalInboxMessageHandler<
any,
Record<string, unknown>,
any
> {
override handleMessage(): Promise<void> {
throw new Error('Method not implemented.');
}
}
describe('TransactionalInboxMessageHandler', () => {
const handler = new TestTransactionalInboxMessageHandler(
{} as any,
{} as any,
{} as any,
) as any; // To access protected method for testing
describe('updateErrorDetails', () => {
it('Update error details with empty message object -> returns original error', () => {
// Arrange
const originalError = new Error('Test Message');
const message = {} as any;
// Act
handler.updateErrorDetails(originalError, message);
// Assert
expect(originalError).toMatchObject({
message: 'Test Message',
stack: expect.toStartWith('Error: Test Message'),
});
expect((originalError as any).details).toBeUndefined();
});
it.each([undefined, null])(
'Update error details with %p routingKey -> returns original error',
(falsyKey) => {
// Arrange
const originalError = new Error('Test Message');
const message = {
metadata: { fields: { routingKey: falsyKey } },
} as any;
// Act
handler.updateErrorDetails(originalError, message);
// Assert
expect(originalError).toMatchObject({
message: 'Test Message',
stack: expect.toStartWith('Error: Test Message'),
});
expect((originalError as any).details).toBeUndefined();
},
);
it('Update error details with valid routingKey -> returns extended error', () => {
// Arrange
const tenantId = '00000000-0000-0000-0000-000000000001';
const environmentId = '00000000-0000-0000-0000-000000000002';
const originalError = new Error('Test Message');
const message = {
metadata: {
fields: {
routingKey: `ax-image-service.${tenantId}.${environmentId}.image_types.declare`,
},
},
} as any;
// Act
handler.updateErrorDetails(originalError, message);
// Assert
expect(originalError).toMatchObject({
message: 'Test Message',
stack: expect.toStartWith('Error: Test Message'),
details: {
tenantId,
environmentId,
},
});
});
it('Update error details with valid routingKey and existing details -> returns extended error preserving details', () => {
// Arrange
const tenantId = '00000000-0000-0000-0000-000000000001';
const environmentId = '00000000-0000-0000-0000-000000000002';
const originalError = new Error('Test Message') as Error & {
details?: Record<string, string>;
};
originalError.details = { custom: 'custom details property' };
const message = {
metadata: {
fields: {
routingKey: `ax-image-service.${tenantId}.${environmentId}.image_types.declare`,
},
},
} as any;
// Act
handler.updateErrorDetails(originalError, message);
// Assert
expect(originalError).toMatchObject({
message: 'Test Message',
stack: expect.toStartWith('Error: Test Message'),
details: {
tenantId,
environmentId,
custom: 'custom details property',
},
});
});
it('Update error details with empty routingKey and existing details -> returns original error preserving details', () => {
// Arrange
const originalError = new Error('Test Message') as Error & {
details?: Record<string, string>;
};
originalError.details = { custom: 'custom details property' };
const message = { metadata: { fields: {} } } as any;
// Act
handler.updateErrorDetails(originalError, message);
// Assert
expect(originalError).toMatchObject({
message: 'Test Message',
stack: expect.toStartWith('Error: Test Message'),
details: {
custom: 'custom details property',
},
});
});
it('Error in the pre-processor is caught and the handleErrorMessage is called with an undefined context', async () => {
// Arrange
const logger = {
warn: jest.fn(),
} as unknown as InboxOutboxLogger;
const preprocessorError = new Error('Preprocessor error');
const preprocessor = jest.fn(() => {
throw preprocessorError;
});
const handler = new TestTransactionalInboxMessageHandler(
{} as any,
logger,
{} as any,
preprocessor,
);
handler.handleErrorMessage = jest.fn();
// Act
await handler.handleError(
new Error('Message handling error'),
{} as any,
{} as any,
false,
);
// Assert
expect(logger.warn).toHaveBeenCalledWith(preprocessorError, {
message: 'The preprocessor in the inbox message error handler failed.',
details: {},
});
expect(handler.handleErrorMessage).toHaveBeenCalled();
});
});
});