From 392db8d81ca5b24010576601785433cb67bba2ac Mon Sep 17 00:00:00 2001 From: Devon Thomson Date: Wed, 6 Jan 2021 10:47:43 -0500 Subject: [PATCH 01/44] [Dashboard] Fix Missing Legacy Redirect (#87246) * Added dashboard no match to run legacy redirect. Added functional test coverage --- .../public/application/dashboard_router.tsx | 10 ++- .../listing/dashboard_listing.test.tsx | 2 + .../listing/dashboard_no_match.tsx | 76 +++++++++++++++++++ .../dashboard/public/application/types.ts | 2 + test/functional/apps/dashboard/legacy_urls.ts | 15 ++++ 5 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 src/plugins/dashboard/public/application/listing/dashboard_no_match.tsx diff --git a/src/plugins/dashboard/public/application/dashboard_router.tsx b/src/plugins/dashboard/public/application/dashboard_router.tsx index 1ea6355b9c558..baa7ffc5b8de3 100644 --- a/src/plugins/dashboard/public/application/dashboard_router.tsx +++ b/src/plugins/dashboard/public/application/dashboard_router.tsx @@ -41,6 +41,7 @@ import { PluginInitializerContext, ScopedHistory, } from '../services/core'; +import { DashboardNoMatch } from './listing/dashboard_no_match'; export const dashboardUrlParams = { showTopMenu: 'show-top-menu', @@ -77,6 +78,7 @@ export async function mountApp({ const { navigation, savedObjects, + urlForwarding, data: dataStart, share: shareStart, embeddable: embeddableStart, @@ -88,6 +90,7 @@ export async function mountApp({ navigation, onAppLeave, savedObjects, + urlForwarding, usageCollection, core: coreStart, data: dataStart, @@ -180,6 +183,10 @@ export async function mountApp({ ); }; + const renderNoMatch = (routeProps: RouteComponentProps) => { + return ; + }; + // make sure the index pattern list is up to date await dataStart.indexPatterns.clearCache(); @@ -202,9 +209,10 @@ export async function mountApp({ render={renderDashboard} /> - + + diff --git a/src/plugins/dashboard/public/application/listing/dashboard_listing.test.tsx b/src/plugins/dashboard/public/application/listing/dashboard_listing.test.tsx index 3aee05554b0d9..8172be46e9f3a 100644 --- a/src/plugins/dashboard/public/application/listing/dashboard_listing.test.tsx +++ b/src/plugins/dashboard/public/application/listing/dashboard_listing.test.tsx @@ -39,6 +39,7 @@ import { dataPluginMock } from '../../../../data/public/mocks'; import { chromeServiceMock, coreMock } from '../../../../../core/public/mocks'; import { I18nProvider } from '@kbn/i18n/react'; import React from 'react'; +import { UrlForwardingStart } from '../../../../url_forwarding/public'; function makeDefaultServices(): DashboardAppServices { const core = coreMock.createStart(); @@ -71,6 +72,7 @@ function makeDefaultServices(): DashboardAppServices { scopedHistory: () => ({} as ScopedHistory), savedQueryService: {} as SavedQueryService, setHeaderActionMenu: (mountPoint) => {}, + urlForwarding: {} as UrlForwardingStart, uiSettings: {} as IUiSettingsClient, restorePreviousUrl: () => {}, onAppLeave: (handler) => {}, diff --git a/src/plugins/dashboard/public/application/listing/dashboard_no_match.tsx b/src/plugins/dashboard/public/application/listing/dashboard_no_match.tsx new file mode 100644 index 0000000000000..a0f13af92ff77 --- /dev/null +++ b/src/plugins/dashboard/public/application/listing/dashboard_no_match.tsx @@ -0,0 +1,76 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiCallOut } from '@elastic/eui'; + +import { RouteComponentProps } from 'react-router-dom'; +import { useKibana, toMountPoint } from '../../services/kibana_react'; +import { DashboardAppServices } from '../types'; +import { DashboardConstants } from '../..'; + +let bannerId: string | undefined; + +export const DashboardNoMatch = ({ history }: { history: RouteComponentProps['history'] }) => { + const { services } = useKibana(); + + useEffect(() => { + services.restorePreviousUrl(); + + const { navigated } = services.urlForwarding.navigateToLegacyKibanaUrl( + history.location.pathname + ); + + if (!navigated) { + const bannerMessage = i18n.translate('dashboard.noMatchRoute.bannerTitleText', { + defaultMessage: 'Page not found', + }); + + bannerId = services.core.overlays.banners.replace( + bannerId, + toMountPoint( + +

+ +

+
+ ) + ); + + // hide the message after the user has had a chance to acknowledge it -- so it doesn't permanently stick around + setTimeout(() => { + if (bannerId) { + services.core.overlays.banners.remove(bannerId); + } + }, 15000); + + history.replace(DashboardConstants.LANDING_PAGE_PATH); + } + }, [services, history]); + + return null; +}; diff --git a/src/plugins/dashboard/public/application/types.ts b/src/plugins/dashboard/public/application/types.ts index d1caaa349d80b..75620fd73360d 100644 --- a/src/plugins/dashboard/public/application/types.ts +++ b/src/plugins/dashboard/public/application/types.ts @@ -33,6 +33,7 @@ import { NavigationPublicPluginStart } from '../services/navigation'; import { SavedObjectsTaggingApi } from '../services/saved_objects_tagging_oss'; import { DataPublicPluginStart, IndexPatternsContract } from '../services/data'; import { SavedObjectLoader, SavedObjectsStart } from '../services/saved_objects'; +import { UrlForwardingStart } from '../../../url_forwarding/public'; export type DashboardRedirect = (props: RedirectToProps) => void; export type RedirectToProps = @@ -75,6 +76,7 @@ export interface DashboardAppServices { uiSettings: IUiSettingsClient; restorePreviousUrl: () => void; savedObjects: SavedObjectsStart; + urlForwarding: UrlForwardingStart; savedDashboards: SavedObjectLoader; scopedHistory: () => ScopedHistory; indexPatterns: IndexPatternsContract; diff --git a/test/functional/apps/dashboard/legacy_urls.ts b/test/functional/apps/dashboard/legacy_urls.ts index 6bb8d808e8daa..2a30bbf5e1f0a 100644 --- a/test/functional/apps/dashboard/legacy_urls.ts +++ b/test/functional/apps/dashboard/legacy_urls.ts @@ -92,6 +92,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.clickMarkdownWidget(); await PageObjects.visEditor.setMarkdownTxt(`[abc](#/dashboard/${testDashboardId})`); await PageObjects.visEditor.clickGo(); + + await PageObjects.visualize.saveVisualizationExpectSuccess('legacy url markdown'); + (await find.byLinkText('abc')).click(); await PageObjects.header.waitUntilLoadingHasFinished(); @@ -109,6 +112,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visEditor.expectMarkdownTextArea(); await browser.goForward(); }); + + it('resolves markdown link from dashboard', async () => { + await PageObjects.common.navigateToApp('dashboard'); + await PageObjects.dashboard.clickNewDashboard(); + await dashboardAddPanel.addVisualization('legacy url markdown'); + (await find.byLinkText('abc')).click(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.timePicker.setDefaultDataRange(); + + await PageObjects.dashboard.waitForRenderComplete(); + await pieChart.expectPieSliceCount(5); + }); }); }); } From 316346ac3ac6d5bd49ef0a33bdfd00101ba8d5b9 Mon Sep 17 00:00:00 2001 From: spalger Date: Wed, 6 Jan 2021 09:16:52 -0700 Subject: [PATCH 02/44] skip flaky suite (#87425) --- x-pack/test/plugin_functional/test_suites/resolver/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/plugin_functional/test_suites/resolver/index.ts b/x-pack/test/plugin_functional/test_suites/resolver/index.ts index 13087a7f9f9bf..5b50afb401793 100644 --- a/x-pack/test/plugin_functional/test_suites/resolver/index.ts +++ b/x-pack/test/plugin_functional/test_suites/resolver/index.ts @@ -25,7 +25,8 @@ export default function ({ const find = getService('find'); const browser = getService('browser'); - describe('Resolver test app', function () { + // FLAKY: https://github.com/elastic/kibana/issues/87425 + describe.skip('Resolver test app', function () { this.tags('ciGroup7'); // Note: these tests are intended to run on the same page in serial. From 14fde6d27768a318d9ca0c90a5c697180cdbc4b8 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 6 Jan 2021 17:13:53 +0000 Subject: [PATCH 03/44] chore(NA): move console out of __tests__ folder (#87368) --- .../{__tests__ => }/input.test.js | 8 ++--- .../output_tokenization.test.js | 6 ++-- .../editor_input1.txt | 0 .../{__tests__ => }/integration.test.js | 8 ++--- .../{__tests__ => }/sense_editor.test.js | 8 ++--- .../{__jest__ => }/url_autocomplete.test.js | 9 ++---- .../{__jest__ => }/url_params.test.js | 4 +-- .../curl_parsing.txt | 0 .../{__tests__ => }/curl_parsing.test.js | 4 +-- .../es/{__tests__ => }/content_type.test.js | 2 +- .../public/lib/kb/{__tests__ => }/kb.test.js | 8 ++--- .../mappings/{__tests__ => }/mapping.test.js | 4 +-- .../lib/utils/{__tests__ => }/utils.test.js | 2 +- .../console/proxy/{tests => }/body.test.ts | 23 +++++++-------- .../console/proxy/{tests => }/headers.test.ts | 29 +++++++++---------- .../api/console/proxy/{tests => }/mocks.ts | 10 +++---- .../console/proxy/{tests => }/params.test.ts | 17 +++++------ .../proxy/{tests => }/proxy_fallback.test.ts | 6 ++-- .../proxy/{tests => }/query_string.test.ts | 20 ++++++------- .../{tests => }/route_validation.test.ts | 2 +- .../api/console/proxy/{tests => }/stubs.ts | 0 21 files changed, 80 insertions(+), 90 deletions(-) rename src/plugins/console/public/application/models/legacy_core_editor/{__tests__ => }/input.test.js (98%) rename src/plugins/console/public/application/models/legacy_core_editor/{__tests__ => }/output_tokenization.test.js (94%) rename src/plugins/console/public/application/models/sense_editor/{__tests__ => __fixtures__}/editor_input1.txt (100%) rename src/plugins/console/public/application/models/sense_editor/{__tests__ => }/integration.test.js (99%) rename src/plugins/console/public/application/models/sense_editor/{__tests__ => }/sense_editor.test.js (98%) rename src/plugins/console/public/lib/autocomplete/{__jest__ => }/url_autocomplete.test.js (98%) rename src/plugins/console/public/lib/autocomplete/{__jest__ => }/url_params.test.js (96%) rename src/plugins/console/public/lib/curl_parsing/{__tests__ => __fixtures__}/curl_parsing.txt (100%) rename src/plugins/console/public/lib/curl_parsing/{__tests__ => }/curl_parsing.test.js (93%) rename src/plugins/console/public/lib/es/{__tests__ => }/content_type.test.js (96%) rename src/plugins/console/public/lib/kb/{__tests__ => }/kb.test.js (96%) rename src/plugins/console/public/lib/mappings/{__tests__ => }/mapping.test.js (98%) rename src/plugins/console/public/lib/utils/{__tests__ => }/utils.test.js (99%) rename src/plugins/console/server/routes/api/console/proxy/{tests => }/body.test.ts (80%) rename src/plugins/console/server/routes/api/console/proxy/{tests => }/headers.test.ts (71%) rename src/plugins/console/server/routes/api/console/proxy/{tests => }/mocks.ts (92%) rename src/plugins/console/server/routes/api/console/proxy/{tests => }/params.test.ts (87%) rename src/plugins/console/server/routes/api/console/proxy/{tests => }/proxy_fallback.test.ts (92%) rename src/plugins/console/server/routes/api/console/proxy/{tests => }/query_string.test.ts (81%) rename src/plugins/console/server/routes/api/console/proxy/{tests => }/route_validation.test.ts (96%) rename src/plugins/console/server/routes/api/console/proxy/{tests => }/stubs.ts (100%) diff --git a/src/plugins/console/public/application/models/legacy_core_editor/__tests__/input.test.js b/src/plugins/console/public/application/models/legacy_core_editor/input.test.js similarity index 98% rename from src/plugins/console/public/application/models/legacy_core_editor/__tests__/input.test.js rename to src/plugins/console/public/application/models/legacy_core_editor/input.test.js index 81171c2bd26fe..f7b618aefd6fd 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/__tests__/input.test.js +++ b/src/plugins/console/public/application/models/legacy_core_editor/input.test.js @@ -16,11 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -import '../legacy_core_editor.test.mocks'; -import RowParser from '../../../../lib/row_parser'; -import { createTokenIterator } from '../../../factories'; +import './legacy_core_editor.test.mocks'; +import RowParser from '../../../lib/row_parser'; +import { createTokenIterator } from '../../factories'; import $ from 'jquery'; -import { create } from '../create'; +import { create } from './create'; describe('Input', () => { let coreEditor; diff --git a/src/plugins/console/public/application/models/legacy_core_editor/__tests__/output_tokenization.test.js b/src/plugins/console/public/application/models/legacy_core_editor/output_tokenization.test.js similarity index 94% rename from src/plugins/console/public/application/models/legacy_core_editor/__tests__/output_tokenization.test.js rename to src/plugins/console/public/application/models/legacy_core_editor/output_tokenization.test.js index ea7530bd21387..aa6b03e5ae290 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/__tests__/output_tokenization.test.js +++ b/src/plugins/console/public/application/models/legacy_core_editor/output_tokenization.test.js @@ -16,11 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -import '../legacy_core_editor.test.mocks'; +import './legacy_core_editor.test.mocks'; import $ from 'jquery'; -import RowParser from '../../../../lib/row_parser'; +import RowParser from '../../../lib/row_parser'; import ace from 'brace'; -import { createReadOnlyAceEditor } from '../create_readonly'; +import { createReadOnlyAceEditor } from './create_readonly'; let output; const tokenIterator = ace.acequire('ace/token_iterator'); diff --git a/src/plugins/console/public/application/models/sense_editor/__tests__/editor_input1.txt b/src/plugins/console/public/application/models/sense_editor/__fixtures__/editor_input1.txt similarity index 100% rename from src/plugins/console/public/application/models/sense_editor/__tests__/editor_input1.txt rename to src/plugins/console/public/application/models/sense_editor/__fixtures__/editor_input1.txt diff --git a/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js b/src/plugins/console/public/application/models/sense_editor/integration.test.js similarity index 99% rename from src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js rename to src/plugins/console/public/application/models/sense_editor/integration.test.js index 89880528943e5..5caf772f04c39 100644 --- a/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js +++ b/src/plugins/console/public/application/models/sense_editor/integration.test.js @@ -16,13 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -import '../sense_editor.test.mocks'; -import { create } from '../create'; +import './sense_editor.test.mocks'; +import { create } from './create'; import _ from 'lodash'; import $ from 'jquery'; -import * as kb from '../../../../lib/kb/kb'; -import * as mappings from '../../../../lib/mappings/mappings'; +import * as kb from '../../../lib/kb/kb'; +import * as mappings from '../../../lib/mappings/mappings'; describe('Integration', () => { let senseEditor; diff --git a/src/plugins/console/public/application/models/sense_editor/__tests__/sense_editor.test.js b/src/plugins/console/public/application/models/sense_editor/sense_editor.test.js similarity index 98% rename from src/plugins/console/public/application/models/sense_editor/__tests__/sense_editor.test.js rename to src/plugins/console/public/application/models/sense_editor/sense_editor.test.js index 04d3cd1a724e1..d1bc4bdd62116 100644 --- a/src/plugins/console/public/application/models/sense_editor/__tests__/sense_editor.test.js +++ b/src/plugins/console/public/application/models/sense_editor/sense_editor.test.js @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -import '../sense_editor.test.mocks'; +import './sense_editor.test.mocks'; import $ from 'jquery'; import _ from 'lodash'; -import { create } from '../create'; -import { XJson } from '../../../../../../es_ui_shared/public'; -import editorInput1 from './editor_input1.txt'; +import { create } from './create'; +import { XJson } from '../../../../../es_ui_shared/public'; +import editorInput1 from './__fixtures__/editor_input1.txt'; const { collapseLiteralStrings } = XJson; diff --git a/src/plugins/console/public/lib/autocomplete/__jest__/url_autocomplete.test.js b/src/plugins/console/public/lib/autocomplete/url_autocomplete.test.js similarity index 98% rename from src/plugins/console/public/lib/autocomplete/__jest__/url_autocomplete.test.js rename to src/plugins/console/public/lib/autocomplete/url_autocomplete.test.js index 0f97416f053ee..4d2692b3ba16c 100644 --- a/src/plugins/console/public/lib/autocomplete/__jest__/url_autocomplete.test.js +++ b/src/plugins/console/public/lib/autocomplete/url_autocomplete.test.js @@ -18,13 +18,8 @@ */ import _ from 'lodash'; -import { - URL_PATH_END_MARKER, - UrlPatternMatcher, - ListComponent, -} from '../../autocomplete/components'; - -import { populateContext } from '../../autocomplete/engine'; +import { URL_PATH_END_MARKER, UrlPatternMatcher, ListComponent } from './components'; +import { populateContext } from './engine'; describe('Url autocomplete', () => { function patternsTest(name, endpoints, tokenPath, expectedContext, globalUrlComponentFactories) { diff --git a/src/plugins/console/public/lib/autocomplete/__jest__/url_params.test.js b/src/plugins/console/public/lib/autocomplete/url_params.test.js similarity index 96% rename from src/plugins/console/public/lib/autocomplete/__jest__/url_params.test.js rename to src/plugins/console/public/lib/autocomplete/url_params.test.js index e624e7ba57b61..d74d9c1c159bd 100644 --- a/src/plugins/console/public/lib/autocomplete/__jest__/url_params.test.js +++ b/src/plugins/console/public/lib/autocomplete/url_params.test.js @@ -17,8 +17,8 @@ * under the License. */ import _ from 'lodash'; -import { UrlParams } from '../../autocomplete/url_params'; -import { populateContext } from '../../autocomplete/engine'; +import { UrlParams } from './url_params'; +import { populateContext } from './engine'; describe('Url params', () => { function paramTest(name, description, tokenPath, expectedContext, globalParams) { diff --git a/src/plugins/console/public/lib/curl_parsing/__tests__/curl_parsing.txt b/src/plugins/console/public/lib/curl_parsing/__fixtures__/curl_parsing.txt similarity index 100% rename from src/plugins/console/public/lib/curl_parsing/__tests__/curl_parsing.txt rename to src/plugins/console/public/lib/curl_parsing/__fixtures__/curl_parsing.txt diff --git a/src/plugins/console/public/lib/curl_parsing/__tests__/curl_parsing.test.js b/src/plugins/console/public/lib/curl_parsing/curl_parsing.test.js similarity index 93% rename from src/plugins/console/public/lib/curl_parsing/__tests__/curl_parsing.test.js rename to src/plugins/console/public/lib/curl_parsing/curl_parsing.test.js index 068dd68be4ba8..6f4e531715f7f 100644 --- a/src/plugins/console/public/lib/curl_parsing/__tests__/curl_parsing.test.js +++ b/src/plugins/console/public/lib/curl_parsing/curl_parsing.test.js @@ -18,8 +18,8 @@ */ import _ from 'lodash'; -import { detectCURL, parseCURL } from '../curl'; -import curlTests from './curl_parsing.txt'; +import { detectCURL, parseCURL } from './curl'; +import curlTests from './__fixtures__/curl_parsing.txt'; describe('CURL', () => { const notCURLS = ['sldhfsljfhs', 's;kdjfsldkfj curl -XDELETE ""', '{ "hello": 1 }']; diff --git a/src/plugins/console/public/lib/es/__tests__/content_type.test.js b/src/plugins/console/public/lib/es/content_type.test.js similarity index 96% rename from src/plugins/console/public/lib/es/__tests__/content_type.test.js rename to src/plugins/console/public/lib/es/content_type.test.js index e800fe41cb018..af62a3cad3f1f 100644 --- a/src/plugins/console/public/lib/es/__tests__/content_type.test.js +++ b/src/plugins/console/public/lib/es/content_type.test.js @@ -17,7 +17,7 @@ * under the License. */ -import { getContentType } from '../es'; +import { getContentType } from './es'; const APPLICATION_JSON = 'application/json'; describe('Content type', () => { diff --git a/src/plugins/console/public/lib/kb/__tests__/kb.test.js b/src/plugins/console/public/lib/kb/kb.test.js similarity index 96% rename from src/plugins/console/public/lib/kb/__tests__/kb.test.js rename to src/plugins/console/public/lib/kb/kb.test.js index eaf5023053880..a7e43f2e94a50 100644 --- a/src/plugins/console/public/lib/kb/__tests__/kb.test.js +++ b/src/plugins/console/public/lib/kb/kb.test.js @@ -18,11 +18,11 @@ */ import _ from 'lodash'; -import { populateContext } from '../../autocomplete/engine'; +import { populateContext } from '../autocomplete/engine'; -import '../../../application/models/sense_editor/sense_editor.test.mocks'; -import * as kb from '../../kb'; -import * as mappings from '../../mappings/mappings'; +import '../../application/models/sense_editor/sense_editor.test.mocks'; +import * as kb from '../kb'; +import * as mappings from '../mappings/mappings'; describe('Knowledge base', () => { beforeEach(() => { diff --git a/src/plugins/console/public/lib/mappings/__tests__/mapping.test.js b/src/plugins/console/public/lib/mappings/mapping.test.js similarity index 98% rename from src/plugins/console/public/lib/mappings/__tests__/mapping.test.js rename to src/plugins/console/public/lib/mappings/mapping.test.js index ce52b060f418f..ab4c08fca1553 100644 --- a/src/plugins/console/public/lib/mappings/__tests__/mapping.test.js +++ b/src/plugins/console/public/lib/mappings/mapping.test.js @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -import '../../../application/models/sense_editor/sense_editor.test.mocks'; -import * as mappings from '../mappings'; +import '../../application/models/sense_editor/sense_editor.test.mocks'; +import * as mappings from './mappings'; describe('Mappings', () => { beforeEach(() => { diff --git a/src/plugins/console/public/lib/utils/__tests__/utils.test.js b/src/plugins/console/public/lib/utils/utils.test.js similarity index 99% rename from src/plugins/console/public/lib/utils/__tests__/utils.test.js rename to src/plugins/console/public/lib/utils/utils.test.js index e47e71c742a81..ee86756da8362 100644 --- a/src/plugins/console/public/lib/utils/__tests__/utils.test.js +++ b/src/plugins/console/public/lib/utils/utils.test.js @@ -17,7 +17,7 @@ * under the License. */ -import * as utils from '../'; +import * as utils from '.'; describe('Utils class', () => { test('extract deprecation messages', function () { diff --git a/src/plugins/console/server/routes/api/console/proxy/tests/body.test.ts b/src/plugins/console/server/routes/api/console/proxy/body.test.ts similarity index 80% rename from src/plugins/console/server/routes/api/console/proxy/tests/body.test.ts rename to src/plugins/console/server/routes/api/console/proxy/body.test.ts index d0c8383792796..b6ba08c13b06b 100644 --- a/src/plugins/console/server/routes/api/console/proxy/tests/body.test.ts +++ b/src/plugins/console/server/routes/api/console/proxy/body.test.ts @@ -18,12 +18,11 @@ */ import { getProxyRouteHandlerDeps } from './mocks'; -import expect from '@kbn/expect'; import { Readable } from 'stream'; -import { kibanaResponseFactory } from '../../../../../../../../core/server'; -import { createHandler } from '../create_handler'; -import * as requestModule from '../../../../../lib/proxy_request'; +import { kibanaResponseFactory } from '../../../../../../../core/server'; +import { createHandler } from './create_handler'; +import * as requestModule from '../../../../lib/proxy_request'; import { createResponseStub } from './stubs'; describe('Console Proxy Route', () => { @@ -62,38 +61,38 @@ describe('Console Proxy Route', () => { describe('GET request', () => { it('returns the exact body', async () => { const { payload } = await request('GET', '/', 'foobar'); - expect(await readStream(payload)).to.be('foobar'); + expect(await readStream(payload)).toBe('foobar'); }); }); describe('POST request', () => { it('returns the exact body', async () => { const { payload } = await request('POST', '/', 'foobar'); - expect(await readStream(payload)).to.be('foobar'); + expect(await readStream(payload)).toBe('foobar'); }); }); describe('PUT request', () => { it('returns the exact body', async () => { const { payload } = await request('PUT', '/', 'foobar'); - expect(await readStream(payload)).to.be('foobar'); + expect(await readStream(payload)).toBe('foobar'); }); }); describe('DELETE request', () => { it('returns the exact body', async () => { const { payload } = await request('DELETE', '/', 'foobar'); - expect(await readStream(payload)).to.be('foobar'); + expect(await readStream(payload)).toBe('foobar'); }); }); describe('HEAD request', () => { it('returns the status code and text', async () => { const { payload } = await request('HEAD', '/'); - expect(typeof payload).to.be('string'); - expect(payload).to.be('200 - OK'); + expect(typeof payload).toBe('string'); + expect(payload).toBe('200 - OK'); }); describe('mixed casing', () => { it('returns the status code and text', async () => { const { payload } = await request('HeAd', '/'); - expect(typeof payload).to.be('string'); - expect(payload).to.be('200 - OK'); + expect(typeof payload).toBe('string'); + expect(payload).toBe('200 - OK'); }); }); }); diff --git a/src/plugins/console/server/routes/api/console/proxy/tests/headers.test.ts b/src/plugins/console/server/routes/api/console/proxy/headers.test.ts similarity index 71% rename from src/plugins/console/server/routes/api/console/proxy/tests/headers.test.ts rename to src/plugins/console/server/routes/api/console/proxy/headers.test.ts index 2d4c616754e33..5ea08e7ada9ba 100644 --- a/src/plugins/console/server/routes/api/console/proxy/tests/headers.test.ts +++ b/src/plugins/console/server/routes/api/console/proxy/headers.test.ts @@ -16,21 +16,20 @@ * specific language governing permissions and limitations * under the License. */ -jest.mock('../../../../../../../../core/server/http/router/request', () => ({ +jest.mock('../../../../../../../core/server/http/router/request', () => ({ ensureRawRequest: jest.fn(), })); -import { kibanaResponseFactory } from '../../../../../../../../core/server'; +import { kibanaResponseFactory } from '../../../../../../../core/server'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ensureRawRequest } from '../../../../../../../../core/server/http/router/request'; +import { ensureRawRequest } from '../../../../../../../core/server/http/router/request'; import { getProxyRouteHandlerDeps } from './mocks'; -import expect from '@kbn/expect'; -import * as requestModule from '../../../../../lib/proxy_request'; +import * as requestModule from '../../../../lib/proxy_request'; -import { createHandler } from '../create_handler'; +import { createHandler } from './create_handler'; import { createResponseStub } from './stubs'; @@ -74,16 +73,16 @@ describe('Console Proxy Route', () => { kibanaResponseFactory ); - expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).to.be(1); + expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).toBe(1); const [[{ headers }]] = (requestModule.proxyRequest as jest.Mock).mock.calls; - expect(headers).to.have.property('x-forwarded-for'); - expect(headers['x-forwarded-for']).to.be('0.0.0.0'); - expect(headers).to.have.property('x-forwarded-port'); - expect(headers['x-forwarded-port']).to.be('1234'); - expect(headers).to.have.property('x-forwarded-proto'); - expect(headers['x-forwarded-proto']).to.be('http'); - expect(headers).to.have.property('x-forwarded-host'); - expect(headers['x-forwarded-host']).to.be('test'); + expect(headers).toHaveProperty('x-forwarded-for'); + expect(headers['x-forwarded-for']).toBe('0.0.0.0'); + expect(headers).toHaveProperty('x-forwarded-port'); + expect(headers['x-forwarded-port']).toBe('1234'); + expect(headers).toHaveProperty('x-forwarded-proto'); + expect(headers['x-forwarded-proto']).toBe('http'); + expect(headers).toHaveProperty('x-forwarded-host'); + expect(headers['x-forwarded-host']).toBe('test'); }); }); }); diff --git a/src/plugins/console/server/routes/api/console/proxy/tests/mocks.ts b/src/plugins/console/server/routes/api/console/proxy/mocks.ts similarity index 92% rename from src/plugins/console/server/routes/api/console/proxy/tests/mocks.ts rename to src/plugins/console/server/routes/api/console/proxy/mocks.ts index 158a4a979683f..4d55a27d7aa2f 100644 --- a/src/plugins/console/server/routes/api/console/proxy/tests/mocks.ts +++ b/src/plugins/console/server/routes/api/console/proxy/mocks.ts @@ -17,15 +17,15 @@ * under the License. */ -jest.mock('../../../../../lib/proxy_request', () => ({ +jest.mock('../../../../lib/proxy_request', () => ({ proxyRequest: jest.fn(), })); import { duration } from 'moment'; -import { ProxyConfigCollection } from '../../../../../lib'; -import { RouteDependencies, ProxyDependencies } from '../../../../../routes'; -import { EsLegacyConfigService, SpecDefinitionsService } from '../../../../../services'; -import { coreMock, httpServiceMock } from '../../../../../../../../core/server/mocks'; +import { ProxyConfigCollection } from '../../../../lib'; +import { RouteDependencies, ProxyDependencies } from '../../../../routes'; +import { EsLegacyConfigService, SpecDefinitionsService } from '../../../../services'; +import { coreMock, httpServiceMock } from '../../../../../../../core/server/mocks'; const defaultProxyValue = Object.freeze({ readLegacyESConfig: async () => ({ diff --git a/src/plugins/console/server/routes/api/console/proxy/tests/params.test.ts b/src/plugins/console/server/routes/api/console/proxy/params.test.ts similarity index 87% rename from src/plugins/console/server/routes/api/console/proxy/tests/params.test.ts rename to src/plugins/console/server/routes/api/console/proxy/params.test.ts index fc1dae7fbcea2..8838fa405b88f 100644 --- a/src/plugins/console/server/routes/api/console/proxy/tests/params.test.ts +++ b/src/plugins/console/server/routes/api/console/proxy/params.test.ts @@ -16,13 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -import { kibanaResponseFactory } from '../../../../../../../../core/server'; +import { kibanaResponseFactory } from '../../../../../../../core/server'; import { getProxyRouteHandlerDeps } from './mocks'; import { createResponseStub } from './stubs'; -import * as requestModule from '../../../../../lib/proxy_request'; -import expect from '@kbn/expect'; +import * as requestModule from '../../../../lib/proxy_request'; -import { createHandler } from '../create_handler'; +import { createHandler } from './create_handler'; describe('Console Proxy Route', () => { let handler: ReturnType; @@ -45,7 +44,7 @@ describe('Console Proxy Route', () => { kibanaResponseFactory ); - expect(status).to.be(403); + expect(status).toBe(403); }); }); describe('one match', () => { @@ -62,8 +61,8 @@ describe('Console Proxy Route', () => { kibanaResponseFactory ); - expect(status).to.be(200); - expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).to.be(1); + expect(status).toBe(200); + expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).toBe(1); }); }); describe('all match', () => { @@ -80,8 +79,8 @@ describe('Console Proxy Route', () => { kibanaResponseFactory ); - expect(status).to.be(200); - expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).to.be(1); + expect(status).toBe(200); + expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).toBe(1); }); }); }); diff --git a/src/plugins/console/server/routes/api/console/proxy/tests/proxy_fallback.test.ts b/src/plugins/console/server/routes/api/console/proxy/proxy_fallback.test.ts similarity index 92% rename from src/plugins/console/server/routes/api/console/proxy/tests/proxy_fallback.test.ts rename to src/plugins/console/server/routes/api/console/proxy/proxy_fallback.test.ts index 17ce715ac1afa..b9575b7abeea3 100644 --- a/src/plugins/console/server/routes/api/console/proxy/tests/proxy_fallback.test.ts +++ b/src/plugins/console/server/routes/api/console/proxy/proxy_fallback.test.ts @@ -20,9 +20,9 @@ import { duration } from 'moment'; import { getProxyRouteHandlerDeps } from './mocks'; -import { kibanaResponseFactory } from '../../../../../../../../core/server'; -import * as requestModule from '../../../../../lib/proxy_request'; -import { createHandler } from '../create_handler'; +import { kibanaResponseFactory } from '../../../../../../../core/server'; +import * as requestModule from '../../../../lib/proxy_request'; +import { createHandler } from './create_handler'; describe('Console Proxy Route', () => { afterEach(async () => { diff --git a/src/plugins/console/server/routes/api/console/proxy/tests/query_string.test.ts b/src/plugins/console/server/routes/api/console/proxy/query_string.test.ts similarity index 81% rename from src/plugins/console/server/routes/api/console/proxy/tests/query_string.test.ts rename to src/plugins/console/server/routes/api/console/proxy/query_string.test.ts index f0e7e5d6e8f9a..7b7bd6b605d96 100644 --- a/src/plugins/console/server/routes/api/console/proxy/tests/query_string.test.ts +++ b/src/plugins/console/server/routes/api/console/proxy/query_string.test.ts @@ -16,14 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -import { kibanaResponseFactory } from '../../../../../../../../core/server'; +import { kibanaResponseFactory } from '../../../../../../../core/server'; import { getProxyRouteHandlerDeps } from './mocks'; import { createResponseStub } from './stubs'; -import * as requestModule from '../../../../../lib/proxy_request'; +import * as requestModule from '../../../../lib/proxy_request'; -import expect from '@kbn/expect'; - -import { createHandler } from '../create_handler'; +import { createHandler } from './create_handler'; describe('Console Proxy Route', () => { let request: any; @@ -50,25 +48,25 @@ describe('Console Proxy Route', () => { describe('contains full url', () => { it('treats the url as a path', async () => { await request('GET', 'http://evil.com/test'); - expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).to.be(1); + expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).toBe(1); const [[args]] = (requestModule.proxyRequest as jest.Mock).mock.calls; - expect(args.uri.href).to.be('http://localhost:9200/http://evil.com/test?pretty=true'); + expect(args.uri.href).toBe('http://localhost:9200/http://evil.com/test?pretty=true'); }); }); describe('starts with a slash', () => { it('combines well with the base url', async () => { await request('GET', '/index/id'); - expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).to.be(1); + expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).toBe(1); const [[args]] = (requestModule.proxyRequest as jest.Mock).mock.calls; - expect(args.uri.href).to.be('http://localhost:9200/index/id?pretty=true'); + expect(args.uri.href).toBe('http://localhost:9200/index/id?pretty=true'); }); }); describe(`doesn't start with a slash`, () => { it('combines well with the base url', async () => { await request('GET', 'index/id'); - expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).to.be(1); + expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).toBe(1); const [[args]] = (requestModule.proxyRequest as jest.Mock).mock.calls; - expect(args.uri.href).to.be('http://localhost:9200/index/id?pretty=true'); + expect(args.uri.href).toBe('http://localhost:9200/index/id?pretty=true'); }); }); }); diff --git a/src/plugins/console/server/routes/api/console/proxy/tests/route_validation.test.ts b/src/plugins/console/server/routes/api/console/proxy/route_validation.test.ts similarity index 96% rename from src/plugins/console/server/routes/api/console/proxy/tests/route_validation.test.ts rename to src/plugins/console/server/routes/api/console/proxy/route_validation.test.ts index 2588c96e3b091..a67c742f09fb5 100644 --- a/src/plugins/console/server/routes/api/console/proxy/tests/route_validation.test.ts +++ b/src/plugins/console/server/routes/api/console/proxy/route_validation.test.ts @@ -17,7 +17,7 @@ * under the License. */ -import { routeValidationConfig } from '../validation_config'; +import { routeValidationConfig } from './validation_config'; const { query } = routeValidationConfig; diff --git a/src/plugins/console/server/routes/api/console/proxy/tests/stubs.ts b/src/plugins/console/server/routes/api/console/proxy/stubs.ts similarity index 100% rename from src/plugins/console/server/routes/api/console/proxy/tests/stubs.ts rename to src/plugins/console/server/routes/api/console/proxy/stubs.ts From 4b4d6a6bb89c5d1b9b5be9af4b2e8661672c4870 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 6 Jan 2021 18:17:16 +0100 Subject: [PATCH 04/44] [Uptime] fix multiple scrolls on waterfall view (#87281) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../components/common/header/page_header.tsx | 6 +- .../waterfall/waterfall_chart_wrapper.tsx | 5 +- .../synthetics/waterfall/components/styles.ts | 4 +- .../waterfall/components/waterfall.test.tsx | 68 +++++++++++++++++++ .../waterfall/components/waterfall_chart.tsx | 30 ++++++-- 5 files changed, 102 insertions(+), 11 deletions(-) create mode 100644 x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall.test.tsx diff --git a/x-pack/plugins/uptime/public/components/common/header/page_header.tsx b/x-pack/plugins/uptime/public/components/common/header/page_header.tsx index 7d093efd31be0..923aee472faa6 100644 --- a/x-pack/plugins/uptime/public/components/common/header/page_header.tsx +++ b/x-pack/plugins/uptime/public/components/common/header/page_header.tsx @@ -44,7 +44,7 @@ export const PageHeader = () => { const DatePickerComponent = () => isCertRoute ? ( - ) : isStepDetailRoute ? null : ( + ) : ( @@ -52,6 +52,10 @@ export const PageHeader = () => { const isMonRoute = useRouteMatch(MONITOR_ROUTE); + if (isStepDetailRoute) { + return null; + } + return ( <> diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx index b10c3844f3002..7aa5a22849321 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx @@ -15,7 +15,7 @@ import { RenderItem, } from '../../waterfall'; -const renderSidebarItem: RenderItem = (item, index) => { +export const renderSidebarItem: RenderItem = (item, index) => { const { status } = item; const isErrorStatusCode = (statusCode: number) => { @@ -43,7 +43,7 @@ const renderSidebarItem: RenderItem = (item, index) => { ); }; -const renderLegendItem: RenderItem = (item) => { +export const renderLegendItem: RenderItem = (item) => { return {item.name}; }; @@ -81,6 +81,7 @@ export const WaterfallChartWrapper: React.FC = ({ data }) => { }} renderSidebarItem={renderSidebarItem} renderLegendItem={renderLegendItem} + fullHeight={true} /> ); diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/styles.ts b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/styles.ts index 320e415585ca3..61a8104eddd31 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/styles.ts +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/styles.ts @@ -9,11 +9,11 @@ import { euiStyled } from '../../../../../../../observability/public'; import { FIXED_AXIS_HEIGHT } from './constants'; interface WaterfallChartOuterContainerProps { - height?: number; + height?: string; } export const WaterfallChartOuterContainer = euiStyled.div` - height: ${(props) => (props.height ? `${props.height}px` : 'auto')}; + height: ${(props) => (props.height ? `${props.height}` : 'auto')}; overflow-y: ${(props) => (props.height ? 'scroll' : 'visible')}; overflow-x: hidden; `; diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall.test.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall.test.tsx new file mode 100644 index 0000000000000..44e63f04f7bec --- /dev/null +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall.test.tsx @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { of } from 'rxjs'; +import { MountWithReduxProvider, mountWithRouter } from '../../../../../lib'; +import { KibanaContextProvider } from '../../../../../../../../../src/plugins/kibana_react/public'; +import { WaterfallChart } from './waterfall_chart'; +import { + renderLegendItem, + renderSidebarItem, +} from '../../step_detail/waterfall/waterfall_chart_wrapper'; +import { EuiThemeProvider } from '../../../../../../../observability/public'; +import { WaterfallChartOuterContainer } from './styles'; + +describe('waterfall', () => { + it('sets the correct height in case of full height', () => { + const core = mockCore(); + + const Component = () => { + return ( + `${Number(d).toFixed(0)} ms`} + domain={{ + max: 3371, + min: 0, + }} + barStyleAccessor={(datum) => { + return datum.datum.config.colour; + }} + renderSidebarItem={renderSidebarItem} + renderLegendItem={renderLegendItem} + fullHeight={true} + /> + ); + }; + + const component = mountWithRouter( + + + + + + + + ); + + const chartWrapper = component.find(WaterfallChartOuterContainer); + + expect(chartWrapper.get(0).props.height).toBe('calc(100vh - 0px)'); + }); +}); + +const mockCore: () => any = () => { + return { + application: { + getUrlForApp: () => '/app/uptime', + navigateToUrl: jest.fn(), + }, + uiSettings: { + get: (key: string) => 'MMM D, YYYY @ HH:mm:ss.SSS', + get$: (key: string) => of('MMM D, YYYY @ HH:mm:ss.SSS'), + }, + }; +}; diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx index d92e26335a6bd..40fa0de2ecec7 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { Axis, @@ -63,11 +63,12 @@ export interface WaterfallChartProps { barStyleAccessor: BarStyleAccessor; renderSidebarItem?: RenderItem; renderLegendItem?: RenderItem; - maxHeight?: number; + maxHeight?: string; + fullHeight?: boolean; } const getUniqueBars = (data: WaterfallData) => { - return data.reduce>((acc, item) => { + return (data ?? []).reduce>((acc, item) => { if (!acc.has(item.x)) { acc.add(item.x); return acc; @@ -86,7 +87,8 @@ export const WaterfallChart = ({ barStyleAccessor, renderSidebarItem, renderLegendItem, - maxHeight = 800, + maxHeight = '800px', + fullHeight = false, }: WaterfallChartProps) => { const { data, sidebarItems, legendItems } = useWaterfallContext(); @@ -100,13 +102,24 @@ export const WaterfallChart = ({ return darkMode ? EUI_CHARTS_THEME_DARK.theme : EUI_CHARTS_THEME_LIGHT.theme; }, [darkMode]); + const chartWrapperDivRef = useRef(null); + + const [height, setHeight] = useState(maxHeight); + const shouldRenderSidebar = sidebarItems && sidebarItems.length > 0 && renderSidebarItem ? true : false; const shouldRenderLegend = legendItems && legendItems.length > 0 && renderLegendItem ? true : false; + useEffect(() => { + if (fullHeight && chartWrapperDivRef.current) { + const chartOffset = chartWrapperDivRef.current.getBoundingClientRect().top; + setHeight(`calc(100vh - ${chartOffset}px)`); + } + }, [chartWrapperDivRef, fullHeight]); + return ( - + <> @@ -153,7 +166,12 @@ export const WaterfallChart = ({ - + {shouldRenderSidebar && ( )} From a95fdbdec3b83363e3416a3bbe5e62faf49694eb Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Wed, 6 Jan 2021 17:18:57 +0000 Subject: [PATCH 05/44] [Actions] Exposes the typing for Actions Type Params (#87465) This PR exposes the types for the Params & ActionTypeIds of all Action Types --- .../server/builtin_action_types/email.ts | 3 +- .../server/builtin_action_types/es_index.ts | 4 +-- .../server/builtin_action_types/index.ts | 28 +++++++++++++++++++ .../server/builtin_action_types/jira/index.ts | 6 ++-- .../server/builtin_action_types/pagerduty.ts | 3 +- .../builtin_action_types/resilient/index.ts | 7 +++-- .../server/builtin_action_types/server_log.ts | 4 +-- .../builtin_action_types/servicenow/index.ts | 7 +++-- .../server/builtin_action_types/slack.ts | 3 +- .../server/builtin_action_types/teams.ts | 3 +- .../server/builtin_action_types/webhook.ts | 3 +- x-pack/plugins/actions/server/index.ts | 24 ++++++++++++++++ .../server/lib/ensure_sufficient_license.ts | 7 ++--- 13 files changed, 83 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/email.ts b/x-pack/plugins/actions/server/builtin_action_types/email.ts index cf4ace99ed5dc..4afbbb3a33615 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/email.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/email.ts @@ -139,10 +139,11 @@ interface GetActionTypeParams { } // action type definition +export const ActionTypeId = '.email'; export function getActionType(params: GetActionTypeParams): EmailActionType { const { logger, publicBaseUrl, configurationUtilities } = params; return { - id: '.email', + id: ActionTypeId, minimumLicenseRequired: 'gold', name: i18n.translate('xpack.actions.builtin.emailTitle', { defaultMessage: 'Email', diff --git a/x-pack/plugins/actions/server/builtin_action_types/es_index.ts b/x-pack/plugins/actions/server/builtin_action_types/es_index.ts index 6926c826f776e..1b739b1567c6d 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/es_index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/es_index.ts @@ -39,11 +39,11 @@ const ParamsSchema = schema.object({ documents: schema.arrayOf(schema.recordOf(schema.string(), schema.any())), }); -export const ES_INDEX_ACTION_TYPE_ID = '.index'; +export const ActionTypeId = '.index'; // action type definition export function getActionType({ logger }: { logger: Logger }): ESIndexActionType { return { - id: ES_INDEX_ACTION_TYPE_ID, + id: ActionTypeId, minimumLicenseRequired: 'basic', name: i18n.translate('xpack.actions.builtin.esIndexTitle', { defaultMessage: 'Index', diff --git a/x-pack/plugins/actions/server/builtin_action_types/index.ts b/x-pack/plugins/actions/server/builtin_action_types/index.ts index c2058d63683bf..3a01b875ec4a0 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/index.ts @@ -18,6 +18,34 @@ import { getActionType as getServiceNowActionType } from './servicenow'; import { getActionType as getJiraActionType } from './jira'; import { getActionType as getResilientActionType } from './resilient'; import { getActionType as getTeamsActionType } from './teams'; +export { ActionParamsType as EmailActionParams, ActionTypeId as EmailActionTypeId } from './email'; +export { + ActionParamsType as IndexActionParams, + ActionTypeId as IndexActionTypeId, +} from './es_index'; +export { + ActionParamsType as PagerDutyActionParams, + ActionTypeId as PagerDutyActionTypeId, +} from './pagerduty'; +export { + ActionParamsType as ServerLogActionParams, + ActionTypeId as ServerLogActionTypeId, +} from './server_log'; +export { ActionParamsType as SlackActionParams, ActionTypeId as SlackActionTypeId } from './slack'; +export { + ActionParamsType as WebhookActionParams, + ActionTypeId as WebhookActionTypeId, +} from './webhook'; +export { + ActionParamsType as ServiceNowActionParams, + ActionTypeId as ServiceNowActionTypeId, +} from './servicenow'; +export { ActionParamsType as JiraActionParams, ActionTypeId as JiraActionTypeId } from './jira'; +export { + ActionParamsType as ResilientActionParams, + ActionTypeId as ResilientActionTypeId, +} from './resilient'; +export { ActionParamsType as TeamsActionParams, ActionTypeId as TeamsActionTypeId } from './teams'; export function registerBuiltInActionTypes({ actionsConfigUtils: configurationUtilities, diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/index.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/index.ts index 4518fa0f119d5..d701fad0e0c2f 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/index.ts @@ -5,7 +5,7 @@ */ import { curry } from 'lodash'; -import { schema } from '@kbn/config-schema'; +import { schema, TypeOf } from '@kbn/config-schema'; import { validate } from './validators'; import { @@ -32,6 +32,7 @@ import { import * as i18n from './translations'; import { Logger } from '../../../../../../src/core/server'; +export type ActionParamsType = TypeOf; interface GetActionTypeParams { logger: Logger; configurationUtilities: ActionsConfigurationUtilities; @@ -47,6 +48,7 @@ const supportedSubActions: string[] = [ 'issue', ]; +export const ActionTypeId = '.jira'; // action type definition export function getActionType( params: GetActionTypeParams @@ -58,7 +60,7 @@ export function getActionType( > { const { logger, configurationUtilities } = params; return { - id: '.jira', + id: ActionTypeId, minimumLicenseRequired: 'gold', name: i18n.NAME, validate: { diff --git a/x-pack/plugins/actions/server/builtin_action_types/pagerduty.ts b/x-pack/plugins/actions/server/builtin_action_types/pagerduty.ts index 4574b748e6014..ccd25da2397bb 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/pagerduty.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/pagerduty.ts @@ -117,6 +117,7 @@ function validateParams(paramsObject: unknown): string | void { } } +export const ActionTypeId = '.pagerduty'; // action type definition export function getActionType({ logger, @@ -126,7 +127,7 @@ export function getActionType({ configurationUtilities: ActionsConfigurationUtilities; }): PagerDutyActionType { return { - id: '.pagerduty', + id: ActionTypeId, minimumLicenseRequired: 'gold', name: i18n.translate('xpack.actions.builtin.pagerdutyTitle', { defaultMessage: 'PagerDuty', diff --git a/x-pack/plugins/actions/server/builtin_action_types/resilient/index.ts b/x-pack/plugins/actions/server/builtin_action_types/resilient/index.ts index 7ce9369289554..fca99f81d62bd 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/resilient/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/resilient/index.ts @@ -5,7 +5,7 @@ */ import { curry } from 'lodash'; -import { schema } from '@kbn/config-schema'; +import { schema, TypeOf } from '@kbn/config-schema'; import { validate } from './validators'; import { @@ -30,6 +30,8 @@ import { import * as i18n from './translations'; import { Logger } from '../../../../../../src/core/server'; +export type ActionParamsType = TypeOf; + interface GetActionTypeParams { logger: Logger; configurationUtilities: ActionsConfigurationUtilities; @@ -37,6 +39,7 @@ interface GetActionTypeParams { const supportedSubActions: string[] = ['getFields', 'pushToService', 'incidentTypes', 'severity']; +export const ActionTypeId = '.resilient'; // action type definition export function getActionType( params: GetActionTypeParams @@ -48,7 +51,7 @@ export function getActionType( > { const { logger, configurationUtilities } = params; return { - id: '.resilient', + id: ActionTypeId, minimumLicenseRequired: 'platinum', name: i18n.NAME, validate: { diff --git a/x-pack/plugins/actions/server/builtin_action_types/server_log.ts b/x-pack/plugins/actions/server/builtin_action_types/server_log.ts index c485de8628f14..4cfea6aa9d889 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/server_log.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/server_log.ts @@ -38,11 +38,11 @@ const ParamsSchema = schema.object({ ), }); -export const SERVER_LOG_ACTION_TYPE_ID = '.server-log'; +export const ActionTypeId = '.server-log'; // action type definition export function getActionType({ logger }: { logger: Logger }): ServerLogActionType { return { - id: SERVER_LOG_ACTION_TYPE_ID, + id: ActionTypeId, minimumLicenseRequired: 'basic', name: i18n.translate('xpack.actions.builtin.serverLogTitle', { defaultMessage: 'Server log', diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts index 3fa8b25b86e8b..1f75d439200e3 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts @@ -5,7 +5,7 @@ */ import { curry } from 'lodash'; -import { schema } from '@kbn/config-schema'; +import { schema, TypeOf } from '@kbn/config-schema'; import { validate } from './validators'; import { @@ -29,11 +29,14 @@ import { ServiceNowExecutorResultData, } from './types'; +export type ActionParamsType = TypeOf; + interface GetActionTypeParams { logger: Logger; configurationUtilities: ActionsConfigurationUtilities; } +export const ActionTypeId = '.servicenow'; // action type definition export function getActionType( params: GetActionTypeParams @@ -45,7 +48,7 @@ export function getActionType( > { const { logger, configurationUtilities } = params; return { - id: '.servicenow', + id: ActionTypeId, minimumLicenseRequired: 'platinum', name: i18n.NAME, validate: { diff --git a/x-pack/plugins/actions/server/builtin_action_types/slack.ts b/x-pack/plugins/actions/server/builtin_action_types/slack.ts index a9155c329c175..c9a3c39afd049 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/slack.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/slack.ts @@ -52,6 +52,7 @@ const ParamsSchema = schema.object({ // action type definition +export const ActionTypeId = '.slack'; // customizing executor is only used for tests export function getActionType({ logger, @@ -63,7 +64,7 @@ export function getActionType({ executor?: ExecutorType<{}, ActionTypeSecretsType, ActionParamsType, unknown>; }): SlackActionType { return { - id: '.slack', + id: ActionTypeId, minimumLicenseRequired: 'gold', name: i18n.translate('xpack.actions.builtin.slackTitle', { defaultMessage: 'Slack', diff --git a/x-pack/plugins/actions/server/builtin_action_types/teams.ts b/x-pack/plugins/actions/server/builtin_action_types/teams.ts index e152a65217ce2..8575ae75d1e6c 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/teams.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/teams.ts @@ -42,6 +42,7 @@ const ParamsSchema = schema.object({ message: schema.string({ minLength: 1 }), }); +export const ActionTypeId = '.teams'; // action type definition export function getActionType({ logger, @@ -51,7 +52,7 @@ export function getActionType({ configurationUtilities: ActionsConfigurationUtilities; }): TeamsActionType { return { - id: '.teams', + id: ActionTypeId, minimumLicenseRequired: 'gold', name: i18n.translate('xpack.actions.builtin.teamsTitle', { defaultMessage: 'Microsoft Teams', diff --git a/x-pack/plugins/actions/server/builtin_action_types/webhook.ts b/x-pack/plugins/actions/server/builtin_action_types/webhook.ts index 089363990643f..4479f7c69bebb 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/webhook.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/webhook.ts @@ -71,6 +71,7 @@ const ParamsSchema = schema.object({ body: schema.maybe(schema.string()), }); +export const ActionTypeId = '.webhook'; // action type definition export function getActionType({ logger, @@ -80,7 +81,7 @@ export function getActionType({ configurationUtilities: ActionsConfigurationUtilities; }): WebhookActionType { return { - id: '.webhook', + id: ActionTypeId, minimumLicenseRequired: 'gold', name: i18n.translate('xpack.actions.builtin.webhookTitle', { defaultMessage: 'Webhook', diff --git a/x-pack/plugins/actions/server/index.ts b/x-pack/plugins/actions/server/index.ts index 39bfe2c2820e2..c43cc20bd4773 100644 --- a/x-pack/plugins/actions/server/index.ts +++ b/x-pack/plugins/actions/server/index.ts @@ -21,6 +21,30 @@ export { ActionType, PreConfiguredAction, } from './types'; + +export type { + EmailActionTypeId, + EmailActionParams, + IndexActionTypeId, + IndexActionParams, + PagerDutyActionTypeId, + PagerDutyActionParams, + ServerLogActionTypeId, + ServerLogActionParams, + SlackActionTypeId, + SlackActionParams, + WebhookActionTypeId, + WebhookActionParams, + ServiceNowActionTypeId, + ServiceNowActionParams, + JiraActionTypeId, + JiraActionParams, + ResilientActionTypeId, + ResilientActionParams, + TeamsActionTypeId, + TeamsActionParams, +} from './builtin_action_types'; + export { PluginSetupContract, PluginStartContract } from './plugin'; export { asSavedObjectExecutionSource, asHttpRequestExecutionSource } from './lib'; diff --git a/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts b/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts index 0f309bb76b76c..f22e87a58ec7f 100644 --- a/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts +++ b/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts @@ -5,14 +5,13 @@ */ import { ActionType } from '../types'; import { LICENSE_TYPE } from '../../../licensing/common/types'; -import { SERVER_LOG_ACTION_TYPE_ID } from '../builtin_action_types/server_log'; -import { ES_INDEX_ACTION_TYPE_ID } from '../builtin_action_types/es_index'; +import { ServerLogActionTypeId, IndexActionTypeId } from '../builtin_action_types'; import { CASE_ACTION_TYPE_ID } from '../../../case/server'; import { ActionTypeConfig, ActionTypeSecrets, ActionTypeParams } from '../types'; const ACTIONS_SCOPED_WITHIN_STACK = new Set([ - SERVER_LOG_ACTION_TYPE_ID, - ES_INDEX_ACTION_TYPE_ID, + ServerLogActionTypeId, + IndexActionTypeId, CASE_ACTION_TYPE_ID, ]); From b4f3a15458f9a07ee67ef3fb426109d1c50b6598 Mon Sep 17 00:00:00 2001 From: Constance Date: Wed, 6 Jan 2021 09:48:44 -0800 Subject: [PATCH 06/44] [Enterprise Search] Kea mount test helper (#87247) * Add Kea logic mount helper * Update existing mount() helpers to use new DRY helper * Add additional unmount helper + example test update --- .../public/applications/__mocks__/index.ts | 8 ++- .../public/applications/__mocks__/kea.mock.ts | 69 ++++++++++++++++++- .../credentials/credentials_logic.test.ts | 21 +----- .../document_creation_logic.test.ts | 22 +----- .../documents/document_detail_logic.test.ts | 21 +----- .../documents/documents_logic.test.ts | 21 +----- .../components/engine/engine_logic.test.ts | 21 +----- .../engine_overview_logic.test.ts | 12 +--- .../log_retention/log_retention_logic.test.ts | 21 +----- 9 files changed, 89 insertions(+), 127 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts index e8944b15978a9..57f4a9f66b987 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts @@ -10,7 +10,13 @@ export { mockLicensingValues } from './licensing_logic.mock'; export { mockHttpValues } from './http_logic.mock'; export { mockTelemetryActions } from './telemetry_logic.mock'; export { mockFlashMessagesValues, mockFlashMessagesActions } from './flash_messages_logic.mock'; -export { mockAllValues, mockAllActions, setMockValues, setMockActions } from './kea.mock'; +export { + mockAllValues, + mockAllActions, + setMockValues, + setMockActions, + LogicMounter, +} from './kea.mock'; export { mountAsync } from './mount_async.mock'; export { mountWithIntl } from './mount_with_i18n.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts index 0176f8c03c632..78ffbcfa3526f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts @@ -40,14 +40,18 @@ jest.mock('kea', () => ({ })); /** + * React component helpers + * * Call this function to override a specific set of Kea values while retaining all other defaults - * Example usage within a component test: * - * import '../../../__mocks__/kea'; - * import { setMockValues } from ''../../../__mocks__'; + * Example usage: + * + * import { setMockValues } from '../../../__mocks__/kea.mock'; + * import { SomeComponent } from './'; * * it('some test', () => { * setMockValues({ someValue: 'hello' }); + * shallow(); * }); */ import { useValues, useActions } from 'kea'; @@ -58,3 +62,62 @@ export const setMockValues = (values: object) => { export const setMockActions = (actions: object) => { (useActions as jest.Mock).mockImplementation(() => ({ ...mockAllActions, ...actions })); }; + +/** + * Kea logic helpers + * + * Call this function to mount a logic file and optionally override default values. + * Automatically DRYs out a lot of cruft for us, such as resetting context, creating the + * nested defaults path obj (see https://kea.js.org/docs/api/context#resetcontext), and + * returning an unmount function + * + * Example usage: + * + * import { LogicMounter } from '../../../__mocks__/kea.mock'; + * import { SomeLogic } from './'; + * + * const { mount, unmount } = new LogicMounter(SomeLogic); + * + * it('some test', () => { + * mount({ someValue: 'hello' }); + * unmount(); + * }); + */ +import { resetContext, Logic, LogicInput } from 'kea'; + +interface LogicFile { + inputs: Array>; + mount(): Function; +} +export class LogicMounter { + private logicFile: LogicFile; + private unmountFn!: Function; + + constructor(logicFile: LogicFile) { + this.logicFile = logicFile; + } + + // Reset context with optional default value overrides + public resetContext = (values?: object) => { + if (!values) { + resetContext({}); + } else { + const path = this.logicFile.inputs[0].path as string[]; // example: ['x', 'y', 'z'] + const defaults = path.reduceRight((value: object, key: string) => ({ [key]: value }), values); // example: { x: { y: { z: values } } } + resetContext({ defaults }); + } + }; + + // Automatically reset context & mount the logic file + public mount = (values?: object) => { + this.resetContext(values); + const unmount = this.logicFile.mount(); + this.unmountFn = unmount; + return unmount; // Keep Kea behavior of returning an unmount fn from mount + }; + + // Also add unmount as a class method that can be destructured on init without becoming stale later + public unmount = () => { + this.unmountFn(); + }; +} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts index 6523b4fb110b0..48be2b0ae8dfd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; +import { LogicMounter } from '../../../__mocks__/kea.mock'; import { mockHttpValues } from '../../../__mocks__'; jest.mock('../../../shared/http', () => ({ @@ -57,24 +57,7 @@ describe('CredentialsLogic', () => { fullEngineAccessChecked: false, }; - const mount = (defaults?: object) => { - if (!defaults) { - resetContext({}); - } else { - resetContext({ - defaults: { - enterprise_search: { - app_search: { - credentials_logic: { - ...defaults, - }, - }, - }, - }, - }); - } - CredentialsLogic.mount(); - }; + const { mount } = new LogicMounter(CredentialsLogic); const newToken = { id: 1, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts index bb0103b07b072..c2a0d29cc1f40 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; +import { LogicMounter } from '../../../__mocks__/kea.mock'; + import dedent from 'dedent'; jest.mock('./utils', () => ({ @@ -39,24 +40,7 @@ describe('DocumentCreationLogic', () => { }; const mockFile = new File(['mockFile'], 'mockFile.json'); - const mount = (defaults?: object) => { - if (!defaults) { - resetContext({}); - } else { - resetContext({ - defaults: { - enterprise_search: { - app_search: { - document_creation_logic: { - ...defaults, - }, - }, - }, - }, - }); - } - DocumentCreationLogic.mount(); - }; + const { mount } = new LogicMounter(DocumentCreationLogic); beforeEach(() => { jest.clearAllMocks(); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts index d9a3de7c078cc..fe735f70247c6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; +import { LogicMounter } from '../../../__mocks__/kea.mock'; import { mockHttpValues } from '../../../__mocks__'; jest.mock('../../../shared/http', () => ({ @@ -36,24 +36,7 @@ describe('DocumentDetailLogic', () => { fields: [], }; - const mount = (defaults?: object) => { - if (!defaults) { - resetContext({}); - } else { - resetContext({ - defaults: { - enterprise_search: { - app_search: { - document_detail_logic: { - ...defaults, - }, - }, - }, - }, - }); - } - DocumentDetailLogic.mount(); - }; + const { mount } = new LogicMounter(DocumentDetailLogic); beforeEach(() => { jest.clearAllMocks(); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents_logic.test.ts index 236172f0f7bdf..2863a39535ef4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents_logic.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; +import { LogicMounter } from '../../../__mocks__/kea.mock'; import { DocumentsLogic } from './documents_logic'; @@ -13,24 +13,7 @@ describe('DocumentsLogic', () => { isDocumentCreationOpen: false, }; - const mount = (defaults?: object) => { - if (!defaults) { - resetContext({}); - } else { - resetContext({ - defaults: { - enterprise_search: { - app_search: { - documents_logic: { - ...defaults, - }, - }, - }, - }, - }); - } - DocumentsLogic.mount(); - }; + const { mount } = new LogicMounter(DocumentsLogic); describe('actions', () => { describe('openDocumentCreation', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts index 13db440df739e..a77c6555b72df 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; +import { LogicMounter } from '../../../__mocks__/kea.mock'; import { mockHttpValues } from '../../../__mocks__'; jest.mock('../../../shared/http', () => ({ @@ -46,24 +46,7 @@ describe('EngineLogic', () => { engineNotFound: false, }; - const mount = (values?: object) => { - if (!values) { - resetContext({}); - } else { - resetContext({ - defaults: { - enterprise_search: { - app_search: { - engine_logic: { - ...values, - }, - }, - }, - }, - }); - } - EngineLogic.mount(); - }; + const { mount } = new LogicMounter(EngineLogic); beforeEach(() => { jest.clearAllMocks(); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_logic.test.ts index d35bde20f4f1e..2063f706a4741 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_logic.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; +import { LogicMounter } from '../../../__mocks__/kea.mock'; import { mockHttpValues } from '../../../__mocks__'; jest.mock('../../../shared/http', () => ({ @@ -48,10 +48,7 @@ describe('EngineOverviewLogic', () => { timeoutId: null, }; - const mount = () => { - resetContext({}); - EngineOverviewLogic.mount(); - }; + const { mount, unmount } = new LogicMounter(EngineOverviewLogic); beforeEach(() => { jest.clearAllMocks(); @@ -141,12 +138,9 @@ describe('EngineOverviewLogic', () => { }); describe('unmount', () => { - let unmount: Function; - beforeEach(() => { jest.useFakeTimers(); - resetContext({}); - unmount = EngineOverviewLogic.mount(); + mount(); }); it('clears existing polling timeouts on unmount', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_logic.test.ts index c86d7e3e915e2..8310e2abe045b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_logic.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; +import { LogicMounter } from '../../../../__mocks__/kea.mock'; import { mockHttpValues } from '../../../../__mocks__'; jest.mock('../../../../shared/http', () => ({ @@ -53,24 +53,7 @@ describe('LogRetentionLogic', () => { isLogRetentionUpdating: false, }; - const mount = (defaults?: object) => { - if (!defaults) { - resetContext({}); - } else { - resetContext({ - defaults: { - enterprise_search: { - app_search: { - log_retention_logic: { - ...defaults, - }, - }, - }, - }, - }); - } - LogRetentionLogic.mount(); - }; + const { mount } = new LogicMounter(LogRetentionLogic); beforeEach(() => { jest.clearAllMocks(); From 93262ba73690b14e2820d0c31417a521e8c13575 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Wed, 6 Jan 2021 19:51:49 +0200 Subject: [PATCH 07/44] [i18n] Integrate 7.11.0 Translations (#87452) --- .../translations/translations/ja-JP.json | 5770 +++++++++++----- .../translations/translations/zh-CN.json | 6118 +++++++++++------ 2 files changed, 8050 insertions(+), 3838 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 4d15f444ad1a8..fef61667168a9 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -84,12 +84,14 @@ "advancedSettings.categoryNames.dashboardLabel": "ダッシュボード", "advancedSettings.categoryNames.discoverLabel": "発見", "advancedSettings.categoryNames.generalLabel": "一般", + "advancedSettings.categoryNames.machineLearningLabel": "機械学習", "advancedSettings.categoryNames.notificationsLabel": "通知", + "advancedSettings.categoryNames.observabilityLabel": "オブザーバビリティ", "advancedSettings.categoryNames.reportingLabel": "レポート", "advancedSettings.categoryNames.searchLabel": "検索", "advancedSettings.categoryNames.securitySolutionLabel": "セキュリティソリューション", "advancedSettings.categoryNames.timelionLabel": "Timelion", - "advancedSettings.categoryNames.visualizationsLabel": "可視化", + "advancedSettings.categoryNames.visualizationsLabel": "ビジュアライゼーション", "advancedSettings.categorySearchLabel": "カテゴリー", "advancedSettings.featureCatalogueTitle": "日付形式の変更、ダークモードの有効化など、Kibanaエクスペリエンスをカスタマイズします。", "advancedSettings.field.changeImageLinkAriaLabel": "{ariaName} を変更", @@ -113,7 +115,7 @@ "advancedSettings.form.cancelButtonLabel": "変更をキャンセル", "advancedSettings.form.clearNoSearchResultText": "(検索結果を消去)", "advancedSettings.form.clearSearchResultText": "(検索結果を消去)", - "advancedSettings.form.countOfSettingsChanged": "{unsavedCount} unsaved {unsavedCount, plural, one {setting} other {settings} }{hiddenCount, plural, =0 {} other {, # hidden} }", + "advancedSettings.form.countOfSettingsChanged": "{unsavedCount}保存されていない {unsavedCount, plural, other {個の設定} }{hiddenCount, plural, =0 {} other {, # 非表示} }", "advancedSettings.form.noSearchResultText": "設定が見つかりませんでした {clearSearch}", "advancedSettings.form.requiresPageReloadToastButtonLabel": "ページを再読み込み", "advancedSettings.form.requiresPageReloadToastDescription": "設定を有効にするためにページの再読み込みが必要です。", @@ -125,8 +127,8 @@ "advancedSettings.searchBar.unableToParseQueryErrorMessage": "クエリをパースできません", "advancedSettings.searchBarAriaLabel": "高度な設定を検索", "advancedSettings.voiceAnnouncement.ariaLabel": "詳細設定結果情報", - "advancedSettings.voiceAnnouncement.noSearchResultScreenReaderMessage": "{sectionLenght, plural, one {# セクション} other {# セクション}}に{optionLenght, plural, one {# オプション} other {# オプション}}があります。", - "advancedSettings.voiceAnnouncement.searchResultScreenReaderMessage": "{query} を検索しました。{sectionLenght, plural, one {# セクション} other {# セクション}}に{optionLenght, plural, one {# オプション} other {# オプション}}があります。", + "advancedSettings.voiceAnnouncement.noSearchResultScreenReaderMessage": "{sectionLenght, plural, other {# セクション}}に{optionLenght, plural, other {# オプション}}があります。", + "advancedSettings.voiceAnnouncement.searchResultScreenReaderMessage": "{query} を検索しました。{sectionLenght, plural, other {# セクション}}に{optionLenght, plural, other {# オプション}}があります。", "apmOss.tutorial.apmAgents.statusCheck.btnLabel": "エージェントステータスを確認", "apmOss.tutorial.apmAgents.statusCheck.errorMessage": "エージェントからまだデータを受け取っていません", "apmOss.tutorial.apmAgents.statusCheck.successMessage": "1 つまたは複数のエージェントからデータを受け取りました", @@ -144,9 +146,10 @@ "apmOss.tutorial.djangoClient.configure.commands.addAgentComment": "インストールされたアプリにエージェントを追加します", "apmOss.tutorial.djangoClient.configure.commands.addTracingMiddlewareComment": "パフォーマンスメトリックを送信するには、追跡ミドルウェアを追加します。", "apmOss.tutorial.djangoClient.configure.commands.allowedCharactersComment": "a-z、A-Z、0-9、-、_、スペース", - "apmOss.tutorial.djangoClient.configure.commands.setCustomApmServerUrlComment": "カスタム APM Server URL (デフォルト: {defaultApmServerUrl})", - "apmOss.tutorial.djangoClient.configure.commands.setRequiredServiceNameComment": "必要なサーバー名を設定します。使用できる文字:", - "apmOss.tutorial.djangoClient.configure.commands.useIfApmServerRequiresTokenComment": "APM Server にトークンが必要な場合に使います", + "apmOss.tutorial.djangoClient.configure.commands.setCustomApmServerUrlComment": "カスタム APM Server URL(デフォルト:{defaultApmServerUrl})を設定します", + "apmOss.tutorial.djangoClient.configure.commands.setRequiredServiceNameComment": "任意のサービス名を設定します。使用できる文字:", + "apmOss.tutorial.djangoClient.configure.commands.setServiceEnvironmentComment": "サービス環境を設定します", + "apmOss.tutorial.djangoClient.configure.commands.useIfApmServerRequiresTokenComment": "APM Server でシークレットトークンが必要な場合に使います", "apmOss.tutorial.djangoClient.configure.textPost": "高度な用途に関しては [ドキュメンテーション]({documentationLink}) をご覧ください。", "apmOss.tutorial.djangoClient.configure.textPre": "エージェントとは、アプリケーションプロセス内で実行されるライブラリです。APM サービスは「SERVICE_NAME」に基づいてプログラムで作成されます。", "apmOss.tutorial.djangoClient.configure.title": "エージェントの構成", @@ -167,19 +170,21 @@ "apmOss.tutorial.flaskClient.configure.commands.allowedCharactersComment": "a-z、A-Z、0-9、-、_、スペース", "apmOss.tutorial.flaskClient.configure.commands.configureElasticApmComment": "またはアプリケーションの設定で ELASTIC_APM を使用するよう構成します。", "apmOss.tutorial.flaskClient.configure.commands.initializeUsingEnvironmentVariablesComment": "環境変数を使用して初期化します", - "apmOss.tutorial.flaskClient.configure.commands.setCustomApmServerUrlComment": "カスタム APM Server URL (デフォルト: {defaultApmServerUrl})", - "apmOss.tutorial.flaskClient.configure.commands.setRequiredServiceNameComment": "必要なサーバー名を設定します。使用できる文字:", - "apmOss.tutorial.flaskClient.configure.commands.useIfApmServerRequiresTokenComment": "APM Server にトークンが必要な場合に使います", + "apmOss.tutorial.flaskClient.configure.commands.setCustomApmServerUrlComment": "カスタム APM Server URL(デフォルト:{defaultApmServerUrl})を設定します", + "apmOss.tutorial.flaskClient.configure.commands.setRequiredServiceNameComment": "任意のサービス名を設定します。使用できる文字:", + "apmOss.tutorial.flaskClient.configure.commands.setServiceEnvironmentComment": "サービス環境を設定します", + "apmOss.tutorial.flaskClient.configure.commands.useIfApmServerRequiresTokenComment": "APM Server でシークレットトークンが必要な場合に使います", "apmOss.tutorial.flaskClient.configure.textPost": "高度な用途に関しては [ドキュメンテーション]({documentationLink}) をご覧ください。", "apmOss.tutorial.flaskClient.configure.textPre": "エージェントとは、アプリケーションプロセス内で実行されるライブラリです。APM サービスは「SERVICE_NAME」に基づいてプログラムで作成されます。", "apmOss.tutorial.flaskClient.configure.title": "エージェントの構成", "apmOss.tutorial.flaskClient.install.textPre": "Python 用の APM エージェントを依存関係としてインストールします。", "apmOss.tutorial.flaskClient.install.title": "APM エージェントのインストール", "apmOss.tutorial.goClient.configure.commands.initializeUsingEnvironmentVariablesComment": "環境変数を使用して初期化します:", - "apmOss.tutorial.goClient.configure.commands.setCustomApmServerUrlComment": "カスタム APM Server URL (デフォルト: {defaultApmServerUrl})", + "apmOss.tutorial.goClient.configure.commands.setCustomApmServerUrlComment": "カスタム APM Server URL(デフォルト:{defaultApmServerUrl})を設定します", + "apmOss.tutorial.goClient.configure.commands.setServiceEnvironment": "サービス環境を設定します", "apmOss.tutorial.goClient.configure.commands.setServiceNameComment": "サービス名を設定します。使用できる文字は # a-z、A-Z、0-9、-、_、スペースです。", - "apmOss.tutorial.goClient.configure.commands.usedExecutableNameComment": "ELASTIC_APM_SERVICE_NAME が指定されていない場合、実行可能な名前が使用されます。", - "apmOss.tutorial.goClient.configure.commands.useIfApmRequiresTokenComment": "APM Server にトークンが必要な場合に使います", + "apmOss.tutorial.goClient.configure.commands.usedExecutableNameComment": "ELASTIC_APM_SERVICE_NAME が指定されていない場合、実行ファイルの名前が使用されます。", + "apmOss.tutorial.goClient.configure.commands.useIfApmRequiresTokenComment": "APM Server でシークレットトークンが必要な場合に使います", "apmOss.tutorial.goClient.configure.textPost": "高度な構成に関しては [ドキュメンテーション]({documentationLink}) をご覧ください。", "apmOss.tutorial.goClient.configure.textPre": "エージェントとは、アプリケーションプロセス内で実行されるライブラリです。APM サービスは実行ファイル名または「ELASTIC_APM_SERVICE_NAME」環境変数に基づいてプログラムで作成されます。", "apmOss.tutorial.goClient.configure.title": "エージェントの構成", @@ -192,23 +197,25 @@ "apmOss.tutorial.javaClient.download.textPre": "[Maven Central]({mavenCentralLink}) からエージェントをダウンロードします。アプリケーションにエージェントを依存関係として「追加しない」でください。", "apmOss.tutorial.javaClient.download.title": "APM エージェントのダウンロード", "apmOss.tutorial.javaClient.startApplication.textPost": "構成オプションと高度な用途に関しては、[ドキュメンテーション]({documentationLink}) をご覧ください。", - "apmOss.tutorial.javaClient.startApplication.textPre": "「-javaagent」フラグを追加してエージェントをシステムプロパティで構成します。\n\n * 必要なサービス名を設定します (使用可能な文字は a-z、A-Z、0-9、-、_、スペースです)\n * カスタム APM Server URL (デフォルト: {customApmServerUrl})\n * アプリケーションのベースパッケージを設定します", + "apmOss.tutorial.javaClient.startApplication.textPre": "「-javaagent」フラグを追加し、システムプロパティを使用してエージェントを構成します。\n\n * 任意のサービス名を設定します (使用可能な文字は a-z、A-Z、0-9、-、_、スペースです)\n * カスタム APM Server URL(デフォルト:{customApmServerUrl})を設定します\n * APM Server シークレットトークンを設定します\n * サービス環境を設定します\n * アプリケーションのベースパッケージを設定します", "apmOss.tutorial.javaClient.startApplication.title": "javaagent フラグでアプリケーションを起動", "apmOss.tutorial.jsClient.enableRealUserMonitoring.textPre": "デフォルトでは、APM Server を実行すると RUM サポートは無効になります。RUM サポートを有効にする手順については、[ドキュメンテーション]({documentationLink}) をご覧ください。", "apmOss.tutorial.jsClient.enableRealUserMonitoring.title": "APMサーバーのリアルユーザー監視サポートを有効にする", - "apmOss.tutorial.jsClient.installDependency.commands.setCustomApmServerUrlComment": "カスタム APM Server URL (デフォルト: {defaultApmServerUrl})", - "apmOss.tutorial.jsClient.installDependency.commands.setRequiredServiceNameComment": "必要なサービス名を設定します (使用可能な文字は a-z、A-Z、0-9、-、_、スペースです)", - "apmOss.tutorial.jsClient.installDependency.commands.setServiceVersionComment": "サービスバージョンを設定します (ソースマップ機能に必要)", + "apmOss.tutorial.jsClient.installDependency.commands.setCustomApmServerUrlComment": "カスタム APM Server URL(デフォルト:{defaultApmServerUrl})を設定します", + "apmOss.tutorial.jsClient.installDependency.commands.setRequiredServiceNameComment": "任意のサービス名を設定します (使用可能な文字は a-z、A-Z、0-9、-、_、スペースです)", + "apmOss.tutorial.jsClient.installDependency.commands.setServiceEnvironmentComment": "サービス環境を設定します", + "apmOss.tutorial.jsClient.installDependency.commands.setServiceVersionComment": "サービスバージョンを設定します(ソースマップ機能に必要)", "apmOss.tutorial.jsClient.installDependency.textPost": "React や Angular などのフレームワーク統合には、カスタム依存関係があります。詳細は [統合ドキュメント]({docLink}) をご覧ください。", "apmOss.tutorial.jsClient.installDependency.textPre": "「npm install @elastic/apm-rum --save」でエージェントをアプリケーションへの依存関係としてインストールできます。\n\nその後で以下のようにアプリケーションでエージェントを初期化して構成できます。", "apmOss.tutorial.jsClient.installDependency.title": "エージェントを依存関係としてセットアップ", "apmOss.tutorial.jsClient.scriptTags.textPre": "または、スクリプトタグを使用してエージェントのセットアップと構成ができます。` を追加