From 1b3083df7bceaa0ee96259c3f6d38a1486cfbcbe Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 20 Jan 2021 14:16:23 -0500 Subject: [PATCH 01/37] New CreateEngine view component --- .../create_engine/create_engine.test.tsx | 17 +++++++++++++++++ .../components/create_engine/create_engine.tsx | 11 +++++++++++ .../components/create_engine/index.ts | 7 +++++++ 3 files changed, 35 insertions(+) create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/index.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx new file mode 100644 index 00000000000000..2d0fdadfe73f21 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx @@ -0,0 +1,17 @@ +/* + * 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 { shallow } from 'enzyme'; + +import { CreateEngine } from './'; + +describe('CreateEngine', () => { + it('renders', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="CreateEngine"]')).toHaveLength(1); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx new file mode 100644 index 00000000000000..7d67c2b8cea894 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx @@ -0,0 +1,11 @@ +/* + * 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'; + +export const CreateEngine: React.FC = () => { + return
; +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/index.ts new file mode 100644 index 00000000000000..44fee51db0ba75 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { CreateEngine } from './create_engine'; From 9d92b036e26931671ba557140801589f2203ea03 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 20 Jan 2021 14:58:58 -0500 Subject: [PATCH 02/37] Add CreateEngine to index router --- .../components/engine/engine_router.test.tsx | 17 +++++++++++++++++ .../public/applications/app_search/index.tsx | 12 +++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx index aa8b406cf7774e..a78bef87d47088 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx @@ -16,6 +16,7 @@ import { Switch, Redirect, useParams } from 'react-router-dom'; import { Loading } from '../../../shared/loading'; import { EngineOverview } from '../engine_overview'; import { AnalyticsRouter } from '../analytics'; +import { CreateEngine } from '../create_engine'; import { EngineRouter } from './engine_router'; @@ -93,4 +94,20 @@ describe('EngineRouter', () => { expect(wrapper.find(AnalyticsRouter)).toHaveLength(1); }); + + describe('CreateEngine', () => { + it('renders when user canManageEngines is true', () => { + setMockValues({ ...values, myRole: { canManageEngines: true } }); + const wrapper = shallow(); + + expect(wrapper.find(CreateEngine)).toHaveLength(1); + }); + + it('does not render when user canManageEngines is false', () => { + setMockValues({ ...values, myRole: { canManageEngines: false } }); + const wrapper = shallow(); + + expect(wrapper.find(CreateEngine)).toHaveLength(0); + }); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index 769230ccffd22c..188254df9651db 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -19,6 +19,7 @@ import { Layout, SideNav, SideNavLink } from '../shared/layout'; import { EngineNav, EngineRouter } from './components/engine'; import { + CREATE_ENGINES_PATH, ROOT_PATH, SETUP_GUIDE_PATH, SETTINGS_PATH, @@ -29,6 +30,7 @@ import { LIBRARY_PATH, } from './routes'; +import { CreateEngine } from './components/create_engine'; import { SetupGuide } from './components/setup_guide'; import { ErrorConnecting } from './components/error_connecting'; import { NotFound } from '../shared/not_found'; @@ -56,7 +58,10 @@ export const AppSearchUnconfigured: React.FC = () => ( export const AppSearchConfigured: React.FC = (props) => { const { initializeAppData } = useActions(AppLogic); - const { hasInitialized } = useValues(AppLogic); + const { + hasInitialized, + myRole: { canManageEngines }, + } = useValues(AppLogic); const { errorConnecting, readOnlyMode } = useValues(HttpLogic); useEffect(() => { @@ -73,6 +78,11 @@ export const AppSearchConfigured: React.FC = (props) => { )} + {canManageEngines && ( + + + + )} } />} readOnlyMode={readOnlyMode}> From cad64945b99e694bc427bd67678ded5a9595c5fc Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 20 Jan 2021 15:08:13 -0500 Subject: [PATCH 03/37] Add Layout-level components for CreateEngine --- .../components/create_engine/constants.ts | 13 ++++++++++++ .../create_engine/create_engine.tsx | 20 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts new file mode 100644 index 00000000000000..32696ec6150973 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts @@ -0,0 +1,13 @@ +/* + * 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 { i18n } from '@kbn/i18n'; + +export const CREATE_ENGINE_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.createEngine.title', + { + defaultMessage: 'Create an Engine', + } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx index 7d67c2b8cea894..2152b6ed9b485b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx @@ -6,6 +6,24 @@ import React from 'react'; +import { EuiPageHeader, EuiPageHeaderSection, EuiTitle } from '@elastic/eui'; + +import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; +import { FlashMessages } from '../../../shared/flash_messages'; +import { CREATE_ENGINE_TITLE } from './constants'; + export const CreateEngine: React.FC = () => { - return
; + return ( +
+ + + + +

{CREATE_ENGINE_TITLE}

+
+
+
+ +
+ ); }; From 4cc79b28cf38aba63f0c65aecc06b835c163ef65 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Tue, 26 Jan 2021 12:08:59 -0500 Subject: [PATCH 04/37] Static create engine view --- .../components/create_engine/constants.ts | 54 ++++++++++++ .../create_engine/create_engine.test.tsx | 20 +++++ .../create_engine/create_engine.tsx | 83 ++++++++++++++++++- 3 files changed, 154 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts index 32696ec6150973..8ce9462850232c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts @@ -11,3 +11,57 @@ export const CREATE_ENGINE_TITLE = i18n.translate( defaultMessage: 'Create an Engine', } ); + +export const CREATE_ENGINE_FORM_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.createEngine.form.title', + { + defaultMessage: 'Name your Engine', + } +); + +export const CREATE_ENGINE_FORM_ENGINE_NAME_LABEL = i18n.translate( + 'xpack.enterpriseSearch.appSearch.createEngine.form.engineName.label', + { + defaultMessage: 'Engine Name', + } +); + +export const ALLOWED_CHARS_NOTE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.createEngine.form.engineName.allowedCharactersNote', + { + defaultMessage: 'Engine names can only contain lowercase letters, numbers, and hyphens', + } +); + +export const getSanitizedNameNote = (name: string): string => { + return i18n.translate( + 'xpack.enterpriseSearch.appSearch.createEngine.form.engineName.sanitizedNameNote', + { + defaultMessage: 'Your engine will be named {name}', + values: { + name, + }, + } + ); +}; + +export const CREATE_ENGINE_FORM_ENGINE_NAME_PLACEHOLDER = i18n.translate( + 'xpack.enterpriseSearch.appSearch.createEngine.form.engineName.placeholder', + { + defaultMessage: 'i.e., my-search-engine', + } +); + +export const CREATE_ENGINE_FORM_ENGINE_LANGUAGE_LABEL = i18n.translate( + 'xpack.enterpriseSearch.appSearch.createEngine.form.engineLanguage.label', + { + defaultMessage: 'Engine Language', + } +); + +export const CREATE_ENGINE_FORM_SUBMIT_BUTTON_LABEL = i18n.translate( + 'xpack.enterpriseSearch.appSearch.createEngine.form.submitButton.label', + { + defaultMessage: 'Create Engine', + } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx index 2d0fdadfe73f21..0c0ae36e9fbb13 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx @@ -14,4 +14,24 @@ describe('CreateEngine', () => { const wrapper = shallow(); expect(wrapper.find('[data-test-subj="CreateEngine"]')).toHaveLength(1); }); + + it('contains a form', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="CreateEngineForm"]')).toHaveLength(1); + }); + + it('contains a name input', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="CreateEngineNameInput"]')).toHaveLength(1); + }); + + it('contains a language input', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="CreateEngineLanguageInput"]')).toHaveLength(1); + }); + + it('contains a submit button', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]')).toHaveLength(1); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx index 2152b6ed9b485b..6c4066a11d45db 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx @@ -6,13 +6,42 @@ import React from 'react'; -import { EuiPageHeader, EuiPageHeaderSection, EuiTitle } from '@elastic/eui'; - +import { + EuiForm, + EuiFlexGroup, + EuiFormRow, + EuiFlexItem, + EuiFieldText, + EuiSelect, + EuiPageHeader, + EuiPageHeaderSection, + EuiSpacer, + EuiText, + EuiTitle, + EuiButton, + EuiPanel, + EuiSelectOption, +} from '@elastic/eui'; import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { FlashMessages } from '../../../shared/flash_messages'; -import { CREATE_ENGINE_TITLE } from './constants'; +import { + ALLOWED_CHARS_NOTE, + CREATE_ENGINE_FORM_ENGINE_LANGUAGE_LABEL, + CREATE_ENGINE_FORM_ENGINE_NAME_LABEL, + CREATE_ENGINE_FORM_ENGINE_NAME_PLACEHOLDER, + CREATE_ENGINE_FORM_SUBMIT_BUTTON_LABEL, + CREATE_ENGINE_FORM_TITLE, + CREATE_ENGINE_TITLE, + getSanitizedNameNote, +} from './constants'; export const CreateEngine: React.FC = () => { + // TODO manage these in a logic file + const rawName = ''; + const name = ''; + const language = ''; + const supportedLanguages: EuiSelectOption[] = []; + return (
@@ -24,6 +53,54 @@ export const CreateEngine: React.FC = () => { + + +
+ + {CREATE_ENGINE_FORM_TITLE} + + + + + + setRawName(event.currentTarget.value)} + autoComplete="off" + fullWidth={true} + data-test-subj="CreateEngineNameInput" + placeholder={CREATE_ENGINE_FORM_ENGINE_NAME_PLACEHOLDER} + autoFocus={true} + /> + + + + + setLanguage(event.target.value)} + /> + + + + + + {CREATE_ENGINE_FORM_SUBMIT_BUTTON_LABEL} + + +
+
); }; From 3886740bd62105e483a5d681a2675555b86f1df6 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 27 Jan 2021 10:24:46 -0500 Subject: [PATCH 05/37] Add new POST route for engines API endpoint --- .../server/routes/app_search/engines.test.ts | 42 +++++++++++++++++++ .../server/routes/app_search/engines.ts | 17 ++++++++ 2 files changed, 59 insertions(+) diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts index 9755fff02f7386..6b3edd7f3a8faa 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts @@ -110,6 +110,48 @@ describe('engine routes', () => { }); }); + describe('POST /api/app_search/engines', () => { + let mockRouter: MockRouter; + + beforeEach(() => { + jest.clearAllMocks(); + mockRouter = new MockRouter({ + method: 'post', + path: '/api/app_search/engines', + payload: 'body', + }); + + registerEnginesRoutes({ + ...mockDependencies, + router: mockRouter.router, + }); + }); + + it('creates a request handler', () => { + mockRouter.callRoute({ body: { name: 'some-engine', language: 'en' } }); + expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ + path: '/as/engines', + }); + }); + + describe('validates', () => { + it('correctly', () => { + const request = { body: { name: 'some-engine', language: 'en' } }; + mockRouter.shouldValidate(request); + }); + + it('missing name', () => { + const request = { body: { language: 'en' } }; + mockRouter.shouldThrow(request); + }); + + it('optional language', () => { + const request = { body: { name: 'some-engine' } }; + mockRouter.shouldValidate(request); + }); + }); + }); + describe('GET /api/app_search/engines/{name}', () => { let mockRouter: MockRouter; diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts index c0bbc40ff8d2df..80d61c7b4ba5c6 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts @@ -44,6 +44,23 @@ export function registerEnginesRoutes({ } ); + router.post( + { + path: '/api/app_search/engines', + validate: { + body: schema.object({ + name: schema.string(), + language: schema.maybe(schema.string()), + }), + }, + }, + async (context, request, response) => { + return enterpriseSearchRequestHandler.createRequest({ + path: `/as/engines`, + })(context, request, response); + } + ); + // Single engine endpoints router.get( { From 7dae33b5d89335e53a4171205b4407c44ffc3f3d Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Tue, 26 Jan 2021 13:44:11 -0500 Subject: [PATCH 06/37] Logic for Create Engine view WIP tests failing --- .../components/create_engine/constants.ts | 7 + .../create_engine/create_engine.test.tsx | 54 ++++--- .../create_engine/create_engine.tsx | 25 ++- .../create_engine/create_engine_logic.test.ts | 148 ++++++++++++++++++ .../create_engine/create_engine_logic.ts | 80 ++++++++++ 5 files changed, 287 insertions(+), 27 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts index 8ce9462850232c..70005bbbe0e4b5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts @@ -65,3 +65,10 @@ export const CREATE_ENGINE_FORM_SUBMIT_BUTTON_LABEL = i18n.translate( defaultMessage: 'Create Engine', } ); + +export const CREATE_ENGINE_SUCCESS_MESSAGE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.createEngine.successMessage', + { + defaultMessage: 'Successfully created engine.', + } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx index 0c0ae36e9fbb13..0804451d0efa42 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx @@ -7,31 +7,47 @@ import React from 'react'; import { shallow } from 'enzyme'; +import '../../../__mocks__/shallow_useeffect.mock'; +import { setMockValues } from '../../../__mocks__'; + import { CreateEngine } from './'; describe('CreateEngine', () => { - it('renders', () => { - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="CreateEngine"]')).toHaveLength(1); - }); + const values = { + name: '', + rawName: '', + language: 'Universal' + } - it('contains a form', () => { - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="CreateEngineForm"]')).toHaveLength(1); - }); + describe('default values', () => { + beforeEach(() => { + setMockValues(values); + }); - it('contains a name input', () => { - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="CreateEngineNameInput"]')).toHaveLength(1); - }); + it('renders', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="CreateEngine"]')).toHaveLength(1); + }); - it('contains a language input', () => { - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="CreateEngineLanguageInput"]')).toHaveLength(1); - }); + it('contains a form', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="CreateEngineForm"]')).toHaveLength(1); + }); + + it('contains a name input', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="CreateEngineNameInput"]')).toHaveLength(1); + }); - it('contains a submit button', () => { - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]')).toHaveLength(1); + it('contains a language input', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="CreateEngineLanguageInput"]')).toHaveLength(1); + }); + + it('contains a submit button', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]')).toHaveLength(1); + }); }); + }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx index 6c4066a11d45db..9540873ac5f1e7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx @@ -22,8 +22,11 @@ import { EuiPanel, EuiSelectOption, } from '@elastic/eui'; +import { useActions, useValues } from 'kea'; + import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { FlashMessages } from '../../../shared/flash_messages'; + import { ALLOWED_CHARS_NOTE, CREATE_ENGINE_FORM_ENGINE_LANGUAGE_LABEL, @@ -34,13 +37,16 @@ import { CREATE_ENGINE_TITLE, getSanitizedNameNote, } from './constants'; +import { CreateEngineLogic } from './create_engine_logic'; export const CreateEngine: React.FC = () => { - // TODO manage these in a logic file - const rawName = ''; - const name = ''; - const language = ''; - const supportedLanguages: EuiSelectOption[] = []; + const { name, rawName, language } = useValues(CreateEngineLogic); + const { setLanguage, setRawName, submitEngine } = useActions(CreateEngineLogic); + + const supportedLanguages: EuiSelectOption[] = [ + { text: 'Universal', value: 'Universal' }, + { text: 'English', value: 'English' }, + ]; return (
@@ -57,7 +63,10 @@ export const CreateEngine: React.FC = () => {
{ + e.preventDefault(); + submitEngine(); + }} > {CREATE_ENGINE_FORM_TITLE} @@ -73,7 +82,7 @@ export const CreateEngine: React.FC = () => { setRawName(event.currentTarget.value)} + onChange={(event) => setRawName(event.currentTarget.value)} autoComplete="off" fullWidth={true} data-test-subj="CreateEngineNameInput" @@ -89,7 +98,7 @@ export const CreateEngine: React.FC = () => { value={language} options={supportedLanguages} data-test-subj="CreateEngineLanguageInput" - // onChange={(event) => setLanguage(event.target.value)} + onChange={(event) => setLanguage(event.target.value)} /> diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts new file mode 100644 index 00000000000000..928bab2ca7dbc7 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts @@ -0,0 +1,148 @@ +/* + * 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 { generatePath } from 'react-router-dom'; + +import { CREATE_ENGINE_SUCCESS_MESSAGE } from './constants'; +import { + LogicMounter, + mockHttpValues, + mockKibanaValues, + mockFlashMessageHelpers, +} from '../../../__mocks__'; +import { ENGINE_PATH } from '../../routes'; +import { formatApiName } from '../../utils/format_api_name'; +import { CreateEngineLogic, DEFAULT_LANGUAGE } from './create_engine_logic'; + +describe('CreateEngineLogic', () => { + const { mount } = new LogicMounter(CreateEngineLogic); + const { http } = mockHttpValues; + const { navigateToUrl } = mockKibanaValues; + const { setSuccessMessage, flashAPIErrors } = mockFlashMessageHelpers; + + const DEFAULT_VALUES = { + name: '', + rawName: '', + language: DEFAULT_LANGUAGE, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('has expected default values', () => { + mount(); + expect(CreateEngineLogic.values).toEqual(DEFAULT_VALUES); + }); + + describe('actions', () => { + describe('onCreateEngineSuccess', () => { + beforeAll(() => { + mount(); + // setup local state + CreateEngineLogic.actions.setLanguage('English'); + CreateEngineLogic.actions.setRawName('test'); + // call action + CreateEngineLogic.actions.onCreateEngineSuccess(); + }); + + it('should set a success message', () => { + expect(setSuccessMessage).toHaveBeenCalledWith(CREATE_ENGINE_SUCCESS_MESSAGE); + }); + + it('should navigate the user to the engine page', () => { + const enginePath = generatePath(ENGINE_PATH, { engineName: CreateEngineLogic.values.name }); + expect(navigateToUrl).toHaveBeenCalledWith(enginePath); + }); + }); + + describe('setLanguage', () => { + const newLanguage = 'English'; + + beforeAll(() => { + mount(); + CreateEngineLogic.actions.setLanguage(newLanguage); + }); + + describe('language', () => { + it('should be set to provided value', () => { + expect(CreateEngineLogic.values.language).toEqual(newLanguage); + }); + }); + }); + + describe('setRawName', () => { + const newName = 'Name__With#$&*%Special--Characters'; + const sanitizedNewName = formatApiName(newName); + + beforeAll(() => { + mount(); + CreateEngineLogic.actions.setRawName(newName); + }); + + describe('rawName', () => { + it('should be set to provided value', () => { + expect(CreateEngineLogic.values.rawName).toEqual(newName); + }); + }); + + describe('name', () => { + it('should be set to a sanitized value', () => { + expect(CreateEngineLogic.values.name).toEqual(sanitizedNewName); + }); + }); + }); + describe('submitEngine', () => { + beforeAll(() => { + mount(); + // setup local state + CreateEngineLogic.actions.setLanguage('English'); + CreateEngineLogic.actions.setRawName('test'); + // jest spying + jest.spyOn(CreateEngineLogic.actions, 'onCreateEngineSuccess'); + }); + + it('POSTS to /api/app_search/engines', () => { + const body = JSON.stringify({ + name: CreateEngineLogic.values.name, + language: CreateEngineLogic.values.language, + }); + expect(http.post).toHaveBeenCalledWith('/api/app_search/engines', { body }); + }); + + describe('valid submission', () => { + beforeEach(async () => { + const promise = (http.post as jest.Mock).mockReturnValueOnce({}); + await CreateEngineLogic.actions.submitEngine(); + await promise; + }); + + it('calls onCreateEngineSuccess', async () => { + expect(CreateEngineLogic.actions.onCreateEngineSuccess).toHaveBeenCalledTimes(1); + }); + }); + + describe('API Error', () => { + beforeEach(async () => { + const promise = (http.post as jest.Mock).mockReturnValueOnce( + Promise.reject({ + body: { + statusCode: 400, + error: 'Bad Request', + message: 'Invalid request payload JSON format', + }, + }) + ); + await CreateEngineLogic.actions.submitEngine(); + await promise; + }); + + it('calls flashAPIErrors', () => { + expect(flashAPIErrors).toHaveBeenCalledTimes(1); + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts new file mode 100644 index 00000000000000..bf4076e38e3737 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts @@ -0,0 +1,80 @@ +/* + * 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 { kea, MakeLogicType } from 'kea'; +import { generatePath } from 'react-router-dom'; + +import { CREATE_ENGINE_SUCCESS_MESSAGE } from './constants'; +import { ENGINE_PATH } from '../../routes'; +import { formatApiName } from '../../utils/format_api_name'; +import { flashAPIErrors, setSuccessMessage } from '../../../shared/flash_messages'; +import { HttpLogic } from '../../../shared/http'; +import { KibanaLogic } from '../../../shared/kibana'; + +export const DEFAULT_LANGUAGE = 'Universal'; + +export interface CreateEngineActions { + onCreateEngineSuccess(): void; + setLanguage(language: string): { language: string }; + setRawName(rawName: string): { rawName: string }; + submitEngine(): void; +} + +export interface CreateEngineValues { + language: string; + name: string; + rawName: string; +} + +export const CreateEngineLogic = kea>({ + path: ['enterprise_search', 'app_search', 'create_engine_logic'], + actions: { + onCreateEngineSuccess: true, + setLanguage: (language) => ({ language }), + setRawName: (rawName) => ({ rawName }), + submitEngine: true, + }, + reducers: { + language: [ + DEFAULT_LANGUAGE, + { + setLanguage: (_, { language }) => language, + }, + ], + rawName: [ + '', + { + setRawName: (_, { rawName }) => rawName, + }, + ], + }, + selectors: ({ selectors }) => ({ + name: [() => [selectors.rawName], (rawName) => formatApiName(rawName)], + }), + listeners: ({ values, actions }) => ({ + submitEngine: async () => { + const { http } = HttpLogic.values; + const { name, language } = values; + + const body = JSON.stringify({ name, language }); + + try { + await http.post('/api/app_search/engines', { body }); + actions.onCreateEngineSuccess(); + } catch (e) { + flashAPIErrors(e); + } + }, + onCreateEngineSuccess: () => { + const { name } = values; + const { navigateToUrl } = KibanaLogic.values; + const enginePath = generatePath(ENGINE_PATH, { engineName: name }); + + setSuccessMessage(CREATE_ENGINE_SUCCESS_MESSAGE); + navigateToUrl(enginePath); + }, + }), +}); From 714fca7547493a165658012f26b35f174f6a11dd Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 27 Jan 2021 11:49:17 -0500 Subject: [PATCH 07/37] Fix enterpriseSearchRequestHandler path --- .../server/routes/app_search/engines.test.ts | 2 +- .../enterprise_search/server/routes/app_search/engines.ts | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts index 6b3edd7f3a8faa..6eccbad67638b8 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts @@ -130,7 +130,7 @@ describe('engine routes', () => { it('creates a request handler', () => { mockRouter.callRoute({ body: { name: 'some-engine', language: 'en' } }); expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ - path: '/as/engines', + path: '/as/engines/collection', }); }); diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts index 80d61c7b4ba5c6..30af2f130eaa06 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts @@ -54,11 +54,9 @@ export function registerEnginesRoutes({ }), }, }, - async (context, request, response) => { - return enterpriseSearchRequestHandler.createRequest({ - path: `/as/engines`, - })(context, request, response); - } + enterpriseSearchRequestHandler.createRequest({ + path: `/as/engines/collection`, + }) ); // Single engine endpoints From efc7de3ec7556645468f8a3e045ef4c262605643 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 27 Jan 2021 11:50:06 -0500 Subject: [PATCH 08/37] Use setQueuedSuccessMessage after engine has been created --- .../components/create_engine/create_engine_logic.test.ts | 4 ++-- .../components/create_engine/create_engine_logic.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts index 928bab2ca7dbc7..3a1f0983eff280 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts @@ -20,7 +20,7 @@ describe('CreateEngineLogic', () => { const { mount } = new LogicMounter(CreateEngineLogic); const { http } = mockHttpValues; const { navigateToUrl } = mockKibanaValues; - const { setSuccessMessage, flashAPIErrors } = mockFlashMessageHelpers; + const { setQueuedSuccessMessage, flashAPIErrors } = mockFlashMessageHelpers; const DEFAULT_VALUES = { name: '', @@ -49,7 +49,7 @@ describe('CreateEngineLogic', () => { }); it('should set a success message', () => { - expect(setSuccessMessage).toHaveBeenCalledWith(CREATE_ENGINE_SUCCESS_MESSAGE); + expect(setQueuedSuccessMessage).toHaveBeenCalledWith(CREATE_ENGINE_SUCCESS_MESSAGE); }); it('should navigate the user to the engine page', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts index bf4076e38e3737..acdc0f2f8476c8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts @@ -10,7 +10,7 @@ import { generatePath } from 'react-router-dom'; import { CREATE_ENGINE_SUCCESS_MESSAGE } from './constants'; import { ENGINE_PATH } from '../../routes'; import { formatApiName } from '../../utils/format_api_name'; -import { flashAPIErrors, setSuccessMessage } from '../../../shared/flash_messages'; +import { flashAPIErrors, setQueuedSuccessMessage } from '../../../shared/flash_messages'; import { HttpLogic } from '../../../shared/http'; import { KibanaLogic } from '../../../shared/kibana'; @@ -73,7 +73,7 @@ export const CreateEngineLogic = kea Date: Wed, 27 Jan 2021 11:50:51 -0500 Subject: [PATCH 09/37] Use exact path for CREATE_ENGINES_PATH (but EngineRouter logic is still firing??) --- .../enterprise_search/public/applications/app_search/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index 188254df9651db..9f488125aa5135 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -79,7 +79,7 @@ export const AppSearchConfigured: React.FC = (props) => { )} {canManageEngines && ( - + )} From 6f7f5121e45fe72062a606fec27f35699395e736 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 27 Jan 2021 11:51:02 -0500 Subject: [PATCH 10/37] Add TODO note --- .../app_search/components/create_engine/create_engine.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx index 9540873ac5f1e7..54dd8c108b5cd2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx @@ -43,6 +43,7 @@ export const CreateEngine: React.FC = () => { const { name, rawName, language } = useValues(CreateEngineLogic); const { setLanguage, setRawName, submitEngine } = useActions(CreateEngineLogic); + // TODO these need to come from AppLogic and/or the Enterprise Search server const supportedLanguages: EuiSelectOption[] = [ { text: 'Universal', value: 'Universal' }, { text: 'English', value: 'English' }, From 35b107fd24a179c782f1c1f2d673a19f4cf498bd Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 27 Jan 2021 12:15:09 -0500 Subject: [PATCH 11/37] Put CreateEngine inside the common App Search Layout --- .../public/applications/app_search/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index 9f488125aa5135..2e9cf552f2fce3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -80,7 +80,9 @@ export const AppSearchConfigured: React.FC = (props) => { )} {canManageEngines && ( - + } readOnlyMode={readOnlyMode}> + + )} From 120c74954fd71c159e4b49248ee6acf0c13a5f3d Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 27 Jan 2021 14:44:49 -0500 Subject: [PATCH 12/37] Fix CreateEngineLogic jest tests --- .../create_engine/create_engine.test.tsx | 5 +- .../create_engine/create_engine_logic.test.ts | 55 +++++++------------ 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx index 0804451d0efa42..e3146586bfd213 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx @@ -16,8 +16,8 @@ describe('CreateEngine', () => { const values = { name: '', rawName: '', - language: 'Universal' - } + language: 'Universal', + }; describe('default values', () => { beforeEach(() => { @@ -49,5 +49,4 @@ describe('CreateEngine', () => { expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]')).toHaveLength(1); }); }); - }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts index 3a1f0983eff280..e135b7912e3dbf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts @@ -28,10 +28,6 @@ describe('CreateEngineLogic', () => { language: DEFAULT_LANGUAGE, }; - beforeEach(() => { - jest.clearAllMocks(); - }); - it('has expected default values', () => { mount(); expect(CreateEngineLogic.values).toEqual(DEFAULT_VALUES); @@ -94,14 +90,13 @@ describe('CreateEngineLogic', () => { }); }); }); + describe('submitEngine', () => { beforeAll(() => { mount(); // setup local state CreateEngineLogic.actions.setLanguage('English'); CreateEngineLogic.actions.setRawName('test'); - // jest spying - jest.spyOn(CreateEngineLogic.actions, 'onCreateEngineSuccess'); }); it('POSTS to /api/app_search/engines', () => { @@ -109,39 +104,31 @@ describe('CreateEngineLogic', () => { name: CreateEngineLogic.values.name, language: CreateEngineLogic.values.language, }); + CreateEngineLogic.actions.submitEngine(); expect(http.post).toHaveBeenCalledWith('/api/app_search/engines', { body }); }); - describe('valid submission', () => { - beforeEach(async () => { - const promise = (http.post as jest.Mock).mockReturnValueOnce({}); - await CreateEngineLogic.actions.submitEngine(); - await promise; - }); - - it('calls onCreateEngineSuccess', async () => { - expect(CreateEngineLogic.actions.onCreateEngineSuccess).toHaveBeenCalledTimes(1); - }); + it('calls onCreateEngineSuccess on valid submission', async () => { + jest.spyOn(CreateEngineLogic.actions, 'onCreateEngineSuccess'); // .mockImplementation(); + const promise = (http.post as jest.Mock).mockReturnValueOnce({}); + await CreateEngineLogic.actions.submitEngine(); + await promise; + expect(CreateEngineLogic.actions.onCreateEngineSuccess).toHaveBeenCalledTimes(1); }); - describe('API Error', () => { - beforeEach(async () => { - const promise = (http.post as jest.Mock).mockReturnValueOnce( - Promise.reject({ - body: { - statusCode: 400, - error: 'Bad Request', - message: 'Invalid request payload JSON format', - }, - }) - ); - await CreateEngineLogic.actions.submitEngine(); - await promise; - }); - - it('calls flashAPIErrors', () => { - expect(flashAPIErrors).toHaveBeenCalledTimes(1); - }); + it('calls flashAPIErrors on API Error', async () => { + const promise = (http.post as jest.Mock).mockReturnValueOnce( + Promise.reject({ + body: { + statusCode: 400, + error: 'Bad Request', + message: 'Invalid request payload JSON format', + }, + }) + ); + await CreateEngineLogic.actions.submitEngine(); + await promise; + expect(flashAPIErrors).toHaveBeenCalledTimes(1); }); }); }); From be7a3df38dea6b675cb098e240eff22a68bcaed8 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 27 Jan 2021 14:55:33 -0500 Subject: [PATCH 13/37] Move create engine view to /create_engine from /engines/new --- .../enterprise_search/public/applications/app_search/routes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts index 7f12f7d29671a7..f72b179a27c7e9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts @@ -16,7 +16,7 @@ export const CREDENTIALS_PATH = '/credentials'; export const ROLE_MAPPINGS_PATH = '#/role-mappings'; // This page seems to 404 if the # isn't included export const ENGINES_PATH = '/engines'; -export const CREATE_ENGINES_PATH = `${ENGINES_PATH}/new`; +export const CREATE_ENGINES_PATH = `/create_engine`; export const ENGINE_PATH = `${ENGINES_PATH}/:engineName`; export const SAMPLE_ENGINE_PATH = `${ENGINES_PATH}/national-parks-demo`; From 8737c69be047c9a5dbea6e6d9b35da52817c69b4 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 27 Jan 2021 15:24:31 -0500 Subject: [PATCH 14/37] Add Create an Engine button to Engines Overview --- .../components/engines/constants.ts | 7 +++++ .../engines/engines_overview.test.tsx | 1 + .../components/engines/engines_overview.tsx | 28 +++++++++++++++---- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.ts index 12545c59b40a02..fe86e3f981a01b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.ts @@ -14,3 +14,10 @@ export const META_ENGINES_TITLE = i18n.translate( 'xpack.enterpriseSearch.appSearch.metaEngines.title', { defaultMessage: 'Meta Engines' } ); + +export const CREATE_AN_ENGINE_BUTTON_LABEL = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engines.createAnEngineButton.label', + { + defaultMessage: 'Create an Engine', + } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx index e2d366e5e5817a..ffabe5f435d1bd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx @@ -72,6 +72,7 @@ describe('EnginesOverview', () => { const wrapper = shallow(); expect(wrapper.find(EnginesTable)).toHaveLength(1); + expect(wrapper.find('[data-test-subj="appSearchEnginesCreateEngineButton"]')).toHaveLength(1); expect(actions.loadEngines).toHaveBeenCalled(); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx index 8a24ee746ed140..c6a3f2c75da5e4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx @@ -7,8 +7,10 @@ import React, { useEffect } from 'react'; import { useValues, useActions } from 'kea'; import { + EuiButton, EuiPageContent, EuiPageContentHeader, + EuiPageContentHeaderSection, EuiPageContentBody, EuiTitle, EuiSpacer, @@ -18,10 +20,12 @@ import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chro import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; import { FlashMessages } from '../../../shared/flash_messages'; import { LicensingLogic } from '../../../shared/licensing'; +import { CREATE_ENGINES_PATH } from '../../routes'; +import { KibanaLogic } from '../../../shared/kibana'; import { EngineIcon } from './assets/engine_icon'; import { MetaEngineIcon } from './assets/meta_engine_icon'; -import { ENGINES_TITLE, META_ENGINES_TITLE } from './constants'; +import { CREATE_AN_ENGINE_BUTTON_LABEL, ENGINES_TITLE, META_ENGINES_TITLE } from './constants'; import { EnginesOverviewHeader, LoadingState, EmptyState } from './components'; import { EnginesTable } from './engines_table'; import { EnginesLogic } from './engines_logic'; @@ -63,11 +67,23 @@ export const EnginesOverview: React.FC = () => { - -

- {ENGINES_TITLE} -

-
+ + +

+ {ENGINES_TITLE} +

+
+
+ + KibanaLogic.values.navigateToUrl(CREATE_ENGINES_PATH)} + > + {CREATE_AN_ENGINE_BUTTON_LABEL} + +
Date: Fri, 29 Jan 2021 19:24:09 -0500 Subject: [PATCH 15/37] Missing FlashMessages on EngineOverview --- .../engine_overview/engine_overview_empty.test.tsx | 6 +++++- .../components/engine_overview/engine_overview_empty.tsx | 2 ++ .../engine_overview/engine_overview_metrics.test.tsx | 6 ++++++ .../components/engine_overview/engine_overview_metrics.tsx | 3 ++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx index 1b6acf341c08eb..4705b62e676b45 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx @@ -9,7 +9,7 @@ import { shallow, ShallowWrapper } from 'enzyme'; import { EuiButton } from '@elastic/eui'; import { docLinks } from '../../../shared/doc_links'; - +import { FlashMessages } from '../../../shared/flash_messages'; import { DocumentCreationButtons, DocumentCreationFlyout } from '../document_creation'; import { EmptyEngineOverview } from './engine_overview_empty'; @@ -26,6 +26,10 @@ describe('EmptyEngineOverview', () => { it('renders a documentation link', () => { expect(wrapper.find(EuiButton).prop('href')).toEqual(`${docLinks.appSearchBase}/index.html`); + + it('contains FlashMessages', () => { + expect(wrapper.find(FlashMessages)).toHaveLength(1); + }); }); it('renders document creation components', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx index 83dd396e5e0801..16a35ead9cbf3a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx @@ -15,6 +15,7 @@ import { EuiButton, } from '@elastic/eui'; +import { FlashMessages } from '../../../shared/flash_messages'; import { DOCS_PREFIX } from '../../routes'; import { DocumentCreationButtons, DocumentCreationFlyout } from '../document_creation'; @@ -40,6 +41,7 @@ export const EmptyEngineOverview: React.FC = () => { + diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx index 8250446e231b35..e8590c51f9886a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx @@ -9,6 +9,7 @@ import { setMockValues } from '../../../__mocks__/kea.mock'; import React from 'react'; import { shallow } from 'enzyme'; +import { FlashMessages } from '../../../shared/flash_messages'; import { UnavailablePrompt, TotalStats, TotalCharts, RecentApiLogs } from './components'; import { EngineOverviewMetrics } from './engine_overview_metrics'; @@ -18,6 +19,11 @@ describe('EngineOverviewMetrics', () => { expect(wrapper.find('h1').text()).toEqual('Engine overview'); }); + it('contains FlashMessages', () => { + const wrapper = shallow(); + expect(wrapper.find(FlashMessages)).toHaveLength(1); + }); + it('renders an unavailable prompt if engine data is still indexing', () => { setMockValues({ apiLogsUnavailable: true }); const wrapper = shallow(); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.tsx index 9630f6fa2f81dc..99a044ee24f262 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { EuiPageHeader, EuiTitle, EuiSpacer } from '@elastic/eui'; import { EngineOverviewLogic } from './'; - +import { FlashMessages } from '../../../shared/flash_messages'; import { UnavailablePrompt, TotalStats, TotalCharts, RecentApiLogs } from './components'; export const EngineOverviewMetrics: React.FC = () => { @@ -28,6 +28,7 @@ export const EngineOverviewMetrics: React.FC = () => {
+ {apiLogsUnavailable ? ( ) : ( From e9382fcfb77ccc9e09981608512a07c0f4846c6e Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Fri, 29 Jan 2021 19:42:51 -0500 Subject: [PATCH 16/37] Fix test for CreateEngine route --- .../components/engine/engine_router.test.tsx | 17 ----------------- .../applications/app_search/index.test.tsx | 18 ++++++++++++++++-- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx index a78bef87d47088..aa8b406cf7774e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx @@ -16,7 +16,6 @@ import { Switch, Redirect, useParams } from 'react-router-dom'; import { Loading } from '../../../shared/loading'; import { EngineOverview } from '../engine_overview'; import { AnalyticsRouter } from '../analytics'; -import { CreateEngine } from '../create_engine'; import { EngineRouter } from './engine_router'; @@ -94,20 +93,4 @@ describe('EngineRouter', () => { expect(wrapper.find(AnalyticsRouter)).toHaveLength(1); }); - - describe('CreateEngine', () => { - it('renders when user canManageEngines is true', () => { - setMockValues({ ...values, myRole: { canManageEngines: true } }); - const wrapper = shallow(); - - expect(wrapper.find(CreateEngine)).toHaveLength(1); - }); - - it('does not render when user canManageEngines is false', () => { - setMockValues({ ...values, myRole: { canManageEngines: false } }); - const wrapper = shallow(); - - expect(wrapper.find(CreateEngine)).toHaveLength(0); - }); - }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index 31007c90ef7ccd..f16118b109eb54 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -13,6 +13,7 @@ import { Redirect } from 'react-router-dom'; import { shallow } from 'enzyme'; import { Layout, SideNav, SideNavLink } from '../shared/layout'; +import { CreateEngine } from './components/create_engine'; import { SetupGuide } from './components/setup_guide'; import { ErrorConnecting } from './components/error_connecting'; import { EnginesOverview } from './components/engines'; @@ -96,8 +97,21 @@ describe('AppSearchConfigured', () => { }); describe('ability checks', () => { - // TODO: Use this section for routes wrapped in canViewX conditionals - // e.g., it('renders settings if a user can view settings') + describe('canManageEngines', () => { + it('renders CreateEngine when user canManageEngines is true', () => { + setMockValues({ myRole: { canManageEngines: true } }); + const wrapper = shallow(); + + expect(wrapper.find(CreateEngine)).toHaveLength(1); + }); + + it('does not render CreateEngine when user canManageEngines is false', () => { + setMockValues({ myRole: { canManageEngines: false } }); + const wrapper = shallow(); + + expect(wrapper.find(CreateEngine)).toHaveLength(0); + }); + }); }); }); From 66dc0b6df9fb919bc1233ccf4cdf5e7a6ba92499 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Fri, 29 Jan 2021 20:04:16 -0500 Subject: [PATCH 17/37] Fix strong'd text in santized name note --- .../components/create_engine/constants.ts | 17 ++++++----------- .../components/create_engine/create_engine.tsx | 12 ++++++++++-- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts index 70005bbbe0e4b5..e8b56c0d81776b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts @@ -33,17 +33,12 @@ export const ALLOWED_CHARS_NOTE = i18n.translate( } ); -export const getSanitizedNameNote = (name: string): string => { - return i18n.translate( - 'xpack.enterpriseSearch.appSearch.createEngine.form.engineName.sanitizedNameNote', - { - defaultMessage: 'Your engine will be named {name}', - values: { - name, - }, - } - ); -}; +export const SANITIZED_NAME_NOTE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.createEngine.form.engineName.sanitizedNameNote', + { + defaultMessage: 'Your engine will be named', + } +); export const CREATE_ENGINE_FORM_ENGINE_NAME_PLACEHOLDER = i18n.translate( 'xpack.enterpriseSearch.appSearch.createEngine.form.engineName.placeholder', diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx index 54dd8c108b5cd2..576b3d78f02815 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx @@ -35,7 +35,7 @@ import { CREATE_ENGINE_FORM_SUBMIT_BUTTON_LABEL, CREATE_ENGINE_FORM_TITLE, CREATE_ENGINE_TITLE, - getSanitizedNameNote, + SANITIZED_NAME_NOTE, } from './constants'; import { CreateEngineLogic } from './create_engine_logic'; @@ -77,7 +77,15 @@ export const CreateEngine: React.FC = () => { 0 && rawName !== name ? ( + <> + {SANITIZED_NAME_NOTE} {name} + + ) : ( + ALLOWED_CHARS_NOTE + ) + } fullWidth={true} > Date: Fri, 29 Jan 2021 20:22:29 -0500 Subject: [PATCH 18/37] Use local constant for Supported Languages --- .../components/create_engine/constants.ts | 67 +++++++++++++++++++ .../create_engine/create_engine.tsx | 11 +-- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts index e8b56c0d81776b..5ac778c83bd0da 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts @@ -67,3 +67,70 @@ export const CREATE_ENGINE_SUCCESS_MESSAGE = i18n.translate( defaultMessage: 'Successfully created engine.', } ); + +export const SUPPORTED_LANGUAGES = [ + { + value: 'Universal', + text: 'Universal', + }, + { + text: '—', + disabled: true, + }, + { + value: 'zh', + text: 'Chinese', + }, + { + value: 'da', + text: 'Danish', + }, + { + value: 'nl', + text: 'Dutch', + }, + { + value: 'en', + text: 'English', + }, + { + value: 'fr', + text: 'French', + }, + { + value: 'de', + text: 'German', + }, + { + value: 'it', + text: 'Italian', + }, + { + value: 'ja', + text: 'Japanese', + }, + { + value: 'ko', + text: 'Korean', + }, + { + value: 'pt', + text: 'Portuguese', + }, + { + value: 'pt-br', + text: 'Portuguese (Brazil)', + }, + { + value: 'ru', + text: 'Russian', + }, + { + value: 'es', + text: 'Spanish', + }, + { + value: 'th', + text: 'Thai', + }, +]; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx index 576b3d78f02815..722702fdc768a2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx @@ -20,13 +20,11 @@ import { EuiTitle, EuiButton, EuiPanel, - EuiSelectOption, } from '@elastic/eui'; import { useActions, useValues } from 'kea'; import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { FlashMessages } from '../../../shared/flash_messages'; - import { ALLOWED_CHARS_NOTE, CREATE_ENGINE_FORM_ENGINE_LANGUAGE_LABEL, @@ -36,6 +34,7 @@ import { CREATE_ENGINE_FORM_TITLE, CREATE_ENGINE_TITLE, SANITIZED_NAME_NOTE, + SUPPORTED_LANGUAGES, } from './constants'; import { CreateEngineLogic } from './create_engine_logic'; @@ -43,12 +42,6 @@ export const CreateEngine: React.FC = () => { const { name, rawName, language } = useValues(CreateEngineLogic); const { setLanguage, setRawName, submitEngine } = useActions(CreateEngineLogic); - // TODO these need to come from AppLogic and/or the Enterprise Search server - const supportedLanguages: EuiSelectOption[] = [ - { text: 'Universal', value: 'Universal' }, - { text: 'English', value: 'English' }, - ]; - return (
@@ -105,7 +98,7 @@ export const CreateEngine: React.FC = () => { setLanguage(event.target.value)} /> From 2ac0a29f07b0cd741b31b0dcaac4bf31a7f0d665 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Fri, 29 Jan 2021 20:41:06 -0500 Subject: [PATCH 19/37] Disable submit button when name is empty --- .../create_engine/create_engine.test.tsx | 33 ++++++++++++++++--- .../create_engine/create_engine.tsx | 8 ++++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx index e3146586bfd213..871601b99d688d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx @@ -13,7 +13,7 @@ import { setMockValues } from '../../../__mocks__'; import { CreateEngine } from './'; describe('CreateEngine', () => { - const values = { + const DEFAULT_VALUES = { name: '', rawName: '', language: 'Universal', @@ -21,32 +21,55 @@ describe('CreateEngine', () => { describe('default values', () => { beforeEach(() => { - setMockValues(values); + jest.clearAllMocks(); }); it('renders', () => { + setMockValues(DEFAULT_VALUES); const wrapper = shallow(); expect(wrapper.find('[data-test-subj="CreateEngine"]')).toHaveLength(1); }); it('contains a form', () => { + setMockValues(DEFAULT_VALUES); const wrapper = shallow(); expect(wrapper.find('[data-test-subj="CreateEngineForm"]')).toHaveLength(1); }); it('contains a name input', () => { + setMockValues(DEFAULT_VALUES); const wrapper = shallow(); expect(wrapper.find('[data-test-subj="CreateEngineNameInput"]')).toHaveLength(1); }); it('contains a language input', () => { + setMockValues(DEFAULT_VALUES); const wrapper = shallow(); expect(wrapper.find('[data-test-subj="CreateEngineLanguageInput"]')).toHaveLength(1); }); - it('contains a submit button', () => { - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]')).toHaveLength(1); + describe('NewEngineSubmitButton', () => { + it('renders', () => { + setMockValues(DEFAULT_VALUES); + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]')).toHaveLength(1); + }); + + it('is disabled when name is empty', () => { + setMockValues(DEFAULT_VALUES); + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]').prop('disabled')).toEqual( + true + ); + }); + + it('is enabled when name has a value', () => { + setMockValues({ ...DEFAULT_VALUES, name: 'test', rawName: 'test' }); + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]').prop('disabled')).toEqual( + false + ); + }); }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx index 722702fdc768a2..a5addc9687ccb7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx @@ -106,7 +106,13 @@ export const CreateEngine: React.FC = () => { - + {CREATE_ENGINE_FORM_SUBMIT_BUTTON_LABEL} From 60bb55f9a751de92f0d42dd180eebc3e5585076f Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Fri, 29 Jan 2021 21:22:07 -0500 Subject: [PATCH 20/37] Bad conflict fix --- .../engine_overview/engine_overview_empty.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx index 4705b62e676b45..9a7e2ee83e8ee8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx @@ -26,10 +26,10 @@ describe('EmptyEngineOverview', () => { it('renders a documentation link', () => { expect(wrapper.find(EuiButton).prop('href')).toEqual(`${docLinks.appSearchBase}/index.html`); + }); - it('contains FlashMessages', () => { - expect(wrapper.find(FlashMessages)).toHaveLength(1); - }); + it('contains FlashMessages', () => { + expect(wrapper.find(FlashMessages)).toHaveLength(1); }); it('renders document creation components', () => { From dabe026fc262f8c1cd829838b5f93dfc6cb5bb66 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 3 Feb 2021 13:38:59 -0500 Subject: [PATCH 21/37] Lint nits --- .../app_search/components/create_engine/constants.ts | 1 + .../components/create_engine/create_engine_logic.test.ts | 9 ++++++--- .../components/create_engine/create_engine_logic.ts | 4 ++-- .../server/routes/app_search/engines.ts | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts index 5ac778c83bd0da..453e88a7d505a6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + import { i18n } from '@kbn/i18n'; export const CREATE_ENGINE_TITLE = i18n.translate( diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts index e135b7912e3dbf..72c872ed4ad635 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts @@ -3,17 +3,20 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { generatePath } from 'react-router-dom'; -import { CREATE_ENGINE_SUCCESS_MESSAGE } from './constants'; import { LogicMounter, mockHttpValues, mockKibanaValues, mockFlashMessageHelpers, } from '../../../__mocks__'; + +import { generatePath } from 'react-router-dom'; + import { ENGINE_PATH } from '../../routes'; import { formatApiName } from '../../utils/format_api_name'; + +import { CREATE_ENGINE_SUCCESS_MESSAGE } from './constants'; import { CreateEngineLogic, DEFAULT_LANGUAGE } from './create_engine_logic'; describe('CreateEngineLogic', () => { @@ -109,7 +112,7 @@ describe('CreateEngineLogic', () => { }); it('calls onCreateEngineSuccess on valid submission', async () => { - jest.spyOn(CreateEngineLogic.actions, 'onCreateEngineSuccess'); // .mockImplementation(); + jest.spyOn(CreateEngineLogic.actions, 'onCreateEngineSuccess'); const promise = (http.post as jest.Mock).mockReturnValueOnce({}); await CreateEngineLogic.actions.submitEngine(); await promise; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts index acdc0f2f8476c8..e267989b9c0171 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts @@ -16,14 +16,14 @@ import { KibanaLogic } from '../../../shared/kibana'; export const DEFAULT_LANGUAGE = 'Universal'; -export interface CreateEngineActions { +interface CreateEngineActions { onCreateEngineSuccess(): void; setLanguage(language: string): { language: string }; setRawName(rawName: string): { rawName: string }; submitEngine(): void; } -export interface CreateEngineValues { +interface CreateEngineValues { language: string; name: string; rawName: string; diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts index 30af2f130eaa06..ffadc4352bbaab 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts @@ -55,7 +55,7 @@ export function registerEnginesRoutes({ }, }, enterpriseSearchRequestHandler.createRequest({ - path: `/as/engines/collection`, + path: '/as/engines/collection', }) ); From d2fccf446c3633526c1a71a0c722ad8f36247cd3 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 3 Feb 2021 13:54:44 -0500 Subject: [PATCH 22/37] Improve CreateEngineLogic tests --- .../create_engine/create_engine_logic.test.ts | 74 ++++++++----------- 1 file changed, 29 insertions(+), 45 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts index 72c872ed4ad635..b14f0462549341 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts @@ -11,6 +11,7 @@ import { mockFlashMessageHelpers, } from '../../../__mocks__'; +import { nextTick } from '@kbn/test/jest'; import { generatePath } from 'react-router-dom'; import { ENGINE_PATH } from '../../routes'; @@ -37,37 +38,13 @@ describe('CreateEngineLogic', () => { }); describe('actions', () => { - describe('onCreateEngineSuccess', () => { - beforeAll(() => { - mount(); - // setup local state - CreateEngineLogic.actions.setLanguage('English'); - CreateEngineLogic.actions.setRawName('test'); - // call action - CreateEngineLogic.actions.onCreateEngineSuccess(); - }); - - it('should set a success message', () => { - expect(setQueuedSuccessMessage).toHaveBeenCalledWith(CREATE_ENGINE_SUCCESS_MESSAGE); - }); - - it('should navigate the user to the engine page', () => { - const enginePath = generatePath(ENGINE_PATH, { engineName: CreateEngineLogic.values.name }); - expect(navigateToUrl).toHaveBeenCalledWith(enginePath); - }); - }); - describe('setLanguage', () => { - const newLanguage = 'English'; - - beforeAll(() => { + it('sets language to the provided value', () => { mount(); - CreateEngineLogic.actions.setLanguage(newLanguage); - }); - - describe('language', () => { - it('should be set to provided value', () => { - expect(CreateEngineLogic.values.language).toEqual(newLanguage); + CreateEngineLogic.actions.setLanguage('English'); + expect(CreateEngineLogic.values).toEqual({ + ...DEFAULT_VALUES, + language: 'English', }); }); }); @@ -93,13 +70,28 @@ describe('CreateEngineLogic', () => { }); }); }); + }); + + describe('listeners', () => { + describe('onCreateEngineSuccess', () => { + beforeAll(() => { + mount({ language: 'English', rawName: 'test' }); + CreateEngineLogic.actions.onCreateEngineSuccess(); + }); + + it('should set a success message', () => { + expect(setQueuedSuccessMessage).toHaveBeenCalledWith(CREATE_ENGINE_SUCCESS_MESSAGE); + }); + + it('should navigate the user to the engine page', () => { + const enginePath = generatePath(ENGINE_PATH, { engineName: CreateEngineLogic.values.name }); + expect(navigateToUrl).toHaveBeenCalledWith(enginePath); + }); + }); describe('submitEngine', () => { beforeAll(() => { - mount(); - // setup local state - CreateEngineLogic.actions.setLanguage('English'); - CreateEngineLogic.actions.setRawName('test'); + mount({ language: 'English', rawName: 'test' }); }); it('POSTS to /api/app_search/engines', () => { @@ -113,24 +105,16 @@ describe('CreateEngineLogic', () => { it('calls onCreateEngineSuccess on valid submission', async () => { jest.spyOn(CreateEngineLogic.actions, 'onCreateEngineSuccess'); - const promise = (http.post as jest.Mock).mockReturnValueOnce({}); + http.post.mockReturnValueOnce(Promise.resolve({})); await CreateEngineLogic.actions.submitEngine(); - await promise; + await nextTick(); expect(CreateEngineLogic.actions.onCreateEngineSuccess).toHaveBeenCalledTimes(1); }); it('calls flashAPIErrors on API Error', async () => { - const promise = (http.post as jest.Mock).mockReturnValueOnce( - Promise.reject({ - body: { - statusCode: 400, - error: 'Bad Request', - message: 'Invalid request payload JSON format', - }, - }) - ); + http.post.mockReturnValueOnce(Promise.reject()); await CreateEngineLogic.actions.submitEngine(); - await promise; + await nextTick(); expect(flashAPIErrors).toHaveBeenCalledTimes(1); }); }); From 0c743fdc696022c8e009af74e4443e73225b899d Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 3 Feb 2021 14:00:06 -0500 Subject: [PATCH 23/37] Improve EngineOverview tests --- .../engine_overview/engine_overview_empty.test.tsx | 5 ----- .../engine_overview/engine_overview_metrics.test.tsx | 6 ------ .../components/engines/engines_overview.test.tsx | 12 ++++++++++-- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx index 9a7e2ee83e8ee8..cf4d4fc2ef84eb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx @@ -9,7 +9,6 @@ import { shallow, ShallowWrapper } from 'enzyme'; import { EuiButton } from '@elastic/eui'; import { docLinks } from '../../../shared/doc_links'; -import { FlashMessages } from '../../../shared/flash_messages'; import { DocumentCreationButtons, DocumentCreationFlyout } from '../document_creation'; import { EmptyEngineOverview } from './engine_overview_empty'; @@ -28,10 +27,6 @@ describe('EmptyEngineOverview', () => { expect(wrapper.find(EuiButton).prop('href')).toEqual(`${docLinks.appSearchBase}/index.html`); }); - it('contains FlashMessages', () => { - expect(wrapper.find(FlashMessages)).toHaveLength(1); - }); - it('renders document creation components', () => { expect(wrapper.find(DocumentCreationButtons)).toHaveLength(1); expect(wrapper.find(DocumentCreationFlyout)).toHaveLength(1); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx index e8590c51f9886a..8250446e231b35 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx @@ -9,7 +9,6 @@ import { setMockValues } from '../../../__mocks__/kea.mock'; import React from 'react'; import { shallow } from 'enzyme'; -import { FlashMessages } from '../../../shared/flash_messages'; import { UnavailablePrompt, TotalStats, TotalCharts, RecentApiLogs } from './components'; import { EngineOverviewMetrics } from './engine_overview_metrics'; @@ -19,11 +18,6 @@ describe('EngineOverviewMetrics', () => { expect(wrapper.find('h1').text()).toEqual('Engine overview'); }); - it('contains FlashMessages', () => { - const wrapper = shallow(); - expect(wrapper.find(FlashMessages)).toHaveLength(1); - }); - it('renders an unavailable prompt if engine data is still indexing', () => { setMockValues({ apiLogsUnavailable: true }); const wrapper = shallow(); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx index ffabe5f435d1bd..1ca49797a8d6d7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx @@ -5,7 +5,7 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions, rerender } from '../../../__mocks__'; +import { setMockValues, setMockActions, rerender, mockKibanaValues } from '../../../__mocks__'; import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; @@ -72,10 +72,18 @@ describe('EnginesOverview', () => { const wrapper = shallow(); expect(wrapper.find(EnginesTable)).toHaveLength(1); - expect(wrapper.find('[data-test-subj="appSearchEnginesCreateEngineButton"]')).toHaveLength(1); expect(actions.loadEngines).toHaveBeenCalled(); }); + it('renders a create engine button which takes users to the create engine page', () => { + const { navigateToUrl } = mockKibanaValues; + const wrapper = shallow(); + + wrapper.find('[data-test-subj="appSearchEnginesCreateEngineButton"]').simulate('click'); + + expect(navigateToUrl).toHaveBeenCalledWith('/create_engine'); + }); + describe('when on a platinum license', () => { it('renders a 2nd meta engines table & makes a 2nd meta engines API call', async () => { setMockValues({ From 7cf884221e38106ef74c8cb4da442b5c70a3eec0 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 3 Feb 2021 14:01:18 -0500 Subject: [PATCH 24/37] Disable EnginesOverview header responsiveness --- .../app_search/components/engines/engines_overview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx index c6a3f2c75da5e4..644eb39a18a08c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx @@ -66,7 +66,7 @@ export const EnginesOverview: React.FC = () => { - +

From c50b0ace8b90f864842c743d34bab92e924dc1a8 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 3 Feb 2021 14:01:41 -0500 Subject: [PATCH 25/37] Moving CreateEngine route --- .../public/applications/app_search/index.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index 2e9cf552f2fce3..c7abf83421df9e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -78,13 +78,6 @@ export const AppSearchConfigured: React.FC = (props) => { )} - {canManageEngines && ( - - } readOnlyMode={readOnlyMode}> - - - - )} } />} readOnlyMode={readOnlyMode}> @@ -108,6 +101,11 @@ export const AppSearchConfigured: React.FC = (props) => { + {canManageEngines && ( + + + + )} From e6eb59c970d0ba5d0cd86073cd737678775ebd87 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 3 Feb 2021 14:15:37 -0500 Subject: [PATCH 26/37] create_engine/CreateEngine -> engine_creation/EngineCreation --- .../constants.ts | 32 ++++++------- .../engine_creation.test.tsx} | 26 +++++------ .../engine_creation.tsx} | 42 ++++++++--------- .../engine_creation_logic.test.ts} | 46 ++++++++++--------- .../engine_creation_logic.ts} | 20 ++++---- .../index.ts | 2 +- .../engines/components/empty_state.tsx | 4 +- .../engines/engines_overview.test.tsx | 4 +- .../components/engines/engines_overview.tsx | 6 +-- .../applications/app_search/index.test.tsx | 10 ++-- .../public/applications/app_search/index.tsx | 8 ++-- .../public/applications/app_search/routes.ts | 2 +- 12 files changed, 102 insertions(+), 100 deletions(-) rename x-pack/plugins/enterprise_search/public/applications/app_search/components/{create_engine => engine_creation}/constants.ts (60%) rename x-pack/plugins/enterprise_search/public/applications/app_search/components/{create_engine/create_engine.test.tsx => engine_creation/engine_creation.test.tsx} (67%) rename x-pack/plugins/enterprise_search/public/applications/app_search/components/{create_engine/create_engine.tsx => engine_creation/engine_creation.tsx} (70%) rename x-pack/plugins/enterprise_search/public/applications/app_search/components/{create_engine/create_engine_logic.test.ts => engine_creation/engine_creation_logic.test.ts} (63%) rename x-pack/plugins/enterprise_search/public/applications/app_search/components/{create_engine/create_engine_logic.ts => engine_creation/engine_creation_logic.ts} (78%) rename x-pack/plugins/enterprise_search/public/applications/app_search/components/{create_engine => engine_creation}/index.ts (82%) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/constants.ts similarity index 60% rename from x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts rename to x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/constants.ts index 453e88a7d505a6..50250750c3f72b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/constants.ts @@ -6,64 +6,64 @@ import { i18n } from '@kbn/i18n'; -export const CREATE_ENGINE_TITLE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.createEngine.title', +export const ENGINE_CREATION_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.title', { defaultMessage: 'Create an Engine', } ); -export const CREATE_ENGINE_FORM_TITLE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.createEngine.form.title', +export const ENGINE_CREATION_FORM_TITLE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.form.title', { defaultMessage: 'Name your Engine', } ); -export const CREATE_ENGINE_FORM_ENGINE_NAME_LABEL = i18n.translate( - 'xpack.enterpriseSearch.appSearch.createEngine.form.engineName.label', +export const ENGINE_CREATION_FORM_ENGINE_NAME_LABEL = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.label', { defaultMessage: 'Engine Name', } ); export const ALLOWED_CHARS_NOTE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.createEngine.form.engineName.allowedCharactersNote', + 'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.allowedCharactersNote', { defaultMessage: 'Engine names can only contain lowercase letters, numbers, and hyphens', } ); export const SANITIZED_NAME_NOTE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.createEngine.form.engineName.sanitizedNameNote', + 'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.sanitizedNameNote', { defaultMessage: 'Your engine will be named', } ); -export const CREATE_ENGINE_FORM_ENGINE_NAME_PLACEHOLDER = i18n.translate( - 'xpack.enterpriseSearch.appSearch.createEngine.form.engineName.placeholder', +export const ENGINE_CREATION_FORM_ENGINE_NAME_PLACEHOLDER = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.placeholder', { defaultMessage: 'i.e., my-search-engine', } ); -export const CREATE_ENGINE_FORM_ENGINE_LANGUAGE_LABEL = i18n.translate( - 'xpack.enterpriseSearch.appSearch.createEngine.form.engineLanguage.label', +export const ENGINE_CREATION_FORM_ENGINE_LANGUAGE_LABEL = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.form.engineLanguage.label', { defaultMessage: 'Engine Language', } ); -export const CREATE_ENGINE_FORM_SUBMIT_BUTTON_LABEL = i18n.translate( - 'xpack.enterpriseSearch.appSearch.createEngine.form.submitButton.label', +export const ENGINE_CREATION_FORM_SUBMIT_BUTTON_LABEL = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.form.submitButton.label', { defaultMessage: 'Create Engine', } ); -export const CREATE_ENGINE_SUCCESS_MESSAGE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.createEngine.successMessage', +export const ENGINE_CREATION_SUCCESS_MESSAGE = i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.successMessage', { defaultMessage: 'Successfully created engine.', } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx similarity index 67% rename from x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx index 871601b99d688d..06eb5c88be6a67 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx @@ -10,9 +10,9 @@ import { shallow } from 'enzyme'; import '../../../__mocks__/shallow_useeffect.mock'; import { setMockValues } from '../../../__mocks__'; -import { CreateEngine } from './'; +import { EngineCreation } from './'; -describe('CreateEngine', () => { +describe('EngineCreation', () => { const DEFAULT_VALUES = { name: '', rawName: '', @@ -26,38 +26,38 @@ describe('CreateEngine', () => { it('renders', () => { setMockValues(DEFAULT_VALUES); - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="CreateEngine"]')).toHaveLength(1); + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="EngineCreation"]')).toHaveLength(1); }); it('contains a form', () => { setMockValues(DEFAULT_VALUES); - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="CreateEngineForm"]')).toHaveLength(1); + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="EngineCreationForm"]')).toHaveLength(1); }); it('contains a name input', () => { setMockValues(DEFAULT_VALUES); - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="CreateEngineNameInput"]')).toHaveLength(1); + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="EngineCreationNameInput"]')).toHaveLength(1); }); it('contains a language input', () => { setMockValues(DEFAULT_VALUES); - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="CreateEngineLanguageInput"]')).toHaveLength(1); + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="EngineCreationLanguageInput"]')).toHaveLength(1); }); describe('NewEngineSubmitButton', () => { it('renders', () => { setMockValues(DEFAULT_VALUES); - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]')).toHaveLength(1); }); it('is disabled when name is empty', () => { setMockValues(DEFAULT_VALUES); - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]').prop('disabled')).toEqual( true ); @@ -65,7 +65,7 @@ describe('CreateEngine', () => { it('is enabled when name has a value', () => { setMockValues({ ...DEFAULT_VALUES, name: 'test', rawName: 'test' }); - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]').prop('disabled')).toEqual( false ); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx similarity index 70% rename from x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx rename to x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx index a5addc9687ccb7..efbdaa19392379 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx @@ -27,28 +27,28 @@ import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chro import { FlashMessages } from '../../../shared/flash_messages'; import { ALLOWED_CHARS_NOTE, - CREATE_ENGINE_FORM_ENGINE_LANGUAGE_LABEL, - CREATE_ENGINE_FORM_ENGINE_NAME_LABEL, - CREATE_ENGINE_FORM_ENGINE_NAME_PLACEHOLDER, - CREATE_ENGINE_FORM_SUBMIT_BUTTON_LABEL, - CREATE_ENGINE_FORM_TITLE, - CREATE_ENGINE_TITLE, + ENGINE_CREATION_FORM_ENGINE_LANGUAGE_LABEL, + ENGINE_CREATION_FORM_ENGINE_NAME_LABEL, + ENGINE_CREATION_FORM_ENGINE_NAME_PLACEHOLDER, + ENGINE_CREATION_FORM_SUBMIT_BUTTON_LABEL, + ENGINE_CREATION_FORM_TITLE, + ENGINE_CREATION_TITLE, SANITIZED_NAME_NOTE, SUPPORTED_LANGUAGES, } from './constants'; -import { CreateEngineLogic } from './create_engine_logic'; +import { EngineCreationLogic } from './engine_creation_logic'; -export const CreateEngine: React.FC = () => { - const { name, rawName, language } = useValues(CreateEngineLogic); - const { setLanguage, setRawName, submitEngine } = useActions(CreateEngineLogic); +export const EngineCreation: React.FC = () => { + const { name, rawName, language } = useValues(EngineCreationLogic); + const { setLanguage, setRawName, submitEngine } = useActions(EngineCreationLogic); return ( -
- +
+ -

{CREATE_ENGINE_TITLE}

+

{ENGINE_CREATION_TITLE}

@@ -56,20 +56,20 @@ export const CreateEngine: React.FC = () => {
{ e.preventDefault(); submitEngine(); }} > - {CREATE_ENGINE_FORM_TITLE} + {ENGINE_CREATION_FORM_TITLE} 0 && rawName !== name ? ( <> @@ -87,19 +87,19 @@ export const CreateEngine: React.FC = () => { onChange={(event) => setRawName(event.currentTarget.value)} autoComplete="off" fullWidth={true} - data-test-subj="CreateEngineNameInput" - placeholder={CREATE_ENGINE_FORM_ENGINE_NAME_PLACEHOLDER} + data-test-subj="EngineCreationNameInput" + placeholder={ENGINE_CREATION_FORM_ENGINE_NAME_PLACEHOLDER} autoFocus={true} /> - + setLanguage(event.target.value)} /> @@ -113,7 +113,7 @@ export const CreateEngine: React.FC = () => { fill color="secondary" > - {CREATE_ENGINE_FORM_SUBMIT_BUTTON_LABEL} + {ENGINE_CREATION_FORM_SUBMIT_BUTTON_LABEL}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts similarity index 63% rename from x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts index b14f0462549341..79c68f80f6da3c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts @@ -17,11 +17,11 @@ import { generatePath } from 'react-router-dom'; import { ENGINE_PATH } from '../../routes'; import { formatApiName } from '../../utils/format_api_name'; -import { CREATE_ENGINE_SUCCESS_MESSAGE } from './constants'; -import { CreateEngineLogic, DEFAULT_LANGUAGE } from './create_engine_logic'; +import { ENGINE_CREATION_SUCCESS_MESSAGE } from './constants'; +import { EngineCreationLogic, DEFAULT_LANGUAGE } from './engine_creation_logic'; -describe('CreateEngineLogic', () => { - const { mount } = new LogicMounter(CreateEngineLogic); +describe('EngineCreationLogic', () => { + const { mount } = new LogicMounter(EngineCreationLogic); const { http } = mockHttpValues; const { navigateToUrl } = mockKibanaValues; const { setQueuedSuccessMessage, flashAPIErrors } = mockFlashMessageHelpers; @@ -34,15 +34,15 @@ describe('CreateEngineLogic', () => { it('has expected default values', () => { mount(); - expect(CreateEngineLogic.values).toEqual(DEFAULT_VALUES); + expect(EngineCreationLogic.values).toEqual(DEFAULT_VALUES); }); describe('actions', () => { describe('setLanguage', () => { it('sets language to the provided value', () => { mount(); - CreateEngineLogic.actions.setLanguage('English'); - expect(CreateEngineLogic.values).toEqual({ + EngineCreationLogic.actions.setLanguage('English'); + expect(EngineCreationLogic.values).toEqual({ ...DEFAULT_VALUES, language: 'English', }); @@ -55,36 +55,38 @@ describe('CreateEngineLogic', () => { beforeAll(() => { mount(); - CreateEngineLogic.actions.setRawName(newName); + EngineCreationLogic.actions.setRawName(newName); }); describe('rawName', () => { it('should be set to provided value', () => { - expect(CreateEngineLogic.values.rawName).toEqual(newName); + expect(EngineCreationLogic.values.rawName).toEqual(newName); }); }); describe('name', () => { it('should be set to a sanitized value', () => { - expect(CreateEngineLogic.values.name).toEqual(sanitizedNewName); + expect(EngineCreationLogic.values.name).toEqual(sanitizedNewName); }); }); }); }); describe('listeners', () => { - describe('onCreateEngineSuccess', () => { + describe('onEngineCreationSuccess', () => { beforeAll(() => { mount({ language: 'English', rawName: 'test' }); - CreateEngineLogic.actions.onCreateEngineSuccess(); + EngineCreationLogic.actions.onEngineCreationSuccess(); }); it('should set a success message', () => { - expect(setQueuedSuccessMessage).toHaveBeenCalledWith(CREATE_ENGINE_SUCCESS_MESSAGE); + expect(setQueuedSuccessMessage).toHaveBeenCalledWith(ENGINE_CREATION_SUCCESS_MESSAGE); }); it('should navigate the user to the engine page', () => { - const enginePath = generatePath(ENGINE_PATH, { engineName: CreateEngineLogic.values.name }); + const enginePath = generatePath(ENGINE_PATH, { + engineName: EngineCreationLogic.values.name, + }); expect(navigateToUrl).toHaveBeenCalledWith(enginePath); }); }); @@ -96,24 +98,24 @@ describe('CreateEngineLogic', () => { it('POSTS to /api/app_search/engines', () => { const body = JSON.stringify({ - name: CreateEngineLogic.values.name, - language: CreateEngineLogic.values.language, + name: EngineCreationLogic.values.name, + language: EngineCreationLogic.values.language, }); - CreateEngineLogic.actions.submitEngine(); + EngineCreationLogic.actions.submitEngine(); expect(http.post).toHaveBeenCalledWith('/api/app_search/engines', { body }); }); - it('calls onCreateEngineSuccess on valid submission', async () => { - jest.spyOn(CreateEngineLogic.actions, 'onCreateEngineSuccess'); + it('calls onEngineCreationSuccess on valid submission', async () => { + jest.spyOn(EngineCreationLogic.actions, 'onEngineCreationSuccess'); http.post.mockReturnValueOnce(Promise.resolve({})); - await CreateEngineLogic.actions.submitEngine(); + await EngineCreationLogic.actions.submitEngine(); await nextTick(); - expect(CreateEngineLogic.actions.onCreateEngineSuccess).toHaveBeenCalledTimes(1); + expect(EngineCreationLogic.actions.onEngineCreationSuccess).toHaveBeenCalledTimes(1); }); it('calls flashAPIErrors on API Error', async () => { http.post.mockReturnValueOnce(Promise.reject()); - await CreateEngineLogic.actions.submitEngine(); + await EngineCreationLogic.actions.submitEngine(); await nextTick(); expect(flashAPIErrors).toHaveBeenCalledTimes(1); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts similarity index 78% rename from x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts index e267989b9c0171..975d565f031c53 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/create_engine_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts @@ -7,7 +7,7 @@ import { kea, MakeLogicType } from 'kea'; import { generatePath } from 'react-router-dom'; -import { CREATE_ENGINE_SUCCESS_MESSAGE } from './constants'; +import { ENGINE_CREATION_SUCCESS_MESSAGE } from './constants'; import { ENGINE_PATH } from '../../routes'; import { formatApiName } from '../../utils/format_api_name'; import { flashAPIErrors, setQueuedSuccessMessage } from '../../../shared/flash_messages'; @@ -16,23 +16,23 @@ import { KibanaLogic } from '../../../shared/kibana'; export const DEFAULT_LANGUAGE = 'Universal'; -interface CreateEngineActions { - onCreateEngineSuccess(): void; +interface EngineCreationActions { + onEngineCreationSuccess(): void; setLanguage(language: string): { language: string }; setRawName(rawName: string): { rawName: string }; submitEngine(): void; } -interface CreateEngineValues { +interface EngineCreationValues { language: string; name: string; rawName: string; } -export const CreateEngineLogic = kea>({ - path: ['enterprise_search', 'app_search', 'create_engine_logic'], +export const EngineCreationLogic = kea>({ + path: ['enterprise_search', 'app_search', 'engine_creation_logic'], actions: { - onCreateEngineSuccess: true, + onEngineCreationSuccess: true, setLanguage: (language) => ({ language }), setRawName: (rawName) => ({ rawName }), submitEngine: true, @@ -63,17 +63,17 @@ export const CreateEngineLogic = kea { + onEngineCreationSuccess: () => { const { name } = values; const { navigateToUrl } = KibanaLogic.values; const enginePath = generatePath(ENGINE_PATH, { engineName: name }); - setQueuedSuccessMessage(CREATE_ENGINE_SUCCESS_MESSAGE); + setQueuedSuccessMessage(ENGINE_CREATION_SUCCESS_MESSAGE); navigateToUrl(enginePath); }, }), diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/index.ts similarity index 82% rename from x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/index.ts rename to x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/index.ts index 44fee51db0ba75..83477b20cd878f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/create_engine/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { CreateEngine } from './create_engine'; +export { EngineCreation } from './engine_creation'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx index 95142782d2272b..e7725607c75492 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx @@ -12,7 +12,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { TelemetryLogic } from '../../../../shared/telemetry'; import { getAppSearchUrl } from '../../../../shared/enterprise_search_url'; import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome'; -import { CREATE_ENGINES_PATH } from '../../../routes'; +import { ENGINE_CREATION_PATH } from '../../../routes'; import { EnginesOverviewHeader } from './header'; @@ -22,7 +22,7 @@ export const EmptyState: React.FC = () => { const { sendAppSearchTelemetry } = useActions(TelemetryLogic); const buttonProps = { - href: getAppSearchUrl(CREATE_ENGINES_PATH), + href: getAppSearchUrl(ENGINE_CREATION_PATH), target: '_blank', onClick: () => sendAppSearchTelemetry({ diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx index 1ca49797a8d6d7..ef92ccae9f6926 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx @@ -79,9 +79,9 @@ describe('EnginesOverview', () => { const { navigateToUrl } = mockKibanaValues; const wrapper = shallow(); - wrapper.find('[data-test-subj="appSearchEnginesCreateEngineButton"]').simulate('click'); + wrapper.find('[data-test-subj="appSearchEnginesEngineCreationButton"]').simulate('click'); - expect(navigateToUrl).toHaveBeenCalledWith('/create_engine'); + expect(navigateToUrl).toHaveBeenCalledWith('/engine_creation'); }); describe('when on a platinum license', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx index 644eb39a18a08c..c186d0d82801e4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx @@ -20,7 +20,7 @@ import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chro import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; import { FlashMessages } from '../../../shared/flash_messages'; import { LicensingLogic } from '../../../shared/licensing'; -import { CREATE_ENGINES_PATH } from '../../routes'; +import { ENGINE_CREATION_PATH } from '../../routes'; import { KibanaLogic } from '../../../shared/kibana'; import { EngineIcon } from './assets/engine_icon'; @@ -78,8 +78,8 @@ export const EnginesOverview: React.FC = () => { KibanaLogic.values.navigateToUrl(CREATE_ENGINES_PATH)} + data-test-subj="appSearchEnginesEngineCreationButton" + onClick={() => KibanaLogic.values.navigateToUrl(ENGINE_CREATION_PATH)} > {CREATE_AN_ENGINE_BUTTON_LABEL} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index f16118b109eb54..f9ed4b83243b5a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -13,7 +13,7 @@ import { Redirect } from 'react-router-dom'; import { shallow } from 'enzyme'; import { Layout, SideNav, SideNavLink } from '../shared/layout'; -import { CreateEngine } from './components/create_engine'; +import { EngineCreation } from './components/engine_creation'; import { SetupGuide } from './components/setup_guide'; import { ErrorConnecting } from './components/error_connecting'; import { EnginesOverview } from './components/engines'; @@ -98,18 +98,18 @@ describe('AppSearchConfigured', () => { describe('ability checks', () => { describe('canManageEngines', () => { - it('renders CreateEngine when user canManageEngines is true', () => { + it('renders EngineCreation when user canManageEngines is true', () => { setMockValues({ myRole: { canManageEngines: true } }); const wrapper = shallow(); - expect(wrapper.find(CreateEngine)).toHaveLength(1); + expect(wrapper.find(EngineCreation)).toHaveLength(1); }); - it('does not render CreateEngine when user canManageEngines is false', () => { + it('does not render EngineCreation when user canManageEngines is false', () => { setMockValues({ myRole: { canManageEngines: false } }); const wrapper = shallow(); - expect(wrapper.find(CreateEngine)).toHaveLength(0); + expect(wrapper.find(EngineCreation)).toHaveLength(0); }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index c7abf83421df9e..4c2b67d790b7d1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -19,7 +19,7 @@ import { Layout, SideNav, SideNavLink } from '../shared/layout'; import { EngineNav, EngineRouter } from './components/engine'; import { - CREATE_ENGINES_PATH, + ENGINE_CREATION_PATH, ROOT_PATH, SETUP_GUIDE_PATH, SETTINGS_PATH, @@ -30,7 +30,7 @@ import { LIBRARY_PATH, } from './routes'; -import { CreateEngine } from './components/create_engine'; +import { EngineCreation } from './components/engine_creation'; import { SetupGuide } from './components/setup_guide'; import { ErrorConnecting } from './components/error_connecting'; import { NotFound } from '../shared/not_found'; @@ -102,8 +102,8 @@ export const AppSearchConfigured: React.FC = (props) => { {canManageEngines && ( - - + + )} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts index f72b179a27c7e9..315c295f98e58b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts @@ -16,7 +16,7 @@ export const CREDENTIALS_PATH = '/credentials'; export const ROLE_MAPPINGS_PATH = '#/role-mappings'; // This page seems to 404 if the # isn't included export const ENGINES_PATH = '/engines'; -export const CREATE_ENGINES_PATH = `/create_engine`; +export const ENGINE_CREATION_PATH = `/engine_creation`; export const ENGINE_PATH = `${ENGINES_PATH}/:engineName`; export const SAMPLE_ENGINE_PATH = `${ENGINES_PATH}/national-parks-demo`; From 4857d56745cf47975bf9be8c41b38f65bc202873 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 3 Feb 2021 14:33:45 -0500 Subject: [PATCH 27/37] Use static values for tests --- .../engine_creation_logic.test.ts | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts index 79c68f80f6da3c..fc3c00e344cfe4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts @@ -18,7 +18,7 @@ import { ENGINE_PATH } from '../../routes'; import { formatApiName } from '../../utils/format_api_name'; import { ENGINE_CREATION_SUCCESS_MESSAGE } from './constants'; -import { EngineCreationLogic, DEFAULT_LANGUAGE } from './engine_creation_logic'; +import { EngineCreationLogic } from './engine_creation_logic'; describe('EngineCreationLogic', () => { const { mount } = new LogicMounter(EngineCreationLogic); @@ -29,7 +29,7 @@ describe('EngineCreationLogic', () => { const DEFAULT_VALUES = { name: '', rawName: '', - language: DEFAULT_LANGUAGE, + language: 'Universal', }; it('has expected default values', () => { @@ -50,23 +50,20 @@ describe('EngineCreationLogic', () => { }); describe('setRawName', () => { - const newName = 'Name__With#$&*%Special--Characters'; - const sanitizedNewName = formatApiName(newName); - beforeAll(() => { mount(); - EngineCreationLogic.actions.setRawName(newName); + EngineCreationLogic.actions.setRawName('Name__With#$&*%Special--Characters'); }); describe('rawName', () => { it('should be set to provided value', () => { - expect(EngineCreationLogic.values.rawName).toEqual(newName); + expect(EngineCreationLogic.values.rawName).toEqual('Name__With#$&*%Special--Characters'); }); }); describe('name', () => { it('should be set to a sanitized value', () => { - expect(EngineCreationLogic.values.name).toEqual(sanitizedNewName); + expect(EngineCreationLogic.values.name).toEqual('name-with-special-characters'); }); }); }); @@ -80,14 +77,11 @@ describe('EngineCreationLogic', () => { }); it('should set a success message', () => { - expect(setQueuedSuccessMessage).toHaveBeenCalledWith(ENGINE_CREATION_SUCCESS_MESSAGE); + expect(setQueuedSuccessMessage).toHaveBeenCalledWith('Successfully created engine.'); }); it('should navigate the user to the engine page', () => { - const enginePath = generatePath(ENGINE_PATH, { - engineName: EngineCreationLogic.values.name, - }); - expect(navigateToUrl).toHaveBeenCalledWith(enginePath); + expect(navigateToUrl).toHaveBeenCalledWith('/engines/test'); }); }); From 1f62ee5a6f58dfb16bc6bf94e8f770f8b9993126 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 3 Feb 2021 15:41:10 -0500 Subject: [PATCH 28/37] Fixing constants, better casing, better ID names, i18ning dropdown labels --- .../components/engine_creation/constants.ts | 123 ++++++++++++++---- .../engine_creation/engine_creation_logic.ts | 3 +- .../components/engines/constants.ts | 4 +- 3 files changed, 103 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/constants.ts index 50250750c3f72b..a421fdb9c1bb65 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/constants.ts @@ -6,36 +6,38 @@ import { i18n } from '@kbn/i18n'; +export const DEFAULT_LANGUAGE = 'Universal'; + export const ENGINE_CREATION_TITLE = i18n.translate( 'xpack.enterpriseSearch.appSearch.engineCreation.title', { - defaultMessage: 'Create an Engine', + defaultMessage: 'Create an engine', } ); export const ENGINE_CREATION_FORM_TITLE = i18n.translate( 'xpack.enterpriseSearch.appSearch.engineCreation.form.title', { - defaultMessage: 'Name your Engine', + defaultMessage: 'Name your engine', } ); export const ENGINE_CREATION_FORM_ENGINE_NAME_LABEL = i18n.translate( 'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.label', { - defaultMessage: 'Engine Name', + defaultMessage: 'Engine name', } ); export const ALLOWED_CHARS_NOTE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.allowedCharactersNote', + 'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.allowedCharactersHelpText', { defaultMessage: 'Engine names can only contain lowercase letters, numbers, and hyphens', } ); export const SANITIZED_NAME_NOTE = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.sanitizedNameNote', + 'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.sanitizedNameHelpText', { defaultMessage: 'Your engine will be named', } @@ -51,14 +53,14 @@ export const ENGINE_CREATION_FORM_ENGINE_NAME_PLACEHOLDER = i18n.translate( export const ENGINE_CREATION_FORM_ENGINE_LANGUAGE_LABEL = i18n.translate( 'xpack.enterpriseSearch.appSearch.engineCreation.form.engineLanguage.label', { - defaultMessage: 'Engine Language', + defaultMessage: 'Engine language', } ); export const ENGINE_CREATION_FORM_SUBMIT_BUTTON_LABEL = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engineCreation.form.submitButton.label', + 'xpack.enterpriseSearch.appSearch.engineCreation.form.submitButton.buttonLabel', { - defaultMessage: 'Create Engine', + defaultMessage: 'Create engine', } ); @@ -72,7 +74,12 @@ export const ENGINE_CREATION_SUCCESS_MESSAGE = i18n.translate( export const SUPPORTED_LANGUAGES = [ { value: 'Universal', - text: 'Universal', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.universalDropDownOptionLabel', + { + defaultMessage: 'Universal', + } + ), }, { text: '—', @@ -80,58 +87,128 @@ export const SUPPORTED_LANGUAGES = [ }, { value: 'zh', - text: 'Chinese', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.chineseDropDownOptionLabel', + { + defaultMessage: 'Chinese', + } + ), }, { value: 'da', - text: 'Danish', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.danishDropDownOptionLabel', + { + defaultMessage: 'Danish', + } + ), }, { value: 'nl', - text: 'Dutch', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.dutchDropDownOptionLabel', + { + defaultMessage: 'Dutch', + } + ), }, { value: 'en', - text: 'English', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.englishDropDownOptionLabel', + { + defaultMessage: 'English', + } + ), }, { value: 'fr', - text: 'French', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.frenchDropDownOptionLabel', + { + defaultMessage: 'French', + } + ), }, { value: 'de', - text: 'German', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.germanDropDownOptionLabel', + { + defaultMessage: 'German', + } + ), }, { value: 'it', - text: 'Italian', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.italianDropDownOptionLabel', + { + defaultMessage: 'Italian', + } + ), }, { value: 'ja', - text: 'Japanese', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.japaneseDropDownOptionLabel', + { + defaultMessage: 'Japanese', + } + ), }, { value: 'ko', - text: 'Korean', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.koreanDropDownOptionLabel', + { + defaultMessage: 'Korean', + } + ), }, { value: 'pt', - text: 'Portuguese', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.portugueseDropDownOptionLabel', + { + defaultMessage: 'Portuguese', + } + ), }, { value: 'pt-br', - text: 'Portuguese (Brazil)', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.portugueseBrazilDropDownOptionLabel', + { + defaultMessage: 'Portuguese (Brazil)', + } + ), }, { value: 'ru', - text: 'Russian', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.russianDropDownOptionLabel', + { + defaultMessage: 'Russian', + } + ), }, { value: 'es', - text: 'Spanish', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.spanishDropDownOptionLabel', + { + defaultMessage: 'Spanish', + } + ), }, { value: 'th', - text: 'Thai', + text: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.thaiDropDownOptionLabel', + { + defaultMessage: 'Thai', + } + ), }, ]; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts index 975d565f031c53..59b8a754e55bae 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts @@ -7,14 +7,13 @@ import { kea, MakeLogicType } from 'kea'; import { generatePath } from 'react-router-dom'; -import { ENGINE_CREATION_SUCCESS_MESSAGE } from './constants'; import { ENGINE_PATH } from '../../routes'; import { formatApiName } from '../../utils/format_api_name'; import { flashAPIErrors, setQueuedSuccessMessage } from '../../../shared/flash_messages'; import { HttpLogic } from '../../../shared/http'; import { KibanaLogic } from '../../../shared/kibana'; -export const DEFAULT_LANGUAGE = 'Universal'; +import { DEFAULT_LANGUAGE, ENGINE_CREATION_SUCCESS_MESSAGE } from './constants'; interface EngineCreationActions { onEngineCreationSuccess(): void; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.ts index fe86e3f981a01b..60c2c1e2cc8c89 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.ts @@ -16,8 +16,8 @@ export const META_ENGINES_TITLE = i18n.translate( ); export const CREATE_AN_ENGINE_BUTTON_LABEL = i18n.translate( - 'xpack.enterpriseSearch.appSearch.engines.createAnEngineButton.label', + 'xpack.enterpriseSearch.appSearch.engines.createAnEngineButton.ButtonLabel', { - defaultMessage: 'Create an Engine', + defaultMessage: 'Create an engine', } ); From b6828de29891e9b6a73b0a638fb3dcb57ccd5015 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Mon, 8 Feb 2021 11:08:08 -0500 Subject: [PATCH 29/37] Removing unused imports --- .../components/engine_creation/engine_creation_logic.test.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts index fc3c00e344cfe4..180a645effe43f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts @@ -12,12 +12,7 @@ import { } from '../../../__mocks__'; import { nextTick } from '@kbn/test/jest'; -import { generatePath } from 'react-router-dom'; -import { ENGINE_PATH } from '../../routes'; -import { formatApiName } from '../../utils/format_api_name'; - -import { ENGINE_CREATION_SUCCESS_MESSAGE } from './constants'; import { EngineCreationLogic } from './engine_creation_logic'; describe('EngineCreationLogic', () => { From 339afda7ed54cec621834283abc001ea84ab32b1 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Mon, 8 Feb 2021 11:08:48 -0500 Subject: [PATCH 30/37] Fix EngineCreation tests --- .../engine_creation/engine_creation.test.tsx | 124 ++++++++++------ .../engine_creation/engine_creation.tsx | 134 +++++++++--------- 2 files changed, 152 insertions(+), 106 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx index 06eb5c88be6a67..e1df8db2aad9cf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx @@ -4,12 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ +import { setMockActions, setMockValues } from '../../../__mocks__'; + import React from 'react'; import { shallow } from 'enzyme'; -import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues } from '../../../__mocks__'; - import { EngineCreation } from './'; describe('EngineCreation', () => { @@ -19,57 +18,100 @@ describe('EngineCreation', () => { language: 'Universal', }; - describe('default values', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); + const MOCK_ACTIONS = { + setRawName: jest.fn(), + setLanguage: jest.fn(), + submitEngine: jest.fn(), + }; - it('renders', () => { - setMockValues(DEFAULT_VALUES); - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="EngineCreation"]')).toHaveLength(1); - }); + beforeEach(() => { + jest.clearAllMocks(); + setMockValues(DEFAULT_VALUES); + setMockActions(MOCK_ACTIONS); + }); - it('contains a form', () => { - setMockValues(DEFAULT_VALUES); - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="EngineCreationForm"]')).toHaveLength(1); - }); + it('renders', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="EngineCreation"]')).toHaveLength(1); + }); + + it('EngineCreationForm calls submitEngine on form submit', () => { + const wrapper = shallow(); + const simulatedEvent = { + preventDefault: jest.fn(), + }; + wrapper.find('[data-test-subj="EngineCreationForm"]').simulate('submit', simulatedEvent); + + expect(MOCK_ACTIONS.submitEngine).toHaveBeenCalledTimes(1); + }); + + it('EngineCreationNameInput calls setRawName on change', () => { + const wrapper = shallow(); + const simulatedEvent = { + currentTarget: { value: 'new-raw-name' }, + }; + wrapper.find('[data-test-subj="EngineCreationNameInput"]').simulate('change', simulatedEvent); - it('contains a name input', () => { - setMockValues(DEFAULT_VALUES); + expect(MOCK_ACTIONS.setRawName).toHaveBeenCalledWith('new-raw-name'); + }); + + it('EngineCreationLanguageInput calls setLanguage on change', () => { + const wrapper = shallow(); + const simulatedEvent = { + currentTarget: { value: 'English' }, + }; + wrapper + .find('[data-test-subj="EngineCreationLanguageInput"]') + .simulate('change', simulatedEvent); + + expect(MOCK_ACTIONS.setLanguage).toHaveBeenCalledWith('English'); + }); + + describe('NewEngineSubmitButton', () => { + it('is disabled when name is empty', () => { + setMockValues({ ...DEFAULT_VALUES, name: '', rawName: '' }); const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="EngineCreationNameInput"]')).toHaveLength(1); + + expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]').prop('disabled')).toEqual( + true + ); }); - it('contains a language input', () => { - setMockValues(DEFAULT_VALUES); + it('is enabled when name has a value', () => { + setMockValues({ ...DEFAULT_VALUES, name: 'test', rawName: 'test' }); const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="EngineCreationLanguageInput"]')).toHaveLength(1); + + expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]').prop('disabled')).toEqual( + false + ); }); + }); - describe('NewEngineSubmitButton', () => { - it('renders', () => { - setMockValues(DEFAULT_VALUES); - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]')).toHaveLength(1); + describe('EngineCreationNameFormRow', () => { + it('renders sanitized name helptext when the raw name is being sanitized', () => { + setMockValues({ + ...DEFAULT_VALUES, + name: 'un-sanitized-name', + rawName: 'un-----sanitized-------name', }); + const wrapper = shallow(); + const formRow = wrapper.find('[data-test-subj="EngineCreationNameFormRow"]').dive(); - it('is disabled when name is empty', () => { - setMockValues(DEFAULT_VALUES); - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]').prop('disabled')).toEqual( - true - ); - }); + expect(formRow.contains('Your engine will be named')).toBeTruthy(); + }); - it('is enabled when name has a value', () => { - setMockValues({ ...DEFAULT_VALUES, name: 'test', rawName: 'test' }); - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]').prop('disabled')).toEqual( - false - ); + it('renders allowed character helptext when rawName and sanitizedName match', () => { + setMockValues({ + ...DEFAULT_VALUES, + name: 'pre-sanitized-name', + rawName: 'pre-sanitized-name', }); + const wrapper = shallow(); + const formRow = wrapper.find('[data-test-subj="EngineCreationNameFormRow"]').dive(); + + expect( + formRow.contains('Engine names can only contain lowercase letters, numbers, and hyphens') + ).toBeTruthy(); }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx index efbdaa19392379..5fa4b1f81af44a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx @@ -13,6 +13,7 @@ import { EuiFlexItem, EuiFieldText, EuiSelect, + EuiPageBody, EuiPageHeader, EuiPageHeaderSection, EuiSpacer, @@ -52,72 +53,75 @@ export const EngineCreation: React.FC = () => { - - - -
{ - e.preventDefault(); - submitEngine(); - }} - > - - {ENGINE_CREATION_FORM_TITLE} - - - - - 0 && rawName !== name ? ( - <> - {SANITIZED_NAME_NOTE} {name} - - ) : ( - ALLOWED_CHARS_NOTE - ) - } - fullWidth={true} - > - setRawName(event.currentTarget.value)} - autoComplete="off" - fullWidth={true} - data-test-subj="EngineCreationNameInput" - placeholder={ENGINE_CREATION_FORM_ENGINE_NAME_PLACEHOLDER} - autoFocus={true} - /> - - - - - setLanguage(event.target.value)} - /> - - - - - + + + + { + e.preventDefault(); + submitEngine(); + }} > - {ENGINE_CREATION_FORM_SUBMIT_BUTTON_LABEL} - - -
-
+ + {ENGINE_CREATION_FORM_TITLE} + + + + + 0 && rawName !== name ? ( + <> + {SANITIZED_NAME_NOTE} {name} + + ) : ( + ALLOWED_CHARS_NOTE + ) + } + fullWidth={true} + > + setRawName(event.currentTarget.value)} + autoComplete="off" + fullWidth={true} + data-test-subj="EngineCreationNameInput" + placeholder={ENGINE_CREATION_FORM_ENGINE_NAME_PLACEHOLDER} + autoFocus={true} + /> + + + + + setLanguage(event.currentTarget.value)} + /> + + + + + + {ENGINE_CREATION_FORM_SUBMIT_BUTTON_LABEL} + + + +
+
); }; From 3a9aba7bf3825dd9ab40e143e631d7c880b2ec74 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Mon, 8 Feb 2021 11:10:34 -0500 Subject: [PATCH 31/37] Fix Engines EmptyState tests --- .../engines/components/empty_state.test.tsx | 28 +++++++++++++----- .../engines/components/empty_state.tsx | 29 ++++++++++--------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx index ad60286f4e052a..32a779779cc8b6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx @@ -8,8 +8,8 @@ import '../../../../__mocks__/kea.mock'; import { mockTelemetryActions } from '../../../../__mocks__'; import React from 'react'; -import { shallow } from 'enzyme'; -import { EuiEmptyPrompt, EuiButton } from '@elastic/eui'; +import { shallow, ShallowWrapper } from 'enzyme'; +import { EuiEmptyPrompt } from '@elastic/eui'; import { EmptyState } from './'; @@ -20,12 +20,24 @@ describe('EmptyState', () => { expect(wrapper.find(EuiEmptyPrompt)).toHaveLength(1); }); - it('sends telemetry on create first engine click', () => { - const wrapper = shallow(); - const prompt = wrapper.find(EuiEmptyPrompt).dive(); - const button = prompt.find(EuiButton); + describe('CTA Button', () => { + let wrapper: ShallowWrapper; + let prompt: ShallowWrapper; + let button: ShallowWrapper; + + beforeEach(() => { + wrapper = shallow(); + prompt = wrapper.find(EuiEmptyPrompt).dive(); + button = prompt.find('[data-test-subj="EmptyStateCreateFirstEngineCta"]'); + }); + + it('sends telemetry on create first engine click', () => { + button.simulate('click'); + expect(mockTelemetryActions.sendAppSearchTelemetry).toHaveBeenCalled(); + }); - button.simulate('click'); - expect(mockTelemetryActions.sendAppSearchTelemetry).toHaveBeenCalled(); + it('sends a user to engine creation', () => { + expect(button.prop('to')).toEqual('/engine_creation'); + }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx index e7725607c75492..85c13a951fa918 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx @@ -6,11 +6,11 @@ import React from 'react'; import { useActions } from 'kea'; -import { EuiPageContent, EuiEmptyPrompt, EuiButton } from '@elastic/eui'; +import { EuiPageContent, EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiButtonTo } from '../../../../shared/react_router_helpers'; import { TelemetryLogic } from '../../../../shared/telemetry'; -import { getAppSearchUrl } from '../../../../shared/enterprise_search_url'; import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome'; import { ENGINE_CREATION_PATH } from '../../../routes'; @@ -21,16 +21,6 @@ import './empty_state.scss'; export const EmptyState: React.FC = () => { const { sendAppSearchTelemetry } = useActions(TelemetryLogic); - const buttonProps = { - href: getAppSearchUrl(ENGINE_CREATION_PATH), - target: '_blank', - onClick: () => - sendAppSearchTelemetry({ - action: 'clicked', - metric: 'create_first_engine_button', - }), - }; - return ( <> @@ -57,12 +47,23 @@ export const EmptyState: React.FC = () => {

} actions={ - + + sendAppSearchTelemetry({ + action: 'clicked', + metric: 'create_first_engine_button', + }) + } + > - + } /> From 31501a72f61dd86768c28778fdf9f4dcaa7940fb Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Mon, 8 Feb 2021 11:10:56 -0500 Subject: [PATCH 32/37] Fix EnginesOverview tests --- .../components/engines/engines_overview.test.tsx | 9 ++++----- .../components/engines/engines_overview.tsx | 11 +++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx index ef92ccae9f6926..727e20515c391c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx @@ -5,7 +5,7 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions, rerender, mockKibanaValues } from '../../../__mocks__'; +import { setMockValues, setMockActions, rerender } from '../../../__mocks__'; import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; @@ -76,12 +76,11 @@ describe('EnginesOverview', () => { }); it('renders a create engine button which takes users to the create engine page', () => { - const { navigateToUrl } = mockKibanaValues; const wrapper = shallow(); - wrapper.find('[data-test-subj="appSearchEnginesEngineCreationButton"]').simulate('click'); - - expect(navigateToUrl).toHaveBeenCalledWith('/engine_creation'); + expect( + wrapper.find('[data-test-subj="appSearchEnginesEngineCreationButton"]').prop('to') + ).toEqual('/engine_creation'); }); describe('when on a platinum license', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx index c186d0d82801e4..18c09500002312 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx @@ -7,7 +7,6 @@ import React, { useEffect } from 'react'; import { useValues, useActions } from 'kea'; import { - EuiButton, EuiPageContent, EuiPageContentHeader, EuiPageContentHeaderSection, @@ -20,8 +19,8 @@ import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chro import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; import { FlashMessages } from '../../../shared/flash_messages'; import { LicensingLogic } from '../../../shared/licensing'; +import { EuiButtonTo } from '../../../shared/react_router_helpers'; import { ENGINE_CREATION_PATH } from '../../routes'; -import { KibanaLogic } from '../../../shared/kibana'; import { EngineIcon } from './assets/engine_icon'; import { MetaEngineIcon } from './assets/meta_engine_icon'; @@ -75,14 +74,14 @@ export const EnginesOverview: React.FC = () => { - KibanaLogic.values.navigateToUrl(ENGINE_CREATION_PATH)} + to={ENGINE_CREATION_PATH} > {CREATE_AN_ENGINE_BUTTON_LABEL} - + From 5bdb4d8cb3ab4b22141254e88848545502ca64ed Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Mon, 8 Feb 2021 11:15:11 -0500 Subject: [PATCH 33/37] Lint fixes --- .../components/engine_creation/constants.ts | 5 +++-- .../engine_creation/engine_creation.test.tsx | 5 +++-- .../components/engine_creation/engine_creation.tsx | 11 ++++++----- .../engine_creation/engine_creation_logic.test.ts | 5 +++-- .../engine_creation/engine_creation_logic.ts | 5 +++-- .../app_search/components/engine_creation/index.ts | 5 +++-- .../public/applications/app_search/routes.ts | 2 +- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/constants.ts index a421fdb9c1bb65..0647eeba787861 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/constants.ts @@ -1,7 +1,8 @@ /* * 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. + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ import { i18n } from '@kbn/i18n'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx index e1df8db2aad9cf..bebc3296b00661 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx @@ -1,7 +1,8 @@ /* * 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. + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ import { setMockActions, setMockValues } from '../../../__mocks__'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx index 5fa4b1f81af44a..ca38b77795f88c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx @@ -1,7 +1,8 @@ /* * 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. + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ import React from 'react'; @@ -82,17 +83,17 @@ export const EngineCreation: React.FC = () => { ALLOWED_CHARS_NOTE ) } - fullWidth={true} + fullWidth > setRawName(event.currentTarget.value)} autoComplete="off" - fullWidth={true} + fullWidth data-test-subj="EngineCreationNameInput" placeholder={ENGINE_CREATION_FORM_ENGINE_NAME_PLACEHOLDER} - autoFocus={true} + autoFocus /> diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts index 180a645effe43f..eff2262e5a75b1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts @@ -1,7 +1,8 @@ /* * 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. + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ import { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts index 59b8a754e55bae..2f4dc3861e6fb1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts @@ -1,7 +1,8 @@ /* * 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. + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ import { kea, MakeLogicType } from 'kea'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/index.ts index 83477b20cd878f..a1770cc50ea93e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/index.ts @@ -1,7 +1,8 @@ /* * 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. + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ export { EngineCreation } from './engine_creation'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts index 69cfa3e14a029b..dee8858fada8b4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts @@ -17,7 +17,7 @@ export const CREDENTIALS_PATH = '/credentials'; export const ROLE_MAPPINGS_PATH = '#/role-mappings'; // This page seems to 404 if the # isn't included export const ENGINES_PATH = '/engines'; -export const ENGINE_CREATION_PATH = `/engine_creation`; +export const ENGINE_CREATION_PATH = '/engine_creation'; export const ENGINE_PATH = `${ENGINES_PATH}/:engineName`; export const SAMPLE_ENGINE_PATH = `${ENGINES_PATH}/national-parks-demo`; From 6aed5c74c5083ff59fd57ad6c5739a8163e1cd1a Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Mon, 8 Feb 2021 11:24:03 -0500 Subject: [PATCH 34/37] Reset mocks after tests --- .../engine_creation_logic.test.ts | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts index eff2262e5a75b1..272e4fb3a25c04 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts @@ -51,16 +51,16 @@ describe('EngineCreationLogic', () => { EngineCreationLogic.actions.setRawName('Name__With#$&*%Special--Characters'); }); - describe('rawName', () => { - it('should be set to provided value', () => { - expect(EngineCreationLogic.values.rawName).toEqual('Name__With#$&*%Special--Characters'); - }); + afterAll(() => { + jest.clearAllMocks(); }); - describe('name', () => { - it('should be set to a sanitized value', () => { - expect(EngineCreationLogic.values.name).toEqual('name-with-special-characters'); - }); + it('should set rawName to provided value', () => { + expect(EngineCreationLogic.values.rawName).toEqual('Name__With#$&*%Special--Characters'); + }); + + it('should set name to a sanitized value', () => { + expect(EngineCreationLogic.values.name).toEqual('name-with-special-characters'); }); }); }); @@ -72,6 +72,10 @@ describe('EngineCreationLogic', () => { EngineCreationLogic.actions.onEngineCreationSuccess(); }); + afterAll(() => { + jest.clearAllMocks(); + }); + it('should set a success message', () => { expect(setQueuedSuccessMessage).toHaveBeenCalledWith('Successfully created engine.'); }); @@ -86,6 +90,10 @@ describe('EngineCreationLogic', () => { mount({ language: 'English', rawName: 'test' }); }); + afterAll(() => { + jest.clearAllMocks(); + }); + it('POSTS to /api/app_search/engines', () => { const body = JSON.stringify({ name: EngineCreationLogic.values.name, @@ -98,14 +106,14 @@ describe('EngineCreationLogic', () => { it('calls onEngineCreationSuccess on valid submission', async () => { jest.spyOn(EngineCreationLogic.actions, 'onEngineCreationSuccess'); http.post.mockReturnValueOnce(Promise.resolve({})); - await EngineCreationLogic.actions.submitEngine(); + EngineCreationLogic.actions.submitEngine(); await nextTick(); expect(EngineCreationLogic.actions.onEngineCreationSuccess).toHaveBeenCalledTimes(1); }); it('calls flashAPIErrors on API Error', async () => { http.post.mockReturnValueOnce(Promise.reject()); - await EngineCreationLogic.actions.submitEngine(); + EngineCreationLogic.actions.submitEngine(); await nextTick(); expect(flashAPIErrors).toHaveBeenCalledTimes(1); }); From 822d34236ded406fe787f184d6e4aa32e2104d8c Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Mon, 8 Feb 2021 11:29:23 -0500 Subject: [PATCH 35/37] Update MockRouter properties --- .../enterprise_search/server/routes/app_search/engines.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts index c0cfd4774880cf..6fbc9f5bd2fc49 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts @@ -118,7 +118,6 @@ describe('engine routes', () => { mockRouter = new MockRouter({ method: 'post', path: '/api/app_search/engines', - payload: 'body', }); registerEnginesRoutes({ From 4b6c2818313a86b341333aecd5cd2ff4e8d1fc29 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Tue, 9 Feb 2021 13:35:19 -0500 Subject: [PATCH 36/37] Revert newline change --- .../components/engine_overview/engine_overview_empty.test.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx index 829de4e2d1e5af..5947618e59c161 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx @@ -6,14 +6,12 @@ */ import React from 'react'; - import { shallow, ShallowWrapper } from 'enzyme'; - import { EuiButton } from '@elastic/eui'; import { docLinks } from '../../../shared/doc_links'; -import { DocumentCreationButtons, DocumentCreationFlyout } from '../document_creation'; +import { DocumentCreationButtons, DocumentCreationFlyout } from '../document_creation'; import { EmptyEngineOverview } from './engine_overview_empty'; describe('EmptyEngineOverview', () => { From 33133543bba8228b057ef9fc27ea994583c3fb31 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Tue, 9 Feb 2021 14:01:58 -0500 Subject: [PATCH 37/37] Lint fix --- .../components/engine_overview/engine_overview_empty.test.tsx | 3 +++ .../public/applications/app_search/index.test.tsx | 1 + 2 files changed, 4 insertions(+) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx index 5947618e59c161..9066283229a041 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx @@ -6,12 +6,15 @@ */ import React from 'react'; + import { shallow, ShallowWrapper } from 'enzyme'; + import { EuiButton } from '@elastic/eui'; import { docLinks } from '../../../shared/doc_links'; import { DocumentCreationButtons, DocumentCreationFlyout } from '../document_creation'; + import { EmptyEngineOverview } from './engine_overview_empty'; describe('EmptyEngineOverview', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index 4388cde0feb5f3..5150a4996eb84d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -12,6 +12,7 @@ import { setMockValues, setMockActions } from '../__mocks__'; import React from 'react'; import { Redirect } from 'react-router-dom'; + import { shallow } from 'enzyme'; import { Layout, SideNav, SideNavLink } from '../shared/layout';