filestack-js
Version:
Official JavaScript library for Filestack
237 lines (235 loc) • 25.1 kB
JavaScript
import { __awaiter, __generator } from "tslib";
/*
* 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.
*/
import { getFile } from './file_tools';
import * as fs from 'fs';
jest.mock('fs');
var mockedTestFile = Buffer.from('text text');
var base64Svg = 'PHN2ZyBoZWlnaHQ9IjEwMCIgd2lkdGg9IjEwMCI+CiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgcj0iNDAiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0icmVkIiAvPgogIFNvcnJ5LCB5b3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBpbmxpbmUgU1ZHLiAgCjwvc3ZnPiA=';
var base64SvgWithHeader = 'data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEwMCIgd2lkdGg9IjEwMCI+CiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgcj0iNDAiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0icmVkIiAvPgogIFNvcnJ5LCB5b3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBpbmxpbmUgU1ZHLiAgCjwvc3ZnPiA=';
describe('Api/Upload/FileTools', function () {
describe('getFileNode', function () {
it('Should return file instance for nodejs loaded file from path', function () { return __awaiter(void 0, void 0, void 0, function () {
var file, meta, slice;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
jest.spyOn(fs, 'existsSync').mockReturnValue(true);
jest.spyOn(fs, 'readFile').mockImplementation(function (path, cb) {
cb(null, mockedTestFile);
});
return [4 /*yield*/, getFile('/testfile.txt')];
case 1:
file = _a.sent();
expect(file.name).toEqual('testfile.txt');
expect(file.mimetype).toEqual('text/plain');
expect(file.size).toEqual(9);
meta = file.getPartMetadata(0, 2);
return [4 /*yield*/, file.getPartByMetadata(meta)];
case 2:
slice = _a.sent();
expect(slice.size).toEqual(2);
return [2 /*return*/];
}
});
}); });
it('Should reject if provided file cannot be read', function () {
jest.spyOn(fs, 'existsSync').mockReturnValue(true);
jest.spyOn(fs, 'readFile').mockImplementation(function (path, cb) {
cb(new Error('error'), null);
});
return expect(getFile('/testfile.txt')).rejects.toEqual(new Error('error'));
});
it('Should return correct mimetype', function () { return __awaiter(void 0, void 0, void 0, function () {
var file;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
jest.unmock('fs');
return [4 /*yield*/, getFile('./package.json')];
case 1:
file = _a.sent();
expect(file.mimetype).toEqual('application/json');
return [2 /*return*/];
}
});
}); });
it('Should return correct file instance from buffer', function () { return __awaiter(void 0, void 0, void 0, function () {
var file;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getFile(mockedTestFile)];
case 1:
file = _a.sent();
expect(file.size).toEqual(9);
expect(file.mimetype).toEqual('text/plain');
return [2 /*return*/];
}
});
}); });
it('Should handle base64 encoded string', function () { return __awaiter(void 0, void 0, void 0, function () {
var file;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getFile({
name: 'test.svg',
file: base64Svg,
})];
case 1:
file = _a.sent();
expect(file.mimetype).toEqual('image/svg+xml');
return [2 /*return*/];
}
});
}); });
it('Should handle base64 encoded string with Header', function () { return __awaiter(void 0, void 0, void 0, function () {
var file;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getFile({
name: 'test.svg',
file: base64SvgWithHeader,
})];
case 1:
file = _a.sent();
expect(file.mimetype).toEqual('image/svg+xml');
return [2 /*return*/];
}
});
}); });
it('Should detect text/plain mimetype', function () { return __awaiter(void 0, void 0, void 0, function () {
var file;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getFile({
name: 'test.undefined',
file: base64Svg,
})];
case 1:
file = _a.sent();
expect(file.mimetype).toEqual('text/plain');
return [2 /*return*/];
}
});
}); });
it('Should handle base64 encoded string with b64 prefix (svg)', function () { return __awaiter(void 0, void 0, void 0, function () {
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = expect;
return [4 /*yield*/, getFile("data:image/svg+xml;base64,".concat(base64Svg))];
case 1:
// it is hard to detect svg mimetype for now using fallback to application/octet-stream
return [2 /*return*/, _a.apply(void 0, [(_b.sent()).mimetype]).toEqual('application/octet-stream')];
}
});
}); });
it('Should get part of the buffer after slice', function () { return __awaiter(void 0, void 0, void 0, function () {
var file, meta, slice;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getFile(mockedTestFile)];
case 1:
file = _a.sent();
meta = file.getPartMetadata(0, 2);
return [4 /*yield*/, file.getPartByMetadata(meta)];
case 2:
slice = _a.sent();
expect(slice.size).toEqual(2);
return [2 /*return*/];
}
});
}); });
it('Should handle base64 encoded string', function () { return __awaiter(void 0, void 0, void 0, function () {
var file;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getFile({
name: 'test.undefined',
file: Buffer.of(12),
})];
case 1:
file = _a.sent();
expect(file.mimetype).toEqual('text/plain');
return [2 /*return*/];
}
});
}); });
it('Should throw error when random string is provided', function () { return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, expect(getFile('asdasdfasdf')).rejects.toEqual(new Error('Unsupported input file type'))];
});
}); });
it('Should pass sanitize options to file instance (buffer)', function () { return __awaiter(void 0, void 0, void 0, function () {
var fileRes;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getFile({
file: mockedTestFile,
name: 'test<.jpg',
}, {
replacement: '=',
})];
case 1:
fileRes = _a.sent();
expect(fileRes.name).toEqual('test=.jpg');
return [2 /*return*/];
}
});
}); });
it('Should pass sanitize options to file instance path', function () { return __awaiter(void 0, void 0, void 0, function () {
var fileRes;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getFile({
file: './package.json',
name: 'test<.jpg',
}, {
replacement: '=',
})];
case 1:
fileRes = _a.sent();
expect(fileRes.name).toEqual('test=.jpg');
return [2 /*return*/];
}
});
}); });
it('Should handle named file input', function () { return __awaiter(void 0, void 0, void 0, function () {
var file;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getFile({
name: '123.jpg',
file: mockedTestFile,
})];
case 1:
file = _a.sent();
expect(file.name).toEqual('123.jpg');
expect(file.size).toEqual(9);
expect(file.mimetype).toEqual('image/jpeg');
return [2 /*return*/];
}
});
}); });
it('Should reject on unsupported input file type', function () {
// @ts-ignore
return expect(getFile({})).rejects.toEqual(new Error('Unsupported input file type'));
});
});
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvYXBpL3VwbG9hZC9maWxlX3Rvb2xzLnNwZWMubm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0E7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN2QyxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUV6QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBRWhCLElBQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDaEQsSUFBTSxTQUFTLEdBQUcsc09BQXNPLENBQUM7QUFDelAsSUFBTSxtQkFBbUIsR0FBRyxnUUFBZ1EsQ0FBQztBQUU3UixRQUFRLENBQUMsc0JBQXNCLEVBQUU7SUFDL0IsUUFBUSxDQUFDLGFBQWEsRUFBRTtRQUV0QixFQUFFLENBQUMsOERBQThELEVBQUU7Ozs7O3dCQUNqRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ25ELElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLFVBQUMsSUFBSSxFQUFFLEVBQUU7NEJBQ3JELEVBQUUsQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDLENBQUM7d0JBQzNCLENBQUMsQ0FBQyxDQUFDO3dCQUVVLHFCQUFNLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBQTs7d0JBQXJDLElBQUksR0FBRyxTQUE4Qjt3QkFFM0MsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7d0JBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO3dCQUM1QyxNQUFNLENBQUMsSUFBSSxDQUFDLElB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QUFDLDhDQUE4QyxFQUFFO1lBQ2pELGFBQWE7WUFDYixPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxDQUFDLDZCQUE2QixDQUFDLENBQUMsQ0FBQztRQUN2RixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJmaWxlIjoibGliL2FwaS91cGxvYWQvZmlsZV90b29scy5zcGVjLm5vZGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTkgYnkgRmlsZXN0YWNrLlxuICogU29tZSByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICdMaWNlbnNlJyk7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gJ0FTIElTJyBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmltcG9ydCB7IGdldEZpbGUgfSBmcm9tICcuL2ZpbGVfdG9vbHMnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuXG5qZXN0Lm1vY2soJ2ZzJyk7XG5cbmNvbnN0IG1vY2tlZFRlc3RGaWxlID0gQnVmZmVyLmZyb20oJ3RleHQgdGV4dCcpO1xuY29uc3QgYmFzZTY0U3ZnID0gJ1BITjJaeUJvWldsbmFIUTlJakV3TUNJZ2QybGtkR2c5SWpFd01DSStDaUFnUEdOcGNtTnNaU0JqZUQwaU5UQWlJR041UFNJMU1DSWdjajBpTkRBaUlITjBjbTlyWlQwaVlteGhZMnNpSUhOMGNtOXJaUzEzYVdSMGFEMGlNeUlnWm1sc2JEMGljbVZrSWlBdlBnb2dJRk52Y25KNUxDQjViM1Z5SUdKeWIzZHpaWElnWkc5bGN5QnViM1FnYzNWd2NHOXlkQ0JwYm14cGJtVWdVMVpITGlBZ0Nqd3ZjM1puUGlBPSc7XG5jb25zdCBiYXNlNjRTdmdXaXRoSGVhZGVyID0gJ2RhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5Qm9aV2xuYUhROUlqRXdNQ0lnZDJsa2RHZzlJakV3TUNJK0NpQWdQR05wY21Oc1pTQmplRDBpTlRBaUlHTjVQU0kxTUNJZ2NqMGlOREFpSUhOMGNtOXJaVDBpWW14aFkyc2lJSE4wY205clpTMTNhV1IwYUQwaU15SWdabWxzYkQwaWNtVmtJaUF2UGdvZ0lGTnZjbko1TENCNWIzVnlJR0p5YjNkelpYSWdaRzlsY3lCdWIzUWdjM1Z3Y0c5eWRDQnBibXhwYm1VZ1UxWkhMaUFnQ2p3dmMzWm5QaUE9JztcblxuZGVzY3JpYmUoJ0FwaS9VcGxvYWQvRmlsZVRvb2xzJywgKCkgPT4ge1xuICBkZXNjcmliZSgnZ2V0RmlsZU5vZGUnLCAoKSA9PiB7XG5cbiAgICBpdCgnU2hvdWxkIHJldHVybiBmaWxlIGluc3RhbmNlIGZvciBub2RlanMgbG9hZGVkIGZpbGUgZnJvbSBwYXRoJywgYXN5bmMgKCkgPT4ge1xuICAgICAgamVzdC5zcHlPbihmcywgJ2V4aXN0c1N5bmMnKS5tb2NrUmV0dXJuVmFsdWUodHJ1ZSk7XG4gICAgICBqZXN0LnNweU9uKGZzLCAncmVhZEZpbGUnKS5tb2NrSW1wbGVtZW50YXRpb24oKHBhdGgsIGNiKSA9PiB7XG4gICAgICAgIGNiKG51bGwsIG1vY2tlZFRlc3RGaWxlKTtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBmaWxlID0gYXdhaXQgZ2V0RmlsZSgnL3Rlc3RmaWxlLnR4dCcpO1xuXG4gICAgICBleHBlY3QoZmlsZS5uYW1lKS50b0VxdWFsKCd0ZXN0ZmlsZS50eHQnKTtcbiAgICAgIGV4cGVjdChmaWxlLm1pbWV0eXBlKS50b0VxdWFsKCd0ZXh0L3BsYWluJyk7XG4gICAgICBleHBlY3QoZmlsZS5zaXplKS50b0VxdWFsKDkpO1xuXG4gICAgICBjb25zdCBtZXRhID0gZmlsZS5nZXRQYXJ0TWV0YWRhdGEoMCwgMik7XG4gICAgICBjb25zdCBzbGljZSA9IGF3YWl0IGZpbGUuZ2V0UGFydEJ5TWV0YWRhdGEobWV0YSk7XG5cbiAgICAgIGV4cGVjdChzbGljZS5zaXplKS50b0VxdWFsKDIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Nob3VsZCByZWplY3QgaWYgcHJvdmlkZWQgZmlsZSBjYW5ub3QgYmUgcmVhZCcsICgpID0+IHtcbiAgICAgIGplc3Quc3B5T24oZnMsICdleGlzdHNTeW5jJykubW9ja1JldHVyblZhbHVlKHRydWUpO1xuICAgICAgamVzdC5zcHlPbihmcywgJ3JlYWRGaWxlJykubW9ja0ltcGxlbWVudGF0aW9uKChwYXRoLCBjYikgPT4ge1xuICAgICAgICBjYihuZXcgRXJyb3IoJ2Vycm9yJyksIG51bGwpO1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBleHBlY3QoZ2V0RmlsZSgnL3Rlc3RmaWxlLnR4dCcpKS5yZWplY3RzLnRvRXF1YWwobmV3IEVycm9yKCdlcnJvcicpKTtcbiAgICB9KTtcblxuICAgIGl0KCdTaG91bGQgcmV0dXJuIGNvcnJlY3QgbWltZXR5cGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBqZXN0LnVubW9jaygnZnMnKTtcblxuICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IGdldEZpbGUoJy4vcGFja2FnZS5qc29uJyk7XG4gICAgICBleHBlY3QoZmlsZS5taW1ldHlwZSkudG9FcXVhbCgnYXBwbGljYXRpb24vanNvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Nob3VsZCByZXR1cm4gY29ycmVjdCBmaWxlIGluc3RhbmNlIGZyb20gYnVmZmVyJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IGdldEZpbGUobW9ja2VkVGVzdEZpbGUpO1xuICAgICAgZXhwZWN0KGZpbGUuc2l6ZSkudG9FcXVhbCg5KTtcbiAgICAgIGV4cGVjdChmaWxlLm1pbWV0eXBlKS50b0VxdWFsKCd0ZXh0L3BsYWluJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIGhhbmRsZSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBmaWxlID0gYXdhaXQgZ2V0RmlsZSh7XG4gICAgICAgIG5hbWU6ICd0ZXN0LnN2ZycsXG4gICAgICAgIGZpbGU6IGJhc2U2NFN2ZyxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoZmlsZS5taW1ldHlwZSkudG9FcXVhbCgnaW1hZ2Uvc3ZnK3htbCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Nob3VsZCBoYW5kbGUgYmFzZTY0IGVuY29kZWQgc3RyaW5nIHdpdGggSGVhZGVyJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IGdldEZpbGUoe1xuICAgICAgICBuYW1lOiAndGVzdC5zdmcnLFxuICAgICAgICBmaWxlOiBiYXNlNjRTdmdXaXRoSGVhZGVyLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChmaWxlLm1pbWV0eXBlKS50b0VxdWFsKCdpbWFnZS9zdmcreG1sJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIGRldGVjdCB0ZXh0L3BsYWluIG1pbWV0eXBlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IGdldEZpbGUoe1xuICAgICAgICBuYW1lOiAndGVzdC51bmRlZmluZWQnLFxuICAgICAgICBmaWxlOiBiYXNlNjRTdmcsXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChmaWxlLm1pbWV0eXBlKS50b0VxdWFsKCd0ZXh0L3BsYWluJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIGhhbmRsZSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgd2l0aCBiNjQgcHJlZml4IChzdmcpJywgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gaXQgaXMgaGFyZCB0byBkZXRlY3Qgc3ZnIG1pbWV0eXBlIGZvciBub3cgdXNpbmcgZmFsbGJhY2sgdG8gYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXG4gICAgICByZXR1cm4gZXhwZWN0KChhd2FpdCBnZXRGaWxlKGBkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LCR7YmFzZTY0U3ZnfWApKS5taW1ldHlwZSkudG9FcXVhbCgnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIGdldCBwYXJ0IG9mIHRoZSBidWZmZXIgYWZ0ZXIgc2xpY2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBmaWxlID0gYXdhaXQgZ2V0RmlsZShtb2NrZWRUZXN0RmlsZSk7XG5cbiAgICAgIGNvbnN0IG1ldGEgPSBmaWxlLmdldFBhcnRNZXRhZGF0YSgwLCAyKTtcbiAgICAgIGNvbnN0IHNsaWNlID0gYXdhaXQgZmlsZS5nZXRQYXJ0QnlNZXRhZGF0YShtZXRhKTtcblxuICAgICAgZXhwZWN0KHNsaWNlLnNpemUpLnRvRXF1YWwoMik7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIGhhbmRsZSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBmaWxlID0gYXdhaXQgZ2V0RmlsZSh7XG4gICAgICAgIG5hbWU6ICd0ZXN0LnVuZGVmaW5lZCcsXG4gICAgICAgIGZpbGU6IEJ1ZmZlci5vZigxMiksXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChmaWxlLm1pbWV0eXBlKS50b0VxdWFsKCd0ZXh0L3BsYWluJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIHRocm93IGVycm9yIHdoZW4gcmFuZG9tIHN0cmluZyBpcyBwcm92aWRlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBleHBlY3QoZ2V0RmlsZSgnYXNkYXNkZmFzZGYnKSkucmVqZWN0cy50b0VxdWFsKG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgaW5wdXQgZmlsZSB0eXBlJykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Nob3VsZCBwYXNzIHNhbml0aXplIG9wdGlvbnMgdG8gZmlsZSBpbnN0YW5jZSAoYnVmZmVyKScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGZpbGVSZXMgPSBhd2FpdCBnZXRGaWxlKHtcbiAgICAgICAgZmlsZTogbW9ja2VkVGVzdEZpbGUsXG4gICAgICAgIG5hbWU6ICd0ZXN0PC5qcGcnLFxuICAgICAgfSwge1xuICAgICAgICByZXBsYWNlbWVudDogJz0nLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChmaWxlUmVzLm5hbWUpLnRvRXF1YWwoJ3Rlc3Q9LmpwZycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Nob3VsZCBwYXNzIHNhbml0aXplIG9wdGlvbnMgdG8gZmlsZSBpbnN0YW5jZSBwYXRoJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZmlsZVJlcyA9IGF3YWl0IGdldEZpbGUoe1xuICAgICAgICBmaWxlOiAnLi9wYWNrYWdlLmpzb24nLFxuICAgICAgICBuYW1lOiAndGVzdDwuanBnJyxcbiAgICAgIH0sIHtcbiAgICAgICAgcmVwbGFjZW1lbnQ6ICc9JyxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoZmlsZVJlcy5uYW1lKS50b0VxdWFsKCd0ZXN0PS5qcGcnKTtcbiAgICB9KTtcblxuICAgIGl0KCdTaG91bGQgaGFuZGxlIG5hbWVkIGZpbGUgaW5wdXQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBmaWxlID0gYXdhaXQgZ2V0RmlsZSh7XG4gICAgICAgIG5hbWU6ICcxMjMuanBnJyxcbiAgICAgICAgZmlsZTogbW9ja2VkVGVzdEZpbGUsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGZpbGUubmFtZSkudG9FcXVhbCgnMTIzLmpwZycpO1xuICAgICAgZXhwZWN0KGZpbGUuc2l6ZSkudG9FcXVhbCg5KTtcbiAgICAgIGV4cGVjdChmaWxlLm1pbWV0eXBlKS50b0VxdWFsKCdpbWFnZS9qcGVnJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIHJlamVjdCBvbiB1bnN1cHBvcnRlZCBpbnB1dCBmaWxlIHR5cGUnLCAoKSA9PiB7XG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICByZXR1cm4gZXhwZWN0KGdldEZpbGUoe30pKS5yZWplY3RzLnRvRXF1YWwobmV3IEVycm9yKCdVbnN1cHBvcnRlZCBpbnB1dCBmaWxlIHR5cGUnKSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=