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 351ebc08d382a..0a1edee4643c7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts @@ -12,10 +12,7 @@ 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_useeffect must be imported directly as a file 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 0000000000000..a33e116c7ca72 --- /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 646c3104c286f..0000000000000 --- 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 0000000000000..55abe1030544f --- /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/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 44afce96c1a6c..f87ea2d422780 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 c66fd24fee12a..4d97a16991b71 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/shared/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx index 0423ae61779af..802a10e3b3db7 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(