@appotter/nestjs-s3
Version:
NestJS provider to integrates with AWS S3
202 lines • 7.76 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const dotenv_1 = __importDefault(require("dotenv"));
const config_1 = require("@nestjs/config");
const testing_1 = require("@nestjs/testing");
const constants_1 = require("./constants");
const s3_service_1 = require("./s3.service");
const client_s3_1 = require("@aws-sdk/client-s3");
const crypto_1 = require("crypto");
const aws_sdk_client_mock_1 = require("aws-sdk-client-mock");
const common_1 = require("@nestjs/common");
const stream_1 = require("stream");
const util_stream_1 = require("@smithy/util-stream");
const configService = new config_1.ConfigService(dotenv_1.default.config());
const fakeS3Client = (0, aws_sdk_client_mock_1.mockClient)(client_s3_1.S3Client);
const mockedFile = {
fieldname: 'file',
originalname: 'file.png',
encoding: '7bit',
mimetype: 'image/png',
buffer: Buffer.from('fake-file.png'),
size: 256,
};
describe('S3Service', () => {
let service;
let accessKeyId;
let secretAccessKey;
let region;
let bucket;
let endpoint;
beforeEach(async () => {
accessKeyId = configService.get('S3_ACCESS_KEY_ID');
secretAccessKey = configService.get('S3_SECRET_ACCESS_KEY');
region = configService.get('S3_REGION');
bucket = configService.get('S3_BUCKET');
endpoint = configService.get('S3_ENDPOINT');
fakeS3Client.reset();
common_1.Logger.error = jest.fn();
const module = await testing_1.Test.createTestingModule({
providers: [
s3_service_1.S3Service,
{
provide: constants_1.S3_CONFIGURATION,
useValue: {
accessKeyId,
secretAccessKey,
region,
bucket,
endpoint,
},
},
],
}).compile();
service = module.get(s3_service_1.S3Service);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
it('call getClient should be object', () => {
const client = service.getClient();
expect(client).toBeDefined();
expect(typeof client === 'object').toBeTruthy();
});
it('should be ok when put a file', async () => {
const { url, origin } = await service.put(mockedFile);
expect(url).toBeDefined();
expect(origin).toBeDefined();
expect(origin.Key).toBe(mockedFile.originalname);
});
it('should be ok when put a file with a path that has an extension', async () => {
const { url, origin } = await service.put(mockedFile, 'avatars/file.png');
expect(url).toBeDefined();
expect(origin).toBeDefined();
expect(origin.Key).toBe('avatars/file.png');
});
it('should be ok when put a file with a path that ending with slash', async () => {
const { url, origin } = await service.put(mockedFile, 'avatars/');
expect(url).toBeDefined();
expect(origin).toBeDefined();
expect(origin.Key).toBe('avatars/file.png');
});
it('should throws exception if cannot put a file', async () => {
fakeS3Client.on(client_s3_1.PutObjectCommand).rejects(new Error('cannot put a file'));
try {
await service.put(mockedFile);
}
catch (error) {
expect(error.message).toBe('cannot put a file');
}
expect(common_1.Logger.error).toHaveBeenCalled();
});
it('put a file as unique name', async () => {
const { url, origin } = await service.putAsUniqueName(mockedFile);
expect(url).toBeDefined();
expect(origin).toBeDefined();
expect(origin.Key).toBeDefined();
});
it('put a file as unique name with folder', async () => {
const { url, origin } = await service.putAsUniqueName(mockedFile, 'avatars');
expect(url).toBeDefined();
expect(origin).toBeDefined();
expect(origin.Key).toContain('avatars');
});
it('list all files', async () => {
fakeS3Client.on(client_s3_1.ListObjectsCommand).resolves({
Name: bucket,
Contents: [
{
Key: 'file1.png',
Size: 1024,
LastModified: new Date(),
},
{
Key: 'file2.jpg',
Size: 1024,
LastModified: new Date(),
},
],
});
const items = await service.lists();
expect(items.length).toBe(2);
expect(items[0].key).toBe('file1.png');
expect(items[1].key).toBe('file2.jpg');
});
it('should throws exception if cannot list all files', async () => {
fakeS3Client
.on(client_s3_1.ListObjectsCommand)
.rejects(new Error('cannot list all files'));
try {
await service.lists();
}
catch (error) {
expect(error.message).toBe('cannot list all files');
}
expect(common_1.Logger.error).toHaveBeenCalled();
});
it('get a file', async () => {
const stream = new stream_1.Readable();
stream.push('hello world');
stream.push(null);
const sdkStream = (0, util_stream_1.sdkStreamMixin)(stream);
fakeS3Client.on(client_s3_1.GetObjectCommand).resolves({
Body: sdkStream,
});
const { key, contentLength, contentType, body } = await service.get('fake.png');
expect(key).toBe('fake.png');
expect(contentLength).toBeDefined();
expect(contentType).toBeDefined();
expect(body).toBeInstanceOf(Buffer);
});
it('should throws exception if cannot get a file', async () => {
fakeS3Client.on(client_s3_1.GetObjectCommand).rejects(new Error('cannot get a file'));
try {
await service.get('fake.png');
}
catch (error) {
expect(error.message).toBe('cannot get a file');
}
expect(common_1.Logger.error).toHaveBeenCalled();
});
it('delete a file', async () => {
fakeS3Client.on(client_s3_1.DeleteObjectCommand).resolves({
DeleteMarker: true,
VersionId: (0, crypto_1.randomUUID)(),
});
const { status, origin } = await service.delete('fake.png');
expect(status).toBeDefined();
expect(status).toBeTruthy();
expect(origin).toBeDefined();
});
it('should throws exception if cannot delete a file', async () => {
fakeS3Client
.on(client_s3_1.DeleteObjectCommand)
.rejects(new Error('cannot delete a file'));
try {
await service.delete('fake.png');
}
catch (error) {
expect(error.message).toBe('cannot delete a file');
}
expect(common_1.Logger.error).toHaveBeenCalled();
});
it('signed url with 60 second', async () => {
const data = await service.signedUrl('fake.png', 60);
expect(data).toContain('X-Amz-Algorithm');
expect(data).toContain('X-Amz-Signature');
});
it('should throws exception if cannot signed url', async () => {
fakeS3Client.on(client_s3_1.GetObjectCommand).rejects(new Error('cannot signed url'));
try {
await service.signedUrl('fake.png', 60);
}
catch (error) {
console.log(error);
expect(error.message).toBe('cannot signed url');
}
});
});
//# sourceMappingURL=s3.service.spec.js.map
;