UNPKG

@appotter/nestjs-s3

Version:

NestJS provider to integrates with AWS S3

202 lines 7.76 kB
"use strict"; 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