kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
195 lines (193 loc) • 29.2 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _react2 = require("@testing-library/react");
var _saveMapModal = _interopRequireDefault(require("./save-map-modal"));
var _componentJestUtils = require("test/helpers/component-jest-utils");
var _useCloudListProvider = require("../hooks/use-cloud-list-provider");
var _constants = require("@kepler.gl/constants");
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
// @ts-nocheck
/**
* I decided to move the next to the actual file because it makes it
* extremely easier to mock adn test features.
* It's easier to mock items with jest using the relative path
* rather than trying to mock imports like @kepler.gl/components
* which creates several side effects.
* Colocating tests is much easier
*/
var SaveMapModal = (0, _saveMapModal["default"])();
var DEFAULT_PROS = {
mapInfo: {
title: 'Test Map',
description: 'test'
},
exportImage: jest.fn(),
isProviderLoading: false,
providerError: null,
onUpdateImageSetting: jest.fn(),
cleanupExportImage: jest.fn(),
onSetMapInfo: jest.fn(),
onCancel: jest.fn(),
onConfirm: jest.fn()
};
var UNDEFINED_MAP_TITLE_PROPS = _objectSpread(_objectSpread({}, DEFAULT_PROS), {}, {
mapInfo: {
description: undefined,
title: undefined
}
});
var DEFAULT_PROVIDER = {
name: 'test provider',
icon: jest.fn(),
getManagementUrl: jest.fn().mockImplementation(function () {
return 'provider.url';
})
};
jest.mock('../hooks/use-cloud-list-provider', function () {
return {
useCloudListProvider: jest.fn().mockImplementation(function () {
return {
provider: null,
setProvider: jest.fn(),
cloudProviders: []
};
})
};
});
describe('SaveMapModal', function () {
afterEach(function () {
jest.clearAllMocks();
});
test('renders SaveMapModal component with provider set to null and map title set', function () {
var _renderWithTheme = (0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, DEFAULT_PROS)),
getByText = _renderWithTheme.getByText;
var confirmButton = getByText('modal.button.save');
expect(confirmButton).toBeInTheDocument();
expect(confirmButton).toBeDisabled();
});
test('renders SaveMapModal component with provider set to null and map title not set', function () {
var _renderWithTheme2 = (0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, UNDEFINED_MAP_TITLE_PROPS)),
getByText = _renderWithTheme2.getByText;
var confirmButton = getByText('modal.button.save');
expect(confirmButton).toBeInTheDocument();
expect(confirmButton).toBeDisabled();
});
test('renders SaveMapModal component with provider correctly set and map title not set', function () {
_useCloudListProvider.useCloudListProvider.mockImplementation(function () {
return {
provider: DEFAULT_PROVIDER,
setProvider: jest.fn(),
cloudProviders: []
};
});
var _renderWithTheme3 = (0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, UNDEFINED_MAP_TITLE_PROPS)),
getByText = _renderWithTheme3.getByText;
var confirmButton = getByText('modal.button.save');
expect(confirmButton).toBeInTheDocument();
expect(confirmButton).toBeDisabled();
});
test('renders SaveMapModal component with provider correctly set and map title set', function () {
_useCloudListProvider.useCloudListProvider.mockImplementation(function () {
return {
provider: DEFAULT_PROVIDER,
setProvider: jest.fn(),
cloudProviders: []
};
});
var _renderWithTheme4 = (0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, DEFAULT_PROS)),
getByText = _renderWithTheme4.getByText;
var confirmButton = getByText('modal.button.save');
expect(confirmButton).toBeInTheDocument();
expect(confirmButton).toBeEnabled();
});
test('calls onCancel when cancel button is clicked', function () {
var _renderWithTheme5 = (0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, DEFAULT_PROS)),
getByText = _renderWithTheme5.getByText;
_react2.fireEvent.click(getByText('modal.button.defaultCancel'));
expect(DEFAULT_PROS.onCancel).toHaveBeenCalled();
});
test('calls onConfirm with provider when confirm button is clicked', function () {
_useCloudListProvider.useCloudListProvider.mockImplementation(function () {
return {
provider: DEFAULT_PROVIDER,
setProvider: jest.fn(),
cloudProviders: []
};
});
var _renderWithTheme6 = (0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, DEFAULT_PROS)),
getByText = _renderWithTheme6.getByText;
var confirmButton = getByText('modal.button.save');
_react2.fireEvent.click(confirmButton);
expect(DEFAULT_PROS.onConfirm).toHaveBeenCalled();
});
test('does not render loading animation when isProviderLoading is true', function () {
var _renderWithTheme7 = (0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, DEFAULT_PROS)),
queryAllByTestId = _renderWithTheme7.queryAllByTestId;
expect(queryAllByTestId(_constants.dataTestIds.providerLoading)).toHaveLength(0);
});
test('renders loading animation when isProviderLoading is true', function () {
var _renderWithTheme8 = (0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, (0, _extends2["default"])({}, DEFAULT_PROS, {
isProviderLoading: true
}))),
getByTestId = _renderWithTheme8.getByTestId;
expect(getByTestId(_constants.dataTestIds.providerLoading)).toBeInTheDocument();
});
test('renders no error if provider error is undefined', function () {
var _renderWithTheme9 = (0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, DEFAULT_PROS)),
queryAllByText = _renderWithTheme9.queryAllByText;
expect(queryAllByText('modal.statusPanel.error')).toHaveLength(0);
});
test('displays provider error message when providerError is present', function () {
var _renderWithTheme10 = (0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, (0, _extends2["default"])({}, DEFAULT_PROS, {
providerError: {
message: 'Error message'
}
}))),
getByText = _renderWithTheme10.getByText;
expect(getByText('modal.statusPanel.error')).toBeInTheDocument();
});
test('call onSetMapInfo upon typing map (provider is set)', function () {
_useCloudListProvider.useCloudListProvider.mockImplementation(function () {
return {
provider: DEFAULT_PROVIDER,
setProvider: jest.fn(),
cloudProviders: []
};
});
var _renderWithTheme11 = (0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, UNDEFINED_MAP_TITLE_PROPS)),
getByTestId = _renderWithTheme11.getByTestId,
getByPlaceholderText = _renderWithTheme11.getByPlaceholderText;
var mapInfoPanel = getByTestId(_constants.dataTestIds.providerMapInfoPanel);
expect(mapInfoPanel).toBeInTheDocument();
var titleInput = getByPlaceholderText('Type map title');
expect(titleInput).toBeInTheDocument();
_react2.fireEvent.change(titleInput, {
target: {
value: 'first kepler map'
}
});
expect(DEFAULT_PROS.onSetMapInfo).toHaveBeenCalledWith({
title: 'first kepler map'
});
});
test('call onUpdateImageSetting', function () {
_useCloudListProvider.useCloudListProvider.mockImplementation(function () {
return {
provider: DEFAULT_PROVIDER,
setProvider: jest.fn(),
cloudProviders: []
};
});
(0, _componentJestUtils.renderWithTheme)( /*#__PURE__*/_react["default"].createElement(SaveMapModal, UNDEFINED_MAP_TITLE_PROPS));
// first time the component mount
expect(DEFAULT_PROS.onUpdateImageSetting).toHaveBeenCalledWith({
exporting: true
});
});
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9yZWFjdDIiLCJfc2F2ZU1hcE1vZGFsIiwiX2NvbXBvbmVudEplc3RVdGlscyIsIl91c2VDbG91ZExpc3RQcm92aWRlciIsIl9jb25zdGFudHMiLCJvd25LZXlzIiwiZSIsInIiLCJ0IiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIm8iLCJmaWx0ZXIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJkZWZpbmVQcm9wZXJ0eSIsIlNhdmVNYXBNb2RhbCIsIlNhdmVNYXBNb2RhbEZhY3RvcnkiLCJERUZBVUxUX1BST1MiLCJtYXBJbmZvIiwidGl0bGUiLCJkZXNjcmlwdGlvbiIsImV4cG9ydEltYWdlIiwiamVzdCIsImZuIiwiaXNQcm92aWRlckxvYWRpbmciLCJwcm92aWRlckVycm9yIiwib25VcGRhdGVJbWFnZVNldHRpbmciLCJjbGVhbnVwRXhwb3J0SW1hZ2UiLCJvblNldE1hcEluZm8iLCJvbkNhbmNlbCIsIm9uQ29uZmlybSIsIlVOREVGSU5FRF9NQVBfVElUTEVfUFJPUFMiLCJ1bmRlZmluZWQiLCJERUZBVUxUX1BST1ZJREVSIiwibmFtZSIsImljb24iLCJnZXRNYW5hZ2VtZW50VXJsIiwibW9ja0ltcGxlbWVudGF0aW9uIiwibW9jayIsInVzZUNsb3VkTGlzdFByb3ZpZGVyIiwicHJvdmlkZXIiLCJzZXRQcm92aWRlciIsImNsb3VkUHJvdmlkZXJzIiwiZGVzY3JpYmUiLCJhZnRlckVhY2giLCJjbGVhckFsbE1vY2tzIiwidGVzdCIsIl9yZW5kZXJXaXRoVGhlbWUiLCJyZW5kZXJXaXRoVGhlbWUiLCJjcmVhdGVFbGVtZW50IiwiZ2V0QnlUZXh0IiwiY29uZmlybUJ1dHRvbiIsImV4cGVjdCIsInRvQmVJblRoZURvY3VtZW50IiwidG9CZURpc2FibGVkIiwiX3JlbmRlcldpdGhUaGVtZTIiLCJfcmVuZGVyV2l0aFRoZW1lMyIsIl9yZW5kZXJXaXRoVGhlbWU0IiwidG9CZUVuYWJsZWQiLCJfcmVuZGVyV2l0aFRoZW1lNSIsImZpcmVFdmVudCIsImNsaWNrIiwidG9IYXZlQmVlbkNhbGxlZCIsIl9yZW5kZXJXaXRoVGhlbWU2IiwiX3JlbmRlcldpdGhUaGVtZTciLCJxdWVyeUFsbEJ5VGVzdElkIiwiZGF0YVRlc3RJZHMiLCJwcm92aWRlckxvYWRpbmciLCJ0b0hhdmVMZW5ndGgiLCJfcmVuZGVyV2l0aFRoZW1lOCIsIl9leHRlbmRzMiIsImdldEJ5VGVzdElkIiwiX3JlbmRlcldpdGhUaGVtZTkiLCJxdWVyeUFsbEJ5VGV4dCIsIl9yZW5kZXJXaXRoVGhlbWUxMCIsIm1lc3NhZ2UiLCJfcmVuZGVyV2l0aFRoZW1lMTEiLCJnZXRCeVBsYWNlaG9sZGVyVGV4dCIsIm1hcEluZm9QYW5lbCIsInByb3ZpZGVyTWFwSW5mb1BhbmVsIiwidGl0bGVJbnB1dCIsImNoYW5nZSIsInRhcmdldCIsInZhbHVlIiwidG9IYXZlQmVlbkNhbGxlZFdpdGgiLCJleHBvcnRpbmciXSwic291cmNlcyI6WyIuLi8uLi9zcmMvbW9kYWxzL3NhdmUtbWFwLW1vZGFsLnNwZWMudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbi8vIEB0cy1ub2NoZWNrXG5cbi8qKlxuICogSSBkZWNpZGVkIHRvIG1vdmUgdGhlIG5leHQgdG8gdGhlIGFjdHVhbCBmaWxlIGJlY2F1c2UgaXQgbWFrZXMgaXRcbiAqIGV4dHJlbWVseSBlYXNpZXIgdG8gbW9jayBhZG4gdGVzdCBmZWF0dXJlcy5cbiAqIEl0J3MgZWFzaWVyIHRvIG1vY2sgaXRlbXMgd2l0aCBqZXN0IHVzaW5nIHRoZSByZWxhdGl2ZSBwYXRoXG4gKiByYXRoZXIgdGhhbiB0cnlpbmcgdG8gbW9jayBpbXBvcnRzIGxpa2UgQGtlcGxlci5nbC9jb21wb25lbnRzXG4gKiB3aGljaCBjcmVhdGVzIHNldmVyYWwgc2lkZSBlZmZlY3RzLlxuICogQ29sb2NhdGluZyB0ZXN0cyBpcyBtdWNoIGVhc2llclxuICovXG5cbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQge2ZpcmVFdmVudH0gZnJvbSAnQHRlc3RpbmctbGlicmFyeS9yZWFjdCc7XG5pbXBvcnQgU2F2ZU1hcE1vZGFsRmFjdG9yeSBmcm9tICcuL3NhdmUtbWFwLW1vZGFsJztcbmltcG9ydCB7cmVuZGVyV2l0aFRoZW1lfSBmcm9tICd0ZXN0L2hlbHBlcnMvY29tcG9uZW50LWplc3QtdXRpbHMnO1xuaW1wb3J0IHt1c2VDbG91ZExpc3RQcm92aWRlcn0gZnJvbSAnLi4vaG9va3MvdXNlLWNsb3VkLWxpc3QtcHJvdmlkZXInO1xuaW1wb3J0IHtkYXRhVGVzdElkc30gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuXG5jb25zdCBTYXZlTWFwTW9kYWwgPSBTYXZlTWFwTW9kYWxGYWN0b3J5KCk7XG5cbmNvbnN0IERFRkFVTFRfUFJPUyA9IHtcbiAgbWFwSW5mbzoge1xuICAgIHRpdGxlOiAnVGVzdCBNYXAnLFxuICAgIGRlc2NyaXB0aW9uOiAndGVzdCdcbiAgfSxcbiAgZXhwb3J0SW1hZ2U6IGplc3QuZm4oKSxcbiAgaXNQcm92aWRlckxvYWRpbmc6IGZhbHNlLFxuICBwcm92aWRlckVycm9yOiBudWxsLFxuICBvblVwZGF0ZUltYWdlU2V0dGluZzogamVzdC5mbigpLFxuICBjbGVhbnVwRXhwb3J0SW1hZ2U6IGplc3QuZm4oKSxcbiAgb25TZXRNYXBJbmZvOiBqZXN0LmZuKCksXG4gIG9uQ2FuY2VsOiBqZXN0LmZuKCksXG4gIG9uQ29uZmlybTogamVzdC5mbigpXG59O1xuXG5jb25zdCBVTkRFRklORURfTUFQX1RJVExFX1BST1BTID0ge1xuICAuLi5ERUZBVUxUX1BST1MsXG4gIG1hcEluZm86IHtcbiAgICBkZXNjcmlwdGlvbjogdW5kZWZpbmVkLFxuICAgIHRpdGxlOiB1bmRlZmluZWRcbiAgfVxufTtcblxuY29uc3QgREVGQVVMVF9QUk9WSURFUiA9IHtcbiAgbmFtZTogJ3Rlc3QgcHJvdmlkZXInLFxuICBpY29uOiBqZXN0LmZuKCksXG4gIGdldE1hbmFnZW1lbnRVcmw6IGplc3QuZm4oKS5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gJ3Byb3ZpZGVyLnVybCcpXG59O1xuXG5qZXN0Lm1vY2soJy4uL2hvb2tzL3VzZS1jbG91ZC1saXN0LXByb3ZpZGVyJywgKCkgPT4gKHtcbiAgdXNlQ2xvdWRMaXN0UHJvdmlkZXI6IGplc3QuZm4oKS5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gKHtcbiAgICBwcm92aWRlcjogbnVsbCxcbiAgICBzZXRQcm92aWRlcjogamVzdC5mbigpLFxuICAgIGNsb3VkUHJvdmlkZXJzOiBbXVxuICB9KSlcbn0pKTtcblxuZGVzY3JpYmUoJ1NhdmVNYXBNb2RhbCcsICgpID0+IHtcbiAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICBqZXN0LmNsZWFyQWxsTW9ja3MoKTtcbiAgfSk7XG5cbiAgdGVzdCgncmVuZGVycyBTYXZlTWFwTW9kYWwgY29tcG9uZW50IHdpdGggcHJvdmlkZXIgc2V0IHRvIG51bGwgYW5kIG1hcCB0aXRsZSBzZXQnLCAoKSA9PiB7XG4gICAgY29uc3Qge2dldEJ5VGV4dH0gPSByZW5kZXJXaXRoVGhlbWUoPFNhdmVNYXBNb2RhbCB7Li4uREVGQVVMVF9QUk9TfSAvPik7XG4gICAgY29uc3QgY29uZmlybUJ1dHRvbiA9IGdldEJ5VGV4dCgnbW9kYWwuYnV0dG9uLnNhdmUnKTtcbiAgICBleHBlY3QoY29uZmlybUJ1dHRvbikudG9CZUluVGhlRG9jdW1lbnQoKTtcbiAgICBleHBlY3QoY29uZmlybUJ1dHRvbikudG9CZURpc2FibGVkKCk7XG4gIH0pO1xuXG4gIHRlc3QoJ3JlbmRlcnMgU2F2ZU1hcE1vZGFsIGNvbXBvbmVudCB3aXRoIHByb3ZpZGVyIHNldCB0byBudWxsIGFuZCBtYXAgdGl0bGUgbm90IHNldCcsICgpID0+IHtcbiAgICBjb25zdCB7Z2V0QnlUZXh0fSA9IHJlbmRlcldpdGhUaGVtZSg8U2F2ZU1hcE1vZGFsIHsuLi5VTkRFRklORURfTUFQX1RJVExFX1BST1BTfSAvPik7XG4gICAgY29uc3QgY29uZmlybUJ1dHRvbiA9IGdldEJ5VGV4dCgnbW9kYWwuYnV0dG9uLnNhdmUnKTtcbiAgICBleHBlY3QoY29uZmlybUJ1dHRvbikudG9CZUluVGhlRG9jdW1lbnQoKTtcbiAgICBleHBlY3QoY29uZmlybUJ1dHRvbikudG9CZURpc2FibGVkKCk7XG4gIH0pO1xuXG4gIHRlc3QoJ3JlbmRlcnMgU2F2ZU1hcE1vZGFsIGNvbXBvbmVudCB3aXRoIHByb3ZpZGVyIGNvcnJlY3RseSBzZXQgYW5kIG1hcCB0aXRsZSBub3Qgc2V0JywgKCkgPT4ge1xuICAgIHVzZUNsb3VkTGlzdFByb3ZpZGVyLm1vY2tJbXBsZW1lbnRhdGlvbigoKSA9PiAoe1xuICAgICAgcHJvdmlkZXI6IERFRkFVTFRfUFJPVklERVIsXG4gICAgICBzZXRQcm92aWRlcjogamVzdC5mbigpLFxuICAgICAgY2xvdWRQcm92aWRlcnM6IFtdXG4gICAgfSkpO1xuICAgIGNvbnN0IHtnZXRCeVRleHR9ID0gcmVuZGVyV2l0aFRoZW1lKDxTYXZlTWFwTW9kYWwgey4uLlVOREVGSU5FRF9NQVBfVElUTEVfUFJPUFN9IC8+KTtcbiAgICBjb25zdCBjb25maXJtQnV0dG9uID0gZ2V0QnlUZXh0KCdtb2RhbC5idXR0b24uc2F2ZScpO1xuICAgIGV4cGVjdChjb25maXJtQnV0dG9uKS50b0JlSW5UaGVEb2N1bWVudCgpO1xuICAgIGV4cGVjdChjb25maXJtQnV0dG9uKS50b0JlRGlzYWJsZWQoKTtcbiAgfSk7XG5cbiAgdGVzdCgncmVuZGVycyBTYXZlTWFwTW9kYWwgY29tcG9uZW50IHdpdGggcHJvdmlkZXIgY29ycmVjdGx5IHNldCBhbmQgbWFwIHRpdGxlIHNldCcsICgpID0+IHtcbiAgICB1c2VDbG91ZExpc3RQcm92aWRlci5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gKHtcbiAgICAgIHByb3ZpZGVyOiBERUZBVUxUX1BST1ZJREVSLFxuICAgICAgc2V0UHJvdmlkZXI6IGplc3QuZm4oKSxcbiAgICAgIGNsb3VkUHJvdmlkZXJzOiBbXVxuICAgIH0pKTtcbiAgICBjb25zdCB7Z2V0QnlUZXh0fSA9IHJlbmRlcldpdGhUaGVtZSg8U2F2ZU1hcE1vZGFsIHsuLi5ERUZBVUxUX1BST1N9IC8+KTtcbiAgICBjb25zdCBjb25maXJtQnV0dG9uID0gZ2V0QnlUZXh0KCdtb2RhbC5idXR0b24uc2F2ZScpO1xuICAgIGV4cGVjdChjb25maXJtQnV0dG9uKS50b0JlSW5UaGVEb2N1bWVudCgpO1xuICAgIGV4cGVjdChjb25maXJtQnV0dG9uKS50b0JlRW5hYmxlZCgpO1xuICB9KTtcblxuICB0ZXN0KCdjYWxscyBvbkNhbmNlbCB3aGVuIGNhbmNlbCBidXR0b24gaXMgY2xpY2tlZCcsICgpID0+IHtcbiAgICBjb25zdCB7Z2V0QnlUZXh0fSA9IHJlbmRlcldpdGhUaGVtZSg8U2F2ZU1hcE1vZGFsIHsuLi5ERUZBVUxUX1BST1N9IC8+KTtcbiAgICBmaXJlRXZlbnQuY2xpY2soZ2V0QnlUZXh0KCdtb2RhbC5idXR0b24uZGVmYXVsdENhbmNlbCcpKTtcbiAgICBleHBlY3QoREVGQVVMVF9QUk9TLm9uQ2FuY2VsKS50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gIH0pO1xuXG4gIHRlc3QoJ2NhbGxzIG9uQ29uZmlybSB3aXRoIHByb3ZpZGVyIHdoZW4gY29uZmlybSBidXR0b24gaXMgY2xpY2tlZCcsICgpID0+IHtcbiAgICB1c2VDbG91ZExpc3RQcm92aWRlci5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gKHtcbiAgICAgIHByb3ZpZGVyOiBERUZBVUxUX1BST1ZJREVSLFxuICAgICAgc2V0UHJvdmlkZXI6IGplc3QuZm4oKSxcbiAgICAgIGNsb3VkUHJvdmlkZXJzOiBbXVxuICAgIH0pKTtcbiAgICBjb25zdCB7Z2V0QnlUZXh0fSA9IHJlbmRlcldpdGhUaGVtZSg8U2F2ZU1hcE1vZGFsIHsuLi5ERUZBVUxUX1BST1N9IC8+KTtcbiAgICBjb25zdCBjb25maXJtQnV0dG9uID0gZ2V0QnlUZXh0KCdtb2RhbC5idXR0b24uc2F2ZScpO1xuICAgIGZpcmVFdmVudC5jbGljayhjb25maXJtQnV0dG9uKTtcbiAgICBleHBlY3QoREVGQVVMVF9QUk9TLm9uQ29uZmlybSkudG9IYXZlQmVlbkNhbGxlZCgpO1xuICB9KTtcblxuICB0ZXN0KCdkb2VzIG5vdCByZW5kZXIgbG9hZGluZyBhbmltYXRpb24gd2hlbiBpc1Byb3ZpZGVyTG9hZGluZyBpcyB0cnVlJywgKCkgPT4ge1xuICAgIGNvbnN0IHtxdWVyeUFsbEJ5VGVzdElkfSA9IHJlbmRlcldpdGhUaGVtZSg8U2F2ZU1hcE1vZGFsIHsuLi5ERUZBVUxUX1BST1N9IC8+KTtcbiAgICBleHBlY3QocXVlcnlBbGxCeVRlc3RJZChkYXRhVGVzdElkcy5wcm92aWRlckxvYWRpbmcpKS50b0hhdmVMZW5ndGgoMCk7XG4gIH0pO1xuXG4gIHRlc3QoJ3JlbmRlcnMgbG9hZGluZyBhbmltYXRpb24gd2hlbiBpc1Byb3ZpZGVyTG9hZGluZyBpcyB0cnVlJywgKCkgPT4ge1xuICAgIGNvbnN0IHtnZXRCeVRlc3RJZH0gPSByZW5kZXJXaXRoVGhlbWUoXG4gICAgICA8U2F2ZU1hcE1vZGFsIHsuLi5ERUZBVUxUX1BST1N9IGlzUHJvdmlkZXJMb2FkaW5nPXt0cnVlfSAvPlxuICAgICk7XG4gICAgZXhwZWN0KGdldEJ5VGVzdElkKGRhdGFUZXN0SWRzLnByb3ZpZGVyTG9hZGluZykpLnRvQmVJblRoZURvY3VtZW50KCk7XG4gIH0pO1xuXG4gIHRlc3QoJ3JlbmRlcnMgbm8gZXJyb3IgaWYgcHJvdmlkZXIgZXJyb3IgaXMgdW5kZWZpbmVkJywgKCkgPT4ge1xuICAgIGNvbnN0IHtxdWVyeUFsbEJ5VGV4dH0gPSByZW5kZXJXaXRoVGhlbWUoPFNhdmVNYXBNb2RhbCB7Li4uREVGQVVMVF9QUk9TfSAvPik7XG4gICAgZXhwZWN0KHF1ZXJ5QWxsQnlUZXh0KCdtb2RhbC5zdGF0dXNQYW5lbC5lcnJvcicpKS50b0hhdmVMZW5ndGgoMCk7XG4gIH0pO1xuXG4gIHRlc3QoJ2Rpc3BsYXlzIHByb3ZpZGVyIGVycm9yIG1lc3NhZ2Ugd2hlbiBwcm92aWRlckVycm9yIGlzIHByZXNlbnQnLCAoKSA9PiB7XG4gICAgY29uc3Qge2dldEJ5VGV4dH0gPSByZW5kZXJXaXRoVGhlbWUoXG4gICAgICA8U2F2ZU1hcE1vZGFsIHsuLi5ERUZBVUxUX1BST1N9IHByb3ZpZGVyRXJyb3I9e3ttZXNzYWdlOiAnRXJyb3IgbWVzc2FnZSd9fSAvPlxuICAgICk7XG4gICAgZXhwZWN0KGdldEJ5VGV4dCgnbW9kYWwuc3RhdHVzUGFuZWwuZXJyb3InKSkudG9CZUluVGhlRG9jdW1lbnQoKTtcbiAgfSk7XG5cbiAgdGVzdCgnY2FsbCBvblNldE1hcEluZm8gdXBvbiB0eXBpbmcgbWFwIChwcm92aWRlciBpcyBzZXQpJywgKCkgPT4ge1xuICAgIHVzZUNsb3VkTGlzdFByb3ZpZGVyLm1vY2tJbXBsZW1lbnRhdGlvbigoKSA9PiAoe1xuICAgICAgcHJvdmlkZXI6IERFRkFVTFRfUFJPVklERVIsXG4gICAgICBzZXRQcm92aWRlcjogamVzdC5mbigpLFxuICAgICAgY2xvdWRQcm92aWRlcnM6IFtdXG4gICAgfSkpO1xuICAgIGNvbnN0IHtnZXRCeVRlc3RJZCwgZ2V0QnlQbGFjZWhvbGRlclRleHR9ID0gcmVuZGVyV2l0aFRoZW1lKFxuICAgICAgPFNhdmVNYXBNb2RhbCB7Li4uVU5ERUZJTkVEX01BUF9USVRMRV9QUk9QU30gLz5cbiAgICApO1xuXG4gICAgY29uc3QgbWFwSW5mb1BhbmVsID0gZ2V0QnlUZXN0SWQoZGF0YVRlc3RJZHMucHJvdmlkZXJNYXBJbmZvUGFuZWwpO1xuICAgIGV4cGVjdChtYXBJbmZvUGFuZWwpLnRvQmVJblRoZURvY3VtZW50KCk7XG5cbiAgICBjb25zdCB0aXRsZUlucHV0ID0gZ2V0QnlQbGFjZWhvbGRlclRleHQoJ1R5cGUgbWFwIHRpdGxlJyk7XG4gICAgZXhwZWN0KHRpdGxlSW5wdXQpLnRvQmVJblRoZURvY3VtZW50KCk7XG5cbiAgICBmaXJlRXZlbnQuY2hhbmdlKHRpdGxlSW5wdXQsIHt0YXJnZXQ6IHt2YWx1ZTogJ2ZpcnN0IGtlcGxlciBtYXAnfX0pO1xuICAgIGV4cGVjdChERUZBVUxUX1BST1Mub25TZXRNYXBJbmZvKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh7dGl0bGU6ICdmaXJzdCBrZXBsZXIgbWFwJ30pO1xuICB9KTtcblxuICB0ZXN0KCdjYWxsIG9uVXBkYXRlSW1hZ2VTZXR0aW5nJywgKCkgPT4ge1xuICAgIHVzZUNsb3VkTGlzdFByb3ZpZGVyLm1vY2tJbXBsZW1lbnRhdGlvbigoKSA9PiAoe1xuICAgICAgcHJvdmlkZXI6IERFRkFVTFRfUFJPVklERVIsXG4gICAgICBzZXRQcm92aWRlcjogamVzdC5mbigpLFxuICAgICAgY2xvdWRQcm92aWRlcnM6IFtdXG4gICAgfSkpO1xuXG4gICAgcmVuZGVyV2l0aFRoZW1lKDxTYXZlTWFwTW9kYWwgey4uLlVOREVGSU5FRF9NQVBfVElUTEVfUFJPUFN9IC8+KTtcblxuICAgIC8vIGZpcnN0IHRpbWUgdGhlIGNvbXBvbmVudCBtb3VudFxuICAgIGV4cGVjdChERUZBVUxUX1BST1Mub25VcGRhdGVJbWFnZVNldHRpbmcpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcbiAgICAgIGV4cG9ydGluZzogdHJ1ZVxuICAgIH0pO1xuICB9KTtcbn0pO1xuIl0sIm1hcHBpbmdzIjoiOzs7OztBQWNBLElBQUFBLE1BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLE9BQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLGFBQUEsR0FBQUgsc0JBQUEsQ0FBQUMsT0FBQTtBQUNB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
;