UNPKG

@genialis/resolwe

Version:
373 lines (372 loc) 66.5 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); var _ = require("lodash"); var Rx = require("rx"); var angular = require("angular"); var api_1 = require("./api"); var mock_1 = require("../../api/mock"); var utils_1 = require("../../api/types/utils"); var base_1 = require("../components/base"); var component_1 = require("../../tests/component"); describe('mock api', function () { it('mocks basic non-reactive queries', function () { var mockApi = new mock_1.MockApi(); var subscriber = jasmine.createSpy('subscriber'); mockApi.createResource('collection'); // Queries are not reactive by default. mockApi.Collection.query().subscribe(subscriber); expect(subscriber).toHaveBeenCalledTimes(1); expect(subscriber.calls.mostRecent().args[0]).toEqual([]); // Add an item. mockApi.addItem('collection', { id: 1, name: 'Hello world' }); expect(subscriber).toHaveBeenCalledTimes(1); // Since it is a non-reactive query, we need to repeat the query. mockApi.Collection.query().subscribe(subscriber); expect(subscriber).toHaveBeenCalledTimes(2); expect(subscriber.calls.mostRecent().args[0]).toEqual([{ id: 1, name: 'Hello world' }]); }); it('mocks basic reactive queries', function () { var mockApi = new mock_1.MockApi(); var subscriber = jasmine.createSpy('subscriber'); mockApi.createResource('collection'); mockApi.Collection.query({}, { reactive: true }).subscribe(subscriber); expect(subscriber).toHaveBeenCalledTimes(1); expect(subscriber.calls.mostRecent().args[0]).toEqual([]); // Add an item. mockApi.addItem('collection', { id: 1, name: 'Hello world' }); expect(subscriber).toHaveBeenCalledTimes(2); expect(subscriber.calls.mostRecent().args[0]).toEqual([{ id: 1, name: 'Hello world' }]); // Update an item. mockApi.updateItem('collection', { id: 1, name: 'Hello mockups' }); expect(subscriber).toHaveBeenCalledTimes(3); expect(subscriber.calls.mostRecent().args[0]).toEqual([{ id: 1, name: 'Hello mockups' }]); // Remove an item. mockApi.removeItem('collection', 1); expect(subscriber).toHaveBeenCalledTimes(4); expect(subscriber.calls.mostRecent().args[0]).toEqual([]); }); it('mocks complex reactive queries', function () { var mockApi = new mock_1.MockApi(); var subscriberPlain = jasmine.createSpy('subscriberPlain'); var subscriberWithFilter = jasmine.createSpy('subscriberWithFilter'); mockApi.createResource('collection', 'id', function (query, items) { if (_.isEmpty(query)) return items; return _.filter(items, function (item) { return item.name === query.name; }); }); mockApi.Collection.query({}, { reactive: true }).subscribe(subscriberPlain); mockApi.Collection.query({ name: 'Hello' }, { reactive: true }).subscribe(subscriberWithFilter); mockApi.addItem('collection', { id: 1, name: 'Collection A' }); mockApi.addItem('collection', { id: 2, name: 'Another one' }); mockApi.addItem('collection', { id: 3, name: 'Hello' }); mockApi.addItem('collection', { id: 4, name: 'Hello world' }); expect(subscriberPlain).toHaveBeenCalledTimes(5); expect(subscriberWithFilter).toHaveBeenCalledTimes(2); }); it('mocks non-query operations', function () { var mockApi = new mock_1.MockApi(); var subscriber = jasmine.createSpy('subscriber'); mockApi.whenPost('/api/collection', subscriber); mockApi.Collection.create({ name: 'Foo' }); expect(subscriber).toHaveBeenCalledTimes(1); expect(subscriber.calls.mostRecent().args[0]).toEqual({}); expect(subscriber.calls.mostRecent().args[1]).toEqual({ name: 'Foo' }); mockApi.whenGet('/api/collection/slug_exists', function (parameters, data) { return parameters.name === 'hello'; }); mockApi.Collection.slugExists('bar').subscribe(subscriber); expect(subscriber).toHaveBeenCalledTimes(2); expect(subscriber.calls.mostRecent().args[0]).toBe(false); mockApi.Collection.slugExists('hello').subscribe(subscriber); expect(subscriber).toHaveBeenCalledTimes(3); expect(subscriber.calls.mostRecent().args[0]).toBe(true); }); it('supports zip operation', function () { var mockApi = new mock_1.MockApi(); var subscriber = jasmine.createSpy('subscriber'); mockApi.createResource('collection'); mockApi.addItem('collection', { id: 1 }); Rx.Observable.zip(mockApi.Collection.query(), mockApi.Collection.query()).subscribe(subscriber); expect(subscriber).toHaveBeenCalledTimes(1); expect(subscriber.calls.mostRecent().args[0]).toEqual([[{ id: 1 }], [{ id: 1 }]]); }); }); component_1.describeComponent('angular mock api', [], function (tester) { var TestComponent = /** @class */ (function (_super) { __extends(TestComponent, _super); // @ngInject TestComponent.$inject = ["$scope", "api"]; function TestComponent($scope, api) { var _this = _super.call(this, $scope) || this; _this.subscribe('collection', api.Collection.queryOne()); return _this; } TestComponent = __decorate([ base_1.component({ module: tester.module, directive: 'gen-test-component', template: "<div class=\"text-name\">Collection name is {{ctrl.collection.name}}</div>", }) ], TestComponent); return TestComponent; }(base_1.ComponentBase)); it('replaces api service', function () { tester.api().createResource('collection'); tester.api().addItem('collection', { id: 1, name: 'Hello world' }); var testComponent = tester.createComponent(TestComponent.asView().template); expect(testComponent.ctrl.collection.id).toBe(1); expect(testComponent.ctrl.collection.name).toBe('Hello world'); expect(testComponent.element.find('.text-name').text()).toBe('Collection name is Hello world'); }); it('mocks uploads', function (done) { var uploaded = false; tester.api().whenUpload(function (data, fileUID) { uploaded = true; return { data: 'hello' }; }); tester.api().upload({}, 'test-uuid').subscribe(function (response) { expect(response.type).toEqual(api_1.UploadEventType.RESULT); if (response.type === api_1.UploadEventType.RESULT) { expect(uploaded).toEqual(true); expect(response.result).toEqual({ data: 'hello' }); done(); } }); }); }); describe('resource', function () { it('correctly caches reactive queries', function (done) { var called = 0; var mockApi = new mock_1.MockApi(); var subscriber = function () { if (++called === 3) { // tslint:disable-line:no-constant-condition done(); } }; mockApi.createResource('process'); mockApi.simulateDelay(true); mockApi.Process.query({}, { reactive: true }).take(1).subscribe(subscriber); mockApi.Process.query({}, { reactive: true }).take(1).subscribe(subscriber); mockApi.Process.query({}, { reactive: true }).take(1).subscribe(subscriber); // Ensure these queries have been delayed. expect(called).toEqual(0); }); describe('Data', function () { it('correctly translates "sample" field to "entity"', function () { var mockApi = new mock_1.MockApi(); var resultSubscriber = jasmine.createSpy('resultSubscriber'); var querySubscriber = jasmine.createSpy('querySubscriber'); mockApi.createResource('data', 'id', function (query, items) { querySubscriber(query); return items; }); var query = { sample: 1, sample__in: [1, 2, 3].join(','), samplex: 1, xsample__in: [1].join(','), status: 'PR', }; var limitedFieldsQuery = utils_1.limitFieldsQuery(query, ['sample__slug', 'status', 'samplex', 'xsample__slug', 'sample__name']); mockApi.Data.query(limitedFieldsQuery).subscribe(resultSubscriber); var transformedQuery = querySubscriber.calls.mostRecent().args[0]; expect(transformedQuery).toEqual({ entity: 1, entity__in: ['1', '2', '3'].join(','), samplex: 1, xsample__in: '1', status: 'PR', // Expect sample to be translated in limiting fields. fields: ['entity__slug', 'status', 'samplex', 'xsample__slug', 'entity__name'].join(','), }); }); }); }); describe('upload', function () { var api; var $httpBackend; var $exceptionHandler; // Auto-retry tests fail if $exceptionHandler rethrows errors. angular.module('ignore_exceptions', []).config(["$exceptionHandlerProvider", function ($exceptionHandlerProvider) { $exceptionHandlerProvider.mode('log'); }]); beforeEach(angular.mock.module('ignore_exceptions')); beforeEach(angular.mock.module('ngFileUpload')); beforeEach(inject(function (Upload, $q, $http, _$httpBackend_, _$exceptionHandler_) { $httpBackend = _$httpBackend_; $exceptionHandler = _$exceptionHandler_; api = new api_1.APIServiceBase(Upload, $q, $http); api.connection = new mock_1.MockConnection(); api.RETRY_DELAY_INCREMENT = 10; })); it('should work for new files', function (done) { $httpBackend.expectGET('/upload/').respond(function (method, url, data, headers, queryParams) { expect(headers['X-File-Uid']).toBeDefined(); return [200, { resume_offset: 0 }, {}, 'OK']; }); $httpBackend.expectPOST('/upload/').respond(200, { files: [{ name: 'a.txt', size: 1000, done: true, temp: '5ed2a' }], }); api.uploadString('a.txt', 'abcd').subscribe(function (response) { expect(response.type).toEqual(api_1.UploadEventType.RESULT); if (response.type === api_1.UploadEventType.RESULT) { expect(response.result.files[0].name).toEqual('a.txt'); expect($exceptionHandler.errors).toEqual([]); done(); } }); $httpBackend.flush(); $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); }); it('should chunk large files', function (done) { $httpBackend.expectGET('/upload/').respond(200, { resume_offset: 0 }); $httpBackend.expectPOST('/upload/').respond(200, {}); $httpBackend.expectPOST('/upload/').respond(200, {}); $httpBackend.expectPOST('/upload/').respond(200, { /* result */}); var largeContent = _.range(3 * api.CHUNK_SIZE - 1).map(function () { return 'a'; }).join(''); api.uploadString('a.txt', largeContent).toArray().subscribe(function (_a) { var response1 = _a[0], response2 = _a[1], response3 = _a[2]; expect(response1.type).toEqual(api_1.UploadEventType.PROGRESS); expect(response2.type).toEqual(api_1.UploadEventType.PROGRESS); expect(response3.type).toEqual(api_1.UploadEventType.RESULT); expect($exceptionHandler.errors).toEqual([]); done(); }); $httpBackend.flush(); $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); }); it('should resume for existing files', function (done) { $httpBackend.expectGET('/upload/').respond(200, { resume_offset: api.CHUNK_SIZE }); $httpBackend.expectPOST('/upload/').respond(200, {}); $httpBackend.expectPOST('/upload/').respond(200, { /* result */}); var largeContent = _.range(3 * api.CHUNK_SIZE - 1).map(function () { return 'a'; }).join(''); api.uploadString('a.txt', largeContent).toArray().subscribe(function (_a) { var response1 = _a[0], response2 = _a[1]; expect(response1.type).toEqual(api_1.UploadEventType.PROGRESS); expect(response2.type).toEqual(api_1.UploadEventType.RESULT); expect($exceptionHandler.errors).toEqual([]); done(); }); $httpBackend.flush(); $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); }); it('should auto-retry after failed requests', function (done) { var consoleInfo = console.info; spyOn(console, 'info').and.callFake(function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } // Suppress the following console infos. if (args[0] === 'Retrying upload after an error') return; return consoleInfo.apply(console, args); }); $httpBackend.expectGET('/upload/').respond(503, {}); var largeContent = _.range(3 * api.CHUNK_SIZE - 1).map(function () { return 'a'; }).join(''); api.uploadString('a.txt', largeContent).toArray().subscribe(function (responses) { expect(responses[0].type).toEqual(api_1.UploadEventType.RETRYING); expect(responses[1].type).toEqual(api_1.UploadEventType.RETRYING); expect(responses[2].type).toEqual(api_1.UploadEventType.PROGRESS); expect(responses[3].type).toEqual(api_1.UploadEventType.RETRYING); expect(responses[4].type).toEqual(api_1.UploadEventType.RESULT); var unexpectedLogs = $exceptionHandler.errors.filter(function (log) { var isExpected = _.isString(log) && /Possibly unhandled rejection: .*"status":503/.test(log); return !isExpected; }); expect(unexpectedLogs).toEqual([]); done(); }); $httpBackend.flush(); $httpBackend.expectGET('/upload/').respond(200, { resume_offset: api.CHUNK_SIZE }); $httpBackend.expectPOST('/upload/').respond(503, {}); setTimeout(function () { $httpBackend.flush(); $httpBackend.expectGET('/upload/').respond(200, { resume_offset: api.CHUNK_SIZE }); $httpBackend.expectPOST('/upload/').respond(200, {}); $httpBackend.expectPOST('/upload/').respond(503, {}); setTimeout(function () { $httpBackend.flush(); $httpBackend.expectGET('/upload/').respond(200, { resume_offset: 2 * api.CHUNK_SIZE }); $httpBackend.expectPOST('/upload/').respond(200, { /* result */}); setTimeout(function () { $httpBackend.flush(); }, 30 + 5); }, 20 + 5); }, 10 + 5); // Wait for RETRY_DELAY_INCREMENT, and 5ms padding time }); it('should stop retrying after too many failed requests', function (done) { var consoleInfo = console.info; spyOn(console, 'info').and.callFake(function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } // Suppress the following console infos. if (args[0] === 'Retrying upload after an error') return; return consoleInfo.apply(console, args); }); $httpBackend.expectGET('/upload/').respond(503, {}); var largeContent = _.range(3 * api.CHUNK_SIZE - 1).map(function () { return 'a'; }).join(''); api.uploadString('a.txt', largeContent).toArray().subscribe(function (responses) { done.fail('Expected upload to fail, not succeed'); }, function (error) { expect(error.config.method).toEqual('POST'); expect(error.status).toEqual(503); var unexpectedLogs = $exceptionHandler.errors.filter(function (log) { var isExpected = _.isString(log) && /Possibly unhandled rejection: .*"status":503/.test(log); return !isExpected; }); expect(unexpectedLogs).toEqual([]); done(); }); $httpBackend.flush(); $httpBackend.expectGET('/upload/').respond(503, {}); setTimeout(function () { $httpBackend.flush(); $httpBackend.expectGET('/upload/').respond(200, { resume_offset: api.CHUNK_SIZE }); $httpBackend.expectPOST('/upload/').respond(503, {}); setTimeout(function () { $httpBackend.flush(); $httpBackend.expectGET('/upload/').respond(503, {}); setTimeout(function () { $httpBackend.flush(); $httpBackend.expectGET('/upload/').respond(200, { resume_offset: api.CHUNK_SIZE }); $httpBackend.expectPOST('/upload/').respond(503, {}); setTimeout(function () { $httpBackend.flush(); $httpBackend.expectGET('/upload/').respond(200, { resume_offset: api.CHUNK_SIZE }); $httpBackend.expectPOST('/upload/').respond(503, {}); setTimeout(function () { $httpBackend.flush(); }, 50 + 5); }, 40 + 5); }, 30 + 5); }, 20 + 5); }, 10 + 5); }); }); //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb3JlL3NlcnZpY2VzL2FwaS5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDBCQUE0QjtBQUM1Qix1QkFBeUI7QUFDekIsaUNBQW1DO0FBRW5DLDZCQUFzRDtBQUV0RCx1Q0FBdUQ7QUFFdkQsK0NBQXVEO0FBQ3ZELDJDQUE0RDtBQUM1RCxtREFBd0Q7QUFLeEQsUUFBUSxDQUFDLFVBQVUsRUFBRTtJQUNqQixFQUFFLENBQUMsa0NBQWtDLEVBQUU7UUFDbkMsSUFBTSxPQUFPLEdBQUcsSUFBSSxjQUFPLEVBQUUsQ0FBQztRQUM5QixJQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRW5ELE9BQU8sQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFckMsdUNBQXVDO1FBQ3ZDLE9BQU8sQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1QyxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFMUQsZUFBZTtRQUNmLE9BQU8sQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFDLENBQUMsQ0FBQztRQUM1RCxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFNUMsaUVBQWlFO1FBQ2pFLE9BQU8sQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sQ0FBQyxVQUFV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T0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztvQkFDckQsVUFBVSxDQUFDO3dCQUNQLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQzt3QkFFckIsWUFBWSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsYUFBYSxFQUFFLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO3dCQUNuRixZQUFZLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7d0JBQ3JELFVBQVUsQ0FBQzs0QkFDUCxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7d0JBQ3pCLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBQ2YsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDZixDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ2YsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNmLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDZixDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMsQ0FBQyxDQUFDIiwiZmlsZSI6ImNvcmUvc2VydmljZXMvYXBpLnNwZWMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgKiBhcyBSeCBmcm9tICdyeCc7XG5pbXBvcnQgKiBhcyBhbmd1bGFyIGZyb20gJ2FuZ3VsYXInO1xuXG5pbXBvcnQge0FQSVNlcnZpY2VCYXNlLCBVcGxvYWRFdmVudFR5cGV9IGZyb20gJy4vYXBpJztcbmltcG9ydCB7UmVzb2x3ZUFwaX0gZnJvbSAnLi4vLi4vYXBpL2luZGV4JztcbmltcG9ydCB7TW9ja0FwaSwgTW9ja0Nvbm5lY3Rpb259IGZyb20gJy4uLy4uL2FwaS9tb2NrJztcbmltcG9ydCB7RmlsZVVwbG9hZFJlc3BvbnNlfSBmcm9tICcuLi8uLi9hcGkvdHlwZXMvbW9kdWxlcyc7XG5pbXBvcnQge2xpbWl0RmllbGRzUXVlcnl9IGZyb20gJy4uLy4uL2FwaS90eXBlcy91dGlscyc7XG5pbXBvcnQge2NvbXBvbmVudCwgQ29tcG9uZW50QmFzZX0gZnJvbSAnLi4vY29tcG9uZW50cy9iYXNlJztcbmltcG9ydCB7ZGVzY3JpYmVDb21wb25lbnR9IGZyb20gJy4uLy4uL3Rlc3RzL2NvbXBvbmVudCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQVBJU2VydmljZSBleHRlbmRzIEFQSVNlcnZpY2VCYXNlLCBSZXNvbHdlQXBpIHtcbn1cblxuZGVzY3JpYmUoJ21vY2sgYXBpJywgKCkgPT4ge1xuICAgIGl0KCdtb2NrcyBiYXNpYyBub24tcmVhY3RpdmUgcXVlcmllcycsICgpID0+IHtcbiAgICAgICAgY29uc3QgbW9ja0FwaSA9IG5ldyBNb2NrQXBpKCk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBqYXNtaW5lLmNyZWF0ZVNweSgnc3Vic2NyaWJlcicpO1xuXG4gICAgICAgIG1vY2tBcGkuY3JlYXRlUmVzb3VyY2UoJ2NvbGxlY3Rpb24nKTtcblxuICAgICAgICAvLyBRdWVyaWVzIGFyZSBub3QgcmVhY3RpdmUgYnkgZGVmYXVsdC5cbiAgICAgICAgbW9ja0FwaS5Db2xsZWN0aW9uLnF1ZXJ5KCkuc3Vic2NyaWJlKHN1YnNjcmliZXIpO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlcikudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDEpO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlci5jYWxscy5tb3N0UmVjZW50KCkuYXJnc1swXSkudG9FcXVhbChbXSk7XG5cbiAgICAgICAgLy8gQWRkIGFuIGl0ZW0uXG4gICAgICAgIG1vY2tBcGkuYWRkSXRlbSgnY29sbGVjdGlvbicsIHtpZDogMSwgbmFtZTogJ0hlbGxvIHdvcmxkJ30pO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlcikudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDEpO1xuXG4gICAgICAgIC8vIFNpbmNlIGl0IGlzIGEgbm9uLXJlYWN0aXZlIHF1ZXJ5LCB3ZSBuZWVkIHRvIHJlcGVhdCB0aGUgcXVlcnkuXG4gICAgICAgIG1vY2tBcGkuQ29sbGVjdGlvbi5xdWVyeSgpLnN1YnNjcmliZShzdWJzY3JpYmVyKTtcbiAgICAgICAgZXhwZWN0KHN1YnNjcmliZXIpLnRvSGF2ZUJlZW5DYWxsZWRUaW1lcygyKTtcbiAgICAgICAgZXhwZWN0KHN1YnNjcmliZXIuY2FsbHMubW9zdFJlY2VudCgpLmFyZ3NbMF0pLnRvRXF1YWwoW3tpZDogMSwgbmFtZTogJ0hlbGxvIHdvcmxkJ31dKTtcbiAgICB9KTtcblxuICAgIGl0KCdtb2NrcyBiYXNpYyByZWFjdGl2ZSBxdWVyaWVzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBtb2NrQXBpID0gbmV3IE1vY2tBcGkoKTtcbiAgICAgICAgY29uc3Qgc3Vic2NyaWJlciA9IGphc21pbmUuY3JlYXRlU3B5KCdzdWJzY3JpYmVyJyk7XG5cbiAgICAgICAgbW9ja0FwaS5jcmVhdGVSZXNvdXJjZSgnY29sbGVjdGlvbicpO1xuXG4gICAgICAgIG1vY2tBcGkuQ29sbGVjdGlvbi5xdWVyeSh7fSwge3JlYWN0aXZlOiB0cnVlfSkuc3Vic2NyaWJlKHN1YnNjcmliZXIpO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlcikudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDEpO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlci5jYWxscy5tb3N0UmVjZW50KCkuYXJnc1swXSkudG9FcXVhbChbXSk7XG5cbiAgICAgICAgLy8gQWRkIGFuIGl0ZW0uXG4gICAgICAgIG1vY2tBcGkuYWRkSXRlbSgnY29sbGVjdGlvbicsIHtpZDogMSwgbmFtZTogJ0hlbGxvIHdvcmxkJ30pO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlcikudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDIpO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlci5jYWxscy5tb3N0UmVjZW50KCkuYXJnc1swXSkudG9FcXVhbChbe2lkOiAxLCBuYW1lOiAnSGVsbG8gd29ybGQnfV0pO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBhbiBpdGVtLlxuICAgICAgICBtb2NrQXBpLnVwZGF0ZUl0ZW0oJ2NvbGxlY3Rpb24nLCB7aWQ6IDEsIG5hbWU6ICdIZWxsbyBtb2NrdXBzJ30pO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlcikudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDMpO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlci5jYWxscy5tb3N0UmVjZW50KCkuYXJnc1swXSkudG9FcXVhbChbe2lkOiAxLCBuYW1lOiAnSGVsbG8gbW9ja3Vwcyd9XSk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGFuIGl0ZW0uXG4gICAgICAgIG1vY2tBcGkucmVtb3ZlSXRlbSgnY29sbGVjdGlvbicsIDEpO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlcikudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDQpO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlci5jYWxscy5tb3N0UmVjZW50KCkuYXJnc1swXSkudG9FcXVhbChbXSk7XG4gICAgfSk7XG5cbiAgICBpdCgnbW9ja3MgY29tcGxleCByZWFjdGl2ZSBxdWVyaWVzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBtb2NrQXBpID0gbmV3IE1vY2tBcGkoKTtcbiAgICAgICAgY29uc3Qgc3Vic2NyaWJlclBsYWluID0gamFzbWluZS5jcmVhdGVTcHkoJ3N1YnNjcmliZXJQbGFpbicpO1xuICAgICAgICBjb25zdCBzdWJzY3JpYmVyV2l0aEZpbHRlciA9IGphc21pbmUuY3JlYXRlU3B5KCdzdWJzY3JpYmVyV2l0aEZpbHRlcicpO1xuXG4gICAgICAgIG1vY2tBcGkuY3JlYXRlUmVzb3VyY2UoJ2NvbGxlY3Rpb24nLCAnaWQnLCAocXVlcnksIGl0ZW1zKSA9PiB7XG4gICAgICAgICAgICBpZiAoXy5pc0VtcHR5KHF1ZXJ5KSkgcmV0dXJuIGl0ZW1zO1xuXG4gICAgICAgICAgICByZXR1cm4gXy5maWx0ZXIoaXRlbXMsIChpdGVtOiBhbnkpID0+IGl0ZW0ubmFtZSA9PT0gcXVlcnkubmFtZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIG1vY2tBcGkuQ29sbGVjdGlvbi5xdWVyeSh7fSwge3JlYWN0aXZlOiB0cnVlfSkuc3Vic2NyaWJlKHN1YnNjcmliZXJQbGFpbik7XG4gICAgICAgIG1vY2tBcGkuQ29sbGVjdGlvbi5xdWVyeSh7bmFtZTogJ0hlbGxvJ30sIHtyZWFjdGl2ZTogdHJ1ZX0pLnN1YnNjcmliZShzdWJzY3JpYmVyV2l0aEZpbHRlcik7XG5cbiAgICAgICAgbW9ja0FwaS5hZGRJdGVtKCdjb2xsZWN0aW9uJywge2lkOiAxLCBuYW1lOiAnQ29sbGVjdGlvbiBBJ30pO1xuICAgICAgICBtb2NrQXBpLmFkZEl0ZW0oJ2NvbGxlY3Rpb24nLCB7aWQ6IDIsIG5hbWU6ICdBbm90aGVyIG9uZSd9KTtcbiAgICAgICAgbW9ja0FwaS5hZGRJdGVtKCdjb2xsZWN0aW9uJywge2lkOiAzLCBuYW1lOiAnSGVsbG8nfSk7XG4gICAgICAgIG1vY2tBcGkuYWRkSXRlbSgnY29sbGVjdGlvbicsIHtpZDogNCwgbmFtZTogJ0hlbGxvIHdvcmxkJ30pO1xuXG4gICAgICAgIGV4cGVjdChzdWJzY3JpYmVyUGxhaW4pLnRvSGF2ZUJlZW5DYWxsZWRUaW1lcyg1KTtcbiAgICAgICAgZXhwZWN0KHN1YnNjcmliZXJXaXRoRmlsdGVyKS50b0hhdmVCZWVuQ2FsbGVkVGltZXMoMik7XG4gICAgfSk7XG5cbiAgICBpdCgnbW9ja3Mgbm9uLXF1ZXJ5IG9wZXJhdGlvbnMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vY2tBcGkgPSBuZXcgTW9ja0FwaSgpO1xuICAgICAgICBjb25zdCBzdWJzY3JpYmVyID0gamFzbWluZS5jcmVhdGVTcHkoJ3N1YnNjcmliZXInKTtcblxuICAgICAgICBtb2NrQXBpLndoZW5Qb3N0KCcvYXBpL2NvbGxlY3Rpb24nLCBzdWJzY3JpYmVyKTtcbiAgICAgICAgbW9ja0FwaS5Db2xsZWN0aW9uLmNyZWF0ZSh7bmFtZTogJ0Zvbyd9KTtcblxuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlcikudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDEpO1xuICAgICAgICBleHBlY3Qoc3Vic2NyaWJlci5jYWxscy5tb3N0UmVjZW50KCkuYXJnc1swXSkudG9FcXVhbCh7fSk7XG4gICAgICAgIGV4cGVjdChzdWJzY3JpYmVyLmNhbGxzLm1vc3RSZWNlbnQoKS5hcmdzWzFdKS50b0VxdWFsKHtuYW1lOiAnRm9vJ30pO1xuXG4gICAgICAgIG1vY2tBcGkud2hlbkdldCgnL2FwaS9jb2xsZWN0aW9uL3NsdWdfZXhpc3RzJywgKHBhcmFtZXRlcnMsIGRhdGEpOiBib29sZWFuID0+IHtcbiAgICAgICAgICAgIHJldHVybiBwYXJhbWV0ZXJzLm5hbWUgPT09ICdoZWxsbyc7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIG1vY2tBcGkuQ29sbGVjdGlvbi5zbHVnRXhpc3RzKCdiYXInKS5zdWJzY3JpYmUoc3Vic2NyaWJlcik7XG4gICAgICAgIGV4cGVjdChzdWJzY3JpYmVyKS50b0hhdmVCZWVuQ2FsbGVkVGltZXMoMik7XG4gICAgICAgIGV4cGVjdChzdWJzY3JpYmVyLmNhbGxzLm1vc3RSZWNlbnQoKS5hcmdzWzBdKS50b0JlKGZhbHNlKTtcblxuICAgICAgICBtb2NrQXBpLkNvbGxlY3Rpb24uc2x1Z0V4aXN0cygnaGVsbG8nKS5zdWJzY3JpYmUoc3Vic2NyaWJlcik7XG4gICAgICAgIGV4cGVjdChzdWJzY3JpYmVyKS50b0hhdmVCZWVuQ2FsbGVkVGltZXMoMyk7XG4gICAgICAgIGV4cGVjdChzdWJzY3JpYmVyLmNhbGxzLm1vc3RSZWNlbnQoKS5hcmdzWzBdKS50b0JlKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3N1cHBvcnRzIHppcCBvcGVyYXRpb24nLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vY2tBcGkgPSBuZXcgTW9ja0FwaSgpO1xuICAgICAgICBjb25zdCBzdWJzY3JpYmVyID0gamFzbWluZS5jcmVhdGVTcHkoJ3N1YnNjcmliZXInKTtcblxuICAgICAgICBtb2NrQXBpLmNyZWF0ZVJlc291cmNlKCdjb2xsZWN0aW9uJyk7XG4gICAgICAgIG1vY2tBcGkuYWRkSXRlbSgnY29sbGVjdGlvbicsIHsgaWQ6IDEgfSk7XG5cbiAgICAgICAgUnguT2JzZXJ2YWJsZS56aXAobW9ja0FwaS5Db2xsZWN0aW9uLnF1ZXJ5KCksIG1vY2tBcGkuQ29sbGVjdGlvbi5xdWVyeSgpKS5zdWJzY3JpYmUoc3Vic2NyaWJlcik7XG4gICAgICAgIGV4cGVjdChzdWJzY3JpYmVyKS50b0hhdmVCZWVuQ2FsbGVkVGltZXMoMSk7XG4gICAgICAgIGV4cGVjdChzdWJzY3JpYmVyLmNhbGxzLm1vc3RSZWNlbnQoKS5hcmdzWzBdKS50b0VxdWFsKFsgWyB7IGlkOiAxIH0gXSwgWyB7IGlkOiAxIH0gXSBdKTtcbiAgICB9KTtcbn0pO1xuXG5kZXNjcmliZUNvbXBvbmVudCgnYW5ndWxhciBtb2NrIGFwaScsIFtdLCAodGVzdGVyKSA9PiB7XG4gICAgQGNvbXBvbmVudCh7XG4gICAgICAgIG1vZHVsZTogdGVzdGVyLm1vZHVsZSxcbiAgICAgICAgZGlyZWN0aXZlOiAnZ2VuLXRlc3QtY29tcG9uZW50JyxcbiAgICAgICAgdGVtcGxhdGU6IGA8ZGl2IGNsYXNzPVwidGV4dC1uYW1lXCI+Q29sbGVjdGlvbiBuYW1lIGlzIHt7Y3RybC5jb2xsZWN0aW9uLm5hbWV9fTwvZGl2PmAsXG4gICAgfSlcbiAgICBjbGFzcyBUZXN0Q29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50QmFzZSB7XG4gICAgICAgIHB1YmxpYyBjb2xsZWN0aW9uOiBhbnk7XG5cbiAg