Ensure no deprecated Node.js core API's are used in Kibana. This is achieved by throwing an error in either development mode or in CI if one of the deprecated API's is called, and as such, new PR's should no longer be able to be merged if they use deprecated API's. Some of these API's (like the `Buffer` constructor`) is a security risk.
This commit is contained in:
parent
dfc0612f26
commit
995a914f63
|
@ -53,7 +53,7 @@
|
||||||
"typespec": "typings-tester --config x-pack/legacy/plugins/canvas/public/lib/aeroelastic/tsconfig.json x-pack/legacy/plugins/canvas/public/lib/aeroelastic/__fixtures__/typescript/typespec_tests.ts",
|
"typespec": "typings-tester --config x-pack/legacy/plugins/canvas/public/lib/aeroelastic/tsconfig.json x-pack/legacy/plugins/canvas/public/lib/aeroelastic/__fixtures__/typescript/typespec_tests.ts",
|
||||||
"checkLicenses": "node scripts/check_licenses --dev",
|
"checkLicenses": "node scripts/check_licenses --dev",
|
||||||
"build": "node scripts/build --all-platforms",
|
"build": "node scripts/build --all-platforms",
|
||||||
"start": "node --trace-warnings --trace-deprecation scripts/kibana --dev ",
|
"start": "node --trace-warnings --throw-deprecation scripts/kibana --dev",
|
||||||
"debug": "node --nolazy --inspect scripts/kibana --dev",
|
"debug": "node --nolazy --inspect scripts/kibana --dev",
|
||||||
"debug-break": "node --nolazy --inspect-brk scripts/kibana --dev",
|
"debug-break": "node --nolazy --inspect-brk scripts/kibana --dev",
|
||||||
"karma": "karma start",
|
"karma": "karma start",
|
||||||
|
@ -401,7 +401,6 @@
|
||||||
"gulp-sourcemaps": "2.6.5",
|
"gulp-sourcemaps": "2.6.5",
|
||||||
"has-ansi": "^3.0.0",
|
"has-ansi": "^3.0.0",
|
||||||
"iedriver": "^3.14.1",
|
"iedriver": "^3.14.1",
|
||||||
"image-diff": "1.6.3",
|
|
||||||
"intl-messageformat-parser": "^1.4.0",
|
"intl-messageformat-parser": "^1.4.0",
|
||||||
"is-path-inside": "^2.1.0",
|
"is-path-inside": "^2.1.0",
|
||||||
"istanbul-instrumenter-loader": "3.0.1",
|
"istanbul-instrumenter-loader": "3.0.1",
|
||||||
|
@ -429,7 +428,7 @@
|
||||||
"node-sass": "^4.9.4",
|
"node-sass": "^4.9.4",
|
||||||
"normalize-path": "^3.0.0",
|
"normalize-path": "^3.0.0",
|
||||||
"nyc": "^14.1.1",
|
"nyc": "^14.1.1",
|
||||||
"pixelmatch": "4.0.2",
|
"pixelmatch": "^5.1.0",
|
||||||
"pkg-up": "^2.0.0",
|
"pkg-up": "^2.0.0",
|
||||||
"pngjs": "^3.4.0",
|
"pngjs": "^3.4.0",
|
||||||
"postcss": "^7.0.5",
|
"postcss": "^7.0.5",
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
import { canRequire } from './can_require';
|
import { canRequire } from './can_require';
|
||||||
import { dependenciesVisitorsGenerator } from './visitors';
|
import { dependenciesVisitorsGenerator } from './visitors';
|
||||||
import { dirname, isAbsolute, resolve } from 'path';
|
import { dirname, isAbsolute, resolve } from 'path';
|
||||||
|
import { builtinModules } from 'module';
|
||||||
|
|
||||||
export function _calculateTopLevelDependency(inputDep, outputDep = '') {
|
export function _calculateTopLevelDependency(inputDep, outputDep = '') {
|
||||||
// The path separator will be always the forward slash
|
// The path separator will be always the forward slash
|
||||||
|
@ -48,14 +49,18 @@ export function _calculateTopLevelDependency(inputDep, outputDep = '') {
|
||||||
return _calculateTopLevelDependency(depSplitPaths.join(pathSeparator), outputDep);
|
return _calculateTopLevelDependency(depSplitPaths.join(pathSeparator), outputDep);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function dependenciesParseStrategy(cwd, parseSingleFile, mainEntry, wasParsed, results) {
|
export async function dependenciesParseStrategy(
|
||||||
// Retrieve native nodeJS modules
|
cwd,
|
||||||
const natives = process.binding('natives');
|
parseSingleFile,
|
||||||
|
mainEntry,
|
||||||
|
wasParsed,
|
||||||
|
results
|
||||||
|
) {
|
||||||
// Get dependencies from a single file and filter
|
// Get dependencies from a single file and filter
|
||||||
// out node native modules from the result
|
// out node native modules from the result
|
||||||
const dependencies = (await parseSingleFile(mainEntry, dependenciesVisitorsGenerator))
|
const dependencies = (await parseSingleFile(mainEntry, dependenciesVisitorsGenerator)).filter(
|
||||||
.filter(dep => !natives[dep]);
|
dep => !builtinModules.includes(dep)
|
||||||
|
);
|
||||||
|
|
||||||
// Return the list of all the new entries found into
|
// Return the list of all the new entries found into
|
||||||
// the current mainEntry that we could use to look for
|
// the current mainEntry that we could use to look for
|
||||||
|
|
|
@ -41,19 +41,9 @@ module.exports = function rewritePackage(buildSource, buildVersion, kibanaVersio
|
||||||
delete pkg.scripts;
|
delete pkg.scripts;
|
||||||
delete pkg.devDependencies;
|
delete pkg.devDependencies;
|
||||||
|
|
||||||
file.contents = toBuffer(JSON.stringify(pkg, null, 2));
|
file.contents = Buffer.from(JSON.stringify(pkg, null, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function toBuffer(string) {
|
|
||||||
if (typeof Buffer.from === 'function') {
|
|
||||||
return Buffer.from(string, 'utf8');
|
|
||||||
} else {
|
|
||||||
// this was deprecated in node v5 in favor
|
|
||||||
// of Buffer.from(string, encoding)
|
|
||||||
return new Buffer(string, 'utf8');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -329,7 +329,7 @@ describe('Response factory', () => {
|
||||||
const router = createRouter('/');
|
const router = createRouter('/');
|
||||||
|
|
||||||
router.get({ path: '/', validate: false }, (context, req, res) => {
|
router.get({ path: '/', validate: false }, (context, req, res) => {
|
||||||
const buffer = new Buffer('abc');
|
const buffer = Buffer.from('abc');
|
||||||
|
|
||||||
return res.ok({
|
return res.ok({
|
||||||
body: buffer,
|
body: buffer,
|
||||||
|
|
|
@ -14,6 +14,8 @@ cacheDir="$HOME/.kibana"
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
C_RESET='\033[0m' # Reset color
|
C_RESET='\033[0m' # Reset color
|
||||||
|
|
||||||
|
export NODE_OPTIONS="$NODE_OPTIONS --throw-deprecation"
|
||||||
|
|
||||||
###
|
###
|
||||||
### Since the Jenkins logging output collector doesn't look like a TTY
|
### Since the Jenkins logging output collector doesn't look like a TTY
|
||||||
### Node/Chalk and other color libs disable their color output. But Jenkins
|
### Node/Chalk and other color libs disable their color output. But Jenkins
|
||||||
|
|
|
@ -28,7 +28,7 @@ import { ProxyConfigCollection } from '../proxy_config_collection';
|
||||||
|
|
||||||
describe('ProxyConfigCollection', function () {
|
describe('ProxyConfigCollection', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
sinon.stub(fs, 'readFileSync').callsFake(() => new Buffer(0));
|
sinon.stub(fs, 'readFileSync').callsFake(() => Buffer.alloc(0));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
|
|
|
@ -43,6 +43,7 @@ const indexPatternsService = {
|
||||||
make: async () => ({
|
make: async () => ({
|
||||||
fieldsFetcher: {
|
fieldsFetcher: {
|
||||||
fetch: noop,
|
fetch: noop,
|
||||||
|
fetchForWildcard: noop,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
|
@ -75,7 +75,7 @@ describe('telemetry_usage_collector', () => {
|
||||||
// empty
|
// empty
|
||||||
writeFileSync(tempFiles.empty, '');
|
writeFileSync(tempFiles.empty, '');
|
||||||
// 1 byte too big
|
// 1 byte too big
|
||||||
writeFileSync(tempFiles.too_big, new Buffer(MAX_FILE_SIZE + 1));
|
writeFileSync(tempFiles.too_big, Buffer.alloc(MAX_FILE_SIZE + 1));
|
||||||
// write-only file
|
// write-only file
|
||||||
writeFileSync(tempFiles.unreadable, 'valid: true', { mode: 0o222 });
|
writeFileSync(tempFiles.unreadable, 'valid: true', { mode: 0o222 });
|
||||||
// valid
|
// valid
|
||||||
|
|
|
@ -95,16 +95,16 @@ describe('yaxis.js', () => {
|
||||||
|
|
||||||
it('throws an error if currency is not three letter code', () => {
|
it('throws an error if currency is not three letter code', () => {
|
||||||
invoke(fn, [seriesList, 1, null, null, null, null, null, 'currency:abcde']).catch(e => {
|
invoke(fn, [seriesList, 1, null, null, null, null, null, 'currency:abcde']).catch(e => {
|
||||||
expect(e).to.be.an(Error);
|
expect(e).to.be.an.instanceof(Error);
|
||||||
});
|
});
|
||||||
invoke(fn, [seriesList, 1, null, null, null, null, null, 'currency:12']).catch(e => {
|
invoke(fn, [seriesList, 1, null, null, null, null, null, 'currency:12']).catch(e => {
|
||||||
expect(e).to.be.an(Error);
|
expect(e).to.be.an.instanceof(Error);
|
||||||
});
|
});
|
||||||
invoke(fn, [seriesList, 1, null, null, null, null, null, 'currency:$#']).catch(e => {
|
invoke(fn, [seriesList, 1, null, null, null, null, null, 'currency:$#']).catch(e => {
|
||||||
expect(e).to.be.an(Error);
|
expect(e).to.be.an.instanceof(Error);
|
||||||
});
|
});
|
||||||
invoke(fn, [seriesList, 1, null, null, null, null, null, 'currency:ab']).catch(e => {
|
invoke(fn, [seriesList, 1, null, null, null, null, null, 'currency:ab']).catch(e => {
|
||||||
expect(e).to.be.an(Error);
|
expect(e).to.be.an.instanceof(Error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ import { PUBLIC_PATH_PLACEHOLDER } from '../../../optimize/public_path_placehold
|
||||||
|
|
||||||
const renderSass = promisify(sass.render);
|
const renderSass = promisify(sass.render);
|
||||||
const writeFile = promisify(fs.writeFile);
|
const writeFile = promisify(fs.writeFile);
|
||||||
const exists = promisify(fs.exists);
|
const access = promisify(fs.access);
|
||||||
const copyFile = promisify(fs.copyFile);
|
const copyFile = promisify(fs.copyFile);
|
||||||
const mkdirAsync = promisify(fs.mkdir);
|
const mkdirAsync = promisify(fs.mkdir);
|
||||||
|
|
||||||
|
@ -145,23 +145,27 @@ export class Build {
|
||||||
];
|
];
|
||||||
|
|
||||||
// verify that asset sources exist and import is valid before writing anything
|
// verify that asset sources exist and import is valid before writing anything
|
||||||
await Promise.all(urlAssets.map(async (asset) => {
|
await Promise.all(
|
||||||
if (!await exists(asset.path)) {
|
urlAssets.map(async asset => {
|
||||||
throw this._makeError(
|
try {
|
||||||
'Invalid url() in css output',
|
await access(asset.path);
|
||||||
`url("${asset.requestUrl}") resolves to "${asset.path}", which does not exist.\n` +
|
} catch (e) {
|
||||||
` Make sure that the request is relative to "${asset.root}"`
|
throw this._makeError(
|
||||||
);
|
'Invalid url() in css output',
|
||||||
}
|
`url("${asset.requestUrl}") resolves to "${asset.path}", which does not exist.\n` +
|
||||||
|
` Make sure that the request is relative to "${asset.root}"`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!isPathInside(asset.path, asset.boundry)) {
|
if (!isPathInside(asset.path, asset.boundry)) {
|
||||||
throw this._makeError(
|
throw this._makeError(
|
||||||
'Invalid url() in css output',
|
'Invalid url() in css output',
|
||||||
`url("${asset.requestUrl}") resolves to "${asset.path}"\n` +
|
`url("${asset.requestUrl}") resolves to "${asset.path}"\n` +
|
||||||
` which is outside of "${asset.boundry}"`
|
` which is outside of "${asset.boundry}"`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// write css
|
// write css
|
||||||
await mkdirAsync(this.targetDir, { recursive: true });
|
await mkdirAsync(this.targetDir, { recursive: true });
|
||||||
|
|
|
@ -40,3 +40,53 @@ const chrome = {
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default chrome;
|
export default chrome;
|
||||||
|
|
||||||
|
// Copied from `src/legacy/ui/public/chrome/chrome.js`
|
||||||
|
import _ from 'lodash';
|
||||||
|
import angular from 'angular';
|
||||||
|
import { metadata } from '../../metadata';
|
||||||
|
|
||||||
|
const internals = _.defaults(
|
||||||
|
_.cloneDeep(metadata),
|
||||||
|
{
|
||||||
|
basePath: '',
|
||||||
|
rootController: null,
|
||||||
|
rootTemplate: null,
|
||||||
|
showAppsLink: null,
|
||||||
|
xsrfToken: null,
|
||||||
|
devMode: true,
|
||||||
|
brand: null,
|
||||||
|
nav: [],
|
||||||
|
applicationClasses: []
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const waitForBootstrap = new Promise(resolve => {
|
||||||
|
chrome.bootstrap = function (targetDomElement) {
|
||||||
|
// import chrome nav controls and hacks now so that they are executed after
|
||||||
|
// everything else, can safely import the chrome, and interact with services
|
||||||
|
// and such setup by all other modules
|
||||||
|
require('uiExports/chromeNavControls');
|
||||||
|
require('uiExports/hacks');
|
||||||
|
|
||||||
|
// sets attribute on body for stylesheet sandboxing
|
||||||
|
document.body.setAttribute('id', `${internals.app.id}-app`);
|
||||||
|
|
||||||
|
chrome.setupAngular();
|
||||||
|
targetDomElement.setAttribute('kbn-chrome', 'true');
|
||||||
|
targetDomElement.setAttribute('ng-class', '{ \'hidden-chrome\': !chrome.getVisible() }');
|
||||||
|
targetDomElement.className = 'app-wrapper';
|
||||||
|
angular.bootstrap(targetDomElement, ['kibana']);
|
||||||
|
resolve(targetDomElement);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
chrome.dangerouslyGetActiveInjector = () => {
|
||||||
|
return waitForBootstrap.then((targetDomElement) => {
|
||||||
|
const $injector = angular.element(targetDomElement).injector();
|
||||||
|
if (!$injector) {
|
||||||
|
return Promise.reject('targetDomElement had no angular context after bootstrapping');
|
||||||
|
}
|
||||||
|
return $injector;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
@ -52,7 +52,7 @@ describe('deepCloneWithBuffers()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('copies buffers but keeps them buffers', () => {
|
it('copies buffers but keeps them buffers', () => {
|
||||||
const input = new Buffer('i am a teapot', 'utf8');
|
const input = Buffer.from('i am a teapot', 'utf8');
|
||||||
const output = deepCloneWithBuffers(input);
|
const output = deepCloneWithBuffers(input);
|
||||||
|
|
||||||
expect(Buffer.isBuffer(input)).toBe(true);
|
expect(Buffer.isBuffer(input)).toBe(true);
|
||||||
|
@ -65,7 +65,7 @@ describe('deepCloneWithBuffers()', () => {
|
||||||
const input = {
|
const input = {
|
||||||
a: {
|
a: {
|
||||||
b: {
|
b: {
|
||||||
c: new Buffer('i am a teapot', 'utf8'),
|
c: Buffer.from('i am a teapot', 'utf8'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { cloneDeep } from 'lodash';
|
||||||
// type of the customizer function doesn't expect that.
|
// type of the customizer function doesn't expect that.
|
||||||
function cloneBuffersCustomizer(val: unknown): any {
|
function cloneBuffersCustomizer(val: unknown): any {
|
||||||
if (Buffer.isBuffer(val)) {
|
if (Buffer.isBuffer(val)) {
|
||||||
return new Buffer(val);
|
return Buffer.from(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ import del from 'del';
|
||||||
|
|
||||||
const readFileAsync = promisify(fs.readFile);
|
const readFileAsync = promisify(fs.readFile);
|
||||||
const mkdirAsync = promisify(fs.mkdir);
|
const mkdirAsync = promisify(fs.mkdir);
|
||||||
const existsAsync = promisify(fs.exists);
|
const accessAsync = promisify(fs.access);
|
||||||
const writeFileAsync = promisify(fs.writeFile);
|
const writeFileAsync = promisify(fs.writeFile);
|
||||||
|
|
||||||
export class DllCompiler {
|
export class DllCompiler {
|
||||||
|
@ -127,13 +127,14 @@ export class DllCompiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
async ensurePathExists(filePath) {
|
async ensurePathExists(filePath) {
|
||||||
const exists = await existsAsync(filePath);
|
try {
|
||||||
|
await accessAsync(filePath);
|
||||||
if (!exists) {
|
} catch (e) {
|
||||||
await mkdirAsync(path.dirname(filePath), { recursive: true });
|
await mkdirAsync(path.dirname(filePath), { recursive: true });
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return exists;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async ensureOutputPathExists() {
|
async ensureOutputPathExists() {
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { isErrorEmbeddable, EmbeddableFactory } from '../embeddable_plugin';
|
import { isErrorEmbeddable, EmbeddableFactory } from '../embeddable_plugin';
|
||||||
import { ReplacePanelAction } from './replace_panel_action';
|
import { ReplacePanelAction } from './replace_panel_action';
|
||||||
import { DashboardContainer } from '../embeddable';
|
import { DashboardContainer } from '../embeddable';
|
||||||
|
@ -29,6 +28,8 @@ import {
|
||||||
ContactCardEmbeddableOutput,
|
ContactCardEmbeddableOutput,
|
||||||
} from '../embeddable_plugin_test_samples';
|
} from '../embeddable_plugin_test_samples';
|
||||||
import { DashboardOptions } from '../embeddable/dashboard_container_factory';
|
import { DashboardOptions } from '../embeddable/dashboard_container_factory';
|
||||||
|
import { coreMock } from '../../../../core/public/mocks';
|
||||||
|
import { CoreStart } from 'kibana/public';
|
||||||
|
|
||||||
const embeddableFactories = new Map<string, EmbeddableFactory>();
|
const embeddableFactories = new Map<string, EmbeddableFactory>();
|
||||||
embeddableFactories.set(
|
embeddableFactories.set(
|
||||||
|
@ -39,8 +40,9 @@ const getEmbeddableFactories = () => embeddableFactories.values();
|
||||||
|
|
||||||
let container: DashboardContainer;
|
let container: DashboardContainer;
|
||||||
let embeddable: ContactCardEmbeddable;
|
let embeddable: ContactCardEmbeddable;
|
||||||
|
let coreStart: CoreStart;
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
coreStart = coreMock.createStart();
|
||||||
const options: DashboardOptions = {
|
const options: DashboardOptions = {
|
||||||
ExitFullScreenButton: () => null,
|
ExitFullScreenButton: () => null,
|
||||||
SavedObjectFinder: () => null,
|
SavedObjectFinder: () => null,
|
||||||
|
@ -50,7 +52,7 @@ beforeEach(async () => {
|
||||||
} as any,
|
} as any,
|
||||||
inspector: {} as any,
|
inspector: {} as any,
|
||||||
notifications: {} as any,
|
notifications: {} as any,
|
||||||
overlays: {} as any,
|
overlays: coreStart.overlays,
|
||||||
savedObjectMetaData: {} as any,
|
savedObjectMetaData: {} as any,
|
||||||
uiActions: {} as any,
|
uiActions: {} as any,
|
||||||
};
|
};
|
||||||
|
@ -80,11 +82,10 @@ beforeEach(async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Executes the replace panel action', async () => {
|
test('Executes the replace panel action', async () => {
|
||||||
let core: any;
|
|
||||||
let SavedObjectFinder: any;
|
let SavedObjectFinder: any;
|
||||||
let notifications: any;
|
let notifications: any;
|
||||||
const action = new ReplacePanelAction(
|
const action = new ReplacePanelAction(
|
||||||
core,
|
coreStart,
|
||||||
SavedObjectFinder,
|
SavedObjectFinder,
|
||||||
notifications,
|
notifications,
|
||||||
getEmbeddableFactories
|
getEmbeddableFactories
|
||||||
|
@ -93,11 +94,10 @@ test('Executes the replace panel action', async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Is not compatible when embeddable is not in a dashboard container', async () => {
|
test('Is not compatible when embeddable is not in a dashboard container', async () => {
|
||||||
let core: any;
|
|
||||||
let SavedObjectFinder: any;
|
let SavedObjectFinder: any;
|
||||||
let notifications: any;
|
let notifications: any;
|
||||||
const action = new ReplacePanelAction(
|
const action = new ReplacePanelAction(
|
||||||
core,
|
coreStart,
|
||||||
SavedObjectFinder,
|
SavedObjectFinder,
|
||||||
notifications,
|
notifications,
|
||||||
getEmbeddableFactories
|
getEmbeddableFactories
|
||||||
|
@ -113,11 +113,10 @@ test('Is not compatible when embeddable is not in a dashboard container', async
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Execute throws an error when called with an embeddable not in a parent', async () => {
|
test('Execute throws an error when called with an embeddable not in a parent', async () => {
|
||||||
let core: any;
|
|
||||||
let SavedObjectFinder: any;
|
let SavedObjectFinder: any;
|
||||||
let notifications: any;
|
let notifications: any;
|
||||||
const action = new ReplacePanelAction(
|
const action = new ReplacePanelAction(
|
||||||
core,
|
coreStart,
|
||||||
SavedObjectFinder,
|
SavedObjectFinder,
|
||||||
notifications,
|
notifications,
|
||||||
getEmbeddableFactories
|
getEmbeddableFactories
|
||||||
|
@ -129,11 +128,10 @@ test('Execute throws an error when called with an embeddable not in a parent', a
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Returns title', async () => {
|
test('Returns title', async () => {
|
||||||
let core: any;
|
|
||||||
let SavedObjectFinder: any;
|
let SavedObjectFinder: any;
|
||||||
let notifications: any;
|
let notifications: any;
|
||||||
const action = new ReplacePanelAction(
|
const action = new ReplacePanelAction(
|
||||||
core,
|
coreStart,
|
||||||
SavedObjectFinder,
|
SavedObjectFinder,
|
||||||
notifications,
|
notifications,
|
||||||
getEmbeddableFactories
|
getEmbeddableFactories
|
||||||
|
@ -142,11 +140,10 @@ test('Returns title', async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Returns an icon', async () => {
|
test('Returns an icon', async () => {
|
||||||
let core: any;
|
|
||||||
let SavedObjectFinder: any;
|
let SavedObjectFinder: any;
|
||||||
let notifications: any;
|
let notifications: any;
|
||||||
const action = new ReplacePanelAction(
|
const action = new ReplacePanelAction(
|
||||||
core,
|
coreStart,
|
||||||
SavedObjectFinder,
|
SavedObjectFinder,
|
||||||
notifications,
|
notifications,
|
||||||
getEmbeddableFactories
|
getEmbeddableFactories
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
import sizeMe from 'react-sizeme';
|
import sizeMe from 'react-sizeme';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { nextTick, mountWithIntl } from 'test_utils/enzyme_helpers';
|
import { mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
import { skip } from 'rxjs/operators';
|
import { skip } from 'rxjs/operators';
|
||||||
import { EmbeddableFactory, GetEmbeddableFactory } from '../../embeddable_plugin';
|
import { EmbeddableFactory, GetEmbeddableFactory } from '../../embeddable_plugin';
|
||||||
import { DashboardGrid, DashboardGridProps } from './dashboard_grid';
|
import { DashboardGrid, DashboardGridProps } from './dashboard_grid';
|
||||||
|
@ -65,10 +65,14 @@ function prepare(props?: Partial<DashboardGridProps>) {
|
||||||
} as any,
|
} as any,
|
||||||
notifications: {} as any,
|
notifications: {} as any,
|
||||||
overlays: {} as any,
|
overlays: {} as any,
|
||||||
inspector: {} as any,
|
inspector: {
|
||||||
|
isAvailable: jest.fn(),
|
||||||
|
} as any,
|
||||||
SavedObjectFinder: () => null,
|
SavedObjectFinder: () => null,
|
||||||
ExitFullScreenButton: () => null,
|
ExitFullScreenButton: () => null,
|
||||||
uiActions: {} as any,
|
uiActions: {
|
||||||
|
getTriggerCompatibleActions: (() => []) as any,
|
||||||
|
} as any,
|
||||||
};
|
};
|
||||||
dashboardContainer = new DashboardContainer(initialInput, options);
|
dashboardContainer = new DashboardContainer(initialInput, options);
|
||||||
const defaultTestProps: DashboardGridProps = {
|
const defaultTestProps: DashboardGridProps = {
|
||||||
|
@ -100,12 +104,11 @@ test('renders DashboardGrid', () => {
|
||||||
<DashboardGrid {...props} />
|
<DashboardGrid {...props} />
|
||||||
</KibanaContextProvider>
|
</KibanaContextProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
const panelElements = component.find('EmbeddableChildPanel');
|
const panelElements = component.find('EmbeddableChildPanel');
|
||||||
expect(panelElements.length).toBe(2);
|
expect(panelElements.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renders DashboardGrid with no visualizations', async () => {
|
test('renders DashboardGrid with no visualizations', () => {
|
||||||
const { props, options } = prepare();
|
const { props, options } = prepare();
|
||||||
const component = mountWithIntl(
|
const component = mountWithIntl(
|
||||||
<KibanaContextProvider services={options}>
|
<KibanaContextProvider services={options}>
|
||||||
|
@ -114,12 +117,11 @@ test('renders DashboardGrid with no visualizations', async () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
props.container.updateInput({ panels: {} });
|
props.container.updateInput({ panels: {} });
|
||||||
await nextTick();
|
|
||||||
component.update();
|
component.update();
|
||||||
expect(component.find('EmbeddableChildPanel').length).toBe(0);
|
expect(component.find('EmbeddableChildPanel').length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('DashboardGrid removes panel when removed from container', async () => {
|
test('DashboardGrid removes panel when removed from container', () => {
|
||||||
const { props, options } = prepare();
|
const { props, options } = prepare();
|
||||||
const component = mountWithIntl(
|
const component = mountWithIntl(
|
||||||
<KibanaContextProvider services={options}>
|
<KibanaContextProvider services={options}>
|
||||||
|
@ -131,13 +133,12 @@ test('DashboardGrid removes panel when removed from container', async () => {
|
||||||
const filteredPanels = { ...originalPanels };
|
const filteredPanels = { ...originalPanels };
|
||||||
delete filteredPanels['1'];
|
delete filteredPanels['1'];
|
||||||
props.container.updateInput({ panels: filteredPanels });
|
props.container.updateInput({ panels: filteredPanels });
|
||||||
await nextTick();
|
|
||||||
component.update();
|
component.update();
|
||||||
const panelElements = component.find('EmbeddableChildPanel');
|
const panelElements = component.find('EmbeddableChildPanel');
|
||||||
expect(panelElements.length).toBe(1);
|
expect(panelElements.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('DashboardGrid renders expanded panel', async () => {
|
test('DashboardGrid renders expanded panel', () => {
|
||||||
const { props, options } = prepare();
|
const { props, options } = prepare();
|
||||||
const component = mountWithIntl(
|
const component = mountWithIntl(
|
||||||
<KibanaContextProvider services={options}>
|
<KibanaContextProvider services={options}>
|
||||||
|
@ -146,7 +147,6 @@ test('DashboardGrid renders expanded panel', async () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
props.container.updateInput({ expandedPanelId: '1' });
|
props.container.updateInput({ expandedPanelId: '1' });
|
||||||
await nextTick();
|
|
||||||
component.update();
|
component.update();
|
||||||
// Both panels should still exist in the dom, so nothing needs to be re-fetched once minimized.
|
// Both panels should still exist in the dom, so nothing needs to be re-fetched once minimized.
|
||||||
expect(component.find('EmbeddableChildPanel').length).toBe(2);
|
expect(component.find('EmbeddableChildPanel').length).toBe(2);
|
||||||
|
@ -156,7 +156,6 @@ test('DashboardGrid renders expanded panel', async () => {
|
||||||
).toBe('1');
|
).toBe('1');
|
||||||
|
|
||||||
props.container.updateInput({ expandedPanelId: undefined });
|
props.container.updateInput({ expandedPanelId: undefined });
|
||||||
await nextTick();
|
|
||||||
component.update();
|
component.update();
|
||||||
expect(component.find('EmbeddableChildPanel').length).toBe(2);
|
expect(component.find('EmbeddableChildPanel').length).toBe(2);
|
||||||
|
|
||||||
|
|
|
@ -56,10 +56,14 @@ function getProps(
|
||||||
} as any,
|
} as any,
|
||||||
notifications: {} as any,
|
notifications: {} as any,
|
||||||
overlays: {} as any,
|
overlays: {} as any,
|
||||||
inspector: {} as any,
|
inspector: {
|
||||||
|
isAvailable: jest.fn(),
|
||||||
|
} as any,
|
||||||
SavedObjectFinder: () => null,
|
SavedObjectFinder: () => null,
|
||||||
ExitFullScreenButton,
|
ExitFullScreenButton,
|
||||||
uiActions: {} as any,
|
uiActions: {
|
||||||
|
getTriggerCompatibleActions: (() => []) as any,
|
||||||
|
} as any,
|
||||||
};
|
};
|
||||||
|
|
||||||
const input = getSampleDashboardInput({
|
const input = getSampleDashboardInput({
|
||||||
|
|
|
@ -148,6 +148,74 @@ exports[`QueryStringInput Should disable autoFocus on EuiFieldText when disableA
|
||||||
"setIsCollapsed": [MockFunction],
|
"setIsCollapsed": [MockFunction],
|
||||||
"setIsVisible": [MockFunction],
|
"setIsVisible": [MockFunction],
|
||||||
},
|
},
|
||||||
|
"data": Object {
|
||||||
|
"autocomplete": Object {
|
||||||
|
"addProvider": [MockFunction],
|
||||||
|
"clearProviders": [MockFunction],
|
||||||
|
"getProvider": [MockFunction],
|
||||||
|
},
|
||||||
|
"fieldFormats": Object {
|
||||||
|
"getByFieldType": [MockFunction],
|
||||||
|
"getConfig": [MockFunction],
|
||||||
|
"getDefaultConfig": [MockFunction],
|
||||||
|
"getDefaultInstance": [MockFunction],
|
||||||
|
"getDefaultInstanceCacheResolver": [MockFunction],
|
||||||
|
"getDefaultInstancePlain": [MockFunction],
|
||||||
|
"getDefaultType": [MockFunction],
|
||||||
|
"getDefaultTypeName": [MockFunction],
|
||||||
|
"getInstance": [MockFunction],
|
||||||
|
"getType": [MockFunction],
|
||||||
|
"getTypeNameByEsTypes": [MockFunction],
|
||||||
|
"init": [MockFunction],
|
||||||
|
"parseDefaultTypeMap": [MockFunction],
|
||||||
|
"register": [MockFunction],
|
||||||
|
},
|
||||||
|
"getSuggestions": [MockFunction],
|
||||||
|
"indexPatterns": Object {
|
||||||
|
"FieldList": Object {},
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
"flattenHitWrapper": [MockFunction],
|
||||||
|
"formatHitProvider": [MockFunction],
|
||||||
|
"indexPatterns": [MockFunction],
|
||||||
|
},
|
||||||
|
"query": Object {
|
||||||
|
"filterManager": [MockFunction],
|
||||||
|
"savedQueries": [MockFunction],
|
||||||
|
"timefilter": Object {
|
||||||
|
"history": Object {
|
||||||
|
"add": [MockFunction],
|
||||||
|
"get": [MockFunction],
|
||||||
|
},
|
||||||
|
"timefilter": Object {
|
||||||
|
"calculateBounds": [MockFunction],
|
||||||
|
"createFilter": [MockFunction],
|
||||||
|
"disableAutoRefreshSelector": [MockFunction],
|
||||||
|
"disableTimeRangeSelector": [MockFunction],
|
||||||
|
"enableAutoRefreshSelector": [MockFunction],
|
||||||
|
"enableTimeRangeSelector": [MockFunction],
|
||||||
|
"getActiveBounds": [MockFunction],
|
||||||
|
"getAutoRefreshFetch$": [MockFunction],
|
||||||
|
"getBounds": [MockFunction],
|
||||||
|
"getEnabledUpdated$": [MockFunction],
|
||||||
|
"getFetch$": [MockFunction],
|
||||||
|
"getRefreshInterval": [MockFunction],
|
||||||
|
"getRefreshIntervalUpdate$": [MockFunction],
|
||||||
|
"getTime": [MockFunction],
|
||||||
|
"getTimeUpdate$": [MockFunction],
|
||||||
|
"isAutoRefreshSelectorEnabled": [MockFunction],
|
||||||
|
"isTimeRangeSelectorEnabled": [MockFunction],
|
||||||
|
"setRefreshInterval": [MockFunction],
|
||||||
|
"setTime": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"search": Object {
|
||||||
|
"search": [MockFunction],
|
||||||
|
},
|
||||||
|
"ui": Object {
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
"docLinks": Object {
|
"docLinks": Object {
|
||||||
"DOC_LINK_VERSION": "mocked-test-branch",
|
"DOC_LINK_VERSION": "mocked-test-branch",
|
||||||
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
||||||
|
@ -710,6 +778,74 @@ exports[`QueryStringInput Should disable autoFocus on EuiFieldText when disableA
|
||||||
"setIsCollapsed": [MockFunction],
|
"setIsCollapsed": [MockFunction],
|
||||||
"setIsVisible": [MockFunction],
|
"setIsVisible": [MockFunction],
|
||||||
},
|
},
|
||||||
|
"data": Object {
|
||||||
|
"autocomplete": Object {
|
||||||
|
"addProvider": [MockFunction],
|
||||||
|
"clearProviders": [MockFunction],
|
||||||
|
"getProvider": [MockFunction],
|
||||||
|
},
|
||||||
|
"fieldFormats": Object {
|
||||||
|
"getByFieldType": [MockFunction],
|
||||||
|
"getConfig": [MockFunction],
|
||||||
|
"getDefaultConfig": [MockFunction],
|
||||||
|
"getDefaultInstance": [MockFunction],
|
||||||
|
"getDefaultInstanceCacheResolver": [MockFunction],
|
||||||
|
"getDefaultInstancePlain": [MockFunction],
|
||||||
|
"getDefaultType": [MockFunction],
|
||||||
|
"getDefaultTypeName": [MockFunction],
|
||||||
|
"getInstance": [MockFunction],
|
||||||
|
"getType": [MockFunction],
|
||||||
|
"getTypeNameByEsTypes": [MockFunction],
|
||||||
|
"init": [MockFunction],
|
||||||
|
"parseDefaultTypeMap": [MockFunction],
|
||||||
|
"register": [MockFunction],
|
||||||
|
},
|
||||||
|
"getSuggestions": [MockFunction],
|
||||||
|
"indexPatterns": Object {
|
||||||
|
"FieldList": Object {},
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
"flattenHitWrapper": [MockFunction],
|
||||||
|
"formatHitProvider": [MockFunction],
|
||||||
|
"indexPatterns": [MockFunction],
|
||||||
|
},
|
||||||
|
"query": Object {
|
||||||
|
"filterManager": [MockFunction],
|
||||||
|
"savedQueries": [MockFunction],
|
||||||
|
"timefilter": Object {
|
||||||
|
"history": Object {
|
||||||
|
"add": [MockFunction],
|
||||||
|
"get": [MockFunction],
|
||||||
|
},
|
||||||
|
"timefilter": Object {
|
||||||
|
"calculateBounds": [MockFunction],
|
||||||
|
"createFilter": [MockFunction],
|
||||||
|
"disableAutoRefreshSelector": [MockFunction],
|
||||||
|
"disableTimeRangeSelector": [MockFunction],
|
||||||
|
"enableAutoRefreshSelector": [MockFunction],
|
||||||
|
"enableTimeRangeSelector": [MockFunction],
|
||||||
|
"getActiveBounds": [MockFunction],
|
||||||
|
"getAutoRefreshFetch$": [MockFunction],
|
||||||
|
"getBounds": [MockFunction],
|
||||||
|
"getEnabledUpdated$": [MockFunction],
|
||||||
|
"getFetch$": [MockFunction],
|
||||||
|
"getRefreshInterval": [MockFunction],
|
||||||
|
"getRefreshIntervalUpdate$": [MockFunction],
|
||||||
|
"getTime": [MockFunction],
|
||||||
|
"getTimeUpdate$": [MockFunction],
|
||||||
|
"isAutoRefreshSelectorEnabled": [MockFunction],
|
||||||
|
"isTimeRangeSelectorEnabled": [MockFunction],
|
||||||
|
"setRefreshInterval": [MockFunction],
|
||||||
|
"setTime": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"search": Object {
|
||||||
|
"search": [MockFunction],
|
||||||
|
},
|
||||||
|
"ui": Object {
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
"docLinks": Object {
|
"docLinks": Object {
|
||||||
"DOC_LINK_VERSION": "mocked-test-branch",
|
"DOC_LINK_VERSION": "mocked-test-branch",
|
||||||
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
||||||
|
@ -1260,6 +1396,74 @@ exports[`QueryStringInput Should pass the query language to the language switche
|
||||||
"setIsCollapsed": [MockFunction],
|
"setIsCollapsed": [MockFunction],
|
||||||
"setIsVisible": [MockFunction],
|
"setIsVisible": [MockFunction],
|
||||||
},
|
},
|
||||||
|
"data": Object {
|
||||||
|
"autocomplete": Object {
|
||||||
|
"addProvider": [MockFunction],
|
||||||
|
"clearProviders": [MockFunction],
|
||||||
|
"getProvider": [MockFunction],
|
||||||
|
},
|
||||||
|
"fieldFormats": Object {
|
||||||
|
"getByFieldType": [MockFunction],
|
||||||
|
"getConfig": [MockFunction],
|
||||||
|
"getDefaultConfig": [MockFunction],
|
||||||
|
"getDefaultInstance": [MockFunction],
|
||||||
|
"getDefaultInstanceCacheResolver": [MockFunction],
|
||||||
|
"getDefaultInstancePlain": [MockFunction],
|
||||||
|
"getDefaultType": [MockFunction],
|
||||||
|
"getDefaultTypeName": [MockFunction],
|
||||||
|
"getInstance": [MockFunction],
|
||||||
|
"getType": [MockFunction],
|
||||||
|
"getTypeNameByEsTypes": [MockFunction],
|
||||||
|
"init": [MockFunction],
|
||||||
|
"parseDefaultTypeMap": [MockFunction],
|
||||||
|
"register": [MockFunction],
|
||||||
|
},
|
||||||
|
"getSuggestions": [MockFunction],
|
||||||
|
"indexPatterns": Object {
|
||||||
|
"FieldList": Object {},
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
"flattenHitWrapper": [MockFunction],
|
||||||
|
"formatHitProvider": [MockFunction],
|
||||||
|
"indexPatterns": [MockFunction],
|
||||||
|
},
|
||||||
|
"query": Object {
|
||||||
|
"filterManager": [MockFunction],
|
||||||
|
"savedQueries": [MockFunction],
|
||||||
|
"timefilter": Object {
|
||||||
|
"history": Object {
|
||||||
|
"add": [MockFunction],
|
||||||
|
"get": [MockFunction],
|
||||||
|
},
|
||||||
|
"timefilter": Object {
|
||||||
|
"calculateBounds": [MockFunction],
|
||||||
|
"createFilter": [MockFunction],
|
||||||
|
"disableAutoRefreshSelector": [MockFunction],
|
||||||
|
"disableTimeRangeSelector": [MockFunction],
|
||||||
|
"enableAutoRefreshSelector": [MockFunction],
|
||||||
|
"enableTimeRangeSelector": [MockFunction],
|
||||||
|
"getActiveBounds": [MockFunction],
|
||||||
|
"getAutoRefreshFetch$": [MockFunction],
|
||||||
|
"getBounds": [MockFunction],
|
||||||
|
"getEnabledUpdated$": [MockFunction],
|
||||||
|
"getFetch$": [MockFunction],
|
||||||
|
"getRefreshInterval": [MockFunction],
|
||||||
|
"getRefreshIntervalUpdate$": [MockFunction],
|
||||||
|
"getTime": [MockFunction],
|
||||||
|
"getTimeUpdate$": [MockFunction],
|
||||||
|
"isAutoRefreshSelectorEnabled": [MockFunction],
|
||||||
|
"isTimeRangeSelectorEnabled": [MockFunction],
|
||||||
|
"setRefreshInterval": [MockFunction],
|
||||||
|
"setTime": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"search": Object {
|
||||||
|
"search": [MockFunction],
|
||||||
|
},
|
||||||
|
"ui": Object {
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
"docLinks": Object {
|
"docLinks": Object {
|
||||||
"DOC_LINK_VERSION": "mocked-test-branch",
|
"DOC_LINK_VERSION": "mocked-test-branch",
|
||||||
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
||||||
|
@ -1819,6 +2023,74 @@ exports[`QueryStringInput Should pass the query language to the language switche
|
||||||
"setIsCollapsed": [MockFunction],
|
"setIsCollapsed": [MockFunction],
|
||||||
"setIsVisible": [MockFunction],
|
"setIsVisible": [MockFunction],
|
||||||
},
|
},
|
||||||
|
"data": Object {
|
||||||
|
"autocomplete": Object {
|
||||||
|
"addProvider": [MockFunction],
|
||||||
|
"clearProviders": [MockFunction],
|
||||||
|
"getProvider": [MockFunction],
|
||||||
|
},
|
||||||
|
"fieldFormats": Object {
|
||||||
|
"getByFieldType": [MockFunction],
|
||||||
|
"getConfig": [MockFunction],
|
||||||
|
"getDefaultConfig": [MockFunction],
|
||||||
|
"getDefaultInstance": [MockFunction],
|
||||||
|
"getDefaultInstanceCacheResolver": [MockFunction],
|
||||||
|
"getDefaultInstancePlain": [MockFunction],
|
||||||
|
"getDefaultType": [MockFunction],
|
||||||
|
"getDefaultTypeName": [MockFunction],
|
||||||
|
"getInstance": [MockFunction],
|
||||||
|
"getType": [MockFunction],
|
||||||
|
"getTypeNameByEsTypes": [MockFunction],
|
||||||
|
"init": [MockFunction],
|
||||||
|
"parseDefaultTypeMap": [MockFunction],
|
||||||
|
"register": [MockFunction],
|
||||||
|
},
|
||||||
|
"getSuggestions": [MockFunction],
|
||||||
|
"indexPatterns": Object {
|
||||||
|
"FieldList": Object {},
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
"flattenHitWrapper": [MockFunction],
|
||||||
|
"formatHitProvider": [MockFunction],
|
||||||
|
"indexPatterns": [MockFunction],
|
||||||
|
},
|
||||||
|
"query": Object {
|
||||||
|
"filterManager": [MockFunction],
|
||||||
|
"savedQueries": [MockFunction],
|
||||||
|
"timefilter": Object {
|
||||||
|
"history": Object {
|
||||||
|
"add": [MockFunction],
|
||||||
|
"get": [MockFunction],
|
||||||
|
},
|
||||||
|
"timefilter": Object {
|
||||||
|
"calculateBounds": [MockFunction],
|
||||||
|
"createFilter": [MockFunction],
|
||||||
|
"disableAutoRefreshSelector": [MockFunction],
|
||||||
|
"disableTimeRangeSelector": [MockFunction],
|
||||||
|
"enableAutoRefreshSelector": [MockFunction],
|
||||||
|
"enableTimeRangeSelector": [MockFunction],
|
||||||
|
"getActiveBounds": [MockFunction],
|
||||||
|
"getAutoRefreshFetch$": [MockFunction],
|
||||||
|
"getBounds": [MockFunction],
|
||||||
|
"getEnabledUpdated$": [MockFunction],
|
||||||
|
"getFetch$": [MockFunction],
|
||||||
|
"getRefreshInterval": [MockFunction],
|
||||||
|
"getRefreshIntervalUpdate$": [MockFunction],
|
||||||
|
"getTime": [MockFunction],
|
||||||
|
"getTimeUpdate$": [MockFunction],
|
||||||
|
"isAutoRefreshSelectorEnabled": [MockFunction],
|
||||||
|
"isTimeRangeSelectorEnabled": [MockFunction],
|
||||||
|
"setRefreshInterval": [MockFunction],
|
||||||
|
"setTime": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"search": Object {
|
||||||
|
"search": [MockFunction],
|
||||||
|
},
|
||||||
|
"ui": Object {
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
"docLinks": Object {
|
"docLinks": Object {
|
||||||
"DOC_LINK_VERSION": "mocked-test-branch",
|
"DOC_LINK_VERSION": "mocked-test-branch",
|
||||||
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
||||||
|
@ -2369,6 +2641,74 @@ exports[`QueryStringInput Should render the given query 1`] = `
|
||||||
"setIsCollapsed": [MockFunction],
|
"setIsCollapsed": [MockFunction],
|
||||||
"setIsVisible": [MockFunction],
|
"setIsVisible": [MockFunction],
|
||||||
},
|
},
|
||||||
|
"data": Object {
|
||||||
|
"autocomplete": Object {
|
||||||
|
"addProvider": [MockFunction],
|
||||||
|
"clearProviders": [MockFunction],
|
||||||
|
"getProvider": [MockFunction],
|
||||||
|
},
|
||||||
|
"fieldFormats": Object {
|
||||||
|
"getByFieldType": [MockFunction],
|
||||||
|
"getConfig": [MockFunction],
|
||||||
|
"getDefaultConfig": [MockFunction],
|
||||||
|
"getDefaultInstance": [MockFunction],
|
||||||
|
"getDefaultInstanceCacheResolver": [MockFunction],
|
||||||
|
"getDefaultInstancePlain": [MockFunction],
|
||||||
|
"getDefaultType": [MockFunction],
|
||||||
|
"getDefaultTypeName": [MockFunction],
|
||||||
|
"getInstance": [MockFunction],
|
||||||
|
"getType": [MockFunction],
|
||||||
|
"getTypeNameByEsTypes": [MockFunction],
|
||||||
|
"init": [MockFunction],
|
||||||
|
"parseDefaultTypeMap": [MockFunction],
|
||||||
|
"register": [MockFunction],
|
||||||
|
},
|
||||||
|
"getSuggestions": [MockFunction],
|
||||||
|
"indexPatterns": Object {
|
||||||
|
"FieldList": Object {},
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
"flattenHitWrapper": [MockFunction],
|
||||||
|
"formatHitProvider": [MockFunction],
|
||||||
|
"indexPatterns": [MockFunction],
|
||||||
|
},
|
||||||
|
"query": Object {
|
||||||
|
"filterManager": [MockFunction],
|
||||||
|
"savedQueries": [MockFunction],
|
||||||
|
"timefilter": Object {
|
||||||
|
"history": Object {
|
||||||
|
"add": [MockFunction],
|
||||||
|
"get": [MockFunction],
|
||||||
|
},
|
||||||
|
"timefilter": Object {
|
||||||
|
"calculateBounds": [MockFunction],
|
||||||
|
"createFilter": [MockFunction],
|
||||||
|
"disableAutoRefreshSelector": [MockFunction],
|
||||||
|
"disableTimeRangeSelector": [MockFunction],
|
||||||
|
"enableAutoRefreshSelector": [MockFunction],
|
||||||
|
"enableTimeRangeSelector": [MockFunction],
|
||||||
|
"getActiveBounds": [MockFunction],
|
||||||
|
"getAutoRefreshFetch$": [MockFunction],
|
||||||
|
"getBounds": [MockFunction],
|
||||||
|
"getEnabledUpdated$": [MockFunction],
|
||||||
|
"getFetch$": [MockFunction],
|
||||||
|
"getRefreshInterval": [MockFunction],
|
||||||
|
"getRefreshIntervalUpdate$": [MockFunction],
|
||||||
|
"getTime": [MockFunction],
|
||||||
|
"getTimeUpdate$": [MockFunction],
|
||||||
|
"isAutoRefreshSelectorEnabled": [MockFunction],
|
||||||
|
"isTimeRangeSelectorEnabled": [MockFunction],
|
||||||
|
"setRefreshInterval": [MockFunction],
|
||||||
|
"setTime": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"search": Object {
|
||||||
|
"search": [MockFunction],
|
||||||
|
},
|
||||||
|
"ui": Object {
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
"docLinks": Object {
|
"docLinks": Object {
|
||||||
"DOC_LINK_VERSION": "mocked-test-branch",
|
"DOC_LINK_VERSION": "mocked-test-branch",
|
||||||
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
||||||
|
@ -2928,6 +3268,74 @@ exports[`QueryStringInput Should render the given query 1`] = `
|
||||||
"setIsCollapsed": [MockFunction],
|
"setIsCollapsed": [MockFunction],
|
||||||
"setIsVisible": [MockFunction],
|
"setIsVisible": [MockFunction],
|
||||||
},
|
},
|
||||||
|
"data": Object {
|
||||||
|
"autocomplete": Object {
|
||||||
|
"addProvider": [MockFunction],
|
||||||
|
"clearProviders": [MockFunction],
|
||||||
|
"getProvider": [MockFunction],
|
||||||
|
},
|
||||||
|
"fieldFormats": Object {
|
||||||
|
"getByFieldType": [MockFunction],
|
||||||
|
"getConfig": [MockFunction],
|
||||||
|
"getDefaultConfig": [MockFunction],
|
||||||
|
"getDefaultInstance": [MockFunction],
|
||||||
|
"getDefaultInstanceCacheResolver": [MockFunction],
|
||||||
|
"getDefaultInstancePlain": [MockFunction],
|
||||||
|
"getDefaultType": [MockFunction],
|
||||||
|
"getDefaultTypeName": [MockFunction],
|
||||||
|
"getInstance": [MockFunction],
|
||||||
|
"getType": [MockFunction],
|
||||||
|
"getTypeNameByEsTypes": [MockFunction],
|
||||||
|
"init": [MockFunction],
|
||||||
|
"parseDefaultTypeMap": [MockFunction],
|
||||||
|
"register": [MockFunction],
|
||||||
|
},
|
||||||
|
"getSuggestions": [MockFunction],
|
||||||
|
"indexPatterns": Object {
|
||||||
|
"FieldList": Object {},
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
"flattenHitWrapper": [MockFunction],
|
||||||
|
"formatHitProvider": [MockFunction],
|
||||||
|
"indexPatterns": [MockFunction],
|
||||||
|
},
|
||||||
|
"query": Object {
|
||||||
|
"filterManager": [MockFunction],
|
||||||
|
"savedQueries": [MockFunction],
|
||||||
|
"timefilter": Object {
|
||||||
|
"history": Object {
|
||||||
|
"add": [MockFunction],
|
||||||
|
"get": [MockFunction],
|
||||||
|
},
|
||||||
|
"timefilter": Object {
|
||||||
|
"calculateBounds": [MockFunction],
|
||||||
|
"createFilter": [MockFunction],
|
||||||
|
"disableAutoRefreshSelector": [MockFunction],
|
||||||
|
"disableTimeRangeSelector": [MockFunction],
|
||||||
|
"enableAutoRefreshSelector": [MockFunction],
|
||||||
|
"enableTimeRangeSelector": [MockFunction],
|
||||||
|
"getActiveBounds": [MockFunction],
|
||||||
|
"getAutoRefreshFetch$": [MockFunction],
|
||||||
|
"getBounds": [MockFunction],
|
||||||
|
"getEnabledUpdated$": [MockFunction],
|
||||||
|
"getFetch$": [MockFunction],
|
||||||
|
"getRefreshInterval": [MockFunction],
|
||||||
|
"getRefreshIntervalUpdate$": [MockFunction],
|
||||||
|
"getTime": [MockFunction],
|
||||||
|
"getTimeUpdate$": [MockFunction],
|
||||||
|
"isAutoRefreshSelectorEnabled": [MockFunction],
|
||||||
|
"isTimeRangeSelectorEnabled": [MockFunction],
|
||||||
|
"setRefreshInterval": [MockFunction],
|
||||||
|
"setTime": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"search": Object {
|
||||||
|
"search": [MockFunction],
|
||||||
|
},
|
||||||
|
"ui": Object {
|
||||||
|
"IndexPatternSelect": [MockFunction],
|
||||||
|
},
|
||||||
|
},
|
||||||
"docLinks": Object {
|
"docLinks": Object {
|
||||||
"DOC_LINK_VERSION": "mocked-test-branch",
|
"DOC_LINK_VERSION": "mocked-test-branch",
|
||||||
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
"ELASTIC_WEBSITE_URL": "https://www.elastic.co/",
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { mount } from 'enzyme';
|
||||||
import { QueryBarTopRow } from './query_bar_top_row';
|
import { QueryBarTopRow } from './query_bar_top_row';
|
||||||
|
|
||||||
import { coreMock } from '../../../../../core/public/mocks';
|
import { coreMock } from '../../../../../core/public/mocks';
|
||||||
|
import { dataPluginMock } from '../../mocks';
|
||||||
import { KibanaContextProvider } from 'src/plugins/kibana_react/public';
|
import { KibanaContextProvider } from 'src/plugins/kibana_react/public';
|
||||||
import { I18nProvider } from '@kbn/i18n/react';
|
import { I18nProvider } from '@kbn/i18n/react';
|
||||||
import { stubIndexPatternWithFields } from '../../stubs';
|
import { stubIndexPatternWithFields } from '../../stubs';
|
||||||
|
@ -95,6 +96,7 @@ function wrapQueryBarTopRowInContext(testProps: any) {
|
||||||
|
|
||||||
const services = {
|
const services = {
|
||||||
...startMock,
|
...startMock,
|
||||||
|
data: dataPluginMock.createStartContract(),
|
||||||
appName: 'discover',
|
appName: 'discover',
|
||||||
storage: createMockStorage(),
|
storage: createMockStorage(),
|
||||||
};
|
};
|
||||||
|
@ -117,7 +119,7 @@ describe('QueryBarTopRowTopRow', () => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should render the given query', () => {
|
it('Should render query and time picker', () => {
|
||||||
const component = mount(
|
const component = mount(
|
||||||
wrapQueryBarTopRowInContext({
|
wrapQueryBarTopRowInContext({
|
||||||
query: kqlQuery,
|
query: kqlQuery,
|
||||||
|
|
|
@ -28,6 +28,7 @@ import React from 'react';
|
||||||
import { QueryLanguageSwitcher } from './language_switcher';
|
import { QueryLanguageSwitcher } from './language_switcher';
|
||||||
import { QueryStringInput, QueryStringInputUI } from './query_string_input';
|
import { QueryStringInput, QueryStringInputUI } from './query_string_input';
|
||||||
import { coreMock } from '../../../../../core/public/mocks';
|
import { coreMock } from '../../../../../core/public/mocks';
|
||||||
|
import { dataPluginMock } from '../../mocks';
|
||||||
const startMock = coreMock.createStart();
|
const startMock = coreMock.createStart();
|
||||||
import { stubIndexPatternWithFields } from '../../stubs';
|
import { stubIndexPatternWithFields } from '../../stubs';
|
||||||
|
|
||||||
|
@ -74,6 +75,7 @@ function wrapQueryStringInputInContext(testProps: any, storage?: any) {
|
||||||
|
|
||||||
const services = {
|
const services = {
|
||||||
...startMock,
|
...startMock,
|
||||||
|
data: dataPluginMock.createStartContract(),
|
||||||
appName: testProps.appName || 'test',
|
appName: testProps.appName || 'test',
|
||||||
storage: storage || createMockStorage(),
|
storage: storage || createMockStorage(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -251,6 +251,7 @@ describe('SavedObjectsFinder', () => {
|
||||||
it('should include additional fields in search if listed in meta data', async () => {
|
it('should include additional fields in search if listed in meta data', async () => {
|
||||||
const core = coreMock.createStart();
|
const core = coreMock.createStart();
|
||||||
core.uiSettings.get.mockImplementation(() => 10);
|
core.uiSettings.get.mockImplementation(() => 10);
|
||||||
|
(core.savedObjects.client.find as jest.Mock).mockResolvedValue({ savedObjects: [] });
|
||||||
|
|
||||||
const wrapper = shallow(
|
const wrapper = shallow(
|
||||||
<SavedObjectFinder
|
<SavedObjectFinder
|
||||||
|
@ -631,6 +632,7 @@ describe('SavedObjectsFinder', () => {
|
||||||
describe('loading state', () => {
|
describe('loading state', () => {
|
||||||
it('should display a spinner during initial loading', () => {
|
it('should display a spinner during initial loading', () => {
|
||||||
const core = coreMock.createStart();
|
const core = coreMock.createStart();
|
||||||
|
(core.savedObjects.client.find as jest.Mock).mockResolvedValue({ savedObjects: [] });
|
||||||
|
|
||||||
const wrapper = shallow(
|
const wrapper = shallow(
|
||||||
<SavedObjectFinder
|
<SavedObjectFinder
|
||||||
|
|
|
@ -17,14 +17,12 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import bluebird, {
|
import bluebird, { promisify } from 'bluebird';
|
||||||
fromNode,
|
|
||||||
promisify,
|
|
||||||
} from 'bluebird';
|
|
||||||
import Handlebars from 'handlebars';
|
import Handlebars from 'handlebars';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import imageDiff from 'image-diff';
|
import { PNG } from 'pngjs';
|
||||||
|
import pixelmatch from 'pixelmatch';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import SimpleGit from 'simple-git';
|
import SimpleGit from 'simple-git';
|
||||||
|
|
||||||
|
@ -110,17 +108,23 @@ async function compareScreenshots() {
|
||||||
screenshot
|
screenshot
|
||||||
);
|
);
|
||||||
|
|
||||||
// Diff the images asynchronously.
|
const sessionImage = PNG.sync.read(await fs.promises.readFile(sessionImagePath));
|
||||||
const diffResult = await fromNode((cb) => {
|
const baselineImage = PNG.sync.read(await fs.promises.readFile(baselineImagePath));
|
||||||
imageDiff.getFullResult({
|
const { width, height } = sessionImage;
|
||||||
actualImage: sessionImagePath,
|
const diff = new PNG({ width, height });
|
||||||
expectedImage: baselineImagePath,
|
|
||||||
diffImage: diffImagePath,
|
|
||||||
shadow: true,
|
|
||||||
}, cb);
|
|
||||||
});
|
|
||||||
|
|
||||||
const change = diffResult.percentage;
|
const numDiffPixels = pixelmatch(
|
||||||
|
sessionImage.data,
|
||||||
|
baselineImage.data,
|
||||||
|
diff.data,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
{ threshold: 0 }
|
||||||
|
);
|
||||||
|
|
||||||
|
await fs.promises.writeFile(diffImagePath, PNG.sync.write(diff));
|
||||||
|
|
||||||
|
const change = numDiffPixels / (width * height);
|
||||||
const changePercentage = (change * 100).toFixed(2);
|
const changePercentage = (change * 100).toFixed(2);
|
||||||
console.log(`(${changePercentage}%) ${screenshot}`);
|
console.log(`(${changePercentage}%) ${screenshot}`);
|
||||||
comparison.percentage = changePercentage;
|
comparison.percentage = changePercentage;
|
||||||
|
|
|
@ -27,7 +27,7 @@ describe('createErrorGroupWatch', () => {
|
||||||
.mockResolvedValue(undefined);
|
.mockResolvedValue(undefined);
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
jest.spyOn(uuid, 'v4').mockReturnValue(new Buffer('mocked-uuid'));
|
jest.spyOn(uuid, 'v4').mockReturnValue(Buffer.from('mocked-uuid'));
|
||||||
|
|
||||||
createWatchResponse = await createErrorGroupWatch({
|
createWatchResponse = await createErrorGroupWatch({
|
||||||
http: {} as HttpServiceBase,
|
http: {} as HttpServiceBase,
|
||||||
|
|
|
@ -10,3 +10,5 @@ export const toastNotifications = {
|
||||||
addWarning: () => {},
|
addWarning: () => {},
|
||||||
addError: () => {},
|
addError: () => {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function fatalError() {}
|
||||||
|
|
|
@ -266,7 +266,6 @@ export class ReportInfoButton extends Component<Props, State> {
|
||||||
info: null,
|
info: null,
|
||||||
error: kfetchError,
|
error: kfetchError,
|
||||||
});
|
});
|
||||||
throw kfetchError;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -246,7 +246,9 @@ describe('Worker class', function () {
|
||||||
it('should use error multiplier when processPendingJobs rejects the Promise', async function () {
|
it('should use error multiplier when processPendingJobs rejects the Promise', async function () {
|
||||||
worker = new Worker(mockQueue, 'test', noop, defaultWorkerOptions);
|
worker = new Worker(mockQueue, 'test', noop, defaultWorkerOptions);
|
||||||
|
|
||||||
const processPendingJobsStub = sinon.stub(worker, '_processPendingJobs').returns(Promise.reject(new Error('test error')));
|
const processPendingJobsStub = sinon
|
||||||
|
.stub(worker, '_processPendingJobs')
|
||||||
|
.rejects(new Error('test error'));
|
||||||
|
|
||||||
await allowPoll(defaultWorkerOptions.interval);
|
await allowPoll(defaultWorkerOptions.interval);
|
||||||
expect(processPendingJobsStub.callCount).to.be(1);
|
expect(processPendingJobsStub.callCount).to.be(1);
|
||||||
|
@ -517,7 +519,7 @@ describe('Worker class', function () {
|
||||||
it('should emit for errors from claiming job', function (done) {
|
it('should emit for errors from claiming job', function (done) {
|
||||||
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
||||||
.withArgs('update')
|
.withArgs('update')
|
||||||
.returns(Promise.reject({ statusCode: 401 }));
|
.rejects({ statusCode: 401 });
|
||||||
|
|
||||||
worker.once(constants.EVENT_WORKER_JOB_CLAIM_ERROR, function (err) {
|
worker.once(constants.EVENT_WORKER_JOB_CLAIM_ERROR, function (err) {
|
||||||
try {
|
try {
|
||||||
|
@ -531,13 +533,13 @@ describe('Worker class', function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
worker._claimPendingJobs(getMockJobs());
|
worker._claimPendingJobs(getMockJobs()).catch(() => {});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reject the promise if an error claiming the job', function () {
|
it('should reject the promise if an error claiming the job', function () {
|
||||||
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
||||||
.withArgs('update')
|
.withArgs('update')
|
||||||
.returns(Promise.reject({ statusCode: 409 }));
|
.rejects({ statusCode: 409 });
|
||||||
return worker._claimPendingJobs(getMockJobs())
|
return worker._claimPendingJobs(getMockJobs())
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
expect(err).to.eql({ statusCode: 409 });
|
expect(err).to.eql({ statusCode: 409 });
|
||||||
|
@ -547,7 +549,7 @@ describe('Worker class', function () {
|
||||||
it('should get the pending job', function () {
|
it('should get the pending job', function () {
|
||||||
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
||||||
.withArgs('update')
|
.withArgs('update')
|
||||||
.returns(Promise.resolve({ test: 'cool' }));
|
.resolves({ test: 'cool' });
|
||||||
sinon.stub(worker, '_performJob').callsFake(identity);
|
sinon.stub(worker, '_performJob').callsFake(identity);
|
||||||
return worker._claimPendingJobs(getMockJobs())
|
return worker._claimPendingJobs(getMockJobs())
|
||||||
.then(claimedJob => {
|
.then(claimedJob => {
|
||||||
|
@ -607,7 +609,7 @@ describe('Worker class', function () {
|
||||||
mockQueue.client.callWithInternalUser.restore();
|
mockQueue.client.callWithInternalUser.restore();
|
||||||
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
||||||
.withArgs('update')
|
.withArgs('update')
|
||||||
.returns(Promise.reject({ statusCode: 409 }));
|
.rejects({ statusCode: 409 });
|
||||||
return worker._failJob(job)
|
return worker._failJob(job)
|
||||||
.then((res) => expect(res).to.equal(true));
|
.then((res) => expect(res).to.equal(true));
|
||||||
});
|
});
|
||||||
|
@ -616,7 +618,7 @@ describe('Worker class', function () {
|
||||||
mockQueue.client.callWithInternalUser.restore();
|
mockQueue.client.callWithInternalUser.restore();
|
||||||
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
||||||
.withArgs('update')
|
.withArgs('update')
|
||||||
.returns(Promise.reject({ statusCode: 401 }));
|
.rejects({ statusCode: 401 });
|
||||||
return worker._failJob(job)
|
return worker._failJob(job)
|
||||||
.then((res) => expect(res).to.equal(false));
|
.then((res) => expect(res).to.equal(false));
|
||||||
});
|
});
|
||||||
|
@ -654,7 +656,7 @@ describe('Worker class', function () {
|
||||||
mockQueue.client.callWithInternalUser.restore();
|
mockQueue.client.callWithInternalUser.restore();
|
||||||
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
||||||
.withArgs('update')
|
.withArgs('update')
|
||||||
.returns(Promise.reject({ statusCode: 401 }));
|
.rejects({ statusCode: 401 });
|
||||||
|
|
||||||
worker.on(constants.EVENT_WORKER_FAIL_UPDATE_ERROR, function (err) {
|
worker.on(constants.EVENT_WORKER_FAIL_UPDATE_ERROR, function (err) {
|
||||||
try {
|
try {
|
||||||
|
@ -842,7 +844,7 @@ describe('Worker class', function () {
|
||||||
|
|
||||||
describe('job failures', function () {
|
describe('job failures', function () {
|
||||||
function getFailStub(workerWithFailure) {
|
function getFailStub(workerWithFailure) {
|
||||||
return sinon.stub(workerWithFailure, '_failJob').returns(Promise.resolve());
|
return sinon.stub(workerWithFailure, '_failJob').resolves();
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('saving output failure', () => {
|
describe('saving output failure', () => {
|
||||||
|
@ -857,7 +859,7 @@ describe('Worker class', function () {
|
||||||
|
|
||||||
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
||||||
.withArgs('update')
|
.withArgs('update')
|
||||||
.returns(Promise.reject({ statusCode: 413 }));
|
.rejects({ statusCode: 413 });
|
||||||
|
|
||||||
const workerFn = function (jobPayload) {
|
const workerFn = function (jobPayload) {
|
||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
|
@ -878,7 +880,7 @@ describe('Worker class', function () {
|
||||||
it('causes _processPendingJobs to reject the Promise', function () {
|
it('causes _processPendingJobs to reject the Promise', function () {
|
||||||
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
sinon.stub(mockQueue.client, 'callWithInternalUser')
|
||||||
.withArgs('search')
|
.withArgs('search')
|
||||||
.returns(Promise.reject(new Error('test error')));
|
.rejects(new Error('test error'));
|
||||||
worker = new Worker(mockQueue, 'test', noop, defaultWorkerOptions);
|
worker = new Worker(mockQueue, 'test', noop, defaultWorkerOptions);
|
||||||
return worker._processPendingJobs()
|
return worker._processPendingJobs()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`it renders without crashing 1`] = `null`;
|
exports[`it renders without crashing 1`] = `<Fragment />`;
|
||||||
|
|
|
@ -10,31 +10,36 @@ import { RoleValidator } from '../../../lib/validate_role';
|
||||||
import { IndexPrivilegeForm } from './index_privilege_form';
|
import { IndexPrivilegeForm } from './index_privilege_form';
|
||||||
import { IndexPrivileges } from './index_privileges';
|
import { IndexPrivileges } from './index_privileges';
|
||||||
|
|
||||||
test('it renders without crashing', () => {
|
// the IndexPrivileges post-mount hook kicks off some promises;
|
||||||
|
// we need to wait for those promises to resolve to ensure any errors are properly caught
|
||||||
|
const flushPromises = () => new Promise(setImmediate);
|
||||||
|
|
||||||
|
test('it renders without crashing', async () => {
|
||||||
const props = {
|
const props = {
|
||||||
role: {
|
role: {
|
||||||
name: '',
|
name: '',
|
||||||
|
kibana: [],
|
||||||
elasticsearch: {
|
elasticsearch: {
|
||||||
cluster: [],
|
cluster: [],
|
||||||
indices: [],
|
indices: [],
|
||||||
run_as: [],
|
run_as: [],
|
||||||
},
|
},
|
||||||
kibana: [],
|
|
||||||
},
|
},
|
||||||
httpClient: jest.fn(),
|
httpClient: jest.fn(),
|
||||||
onChange: jest.fn(),
|
onChange: jest.fn(),
|
||||||
indexPatterns: [],
|
indexPatterns: [],
|
||||||
|
editable: true,
|
||||||
allowDocumentLevelSecurity: true,
|
allowDocumentLevelSecurity: true,
|
||||||
allowFieldLevelSecurity: true,
|
allowFieldLevelSecurity: true,
|
||||||
editable: true,
|
|
||||||
validator: new RoleValidator(),
|
validator: new RoleValidator(),
|
||||||
availableIndexPrivileges: ['all', 'read', 'write', 'index'],
|
availableIndexPrivileges: ['all', 'read', 'write', 'index'],
|
||||||
};
|
};
|
||||||
const wrapper = shallowWithIntl(<IndexPrivileges {...props} />);
|
const wrapper = shallowWithIntl(<IndexPrivileges {...props} />);
|
||||||
|
await flushPromises();
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it renders a IndexPrivilegeForm for each privilege on the role', () => {
|
test('it renders a IndexPrivilegeForm for each privilege on the role', async () => {
|
||||||
const props = {
|
const props = {
|
||||||
role: {
|
role: {
|
||||||
name: '',
|
name: '',
|
||||||
|
@ -64,5 +69,6 @@ test('it renders a IndexPrivilegeForm for each privilege on the role', () => {
|
||||||
availableIndexPrivileges: ['all', 'read', 'write', 'index'],
|
availableIndexPrivileges: ['all', 'read', 'write', 'index'],
|
||||||
};
|
};
|
||||||
const wrapper = mountWithIntl(<IndexPrivileges {...props} />);
|
const wrapper = mountWithIntl(<IndexPrivileges {...props} />);
|
||||||
|
await flushPromises();
|
||||||
expect(wrapper.find(IndexPrivilegeForm)).toHaveLength(1);
|
expect(wrapper.find(IndexPrivilegeForm)).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React, { Component } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import { Role, RoleIndexPrivilege } from '../../../../../../../common/model';
|
import { Role, RoleIndexPrivilege } from '../../../../../../../common/model';
|
||||||
import { isReadOnlyRole, isRoleEnabled } from '../../../../../../lib/role_utils';
|
import { isReadOnlyRole, isRoleEnabled } from '../../../../../../lib/role_utils';
|
||||||
import { getFields } from '../../../../../../objects';
|
import { getFields } from '../../../../../../objects';
|
||||||
|
@ -74,7 +74,7 @@ export class IndexPrivileges extends Component<Props, State> {
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
return forms;
|
return <Fragment>{forms}</Fragment>;
|
||||||
}
|
}
|
||||||
|
|
||||||
public addIndexPrivilege = () => {
|
public addIndexPrivilege = () => {
|
||||||
|
|
|
@ -23,7 +23,12 @@ function mockGetXPackLicense(callCluster, license, req) {
|
||||||
local: 'true'
|
local: 'true'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.returns(license.then(response => ({ license: response })));
|
.returns(
|
||||||
|
license.then(
|
||||||
|
response => ({ license: response }),
|
||||||
|
() => {} // Catch error so that we don't emit UnhandledPromiseRejectionWarning for tests with invalid license
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
callCluster.withArgs('transport.request', {
|
callCluster.withArgs('transport.request', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
@ -33,7 +38,12 @@ function mockGetXPackLicense(callCluster, license, req) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// conveniently wraps the passed in license object as { license: response }, like it really is
|
// conveniently wraps the passed in license object as { license: response }, like it really is
|
||||||
.returns(license.then(response => ({ license: response })));
|
.returns(
|
||||||
|
license.then(
|
||||||
|
response => ({ license: response }),
|
||||||
|
() => {} // Catch error so that we don't emit UnhandledPromiseRejectionWarning for tests with invalid license
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mockGetXPackUsage(callCluster, usage, req) {
|
function mockGetXPackUsage(callCluster, usage, req) {
|
||||||
|
|
|
@ -151,7 +151,7 @@
|
||||||
"null-loader": "^3.0.0",
|
"null-loader": "^3.0.0",
|
||||||
"pdf-image": "2.0.0",
|
"pdf-image": "2.0.0",
|
||||||
"pdfjs-dist": "^2.0.943",
|
"pdfjs-dist": "^2.0.943",
|
||||||
"pixelmatch": "4.0.2",
|
"pixelmatch": "^5.1.0",
|
||||||
"proxyquire": "1.8.0",
|
"proxyquire": "1.8.0",
|
||||||
"react-docgen-typescript-loader": "^3.1.1",
|
"react-docgen-typescript-loader": "^3.1.1",
|
||||||
"react-test-renderer": "^16.12.0",
|
"react-test-renderer": "^16.12.0",
|
||||||
|
|
|
@ -516,16 +516,19 @@ describe('Authenticator', () => {
|
||||||
expect(mockSessionStorage.clear).not.toHaveBeenCalled();
|
expect(mockSessionStorage.clear).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('only updates the session lifespan expiration if it does not match the current server config.', async () => {
|
describe('conditionally updates the session lifespan expiration', () => {
|
||||||
const user = mockAuthenticatedUser();
|
|
||||||
const request = httpServerMock.createKibanaRequest();
|
|
||||||
const hr = 1000 * 60 * 60;
|
const hr = 1000 * 60 * 60;
|
||||||
|
const currentDate = new Date(Date.UTC(2019, 10, 10)).valueOf();
|
||||||
|
|
||||||
async function createAndUpdateSession(
|
async function createAndUpdateSession(
|
||||||
lifespan: number | null,
|
lifespan: number | null,
|
||||||
oldExpiration: number | null,
|
oldExpiration: number | null,
|
||||||
newExpiration: number | null
|
newExpiration: number | null
|
||||||
) {
|
) {
|
||||||
|
const user = mockAuthenticatedUser();
|
||||||
|
const request = httpServerMock.createKibanaRequest();
|
||||||
|
jest.spyOn(Date, 'now').mockImplementation(() => currentDate);
|
||||||
|
|
||||||
mockOptions = getMockOptions({
|
mockOptions = getMockOptions({
|
||||||
session: {
|
session: {
|
||||||
idleTimeout: null,
|
idleTimeout: null,
|
||||||
|
@ -537,7 +540,7 @@ describe('Authenticator', () => {
|
||||||
mockSessionStorage = sessionStorageMock.create();
|
mockSessionStorage = sessionStorageMock.create();
|
||||||
mockSessionStorage.get.mockResolvedValue({
|
mockSessionStorage.get.mockResolvedValue({
|
||||||
...mockSessVal,
|
...mockSessVal,
|
||||||
idleTimeoutExpiration: 1,
|
idleTimeoutExpiration: null,
|
||||||
lifespanExpiration: oldExpiration,
|
lifespanExpiration: oldExpiration,
|
||||||
});
|
});
|
||||||
mockOptions.sessionStorageFactory.asScoped.mockReturnValue(mockSessionStorage);
|
mockOptions.sessionStorageFactory.asScoped.mockReturnValue(mockSessionStorage);
|
||||||
|
@ -555,17 +558,24 @@ describe('Authenticator', () => {
|
||||||
expect(mockSessionStorage.set).toHaveBeenCalledTimes(1);
|
expect(mockSessionStorage.set).toHaveBeenCalledTimes(1);
|
||||||
expect(mockSessionStorage.set).toHaveBeenCalledWith({
|
expect(mockSessionStorage.set).toHaveBeenCalledWith({
|
||||||
...mockSessVal,
|
...mockSessVal,
|
||||||
idleTimeoutExpiration: 1,
|
idleTimeoutExpiration: null,
|
||||||
lifespanExpiration: newExpiration,
|
lifespanExpiration: newExpiration,
|
||||||
});
|
});
|
||||||
expect(mockSessionStorage.clear).not.toHaveBeenCalled();
|
expect(mockSessionStorage.clear).not.toHaveBeenCalled();
|
||||||
}
|
}
|
||||||
// do not change max expiration
|
|
||||||
createAndUpdateSession(hr * 8, 1234, 1234);
|
it('does not change a non-null lifespan expiration when configured to non-null value.', async () => {
|
||||||
createAndUpdateSession(null, null, null);
|
await createAndUpdateSession(hr * 8, 1234, 1234);
|
||||||
// change max expiration
|
});
|
||||||
createAndUpdateSession(null, 1234, null);
|
it('does not change a null lifespan expiration when configured to null value.', async () => {
|
||||||
createAndUpdateSession(hr * 8, null, hr * 8);
|
await createAndUpdateSession(null, null, null);
|
||||||
|
});
|
||||||
|
it('does change a non-null lifespan expiration when configured to null value.', async () => {
|
||||||
|
await createAndUpdateSession(null, 1234, null);
|
||||||
|
});
|
||||||
|
it('does change a null lifespan expiration when configured to non-null value', async () => {
|
||||||
|
await createAndUpdateSession(hr * 8, null, currentDate + hr * 8);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not touch session for system API calls if authentication fails with non-401 reason.', async () => {
|
it('does not touch session for system API calls if authentication fails with non-401 reason.', async () => {
|
||||||
|
|
90
yarn.lock
90
yarn.lock
|
@ -5495,21 +5495,11 @@ array-map@~0.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
|
resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
|
||||||
integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=
|
integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=
|
||||||
|
|
||||||
array-parallel@~0.1.3:
|
|
||||||
version "0.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/array-parallel/-/array-parallel-0.1.3.tgz#8f785308926ed5aa478c47e64d1b334b6c0c947d"
|
|
||||||
integrity sha1-j3hTCJJu1apHjEfmTRszS2wMlH0=
|
|
||||||
|
|
||||||
array-reduce@~0.0.0:
|
array-reduce@~0.0.0:
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
|
resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
|
||||||
integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=
|
integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=
|
||||||
|
|
||||||
array-series@~0.1.5:
|
|
||||||
version "0.1.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/array-series/-/array-series-0.1.5.tgz#df5d37bfc5c2ef0755e2aa4f92feae7d4b5a972f"
|
|
||||||
integrity sha1-3103v8XC7wdV4qpPkv6ufUtaly8=
|
|
||||||
|
|
||||||
array-slice@^0.2.3:
|
array-slice@^0.2.3:
|
||||||
version "0.2.3"
|
version "0.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5"
|
resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5"
|
||||||
|
@ -5785,11 +5775,6 @@ async@^2.6.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
lodash "^4.17.14"
|
lodash "^4.17.14"
|
||||||
|
|
||||||
async@~0.2.9:
|
|
||||||
version "0.2.10"
|
|
||||||
resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
|
|
||||||
integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E=
|
|
||||||
|
|
||||||
async@~1.0.0:
|
async@~1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9"
|
resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9"
|
||||||
|
@ -7100,15 +7085,6 @@ buffer@^5.1.0, buffer@^5.2.0:
|
||||||
base64-js "^1.0.2"
|
base64-js "^1.0.2"
|
||||||
ieee754 "^1.1.4"
|
ieee754 "^1.1.4"
|
||||||
|
|
||||||
buffered-spawn@~1.1.1:
|
|
||||||
version "1.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/buffered-spawn/-/buffered-spawn-1.1.2.tgz#21ad9735dfbf6576745be0d74a23ef257bf3c58d"
|
|
||||||
integrity sha1-Ia2XNd+/ZXZ0W+DXSiPvJXvzxY0=
|
|
||||||
dependencies:
|
|
||||||
cross-spawn-async "^1.0.1"
|
|
||||||
err-code "^0.1.0"
|
|
||||||
q "^1.0.1"
|
|
||||||
|
|
||||||
builtin-modules@^1.0.0:
|
builtin-modules@^1.0.0:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
|
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
|
||||||
|
@ -8345,13 +8321,6 @@ commander@~2.8.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
graceful-readlink ">= 1.0.0"
|
graceful-readlink ">= 1.0.0"
|
||||||
|
|
||||||
commander@~2.9.0:
|
|
||||||
version "2.9.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
|
|
||||||
integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=
|
|
||||||
dependencies:
|
|
||||||
graceful-readlink ">= 1.0.0"
|
|
||||||
|
|
||||||
common-tags@1.8.0, common-tags@^1.8.0:
|
common-tags@1.8.0, common-tags@^1.8.0:
|
||||||
version "1.8.0"
|
version "1.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
|
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
|
||||||
|
@ -8935,14 +8904,6 @@ cross-fetch@2.2.2:
|
||||||
node-fetch "2.1.2"
|
node-fetch "2.1.2"
|
||||||
whatwg-fetch "2.0.4"
|
whatwg-fetch "2.0.4"
|
||||||
|
|
||||||
cross-spawn-async@^1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn-async/-/cross-spawn-async-1.0.1.tgz#bb525c1e420d9942552e04791a3eb2d9887a105f"
|
|
||||||
integrity sha1-u1JcHkINmUJVLgR5Gj6y2Yh6EF8=
|
|
||||||
dependencies:
|
|
||||||
lru-cache "^2.6.5"
|
|
||||||
which "^1.1.1"
|
|
||||||
|
|
||||||
cross-spawn-async@^2.1.1:
|
cross-spawn-async@^2.1.1:
|
||||||
version "2.2.5"
|
version "2.2.5"
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz#845ff0c0834a3ded9d160daca6d390906bb288cc"
|
resolved "https://registry.yarnpkg.com/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz#845ff0c0834a3ded9d160daca6d390906bb288cc"
|
||||||
|
@ -9679,7 +9640,7 @@ debug-fabulous@1.X:
|
||||||
memoizee "0.4.X"
|
memoizee "0.4.X"
|
||||||
object-assign "4.X"
|
object-assign "4.X"
|
||||||
|
|
||||||
debug@2.6.9, debug@^2.0.0, debug@^2.1.0, debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9, debug@~2.2.0:
|
debug@2.6.9, debug@^2.0.0, debug@^2.1.0, debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9:
|
||||||
version "2.6.9"
|
version "2.6.9"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||||
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
|
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
|
||||||
|
@ -10968,11 +10929,6 @@ enzyme@^3.10.0:
|
||||||
rst-selector-parser "^2.2.3"
|
rst-selector-parser "^2.2.3"
|
||||||
string.prototype.trim "^1.1.2"
|
string.prototype.trim "^1.1.2"
|
||||||
|
|
||||||
err-code@^0.1.0:
|
|
||||||
version "0.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/err-code/-/err-code-0.1.2.tgz#122a92b3342b9899da02b5ac994d30f95d4763ee"
|
|
||||||
integrity sha1-EiqSszQrmJnaArWsmU0w+V1HY+4=
|
|
||||||
|
|
||||||
errlop@^1.1.2:
|
errlop@^1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/errlop/-/errlop-1.1.2.tgz#a99a48f37aa264d614e342ffdbbaa49eec9220e0"
|
resolved "https://registry.yarnpkg.com/errlop/-/errlop-1.1.2.tgz#a99a48f37aa264d614e342ffdbbaa49eec9220e0"
|
||||||
|
@ -13809,15 +13765,6 @@ glogg@^1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
sparkles "^1.0.0"
|
sparkles "^1.0.0"
|
||||||
|
|
||||||
gm@~1.21.1:
|
|
||||||
version "1.21.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/gm/-/gm-1.21.1.tgz#7ed5ed05db36d30c1943f39c3bc1c839b8f2361d"
|
|
||||||
integrity sha1-ftXtBds20wwZQ/OcO8HIObjyNh0=
|
|
||||||
dependencies:
|
|
||||||
array-parallel "~0.1.3"
|
|
||||||
array-series "~0.1.5"
|
|
||||||
debug "~2.2.0"
|
|
||||||
|
|
||||||
gonzales-pe-sl@^4.2.3:
|
gonzales-pe-sl@^4.2.3:
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz#6a868bc380645f141feeb042c6f97fcc71b59fe6"
|
resolved "https://registry.yarnpkg.com/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz#6a868bc380645f141feeb042c6f97fcc71b59fe6"
|
||||||
|
@ -15276,18 +15223,6 @@ ignore@^5.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.2.tgz#e28e584d43ad7e92f96995019cc43b9e1ac49558"
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.2.tgz#e28e584d43ad7e92f96995019cc43b9e1ac49558"
|
||||||
integrity sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==
|
integrity sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==
|
||||||
|
|
||||||
image-diff@1.6.3:
|
|
||||||
version "1.6.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/image-diff/-/image-diff-1.6.3.tgz#818a0e656ae89480e802e7ef14db460826f730fc"
|
|
||||||
integrity sha1-gYoOZWrolIDoAufvFNtGCCb3MPw=
|
|
||||||
dependencies:
|
|
||||||
async "~0.2.9"
|
|
||||||
buffered-spawn "~1.1.1"
|
|
||||||
commander "~2.9.0"
|
|
||||||
gm "~1.21.1"
|
|
||||||
mkdirp "~0.3.5"
|
|
||||||
tmp "0.0.23"
|
|
||||||
|
|
||||||
image-size@~0.5.0:
|
image-size@~0.5.0:
|
||||||
version "0.5.5"
|
version "0.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c"
|
resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c"
|
||||||
|
@ -18713,11 +18648,6 @@ lru-cache@4.1.x, lru-cache@^4.0.0:
|
||||||
pseudomap "^1.0.2"
|
pseudomap "^1.0.2"
|
||||||
yallist "^2.1.2"
|
yallist "^2.1.2"
|
||||||
|
|
||||||
lru-cache@^2.6.5:
|
|
||||||
version "2.7.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952"
|
|
||||||
integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=
|
|
||||||
|
|
||||||
lru-cache@^5.1.1:
|
lru-cache@^5.1.1:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
|
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
|
||||||
|
@ -19552,7 +19482,7 @@ mixin-object@^2.0.1:
|
||||||
for-in "^0.1.3"
|
for-in "^0.1.3"
|
||||||
is-extendable "^0.1.1"
|
is-extendable "^0.1.1"
|
||||||
|
|
||||||
mkdirp@0.3.5, mkdirp@^0.3.5, mkdirp@~0.3.5:
|
mkdirp@0.3.5, mkdirp@^0.3.5:
|
||||||
version "0.3.5"
|
version "0.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7"
|
||||||
integrity sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=
|
integrity sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=
|
||||||
|
@ -21797,13 +21727,20 @@ pirates@^4.0.0, pirates@^4.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
node-modules-regexp "^1.0.0"
|
node-modules-regexp "^1.0.0"
|
||||||
|
|
||||||
pixelmatch@4.0.2, pixelmatch@^4.0.2:
|
pixelmatch@^4.0.2:
|
||||||
version "4.0.2"
|
version "4.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854"
|
resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854"
|
||||||
integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=
|
integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=
|
||||||
dependencies:
|
dependencies:
|
||||||
pngjs "^3.0.0"
|
pngjs "^3.0.0"
|
||||||
|
|
||||||
|
pixelmatch@^5.1.0:
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-5.1.0.tgz#b640f0e5a03a09f235a4b818ef3b9b98d9d0b911"
|
||||||
|
integrity sha512-HqtgvuWN12tBzKJf7jYsc38Ha28Q2NYpmBL9WostEGgDHJqbTLkjydZXL1ZHM02ZnB+Dkwlxo87HBY38kMiD6A==
|
||||||
|
dependencies:
|
||||||
|
pngjs "^3.4.0"
|
||||||
|
|
||||||
pkg-dir@^2.0.0:
|
pkg-dir@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
|
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
|
||||||
|
@ -22605,7 +22542,7 @@ puppeteer@^1.13.0:
|
||||||
rimraf "^2.6.1"
|
rimraf "^2.6.1"
|
||||||
ws "^6.1.0"
|
ws "^6.1.0"
|
||||||
|
|
||||||
q@^1.0.1, q@^1.1.2:
|
q@^1.1.2:
|
||||||
version "1.5.1"
|
version "1.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||||
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
|
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
|
||||||
|
@ -27422,11 +27359,6 @@ titleize@^1.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/titleize/-/titleize-1.0.1.tgz#21bc24fcca658eadc6d3bd3c38f2bd173769b4c5"
|
resolved "https://registry.yarnpkg.com/titleize/-/titleize-1.0.1.tgz#21bc24fcca658eadc6d3bd3c38f2bd173769b4c5"
|
||||||
integrity sha512-rUwGDruKq1gX+FFHbTl5qjI7teVO7eOe+C8IcQ7QT+1BK3eEUXJqbZcBOeaRP4FwSC/C1A5jDoIVta0nIQ9yew==
|
integrity sha512-rUwGDruKq1gX+FFHbTl5qjI7teVO7eOe+C8IcQ7QT+1BK3eEUXJqbZcBOeaRP4FwSC/C1A5jDoIVta0nIQ9yew==
|
||||||
|
|
||||||
tmp@0.0.23:
|
|
||||||
version "0.0.23"
|
|
||||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.23.tgz#de874aa5e974a85f0a32cdfdbd74663cb3bd9c74"
|
|
||||||
integrity sha1-3odKpel0qF8KMs39vXRmPLO9nHQ=
|
|
||||||
|
|
||||||
tmp@0.0.30:
|
tmp@0.0.30:
|
||||||
version "0.0.30"
|
version "0.0.30"
|
||||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed"
|
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed"
|
||||||
|
|
Loading…
Reference in a new issue