From 3e426a0eab4bad404e3de7cfa3db39d8e88465b1 Mon Sep 17 00:00:00 2001 From: Constance Date: Mon, 28 Sep 2020 12:04:05 -0700 Subject: [PATCH] [Enterprise Search] Remove all instances of KibanaContext to Kea store (#78513) * Add KibanaLogic store/mount * Update usage of setBreadcrumbs/setDocTitle to KibanaLogic * Update usage of Kibana config context to KibanaLogic * Update usage of navigateToUrl context to KibanaLogic * :fire: Remove unused shallow_usecontext mocks, repurpose file to shallow_useeffect - The file is now no longer used to mock useContext, only unseEffect, hence the rename * :fire: Delete/repurpose mount with context helpers - Remove mountWithKibanaContext completely - Change mountWithContext to mountWithIntl, since that's the only context remaining, and move it to its own file - Change mountWithAsyncContext to just mountAsync and move it to its own file + add an option to pair it w/ mountWithIntl for formatted date/number support * :fire: Delete KibanaContext and mockKibanaContext + minor newline linting/grouping tweaks Co-authored-by: Elastic Machine --- .../public/applications/__mocks__/index.ts | 12 +-- .../public/applications/__mocks__/kea.mock.ts | 2 + ...a_context.mock.ts => kibana_logic.mock.ts} | 8 +- .../__mocks__/mount_async.mock.tsx | 46 ++++++++++ .../__mocks__/mount_with_context.mock.tsx | 83 ------------------- .../__mocks__/mount_with_i18n.mock.tsx | 21 +++++ .../__mocks__/shallow_usecontext.mock.ts | 40 --------- .../__mocks__/shallow_useeffect.mock.ts | 21 +++++ .../engine_overview/engine_overview.test.tsx | 12 +-- .../engine_overview/engine_table.test.tsx | 47 +++++------ .../applications/app_search/index.test.tsx | 8 +- .../public/applications/app_search/index.tsx | 6 +- .../product_card/product_card.test.tsx | 8 +- .../components/product_card/product_card.tsx | 11 +-- .../product_selector.test.tsx | 9 +- .../product_selector/product_selector.tsx | 17 ++-- .../enterprise_search/index.test.tsx | 20 ++--- .../applications/enterprise_search/index.tsx | 6 +- .../public/applications/index.tsx | 50 +++++------ .../error_state/error_state_prompt.test.tsx | 2 +- .../shared/error_state/error_state_prompt.tsx | 7 +- .../applications/shared/kibana/index.ts | 7 ++ .../shared/kibana/kibana_logic.test.ts | 32 +++++++ .../shared/kibana/kibana_logic.ts | 32 +++++++ .../generate_breadcrumbs.test.ts | 10 +-- .../kibana_chrome/generate_breadcrumbs.ts | 6 +- .../shared/kibana_chrome/set_chrome.test.tsx | 23 ++--- .../shared/kibana_chrome/set_chrome.tsx | 12 +-- .../react_router_helpers/eui_link.test.tsx | 8 +- .../shared/react_router_helpers/eui_link.tsx | 7 +- .../shared/setup_guide/setup_guide.test.tsx | 4 +- .../shared/telemetry/send_telemetry.test.tsx | 2 +- .../content_section/content_section.test.tsx | 2 - .../shared/loading/loading.test.tsx | 2 - .../shared/source_icon/source_icon.test.tsx | 2 - .../shared/source_row/source_row.test.tsx | 2 - .../view_content_header.test.tsx | 2 - .../workplace_search/index.test.tsx | 8 +- .../applications/workplace_search/index.tsx | 6 +- .../views/error_state/error_state.test.tsx | 2 - .../overview/organization_stats.test.tsx | 1 - 41 files changed, 300 insertions(+), 306 deletions(-) rename x-pack/plugins/enterprise_search/public/applications/__mocks__/{kibana_context.mock.ts => kibana_logic.mock.ts} (65%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx delete mode 100644 x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_context.mock.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx delete mode 100644 x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_usecontext.mock.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_useeffect.mock.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/kibana/index.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts index 88a900f69c5ecf..f48f5fb91e3e70 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts @@ -5,17 +5,13 @@ */ export { mockHistory, mockLocation } from './react_router_history.mock'; -export { mockKibanaContext } from './kibana_context.mock'; +export { mockKibanaValues } from './kibana_logic.mock'; export { mockLicensingValues } from './licensing_logic.mock'; export { mockHttpValues } from './http_logic.mock'; export { mockFlashMessagesValues, mockFlashMessagesActions } from './flash_messages_logic.mock'; export { mockAllValues, mockAllActions, setMockValues } from './kea.mock'; -export { - mountWithContext, - mountWithKibanaContext, - mountWithAsyncContext, -} from './mount_with_context.mock'; +export { mountAsync } from './mount_async.mock'; +export { mountWithIntl } from './mount_with_i18n.mock'; export { shallowWithIntl } from './shallow_with_i18n.mock'; - -// Note: shallow_usecontext must be imported directly as a file +// Note: shallow_useeffect must be imported directly as a file diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts index bad6beaa1652ee..b616cbab03e28e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts @@ -10,11 +10,13 @@ * NOTE: These variable names MUST start with 'mock*' in order for * Jest to accept its use within a jest.mock() */ +import { mockKibanaValues } from './kibana_logic.mock'; import { mockLicensingValues } from './licensing_logic.mock'; import { mockHttpValues } from './http_logic.mock'; import { mockFlashMessagesValues, mockFlashMessagesActions } from './flash_messages_logic.mock'; export const mockAllValues = { + ...mockKibanaValues, ...mockLicensingValues, ...mockHttpValues, ...mockFlashMessagesValues, diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts similarity index 65% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts rename to x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts index ee77b0937cd82a..9f3c2443bc9b8d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts @@ -4,13 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -/** - * A set of default Kibana context values to use across component tests. - * @see enterprise_search/public/index.tsx for the KibanaContext definition/import - */ -export const mockKibanaContext = { +export const mockKibanaValues = { + config: { host: 'http://localhost:3002' }, navigateToUrl: jest.fn(), setBreadcrumbs: jest.fn(), setDocTitle: jest.fn(), - config: { host: 'http://localhost:3002' }, }; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx new file mode 100644 index 00000000000000..a33e116c7ca726 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx @@ -0,0 +1,46 @@ +/* + * 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 { act } from 'react-dom/test-utils'; +import { mount, ReactWrapper } from 'enzyme'; + +import { mountWithIntl } from './'; + +/** + * This helper is intended for components that have async effects + * (e.g. http fetches) on mount. It mostly adds act/update boilerplate + * that's needed for the wrapper to play nice with Enzyme/Jest + * + * Example usage: + * + * const wrapper = mountAsync(); + */ + +interface IOptions { + i18n?: boolean; +} + +export const mountAsync = async ( + children: React.ReactElement, + options: IOptions +): Promise => { + let wrapper: ReactWrapper | undefined; + + // We get a lot of act() warning/errors in the terminal without this. + // TBH, I don't fully understand why since Enzyme's mount is supposed to + // have act() baked in - could be because of the wrapping context provider? + await act(async () => { + wrapper = options.i18n ? mountWithIntl(children) : mount(children); + }); + if (wrapper) { + wrapper.update(); // This seems to be required for the DOM to actually update + + return wrapper; + } else { + throw new Error('Could not mount wrapper'); + } +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_context.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_context.mock.tsx deleted file mode 100644 index 646c3104c286fa..00000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_context.mock.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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 { act } from 'react-dom/test-utils'; -import { mount, ReactWrapper } from 'enzyme'; - -import { Provider } from 'react-redux'; -import { Store } from 'redux'; -import { getContext, resetContext } from 'kea'; - -import { I18nProvider } from '@kbn/i18n/react'; -import { KibanaContext } from '../'; -import { mockKibanaContext } from './kibana_context.mock'; - -/** - * This helper mounts a component with all the contexts/providers used - * by the production app, while allowing custom context to be - * passed in via a second arg - * - * Example usage: - * - * const wrapper = mountWithContext(, { config: { host: 'someOverride' } }); - */ -export const mountWithContext = (children: React.ReactNode, context?: object) => { - resetContext({ createStore: true }); - const store = getContext().store as Store; - - return mount( - - - {children} - - - ); -}; - -/** - * This helper mounts a component with just the default KibanaContext - - * useful for isolated / helper components that only need this context - * - * Same usage/override functionality as mountWithContext - */ -export const mountWithKibanaContext = (children: React.ReactNode, context?: object) => { - return mount( - - {children} - - ); -}; - -/** - * This helper is intended for components that have async effects - * (e.g. http fetches) on mount. It mostly adds act/update boilerplate - * that's needed for the wrapper to play nice with Enzyme/Jest - * - * Example usage: - * - * const wrapper = mountWithAsyncContext(, { http: { get: () => someData } }); - */ -export const mountWithAsyncContext = async ( - children: React.ReactNode, - context?: object -): Promise => { - let wrapper: ReactWrapper | undefined; - - // We get a lot of act() warning/errors in the terminal without this. - // TBH, I don't fully understand why since Enzyme's mount is supposed to - // have act() baked in - could be because of the wrapping context provider? - await act(async () => { - wrapper = mountWithContext(children, context); - }); - if (wrapper) { - wrapper.update(); // This seems to be required for the DOM to actually update - - return wrapper; - } else { - throw new Error('Could not mount wrapper'); - } -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx new file mode 100644 index 00000000000000..55abe1030544fa --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx @@ -0,0 +1,21 @@ +/* + * 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 { mount } from 'enzyme'; +import { I18nProvider } from '@kbn/i18n/react'; + +/** + * This helper wraps a component with react-intl's which + * fixes "Could not find required `intl` object" console errors when running tests + * + * Example usage (should be the same as mount()): + * + * const wrapper = mountWithI18n(); + */ +export const mountWithIntl = (children: React.ReactElement) => { + return mount({children}); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_usecontext.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_usecontext.mock.ts deleted file mode 100644 index df9e58994e36b4..00000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_usecontext.mock.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - */ - -/** - * NOTE: These variable names MUST start with 'mock*' in order for - * Jest to accept its use within a jest.mock() - */ -import { mockKibanaContext } from './kibana_context.mock'; - -jest.mock('react', () => ({ - ...(jest.requireActual('react') as object), - useContext: jest.fn(() => ({ ...mockKibanaContext })), - useEffect: jest.fn((fn) => fn()), // Calls on mount/every update - use mount for more complex behavior -})); - -/** - * Example usage within a component test using shallow(): - * - * import '../../../__mocks__/shallow_usecontext'; // Must come before React's import, adjust relative path as needed - * - * import React from 'react'; - * import { shallow } from 'enzyme'; - * - * // ... etc. - */ - -/** - * If you need to override the default mock context values, you can do so via jest.mockImplementation: - * - * import React, { useContext } from 'react'; - * - * // ... etc. - * - * it('some test', () => { - * useContext.mockImplementationOnce(() => ({ config: { host: 'someOverride' } })); - * }); - */ diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_useeffect.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_useeffect.mock.ts new file mode 100644 index 00000000000000..732786b5f92495 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_useeffect.mock.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ + +jest.mock('react', () => ({ + ...(jest.requireActual('react') as object), + useEffect: jest.fn((fn) => fn()), // Calls on mount/every update - use mount for more complex behavior +})); + +/** + * Example usage within a component test using shallow(): + * + * import '../../../__mocks__/shallow_useeffect.mock'; // Must come before React's import, adjust relative path as needed + * + * import React from 'react'; + * import { shallow } from 'enzyme'; + * + * // ... etc. + */ diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx index 44afce96c1a6c0..f87ea2d4227803 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx @@ -11,7 +11,7 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { shallow, ReactWrapper } from 'enzyme'; -import { mountWithAsyncContext, mockHttpValues, setMockValues } from '../../../__mocks__'; +import { mountAsync, mockHttpValues, setMockValues } from '../../../__mocks__'; import { LoadingState, EmptyState } from './components'; import { EngineTable } from './engine_table'; @@ -36,7 +36,7 @@ describe('EngineOverview', () => { }), }, }); - const wrapper = await mountWithAsyncContext(); + const wrapper = await mountAsync(, { i18n: true }); expect(wrapper.find(EmptyState)).toHaveLength(1); }); @@ -69,7 +69,7 @@ describe('EngineOverview', () => { }); it('renders and calls the engines API', async () => { - const wrapper = await mountWithAsyncContext(); + const wrapper = await mountAsync(, { i18n: true }); expect(wrapper.find(EngineTable)).toHaveLength(1); expect(mockApi).toHaveBeenNthCalledWith(1, '/api/app_search/engines', { @@ -86,7 +86,7 @@ describe('EngineOverview', () => { hasPlatinumLicense: true, http: { ...mockHttpValues.http, get: mockApi }, }); - const wrapper = await mountWithAsyncContext(); + const wrapper = await mountAsync(, { i18n: true }); expect(wrapper.find(EngineTable)).toHaveLength(2); expect(mockApi).toHaveBeenNthCalledWith(2, '/api/app_search/engines', { @@ -103,7 +103,7 @@ describe('EngineOverview', () => { wrapper.find(EngineTable).prop('pagination'); it('passes down page data from the API', async () => { - const wrapper = await mountWithAsyncContext(); + const wrapper = await mountAsync(, { i18n: true }); const pagination = getTablePagination(wrapper); expect(pagination.totalEngines).toEqual(100); @@ -111,7 +111,7 @@ describe('EngineOverview', () => { }); it('re-polls the API on page change', async () => { - const wrapper = await mountWithAsyncContext(); + const wrapper = await mountAsync(, { i18n: true }); await act(async () => getTablePagination(wrapper).onPaginate(5)); wrapper.update(); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx index c66fd24fee12a8..4d97a16991b715 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx @@ -6,11 +6,9 @@ import '../../../__mocks__/kea.mock'; import '../../../__mocks__/enterprise_search_url.mock'; -import { mockHttpValues } from '../../../__mocks__/'; +import { mockHttpValues, mountWithIntl } from '../../../__mocks__/'; import React from 'react'; -import { mount } from 'enzyme'; -import { I18nProvider } from '@kbn/i18n/react'; import { EuiBasicTable, EuiPagination, EuiButtonEmpty, EuiLink } from '@elastic/eui'; jest.mock('../../../shared/telemetry', () => ({ sendTelemetry: jest.fn() })); @@ -21,24 +19,22 @@ import { EngineTable } from './engine_table'; describe('EngineTable', () => { const onPaginate = jest.fn(); // onPaginate updates the engines API call upstream - const wrapper = mount( - - - + const wrapper = mountWithIntl( + ); const table = wrapper.find(EuiBasicTable); @@ -78,13 +74,8 @@ describe('EngineTable', () => { }); it('handles empty data', () => { - const emptyWrapper = mount( - - {} }} - /> - + const emptyWrapper = mountWithIntl( + {} }} /> ); const emptyTable = emptyWrapper.find(EuiBasicTable); 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 052f4446e4409b..c54d6ed3ddd6f0 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 @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../__mocks__/shallow_usecontext.mock'; +import '../__mocks__/shallow_useeffect.mock'; import '../__mocks__/kea.mock'; import '../__mocks__/enterprise_search_url.mock'; -import React, { useContext } from 'react'; +import React from 'react'; import { Redirect } from 'react-router-dom'; import { shallow } from 'enzyme'; import { useValues, useActions } from 'kea'; @@ -21,14 +21,14 @@ import { AppSearch, AppSearchUnconfigured, AppSearchConfigured, AppSearchNav } f describe('AppSearch', () => { it('renders AppSearchUnconfigured when config.host is not set', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); + (useValues as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); const wrapper = shallow(); expect(wrapper.find(AppSearchUnconfigured)).toHaveLength(1); }); it('renders AppSearchConfigured when config.host set', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'some.url' } })); + (useValues as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'some.url' } })); const wrapper = shallow(); expect(wrapper.find(AppSearchConfigured)).toHaveLength(1); 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 410f6eb524822c..9aa2cce9c74df2 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 @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext, useEffect } from 'react'; +import React, { useEffect } from 'react'; import { Route, Redirect, Switch } from 'react-router-dom'; import { useActions, useValues } from 'kea'; import { i18n } from '@kbn/i18n'; -import { KibanaContext, IKibanaContext } from '../index'; import { getAppSearchUrl } from '../shared/enterprise_search_url'; +import { KibanaLogic } from '../shared/kibana'; import { HttpLogic } from '../shared/http'; import { AppLogic } from './app_logic'; import { IInitialAppData } from '../../../common/types'; @@ -34,7 +34,7 @@ import { NotFound } from '../shared/not_found'; import { EngineOverview } from './components/engine_overview'; export const AppSearch: React.FC = (props) => { - const { config } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); return !config.host ? : ; }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx index 35301af44b413d..b2030ec910cd87 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx @@ -5,9 +5,9 @@ */ import '../../../__mocks__/kea.mock'; -import '../../../__mocks__/shallow_usecontext.mock'; -import React, { useContext } from 'react'; +import React from 'react'; +import { useValues } from 'kea'; import { shallow } from 'enzyme'; import { EuiCard } from '@elastic/eui'; @@ -27,7 +27,6 @@ describe('ProductCard', () => { }); it('renders an App Search card', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'localhost' } })); const wrapper = shallow(); const card = wrapper.find(EuiCard).dive().shallow(); @@ -43,7 +42,6 @@ describe('ProductCard', () => { }); it('renders a Workplace Search card', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'localhost' } })); const wrapper = shallow(); const card = wrapper.find(EuiCard).dive().shallow(); @@ -61,7 +59,7 @@ describe('ProductCard', () => { }); it('renders correct button text when host not present', () => { - (useContext as jest.Mock).mockImplementation(() => ({ config: { host: '' } })); + (useValues as jest.Mock).mockImplementation(() => ({ config: { host: '' } })); const wrapper = shallow(); const card = wrapper.find(EuiCard).dive().shallow(); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx index 482d68736af013..1d05128adc2e3a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx @@ -4,17 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; import { useValues } from 'kea'; import { snakeCase } from 'lodash'; import { i18n } from '@kbn/i18n'; import { EuiCard, EuiTextColor } from '@elastic/eui'; -import { KibanaContext, IKibanaContext } from '../../../index'; - import { EuiButton } from '../../../shared/react_router_helpers'; import { sendTelemetry } from '../../../shared/telemetry'; import { HttpLogic } from '../../../shared/http'; +import { KibanaLogic } from '../../../shared/kibana'; import './product_card.scss'; @@ -31,9 +30,7 @@ interface IProductCard { export const ProductCard: React.FC = ({ product, image }) => { const { http } = useValues(HttpLogic); - const { - config: { host }, - } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); const LAUNCH_BUTTON_TEXT = i18n.translate( 'xpack.enterpriseSearch.overview.productCard.launchButton', @@ -80,7 +77,7 @@ export const ProductCard: React.FC = ({ product, image }) => { }) } > - {host ? LAUNCH_BUTTON_TEXT : SETUP_BUTTON_TEXT} + {config.host ? LAUNCH_BUTTON_TEXT : SETUP_BUTTON_TEXT} } /> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx index 44efa57db897ff..f1f16d1a6f7a46 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx @@ -4,9 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/shallow_usecontext.mock'; +import '../../../__mocks__/kea.mock'; -import React, { useContext } from 'react'; +import React from 'react'; +import { useValues } from 'kea'; import { shallow } from 'enzyme'; import { EuiPage } from '@elastic/eui'; @@ -15,7 +16,7 @@ import { ProductCard } from '../product_card'; describe('ProductSelector', () => { it('renders the overview page and product cards with no host set', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); + (useValues as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); const wrapper = shallow(); expect(wrapper.find(EuiPage).hasClass('enterpriseSearchOverview')).toBe(true); @@ -24,7 +25,7 @@ describe('ProductSelector', () => { describe('access checks when host is set', () => { beforeEach(() => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'localhost' } })); + (useValues as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'localhost' } })); }); it('does not render the App Search card if the user does not have access to AS', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx index 07b8d4b9926d7f..5c2d105e69c408 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx @@ -9,8 +9,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; - +import React from 'react'; +import { useValues } from 'kea'; import { EuiPage, EuiPageBody, @@ -24,10 +24,8 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { KibanaContext, IKibanaContext } from '../../../index'; - import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; - +import { KibanaLogic } from '../../../shared/kibana'; import { SetEnterpriseSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; @@ -45,12 +43,11 @@ interface IProductSelectorProps { export const ProductSelector: React.FC = ({ access }) => { const { hasAppSearchAccess, hasWorkplaceSearchAccess } = access; - const { - config: { host }, - } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); - const shouldShowAppSearchCard = !host || hasAppSearchAccess; - const shouldShowWorkplaceSearchCard = !host || hasWorkplaceSearchAccess; + // If Enterprise Search hasn't been set up yet, show all products. Otherwise, only show products the user has access to + const shouldShowAppSearchCard = !config.host || hasAppSearchAccess; + const shouldShowWorkplaceSearchCard = !config.host || hasWorkplaceSearchAccess; return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx index 2c0902163e3d6a..803d2c8462b1bd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../__mocks__/shallow_usecontext.mock'; - -import React, { useContext } from 'react'; +import React from 'react'; import { shallow } from 'enzyme'; import { EuiPage } from '@elastic/eui'; @@ -19,12 +17,11 @@ import { ErrorConnecting } from './components/error_connecting'; import { ProductSelector } from './components/product_selector'; describe('EnterpriseSearch', () => { - beforeEach(() => { - (useValues as jest.Mock).mockReturnValue({ errorConnecting: false }); - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'localhost' } })); - }); - it('renders the Setup Guide and Product Selector', () => { + (useValues as jest.Mock).mockReturnValue({ + errorConnecting: false, + config: { host: 'localhost' }, + }); const wrapper = shallow(); expect(wrapper.find(SetupGuide)).toHaveLength(1); @@ -32,9 +29,10 @@ describe('EnterpriseSearch', () => { }); it('renders the error connecting prompt when host is not configured', () => { - (useValues as jest.Mock).mockReturnValueOnce({ errorConnecting: true }); - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); - + (useValues as jest.Mock).mockReturnValueOnce({ + errorConnecting: true, + config: { host: '' }, + }); const wrapper = shallow(); expect(wrapper.find(ErrorConnecting)).toHaveLength(1); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx index e2c05434dd0bbc..7b97c6c9e58b6e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; import { Route, Switch } from 'react-router-dom'; import { useValues } from 'kea'; -import { KibanaContext, IKibanaContext } from '../index'; +import { KibanaLogic } from '../shared/kibana'; import { IInitialAppData } from '../../../common/types'; import { HttpLogic } from '../shared/http'; @@ -23,7 +23,7 @@ import './index.scss'; export const EnterpriseSearch: React.FC = ({ access = {} }) => { const { errorConnecting } = useValues(HttpLogic); - const { config } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); const showErrorConnecting = config.host && errorConnecting; diff --git a/x-pack/plugins/enterprise_search/public/applications/index.tsx b/x-pack/plugins/enterprise_search/public/applications/index.tsx index 2c6bc787923e36..63be9b684e56f2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/index.tsx @@ -7,28 +7,20 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { Router } from 'react-router-dom'; - import { Provider } from 'react-redux'; import { Store } from 'redux'; import { getContext, resetContext } from 'kea'; - import { I18nProvider } from '@kbn/i18n/react'; -import { AppMountParameters, CoreStart, ApplicationStart, ChromeBreadcrumb } from 'src/core/public'; + +import { AppMountParameters, CoreStart } from 'src/core/public'; import { PluginsStart, ClientConfigType, ClientData } from '../plugin'; +import { IInitialAppData } from '../../common/types'; + +import { mountKibanaLogic } from './shared/kibana'; import { mountLicensingLogic } from './shared/licensing'; import { mountHttpLogic } from './shared/http'; import { mountFlashMessagesLogic } from './shared/flash_messages'; import { externalUrl } from './shared/enterprise_search_url'; -import { IInitialAppData } from '../../common/types'; - -export interface IKibanaContext { - config: { host?: string }; - navigateToUrl: ApplicationStart['navigateToUrl']; - setBreadcrumbs(crumbs: ChromeBreadcrumb[]): void; - setDocTitle(title: string): void; -} - -export const KibanaContext = React.createContext({}); /** * This file serves as a reusable wrapper to share Kibana-level context and other helpers @@ -47,39 +39,37 @@ export const renderApp = ( resetContext({ createStore: true }); const store = getContext().store as Store; + const unmountKibanaLogic = mountKibanaLogic({ + config, + navigateToUrl: core.application.navigateToUrl, + setBreadcrumbs: core.chrome.setBreadcrumbs, + setDocTitle: core.chrome.docTitle.change, + }); const unmountLicensingLogic = mountLicensingLogic({ license$: plugins.licensing.license$, }); - const unmountHttpLogic = mountHttpLogic({ http: core.http, errorConnecting, readOnlyMode: initialData.readOnlyMode, }); - - const unmountFlashMessagesLogic = mountFlashMessagesLogic({ history: params.history }); + const unmountFlashMessagesLogic = mountFlashMessagesLogic({ + history: params.history, + }); ReactDOM.render( - - - - - - - + + + + + , params.element ); return () => { ReactDOM.unmountComponentAtNode(params.element); + unmountKibanaLogic(); unmountLicensingLogic(); unmountHttpLogic(); unmountFlashMessagesLogic(); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx index 29b773b80158af..25a02e847ccbd7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../__mocks__/shallow_usecontext.mock'; +import '../../__mocks__/kea.mock'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx index a2cb424dadee89..b92a5bbf1c64e6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx @@ -4,17 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; +import { useValues } from 'kea'; import { EuiEmptyPrompt, EuiCode } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiButton } from '../react_router_helpers'; -import { KibanaContext, IKibanaContext } from '../../index'; +import { KibanaLogic } from '../../shared/kibana'; import './error_state_prompt.scss'; export const ErrorStatePrompt: React.FC = () => { - const { config } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); return ( { + beforeEach(() => { + jest.clearAllMocks(); + resetContext({}); + }); + + describe('mounts', () => { + it('sets values from props', () => { + mountKibanaLogic(mockKibanaValues); + + expect(KibanaLogic.values).toEqual(mockKibanaValues); + }); + + it('gracefully handles missing configs', () => { + mountKibanaLogic({ ...mockKibanaValues, config: undefined } as any); + + expect(KibanaLogic.values.config).toEqual({}); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts new file mode 100644 index 00000000000000..a884acb02d10ae --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts @@ -0,0 +1,32 @@ +/* + * 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 { ApplicationStart, ChromeBreadcrumb } from 'src/core/public'; + +export interface IKibanaValues { + config: { host?: string }; + navigateToUrl: ApplicationStart['navigateToUrl']; + setBreadcrumbs(crumbs: ChromeBreadcrumb[]): void; + setDocTitle(title: string): void; +} + +export const KibanaLogic = kea>({ + path: ['enterprise_search', 'kibana_logic'], + reducers: ({ props }) => ({ + config: [props.config || {}, {}], + navigateToUrl: [props.navigateToUrl, {}], + setBreadcrumbs: [props.setBreadcrumbs, {}], + setDocTitle: [props.setDocTitle, {}], + }), +}); + +export const mountKibanaLogic = (props: IKibanaValues) => { + KibanaLogic(props); + const unmount = KibanaLogic.mount(); + return unmount; +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts index 3c8b3a72188627..a2c0bcae6fc189 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../__mocks__/shallow_usecontext.mock'; +import '../../__mocks__/kea.mock'; import '../../__mocks__/react_router_history.mock'; -import { mockKibanaContext, mockHistory } from '../../__mocks__'; +import { mockKibanaValues, mockHistory } from '../../__mocks__'; jest.mock('../react_router_helpers', () => ({ letBrowserHandleEvent: jest.fn(() => false) })); import { letBrowserHandleEvent } from '../react_router_helpers'; @@ -53,7 +53,7 @@ describe('useBreadcrumbs', () => { const event = { preventDefault: jest.fn() }; breadcrumb.onClick(event); - expect(mockKibanaContext.navigateToUrl).toHaveBeenCalledWith('/app/enterprise_search/test'); + expect(mockKibanaValues.navigateToUrl).toHaveBeenCalledWith('/app/enterprise_search/test'); expect(mockHistory.createHref).toHaveBeenCalled(); expect(event.preventDefault).toHaveBeenCalled(); }); @@ -64,7 +64,7 @@ describe('useBreadcrumbs', () => { ])[0] as any; breadcrumb.onClick({ preventDefault: () => null }); - expect(mockKibanaContext.navigateToUrl).toHaveBeenCalledWith('/test'); + expect(mockKibanaValues.navigateToUrl).toHaveBeenCalledWith('/test'); expect(mockHistory.createHref).not.toHaveBeenCalled(); }); @@ -74,7 +74,7 @@ describe('useBreadcrumbs', () => { (letBrowserHandleEvent as jest.Mock).mockImplementationOnce(() => true); breadcrumb.onClick(); - expect(mockKibanaContext.navigateToUrl).not.toHaveBeenCalled(); + expect(mockKibanaValues.navigateToUrl).not.toHaveBeenCalled(); }); it('does not generate link behavior if path is excluded', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts index 19714608e73e9b..ff7f29e2e393c0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { useContext } from 'react'; +import { useValues } from 'kea'; import { useHistory } from 'react-router-dom'; import { EuiBreadcrumb } from '@elastic/eui'; -import { KibanaContext, IKibanaContext } from '../../index'; +import { KibanaLogic } from '../../shared/kibana'; import { ENTERPRISE_SEARCH_PLUGIN, @@ -34,7 +34,7 @@ export type TBreadcrumbs = IBreadcrumb[]; export const useBreadcrumbs = (breadcrumbs: TBreadcrumbs) => { const history = useHistory(); - const { navigateToUrl } = useContext(KibanaContext) as IKibanaContext; + const { navigateToUrl } = useValues(KibanaLogic); return breadcrumbs.map(({ text, path, shouldNotCreateHref }) => { const breadcrumb = { text } as EuiBreadcrumb; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx index 61a066bb92216f..2aee224304f89b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx @@ -4,12 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../__mocks__/shallow_usecontext.mock'; +import '../../__mocks__/kea.mock'; +import '../../__mocks__/shallow_useeffect.mock'; import '../../__mocks__/react_router_history.mock'; +import { mockKibanaValues } from '../../__mocks__'; import React from 'react'; - -import { mockKibanaContext, mountWithKibanaContext } from '../../__mocks__'; +import { shallow } from 'enzyme'; jest.mock('./generate_breadcrumbs', () => ({ useEnterpriseSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), @@ -37,13 +38,13 @@ describe('Set Kibana Chrome helpers', () => { }); afterEach(() => { - expect(mockKibanaContext.setBreadcrumbs).toHaveBeenCalled(); - expect(mockKibanaContext.setDocTitle).toHaveBeenCalled(); + expect(mockKibanaValues.setBreadcrumbs).toHaveBeenCalled(); + expect(mockKibanaValues.setDocTitle).toHaveBeenCalled(); }); describe('SetEnterpriseSearchChrome', () => { it('sets breadcrumbs and document title', () => { - mountWithKibanaContext(); + shallow(); expect(enterpriseSearchTitle).toHaveBeenCalledWith(['Hello World']); expect(useEnterpriseSearchBreadcrumbs).toHaveBeenCalledWith([ @@ -55,7 +56,7 @@ describe('Set Kibana Chrome helpers', () => { }); it('sets empty breadcrumbs and document title when isRoot is true', () => { - mountWithKibanaContext(); + shallow(); expect(enterpriseSearchTitle).toHaveBeenCalledWith([]); expect(useEnterpriseSearchBreadcrumbs).toHaveBeenCalledWith([]); @@ -64,7 +65,7 @@ describe('Set Kibana Chrome helpers', () => { describe('SetAppSearchChrome', () => { it('sets breadcrumbs and document title', () => { - mountWithKibanaContext(); + shallow(); expect(appSearchTitle).toHaveBeenCalledWith(['Engines']); expect(useAppSearchBreadcrumbs).toHaveBeenCalledWith([ @@ -76,7 +77,7 @@ describe('Set Kibana Chrome helpers', () => { }); it('sets empty breadcrumbs and document title when isRoot is true', () => { - mountWithKibanaContext(); + shallow(); expect(appSearchTitle).toHaveBeenCalledWith([]); expect(useAppSearchBreadcrumbs).toHaveBeenCalledWith([]); @@ -85,7 +86,7 @@ describe('Set Kibana Chrome helpers', () => { describe('SetWorkplaceSearchChrome', () => { it('sets breadcrumbs and document title', () => { - mountWithKibanaContext(); + shallow(); expect(workplaceSearchTitle).toHaveBeenCalledWith(['Sources']); expect(useWorkplaceSearchBreadcrumbs).toHaveBeenCalledWith([ @@ -97,7 +98,7 @@ describe('Set Kibana Chrome helpers', () => { }); it('sets empty breadcrumbs and document title when isRoot is true', () => { - mountWithKibanaContext(); + shallow(); expect(workplaceSearchTitle).toHaveBeenCalledWith([]); expect(useWorkplaceSearchBreadcrumbs).toHaveBeenCalledWith([]); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx index 5e8d972e1a1355..2ae3ca0137d548 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext, useEffect } from 'react'; +import React, { useEffect } from 'react'; +import { useValues } from 'kea'; import { useHistory } from 'react-router-dom'; import { EuiBreadcrumb } from '@elastic/eui'; -import { KibanaContext, IKibanaContext } from '../../index'; +import { KibanaLogic } from '../kibana'; + import { useEnterpriseSearchBreadcrumbs, useAppSearchBreadcrumbs, @@ -41,7 +43,7 @@ type TBreadcrumbsProps = IBreadcrumbsProps | IRootBreadcrumbsProps; export const SetEnterpriseSearchChrome: React.FC = ({ text, isRoot }) => { const history = useHistory(); - const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; + const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic); const title = isRoot ? [] : [text]; const docTitle = enterpriseSearchTitle(title as TTitle | []); @@ -59,7 +61,7 @@ export const SetEnterpriseSearchChrome: React.FC = ({ text, i export const SetAppSearchChrome: React.FC = ({ text, isRoot }) => { const history = useHistory(); - const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; + const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic); const title = isRoot ? [] : [text]; const docTitle = appSearchTitle(title as TTitle | []); @@ -77,7 +79,7 @@ export const SetAppSearchChrome: React.FC = ({ text, isRoot } export const SetWorkplaceSearchChrome: React.FC = ({ text, isRoot }) => { const history = useHistory(); - const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; + const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic); const title = isRoot ? [] : [text]; const docTitle = workplaceSearchTitle(title as TTitle | []); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx index 0c7bac99085dd5..eba632d86dc662 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../__mocks__/shallow_usecontext.mock'; +import '../../__mocks__/kea.mock'; import '../../__mocks__/react_router_history.mock'; import React from 'react'; import { shallow, mount } from 'enzyme'; import { EuiLink, EuiButton } from '@elastic/eui'; -import { mockKibanaContext, mockHistory } from '../../__mocks__'; +import { mockKibanaValues, mockHistory } from '../../__mocks__'; import { EuiReactRouterLink, EuiReactRouterButton } from './eui_link'; @@ -69,7 +69,7 @@ describe('EUI & React Router Component Helpers', () => { wrapper.find(EuiLink).simulate('click', simulatedEvent); expect(simulatedEvent.preventDefault).toHaveBeenCalled(); - expect(mockKibanaContext.navigateToUrl).toHaveBeenCalled(); + expect(mockKibanaValues.navigateToUrl).toHaveBeenCalled(); }); it('does not prevent default browser behavior on new tab/window clicks', () => { @@ -81,7 +81,7 @@ describe('EUI & React Router Component Helpers', () => { }; wrapper.find(EuiLink).simulate('click', simulatedEvent); - expect(mockKibanaContext.navigateToUrl).not.toHaveBeenCalled(); + expect(mockKibanaValues.navigateToUrl).not.toHaveBeenCalled(); }); it('calls inherited onClick actions in addition to default navigation', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx index e3b46632ddf9e6..99314515f2734f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx @@ -4,11 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; +import { useValues } from 'kea'; import { useHistory } from 'react-router-dom'; import { EuiLink, EuiButton, EuiButtonProps, EuiLinkAnchorProps } from '@elastic/eui'; -import { KibanaContext, IKibanaContext } from '../../index'; +import { KibanaLogic } from '../../shared/kibana'; import { letBrowserHandleEvent } from './link_events'; /** @@ -33,7 +34,7 @@ export const EuiReactRouterHelper: React.FC = ({ children, }) => { const history = useHistory(); - const { navigateToUrl } = useContext(KibanaContext) as IKibanaContext; + const { navigateToUrl } = useValues(KibanaLogic); // Generate the correct link href (with basename etc. accounted for) const href = shouldNotCreateHref ? to : history.createHref({ pathname: to }); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx index 0423ae61779af1..802a10e3b3db76 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import { EuiSteps, EuiIcon, EuiLink } from '@elastic/eui'; -import { mountWithContext } from '../../__mocks__'; +import { mountWithIntl } from '../../__mocks__'; import { SetupGuide } from './'; @@ -27,7 +27,7 @@ describe('SetupGuide', () => { }); it('renders with optional auth links', () => { - const wrapper = mountWithContext( + const wrapper = mountWithIntl( { it('renders WorkplaceSearchUnconfigured when config.host is not set', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); + (useValues as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); const wrapper = shallow(); expect(wrapper.find(WorkplaceSearchUnconfigured)).toHaveLength(1); }); it('renders WorkplaceSearchConfigured when config.host set', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'some.url' } })); + (useValues as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'some.url' } })); const wrapper = shallow(); expect(wrapper.find(WorkplaceSearchConfigured)).toHaveLength(1); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx index a68dfaf8ea4711..4769358a3eb306 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext, useEffect } from 'react'; +import React, { useEffect } from 'react'; import { Route, Redirect, Switch } from 'react-router-dom'; import { useActions, useValues } from 'kea'; import { WORKPLACE_SEARCH_PLUGIN } from '../../../common/constants'; import { IInitialAppData } from '../../../common/types'; -import { KibanaContext, IKibanaContext } from '../index'; +import { KibanaLogic } from '../shared/kibana'; import { HttpLogic } from '../shared/http'; import { AppLogic } from './app_logic'; import { Layout } from '../shared/layout'; @@ -24,7 +24,7 @@ import { NotFound } from '../shared/not_found'; import { Overview } from './views/overview'; export const WorkplaceSearch: React.FC = (props) => { - const { config } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); return !config.host ? : ; }; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx index ab5cd7f0de90fb..a757e187da0980 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/shallow_usecontext.mock'; - import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx index d9b05c5da777df..d9d03245f6141d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/shallow_usecontext.mock'; import './__mocks__/overview_logic.mock'; import { setMockValues } from './__mocks__';