@gp_jcisneros/aws-utils
Version:
AWS SDK utilities for GreenPay microservices
245 lines (203 loc) • 6.99 kB
JavaScript
const { S3Utils } = require('../src/S3Utils');
const { AWSError } = require('@gp_jcisneros/errors');
const { S3Client } = require('@aws-sdk/client-s3');
// Mock functions
const mockSend = jest.fn();
// Reset mocks before each test
beforeEach(() => {
jest.clearAllMocks();
// Setup default mock implementation
S3Client.mockImplementation(() => ({
send: mockSend,
destroy: jest.fn().mockResolvedValue(undefined),
}));
});
describe('S3Utils', () => {
describe('constructor', () => {
it('should create S3Utils instance', () => {
const s3Utils = new S3Utils();
expect(s3Utils).toBeInstanceOf(S3Utils);
expect(s3Utils.client).toBeDefined();
});
it('should create S3Utils instance with custom region', () => {
const s3Utils = new S3Utils('us-west-2');
expect(s3Utils).toBeInstanceOf(S3Utils);
});
});
describe('uploadFile', () => {
it('should upload file successfully', async () => {
const mockResponse = {
ETag: '"test-etag"',
VersionId: 'test-version',
};
mockSend.mockResolvedValue(mockResponse);
const s3Utils = new S3Utils();
const result = await s3Utils.uploadFile(
'test-bucket',
'test-key',
Buffer.from('test data')
);
expect(result).toEqual({
success: true,
etag: '"test-etag"',
location: 's3://test-bucket/test-key',
versionId: 'test-version',
});
expect(mockSend).toHaveBeenCalledTimes(1);
});
it('should handle upload error', async () => {
mockSend.mockRejectedValue(new Error('Upload failed'));
const s3Utils = new S3Utils();
await expect(
s3Utils.uploadFile('test-bucket', 'test-key', Buffer.from('test'))
).rejects.toThrow(AWSError);
});
});
describe('downloadFile', () => {
it('should download file successfully', async () => {
const mockBody = {
transformToString: jest.fn().mockResolvedValue('test data'),
};
const mockResponse = {
Body: mockBody,
ContentType: 'text/plain',
LastModified: new Date('2023-01-01'),
ETag: '"test-etag"',
};
mockSend.mockResolvedValue(mockResponse);
const s3Utils = new S3Utils();
const result = await s3Utils.downloadFile('test-bucket', 'test-key');
expect(result).toEqual({
data: 'test data',
contentType: 'text/plain',
lastModified: new Date('2023-01-01'),
etag: '"test-etag"',
});
});
it('should handle download error', async () => {
mockSend.mockRejectedValue(new Error('Download failed'));
const s3Utils = new S3Utils();
await expect(
s3Utils.downloadFile('test-bucket', 'test-key')
).rejects.toThrow(AWSError);
});
});
describe('deleteFile', () => {
it('should delete file successfully', async () => {
const mockResponse = {
VersionId: 'test-version',
DeleteMarker: false,
};
mockSend.mockResolvedValue(mockResponse);
const s3Utils = new S3Utils();
const result = await s3Utils.deleteFile('test-bucket', 'test-key');
expect(result).toEqual({
success: true,
versionId: 'test-version',
});
});
it('should handle delete error', async () => {
mockSend.mockRejectedValue(new Error('Delete failed'));
const s3Utils = new S3Utils();
await expect(
s3Utils.deleteFile('test-bucket', 'test-key')
).rejects.toThrow(AWSError);
});
});
describe('uploadJson', () => {
it('should upload JSON successfully', async () => {
const mockResponse = {
ETag: '"test-etag"',
VersionId: 'test-version',
};
mockSend.mockResolvedValue(mockResponse);
const s3Utils = new S3Utils();
const jsonData = { test: 'data' };
const result = await s3Utils.uploadJson(
'test-bucket',
'test-key.json',
jsonData
);
expect(result).toEqual({
success: true,
etag: '"test-etag"',
location: 's3://test-bucket/test-key.json',
versionId: 'test-version',
});
});
});
describe('downloadJson', () => {
it('should download JSON successfully', async () => {
const jsonData = { test: 'data' };
const mockBody = {
transformToString: jest
.fn()
.mockResolvedValue(JSON.stringify(jsonData)),
};
const mockResponse = {
Body: mockBody,
ContentType: 'application/json',
LastModified: new Date('2023-01-01'),
ETag: '"test-etag"',
};
mockSend.mockResolvedValue(mockResponse);
const s3Utils = new S3Utils();
const result = await s3Utils.downloadJson('test-bucket', 'test-key.json');
expect(result).toEqual(jsonData);
});
it('should handle invalid JSON', async () => {
const mockBody = {
transformToString: jest.fn().mockResolvedValue('invalid json'),
};
const mockResponse = {
Body: mockBody,
ContentType: 'application/json',
LastModified: new Date('2023-01-01'),
ETag: '"test-etag"',
};
mockSend.mockResolvedValue(mockResponse);
const s3Utils = new S3Utils();
await expect(
s3Utils.downloadJson('test-bucket', 'test-key.json')
).rejects.toThrow(SyntaxError);
});
});
describe('static methods', () => {
it('should have static uploadFile method', () => {
expect(typeof S3Utils.uploadFile).toBe('function');
});
it('should have static downloadFile method', () => {
expect(typeof S3Utils.downloadFile).toBe('function');
});
it('should have static deleteFile method', () => {
expect(typeof S3Utils.deleteFile).toBe('function');
});
it('should have static uploadJson method', () => {
expect(typeof S3Utils.uploadJson).toBe('function');
});
it('should have static downloadJson method', () => {
expect(typeof S3Utils.downloadJson).toBe('function');
});
});
describe('error handling', () => {
it('should create AWSError with correct properties', () => {
const error = new AWSError('Test error', 'S3', 'UPLOAD_ERROR');
expect(error).toBeInstanceOf(AWSError);
expect(error.message).toBe('Test error');
expect(error.service).toBe('S3');
expect(error.awsErrorCode).toBe('UPLOAD_ERROR');
expect(error.statusCode).toBe(500);
expect(error.errorCode).toBe('AWS_S3');
expect(error.description).toBe('Test error');
expect(error.integration).toBe('aws-service');
});
it('should re-throw custom errors', async () => {
const customError = new AWSError('Custom error', 'S3', 'TEST_ERROR');
mockSend.mockRejectedValue(customError);
const s3Utils = new S3Utils();
await expect(
s3Utils.uploadFile('test-bucket', 'test-key', Buffer.from('test'))
).rejects.toBe(customError);
});
});
});