@gp_jcisneros/aws-utils
Version:
AWS SDK utilities for GreenPay microservices
349 lines (294 loc) • 10.1 kB
JavaScript
const { SQSUtils } = require('../src/SQSUtils');
const { IntegrationError } = require('@gp_jcisneros/errors');
const { SQSClient } = require('@aws-sdk/client-sqs');
// Mock functions
const mockSend = jest.fn();
// Reset mocks before each test
beforeEach(() => {
jest.clearAllMocks();
// Setup default mock implementation
SQSClient.mockImplementation(() => ({
send: mockSend,
destroy: jest.fn().mockResolvedValue(undefined),
}));
});
describe('SQSUtils', () => {
describe('constructor', () => {
it('should create SQSUtils instance', () => {
const sqsUtils = new SQSUtils();
expect(sqsUtils).toBeInstanceOf(SQSUtils);
expect(sqsUtils.client).toBeDefined();
});
it('should create SQSUtils instance with custom region', () => {
const sqsUtils = new SQSUtils('us-west-2');
expect(sqsUtils).toBeInstanceOf(SQSUtils);
});
});
describe('sendMessage', () => {
it('should send message successfully', async () => {
const mockResponse = {
MessageId: 'test-message-id',
MD5OfMessageBody: 'test-md5',
SequenceNumber: '123',
};
mockSend.mockResolvedValue(mockResponse);
const sqsUtils = new SQSUtils();
const result = await sqsUtils.sendMessage(
'https://sqs.test.com/queue',
'test message'
);
expect(result).toEqual({
success: true,
messageId: 'test-message-id',
md5OfMessageBody: 'test-md5',
sequenceNumber: '123',
});
expect(mockSend).toHaveBeenCalledTimes(1);
});
it('should handle send error', async () => {
mockSend.mockRejectedValue(new Error('Send failed'));
const sqsUtils = new SQSUtils();
await expect(
sqsUtils.sendMessage('https://sqs.test.com/queue', 'test message')
).rejects.toThrow(IntegrationError);
});
it('should send message without FIFO parameters when not provided', async () => {
const mockResponse = {
MessageId: 'test-message-id',
MD5OfMessageBody: 'test-md5',
};
mockSend.mockResolvedValue(mockResponse);
const sqsUtils = new SQSUtils();
const result = await sqsUtils.sendMessage(
'https://sqs.test.com/queue',
'test message',
{ messageAttributes: { test: { StringValue: 'value' } } }
);
expect(result).toEqual({
success: true,
messageId: 'test-message-id',
md5OfMessageBody: 'test-md5',
sequenceNumber: undefined,
});
// Verificar que se llamó al menos una vez
expect(mockSend).toHaveBeenCalledTimes(1);
});
it('should send message with FIFO parameters when provided', async () => {
const mockResponse = {
MessageId: 'test-message-id',
MD5OfMessageBody: 'test-md5',
SequenceNumber: '123',
};
mockSend.mockResolvedValue(mockResponse);
const sqsUtils = new SQSUtils();
const result = await sqsUtils.sendMessage(
'https://sqs.test.com/queue.fifo',
'test message',
{
messageGroupId: 'test-group',
messageDeduplicationId: 'test-dedup'
}
);
expect(result).toEqual({
success: true,
messageId: 'test-message-id',
md5OfMessageBody: 'test-md5',
sequenceNumber: '123',
});
// Verificar que se llamó al menos una vez
expect(mockSend).toHaveBeenCalledTimes(1);
});
});
describe('receiveMessages', () => {
it('should receive messages successfully', async () => {
const mockMessages = [
{
MessageId: 'msg-1',
Body: 'test message 1',
ReceiptHandle: 'receipt-1',
},
{
MessageId: 'msg-2',
Body: 'test message 2',
ReceiptHandle: 'receipt-2',
},
];
const mockResponse = {
Messages: mockMessages,
};
mockSend.mockResolvedValue(mockResponse);
const sqsUtils = new SQSUtils();
const result = await sqsUtils.receiveMessages(
'https://sqs.test.com/queue'
);
expect(result).toEqual(mockMessages);
});
it('should return empty array when no messages', async () => {
mockSend.mockResolvedValue({});
const sqsUtils = new SQSUtils();
const result = await sqsUtils.receiveMessages(
'https://sqs.test.com/queue'
);
expect(result).toEqual([]);
});
it('should handle receive error', async () => {
mockSend.mockRejectedValue(new Error('Receive failed'));
const sqsUtils = new SQSUtils();
await expect(
sqsUtils.receiveMessages('https://sqs.test.com/queue')
).rejects.toThrow(IntegrationError);
});
});
describe('deleteMessage', () => {
it('should delete message successfully', async () => {
mockSend.mockResolvedValue({});
const sqsUtils = new SQSUtils();
const result = await sqsUtils.deleteMessage(
'https://sqs.test.com/queue',
'test-receipt'
);
expect(result).toEqual({ success: true });
});
it('should handle delete error', async () => {
mockSend.mockRejectedValue(new Error('Delete failed'));
const sqsUtils = new SQSUtils();
await expect(
sqsUtils.deleteMessage('https://sqs.test.com/queue', 'test-receipt')
).rejects.toThrow(IntegrationError);
});
});
describe('sendJsonMessage', () => {
it('should send JSON message successfully', async () => {
const mockResponse = {
MessageId: 'test-message-id',
MD5OfMessageBody: 'test-md5',
SequenceNumber: '123',
};
mockSend.mockResolvedValue(mockResponse);
const sqsUtils = new SQSUtils();
const jsonData = { test: 'data' };
const result = await sqsUtils.sendJsonMessage(
'https://sqs.test.com/queue',
jsonData
);
expect(result).toEqual({
success: true,
messageId: 'test-message-id',
md5OfMessageBody: 'test-md5',
sequenceNumber: '123',
});
});
});
describe('processMessages', () => {
it('should process messages successfully', async () => {
const mockMessages = [
{
MessageId: 'msg-1',
Body: 'test message',
ReceiptHandle: 'receipt-1',
},
];
mockSend
.mockResolvedValueOnce({ Messages: mockMessages }) // receiveMessages
.mockResolvedValueOnce({}); // deleteMessage
const processor = jest.fn().mockResolvedValue(true);
const sqsUtils = new SQSUtils();
const result = await sqsUtils.processMessages(
'https://sqs.test.com/queue',
processor
);
expect(result).toEqual({
processed: 1,
successful: 1,
failed: 0,
results: [
{
success: true,
messageId: 'msg-1',
result: true,
},
],
});
expect(processor).toHaveBeenCalledWith(mockMessages[0]);
expect(mockSend).toHaveBeenCalledTimes(2); // receive + delete
});
it('should handle processor errors', async () => {
const mockMessages = [
{
MessageId: 'msg-1',
Body: 'test message',
ReceiptHandle: 'receipt-1',
},
];
mockSend.mockResolvedValue({ Messages: mockMessages });
const processor = jest
.fn()
.mockRejectedValue(new Error('Processing failed'));
const sqsUtils = new SQSUtils();
const result = await sqsUtils.processMessages(
'https://sqs.test.com/queue',
processor
);
expect(result).toEqual({
processed: 1,
successful: 0,
failed: 1,
results: [
{
success: false,
messageId: 'msg-1',
error: 'Processing failed',
},
],
});
});
});
describe('static methods', () => {
it('should have static sendMessage method', () => {
expect(typeof SQSUtils.sendMessage).toBe('function');
});
it('should have static receiveMessages method', () => {
expect(typeof SQSUtils.receiveMessages).toBe('function');
});
it('should have static deleteMessage method', () => {
expect(typeof SQSUtils.deleteMessage).toBe('function');
});
it('should have static sendJsonMessage method', () => {
expect(typeof SQSUtils.sendJsonMessage).toBe('function');
});
it('should have static processMessages method', () => {
expect(typeof SQSUtils.processMessages).toBe('function');
});
});
describe('error handling', () => {
it('should create IntegrationError with correct properties', () => {
const error = new IntegrationError(
'Test error',
'SQS_SEND_ERROR',
'sqs',
{ queueUrl: 'test' }
);
expect(error).toBeInstanceOf(IntegrationError);
expect(error.message).toBe('Test error');
expect(error.integrationCode).toBe('SQS_SEND_ERROR');
expect(error.integrationName).toBe('sqs');
expect(error.statusCode).toBe(502);
expect(error.errorCode).toBe('SQS_SEND_ERROR');
expect(error.description).toBe('Test error');
expect(error.integration).toBe('sqs');
expect(error.context).toEqual({ queueUrl: 'test' });
});
it('should re-throw custom errors', async () => {
const customError = new IntegrationError(
'Custom error',
'SQS_TEST_ERROR',
'sqs'
);
mockSend.mockRejectedValue(customError);
const sqsUtils = new SQSUtils();
await expect(
sqsUtils.sendMessage('https://sqs.test.com/queue', 'test')
).rejects.toBe(customError);
});
});
});