filestack-js
Version:
Official JavaScript library for Filestack
976 lines (975 loc) • 154 kB
JavaScript
"use strict";
/*
* Copyright (c) 2019 by Filestack.
* Some rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var s3_1 = require("./s3");
var file_1 = require("./../file");
var nock_1 = tslib_1.__importDefault(require("nock"));
var abstract_1 = require("./abstract");
var utils = tslib_1.__importStar(require("../../../utils/index.node"));
var testBufferSize = 1024 * 1024 * 9;
var testSmallBufferSize = 1024 * 1024 * 2;
var testBuff = Buffer.alloc(testBufferSize).fill('t', 0, testBufferSize);
var smallTestBuff = Buffer.alloc(testSmallBufferSize).fill('t', 0, testSmallBufferSize);
var scope;
var interceptorS3;
var interceptorStart;
var interceptorCommit;
var interceptorUpload;
var interceptorComplete;
var getTestFile = function () {
return new file_1.File({
slice: function (start, end) { return Promise.resolve(testBuff.slice(start, end)); },
type: 'text/plain',
// @ts-ignore
size: testBuff.length,
name: 'test.txt',
});
};
var getSmallTestFile = function () {
return new file_1.File({
slice: function (start, end) { return Promise.resolve(testBuff.slice(start, end)); },
type: 'text/plain',
// @ts-ignore
size: smallTestBuff.length,
name: 'test.txt',
});
};
var getNullSizeFile = function () {
return new file_1.File({
slice: function (start, end) { return Promise.resolve(testBuff.slice(start, end)); },
type: 'text/plain',
// @ts-ignore
size: 0,
name: 'test.txt',
});
};
var testApikey = 'testapikey';
var testHost = 'https://filestack-test.com';
var mockUploadId = '123132123';
var mockRegion = 'test-region';
var mockedUri = '/sometest';
var s3Url = testHost + '/fakes3';
var mockStart = jest.fn().mockName('multipart/start');
var mockUpload = jest.fn().mockName('multipart/upload');
var mockPut = jest.fn().mockName('s3/put');
var mockCommit = jest.fn().mockName('multipart/commit');
var mockComplete = jest.fn().mockName('multipart/complete');
var s3Callback = function (url) {
return mockPut(url, this.req.headers);
};
describe('Api/Upload/Uploaders/S3', function () {
beforeEach(function () {
scope = (0, nock_1.default)(testHost);
// scope.defaultReplyHeaders({ 'access-control-allow-origin': '*', 'content-type': 'application/json' });
scope.persist();
interceptorStart = scope.post('/multipart/start');
interceptorUpload = scope.post('/multipart/upload');
interceptorCommit = scope.post('/multipart/commit');
interceptorComplete = scope.post('/multipart/complete');
interceptorS3 = scope.put('/fakes3');
interceptorStart.reply(200, function (_, data) { return mockStart(data); });
interceptorUpload.twice().reply(200, function (_, data) { return mockUpload(data); });
interceptorCommit.reply(200, function (_, data) { return mockCommit(data); });
interceptorComplete.reply(200, function (_, data) { return mockComplete(data); });
interceptorS3.twice().reply(201, s3Callback, { etag: 'test' });
mockStart.mockReturnValue({
uri: mockedUri,
region: mockRegion,
upload_id: mockUploadId,
location_url: testHost,
});
mockUpload.mockReturnValue({
url: s3Url,
headers: {
test: 'test',
},
location_url: testHost,
});
mockPut.mockReturnValue({});
mockCommit.mockReturnValue({});
mockComplete.mockReturnValue({
handle: 'test_handle',
url: 'test_url',
filename: 'test_filename',
size: 123,
mimetype: 'test_mimetype',
status: 'test_status',
upload_tags: { test: 123 },
});
});
afterEach(function () {
nock_1.default.cleanAll();
nock_1.default.enableNetConnect();
jest.clearAllMocks();
});
describe('Standart tests', function () {
it('should initialize class without errors', function () {
expect(function () {
var u = new s3_1.S3Uploader({});
var uu = new s3_1.S3Uploader({}, 10);
}).not.toThrowError();
});
it('should allow adding files', function () {
var u = new s3_1.S3Uploader({});
u.addFile(getTestFile());
});
it('should not allow to set min part size lower than defined', function () {
var u = new s3_1.S3Uploader({});
expect(function () { return u.setPartSize(10); }).toThrowError();
});
it('should throw an error when setting to small intelligent chunk size', function () {
var u = new s3_1.S3Uploader({});
expect(function () { return u.setIntelligentChunkSize(10); }).toThrowError();
});
it('should throw an error when trying to get host when it is undefined', function () {
var u = new s3_1.S3Uploader({});
expect(function () { return u.getUrl(); }).toThrowError();
});
it('should set intelligent mobile chunk size on mobile devices', function () {
jest.spyOn(utils, 'isMobile').mockReturnValue(true);
var u = new s3_1.S3Uploader({});
return expect(u.getIntelligentChunkSize()).toEqual(abstract_1.INTELLIGENT_MOBILE_CHUNK_SIZE);
});
it('should allow to set part size on other mode thant regular', function () {
var u = new s3_1.S3Uploader({});
u.setUploadMode("intelligent" /* UploadMode.INTELLIGENT */);
var partSize = 1024 * 1024;
u.setPartSize(partSize);
expect(u.getPartSize()).toEqual(abstract_1.DEFAULT_PART_SIZE);
});
it('should retry complete request on 202 status code', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var mock202, u, res;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
mock202 = jest
.fn()
.mockName('202 mock')
.mockReturnValue('');
nock_1.default.removeInterceptor(interceptorComplete);
scope.persist(false);
scope.post('/multipart/complete').reply(202, function () { return mock202(); });
scope.post('/multipart/complete').reply(200, function (_, data) { return mockComplete(data); });
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].handle).toEqual('test_handle');
expect(res[0].status).toEqual('test_status');
expect(mock202).toHaveBeenCalledTimes(1);
expect(mockComplete).toHaveBeenCalledTimes(1);
return [2 /*return*/];
}
});
}); });
it('should respect provided store options', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var storeOption, u;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
storeOption = {
container: 'test',
location: abstract_1.DEFAULT_STORE_LOCATION,
workflows: [{
id: 'test',
}],
};
u = new s3_1.S3Uploader(storeOption);
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
_a.sent();
expect(mockStart).toHaveBeenCalledWith(expect.objectContaining({ store: storeOption }));
expect(mockComplete).toHaveBeenCalledWith(expect.objectContaining({ store: storeOption }));
return [2 /*return*/];
}
});
}); });
it('should add https protocol to location_url', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, res;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
mockStart.mockReturnValue({
uri: mockedUri,
region: mockRegion,
upload_id: mockUploadId,
location_url: testHost.replace('https://', ''),
});
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].handle).toEqual('test_handle');
expect(res[0].status).toEqual('test_status');
expect(mockPut).toHaveBeenCalled();
return [2 /*return*/];
}
});
}); });
it('should throw error on file size 0', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, res;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
mockStart.mockReturnValue({
uri: mockedUri,
region: mockRegion,
upload_id: mockUploadId,
location_url: testHost.replace('https://', ''),
});
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getNullSizeFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].status).toEqual('Failed');
expect(mockStart).not.toHaveBeenCalled();
return [2 /*return*/];
}
});
}); });
it('should throw error on wrong etag field', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
mockStart.mockReturnValue({
uri: mockedUri,
region: mockRegion,
upload_id: mockUploadId,
location_url: testHost.replace('https://', ''),
});
interceptorS3.once().reply(200, s3Callback, {});
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getSmallTestFile());
u.on('error', function (err) {
expect(err.message).toEqual('Cannot upload file, check S3 bucket settings');
});
return [4 /*yield*/, u.execute()];
case 1:
_a.sent();
return [2 /*return*/];
}
});
}); });
it('should add Filestack-Upload-Region header on location_region param', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, res, testFile, firstPartMetadata, firstPartChunk;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
mockStart.mockReturnValue({
uri: mockedUri,
region: mockRegion,
upload_id: mockUploadId,
location_region: 'test',
location_url: testHost.replace('https://', ''),
});
interceptorUpload.reply(200, function (_, data) {
return mockUpload(data, this.req.headers);
});
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].handle).toEqual('test_handle');
expect(res[0].status).toEqual('test_status');
testFile = getSmallTestFile();
firstPartMetadata = testFile.getPartMetadata(0, abstract_1.DEFAULT_PART_SIZE);
return [4 /*yield*/, testFile.getPartByMetadata(firstPartMetadata)];
case 2:
firstPartChunk = _a.sent();
expect(mockUpload).toHaveBeenCalledWith({
md5: firstPartChunk.md5,
size: testFile.size,
apikey: testApikey,
region: mockRegion,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
uri: mockedUri,
upload_id: mockUploadId,
part: 1,
}, expect.objectContaining({ 'filestack-upload-region': 'test' }));
expect(mockPut).toHaveBeenCalled();
return [2 /*return*/];
}
});
}); });
it('should respect pause() and resume() command', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, res;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getTestFile());
setImmediate(function () { return u.pause(); });
setTimeout(function () { return u.resume(); }, 10);
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].handle).toEqual('test_handle');
expect(res[0].status).toEqual('test_status');
return [2 /*return*/];
}
});
}); });
it('should respect abort() command', function (done) {
var u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getTestFile());
setImmediate(function () { return u.abort(); });
u.execute().then(function (res) {
expect(res[0].status).toEqual('Failed');
done();
}).catch(function () {
done('Execution failed');
});
});
it('should send correct security', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var testSecurity, u, res;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
testSecurity = {
policy: 'test_p',
signature: 'test_s',
};
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.setSecurity(testSecurity);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].status).toEqual('test_status');
expect(mockStart).toHaveBeenCalledWith(expect.objectContaining(testSecurity));
expect(mockUpload).toHaveBeenCalledWith(expect.objectContaining(testSecurity));
expect(mockComplete).toHaveBeenCalledWith(expect.objectContaining(testSecurity));
return [2 /*return*/];
}
});
}); });
it('should respect disableStorageKey option', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, res, storageKeyExpect;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
u = new s3_1.S3Uploader({
disableStorageKey: true,
path: '/test/',
});
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].status).toEqual('test_status');
storageKeyExpect = {
store: {
location: 's3',
path: '/test/test.txt',
},
};
expect(mockStart).toHaveBeenCalledWith(expect.objectContaining(storageKeyExpect));
expect(mockUpload).toHaveBeenCalledWith(expect.objectContaining(storageKeyExpect));
expect(mockComplete).toHaveBeenCalledWith(expect.objectContaining(storageKeyExpect));
return [2 /*return*/];
}
});
}); });
it('should respect disableStorageKey option when path is missing', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, res, storageKeyExpect;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
u = new s3_1.S3Uploader({
disableStorageKey: true,
});
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].status).toEqual('test_status');
storageKeyExpect = {
store: {
location: 's3',
path: '/test.txt',
},
};
expect(mockStart).toHaveBeenCalledWith(expect.objectContaining(storageKeyExpect));
expect(mockUpload).toHaveBeenCalledWith(expect.objectContaining(storageKeyExpect));
expect(mockComplete).toHaveBeenCalledWith(expect.objectContaining(storageKeyExpect));
return [2 /*return*/];
}
});
}); });
it('should respect disableStorageKey option when path has missing /', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, res, storageKeyExpect;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
u = new s3_1.S3Uploader({
disableStorageKey: true,
path: '/test',
});
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].status).toEqual('test_status');
storageKeyExpect = {
store: {
location: 's3',
path: '/test/test.txt',
},
};
expect(mockStart).toHaveBeenCalledWith(expect.objectContaining(storageKeyExpect));
expect(mockUpload).toHaveBeenCalledWith(expect.objectContaining(storageKeyExpect));
expect(mockComplete).toHaveBeenCalledWith(expect.objectContaining(storageKeyExpect));
return [2 /*return*/];
}
});
}); });
});
describe('Tags', function () {
it('Make correct request with upload tags', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, tags, res, tagsExpected;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
u = new s3_1.S3Uploader({
disableStorageKey: true,
path: '/test',
});
tags = {
test: '123',
test2: 'test',
};
u.setUrl(testHost);
u.setApikey(testApikey);
u.addFile(getSmallTestFile());
u.setUploadTags(tags);
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].status).toEqual('test_status');
tagsExpected = {
upload_tags: tags,
};
expect(res[0].uploadTags).toEqual({ test: 123 });
expect(mockComplete).toHaveBeenCalledWith(expect.objectContaining(tagsExpected));
return [2 /*return*/];
}
});
}); });
});
describe('Upload modes', function () {
describe('Intelligent ingession', function () {
beforeEach(function () {
mockStart.mockReturnValue({
uri: mockedUri,
region: mockRegion,
upload_id: mockUploadId,
location_url: testHost,
upload_type: 'intelligent_ingestion',
});
});
it('should upload file', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var chunkSize, u, res, testFile, firstPartOffset, _a, partsCount, dynamicPartSize, firstPartMetadata, firstPartChunk;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
chunkSize = 1024 * 1024;
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.setUploadMode("intelligent" /* UploadMode.INTELLIGENT */);
u.setIntelligentChunkSize(chunkSize);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _b.sent();
expect(res[0].handle).toEqual('test_handle');
testFile = getSmallTestFile();
expect(mockStart).toHaveBeenCalledWith({
filename: testFile.name,
mimetype: testFile.mimetype,
size: testFile.size,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
apikey: testApikey,
fii: true,
});
firstPartOffset = 0;
_a = testFile.getPartsCount(abstract_1.INTELLIGENT_CHUNK_SIZE, true), partsCount = _a.partsCount, dynamicPartSize = _a.chunkSize;
firstPartMetadata = testFile.getPartMetadata(0, dynamicPartSize);
return [4 /*yield*/, testFile.getChunkByMetadata(firstPartMetadata, firstPartOffset, dynamicPartSize)];
case 2:
firstPartChunk = _b.sent();
expect(mockUpload).toHaveBeenCalledWith({
md5: firstPartChunk.md5,
size: firstPartChunk.size,
apikey: testApikey,
region: mockRegion,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
uri: mockedUri,
upload_id: mockUploadId,
offset: firstPartOffset,
fii: true,
part: 1,
});
expect(mockPut).toHaveBeenCalledWith('/fakes3', expect.any(Object));
expect(mockPut).toHaveBeenCalledWith('/fakes3', expect.any(Object));
expect(mockCommit).toHaveBeenCalledWith({
apikey: testApikey,
part: 1,
size: testFile.size,
region: mockRegion,
uri: mockedUri,
upload_id: mockUploadId,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
});
expect(mockComplete).toHaveBeenCalledWith({
apikey: testApikey,
filename: testFile.name,
mimetype: testFile.mimetype,
size: testFile.size,
region: mockRegion,
upload_id: mockUploadId,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
fii: true,
uri: mockedUri,
});
return [2 /*return*/];
}
});
}); });
it('should upload file', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var chunkSize, u, res, testFile, firstPartOffset, _a, partsCount, dynamicPartSize, firstPartMetadata, firstPartChunk;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
chunkSize = 1024 * 1024;
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.setUploadMode("intelligent" /* UploadMode.INTELLIGENT */);
u.setIntelligentChunkSize(chunkSize);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _b.sent();
expect(res[0].handle).toEqual('test_handle');
testFile = getSmallTestFile();
expect(mockStart).toHaveBeenCalledWith({
filename: testFile.name,
mimetype: testFile.mimetype,
size: testFile.size,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
apikey: testApikey,
fii: true,
});
firstPartOffset = 0;
_a = testFile.getPartsCount(abstract_1.INTELLIGENT_CHUNK_SIZE, true), partsCount = _a.partsCount, dynamicPartSize = _a.chunkSize;
firstPartMetadata = testFile.getPartMetadata(0, dynamicPartSize);
return [4 /*yield*/, testFile.getChunkByMetadata(firstPartMetadata, firstPartOffset, dynamicPartSize)];
case 2:
firstPartChunk = _b.sent();
expect(mockUpload).toHaveBeenCalledWith({
md5: firstPartChunk.md5,
size: firstPartChunk.size,
apikey: testApikey,
region: mockRegion,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
uri: mockedUri,
upload_id: mockUploadId,
offset: firstPartOffset,
fii: true,
part: 1,
});
expect(mockPut).toHaveBeenCalledWith('/fakes3', expect.any(Object));
expect(mockPut).toHaveBeenCalledWith('/fakes3', expect.any(Object));
expect(mockCommit).toHaveBeenCalledWith({
apikey: testApikey,
part: 1,
size: testFile.size,
region: mockRegion,
uri: mockedUri,
upload_id: mockUploadId,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
});
expect(mockComplete).toHaveBeenCalledWith({
apikey: testApikey,
filename: testFile.name,
mimetype: testFile.mimetype,
size: testFile.size,
region: mockRegion,
upload_id: mockUploadId,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
fii: true,
uri: mockedUri,
});
return [2 /*return*/];
}
});
}); });
it('should lower chunk size on network error', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var putRequestTimeout, delayApplied, u, res, testFile, _a, partsCount, dynamicPartSize, firstPartMetadata, firstPartChunk, chunkSize, updatedFirstPartMetaData, chunk1;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
putRequestTimeout = 300;
delayApplied = false;
nock_1.default.removeInterceptor(interceptorS3);
scope.put('/fakes3').reply(function (url, _, cb) {
if (!delayApplied) {
delayApplied = true;
setTimeout(function () {
cb(504);
}, 3000);
}
else {
cb(null, [201, mockPut(url, this.req.headers), { etag: 'test' }]);
}
});
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.setTimeout(putRequestTimeout);
u.setUploadMode("intelligent" /* UploadMode.INTELLIGENT */);
u.setIntelligentChunkSize(abstract_1.INTELLIGENT_CHUNK_SIZE);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _b.sent();
expect(res[0].handle).toEqual('test_handle');
expect(res[0].status).toEqual('test_status');
testFile = getSmallTestFile();
_a = testFile.getPartsCount(abstract_1.INTELLIGENT_CHUNK_SIZE, true), partsCount = _a.partsCount, dynamicPartSize = _a.chunkSize;
firstPartMetadata = testFile.getPartMetadata(0, dynamicPartSize);
return [4 /*yield*/, testFile.getChunkByMetadata(firstPartMetadata, 0, dynamicPartSize)];
case 2:
firstPartChunk = _b.sent();
// this request will be aborted but called on mock upload
expect(mockUpload).toHaveBeenNthCalledWith(1, {
md5: firstPartChunk.md5,
size: firstPartChunk.size,
apikey: testApikey,
region: mockRegion,
fii: true,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
uri: mockedUri,
upload_id: mockUploadId,
offset: 0,
part: 1,
});
chunkSize = testFile.getPartsCount(abstract_1.INTELLIGENT_CHUNK_SIZE, true).chunkSize;
chunkSize = chunkSize / 2;
updatedFirstPartMetaData = testFile.getPartMetadata(0, chunkSize);
return [4 /*yield*/, testFile.getChunkByMetadata(updatedFirstPartMetaData, 0, chunkSize)];
case 3:
chunk1 = _b.sent();
expect(mockUpload).toHaveBeenNthCalledWith(2, {
md5: chunk1.md5,
size: chunk1.size,
apikey: testApikey,
region: mockRegion,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
fii: true,
uri: mockedUri,
upload_id: mockUploadId,
offset: 0,
part: 1,
});
return [2 /*return*/];
}
});
}); });
it('should exit on 4xx errors', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, res;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
mockStart.mockReturnValue({
uri: mockedUri,
region: mockRegion,
upload_id: mockUploadId,
location_url: testHost,
upload_type: 'intelligent_ingestion',
});
interceptorS3.reply(400, {
message: 'something awful happened',
code: 'bad_request',
});
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.setTimeout(100);
u.setUploadMode("intelligent" /* UploadMode.INTELLIGENT */);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].status).toEqual('Failed');
return [2 /*return*/];
}
});
}); });
it('should nor process upload on multipart/upload network error', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, res;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
interceptorUpload.reply(400, {
message: 'something awful happened',
code: 'bad_request',
});
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.setUploadMode("intelligent" /* UploadMode.INTELLIGENT */);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].status).toEqual('Failed');
expect(mockStart).toHaveBeenCalled();
expect(mockPut).not.toHaveBeenCalled();
expect(mockCommit).not.toHaveBeenCalled();
expect(mockComplete).not.toHaveBeenCalled();
return [2 /*return*/];
}
});
}); });
});
describe('Fallback mode', function () {
it('should switch to fallback mode if regular upload fails', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var networkFail, u, res, testFile, firstPartMeta, firstPart;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
mockStart.mockReturnValue({
uri: mockedUri,
region: mockRegion,
upload_id: mockUploadId,
location_url: testHost,
upload_type: 'intelligent_ingestion',
});
networkFail = true;
nock_1.default.removeInterceptor(interceptorS3);
scope.put('/fakes3').reply(function (url, _, cb) {
if (networkFail) {
networkFail = false;
return cb('Error');
}
cb(null, [201, mockPut(url, this.req.headers), { etag: 'test' }]);
});
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.setUploadMode("fallback" /* UploadMode.FALLBACK */);
u.setIntelligentChunkSize(abstract_1.INTELLIGENT_CHUNK_SIZE);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].handle).toEqual('test_handle');
expect(res[0].status).toEqual('test_status');
testFile = getSmallTestFile();
firstPartMeta = testFile.getPartMetadata(0, abstract_1.DEFAULT_PART_SIZE);
return [4 /*yield*/, testFile.getPartByMetadata(firstPartMeta)];
case 2:
firstPart = _a.sent();
expect(mockUpload).toHaveBeenNthCalledWith(1, {
md5: firstPart.md5,
size: firstPart.size,
apikey: testApikey,
region: mockRegion,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
uri: mockedUri,
upload_id: mockUploadId,
part: 1,
});
expect(mockUpload).toHaveBeenNthCalledWith(2, {
md5: firstPart.md5,
size: firstPart.size,
fii: true,
apikey: testApikey,
region: mockRegion,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
uri: mockedUri,
offset: 0,
upload_id: mockUploadId,
part: 1,
});
return [2 /*return*/];
}
});
}); });
it('should exit if intelligent ingestion is not enabled in account settings', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var networkFail, u, res;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
mockStart.mockReturnValue({
uri: mockedUri,
region: mockRegion,
upload_id: mockUploadId,
location_url: testHost,
});
networkFail = true;
interceptorS3.reply(function (url, _, cb) {
if (networkFail) {
networkFail = false;
return cb({
message: 'ConnectionError',
code: 'ETIMEDOUT',
});
}
cb(null, [201, mockPut(url, this.req.headers), { etag: 'test' }]);
});
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.setUploadMode("fallback" /* UploadMode.FALLBACK */);
u.addFile(getSmallTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
expect(res[0].status).toEqual('Failed');
expect(mockCommit).not.toHaveBeenCalled();
expect(mockComplete).not.toHaveBeenCalled();
return [2 /*return*/];
}
});
}); });
});
});
describe('Regular upload', function () {
it('should upload file', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var partSize, u, res, testFile, firstPartMeta, firstPart, secondPartMeta, secondPart;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
partSize = 1024 * 1024 * 7;
u = new s3_1.S3Uploader({});
u.setUrl(testHost);
u.setApikey(testApikey);
u.setPartSize(partSize);
u.addFile(getTestFile());
return [4 /*yield*/, u.execute()];
case 1:
res = _a.sent();
testFile = getTestFile();
expect(mockStart).toHaveBeenCalledWith({
filename: testFile.name,
mimetype: testFile.mimetype,
size: testFile.size,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
apikey: testApikey,
});
firstPartMeta = testFile.getPartMetadata(0, partSize);
return [4 /*yield*/, testFile.getPartByMetadata(firstPartMeta)];
case 2:
firstPart = _a.sent();
expect(mockUpload).toHaveBeenNthCalledWith(1, {
md5: firstPart.md5,
size: firstPart.size,
apikey: testApikey,
region: mockRegion,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
uri: mockedUri,
upload_id: mockUploadId,
part: 1,
});
secondPartMeta = testFile.getPartMetadata(1, partSize);
return [4 /*yield*/, testFile.getPartByMetadata(secondPartMeta)];
case 3:
secondPart = _a.sent();
expect(mockUpload).toHaveBeenNthCalledWith(2, {
md5: secondPart.md5,
size: secondPart.size,
apikey: testApikey,
region: mockRegion,
store: {
location: abstract_1.DEFAULT_STORE_LOCATION,
},
uri: mockedUri,
upload_id: mockUploadId,
part: 2,
});
expect(mockPut).toHaveBeenCalledWith('/fakes3', expect.any(Object));
expect(mockComplete).toHaveBeenCalledWith({
apikey: testApikey,
filename: testFile.name,
mimetype: testFile.mimetype,
size: testFile.size,
parts: [{ part_number: 1, etag: 'test' }, { part_number: 2, etag: 'test' }],