From b88e211313ed5768dc2d69b6f263243d2c18baab Mon Sep 17 00:00:00 2001 From: Davis McPhee Date: Wed, 22 Nov 2023 21:15:44 -0400 Subject: [PATCH] Fix types and Jest tests --- .../public/__mocks__/discover_state.mock.ts | 4 ++ .../application/discover_router.test.tsx | 42 ++++++++++++++++--- .../public/application/discover_router.tsx | 2 +- .../layout/__stories__/get_layout_props.ts | 9 +++- .../top_nav/discover_topnav.test.tsx | 2 - .../top_nav/on_save_search.test.tsx | 4 ++ .../main/discover_main_route.test.tsx | 8 +++- .../main/services/discover_state.test.ts | 32 ++++++++++---- src/plugins/discover/public/mocks.tsx | 1 + src/plugins/discover/public/plugin.tsx | 2 +- .../public/top_nav_menu/top_nav_menu.test.tsx | 18 ++++---- .../log_explorer/log_explorer_locator.test.ts | 1 + 12 files changed, 95 insertions(+), 30 deletions(-) diff --git a/src/plugins/discover/public/__mocks__/discover_state.mock.ts b/src/plugins/discover/public/__mocks__/discover_state.mock.ts index 3e0a36de1d595e0..60e790cd7521816 100644 --- a/src/plugins/discover/public/__mocks__/discover_state.mock.ts +++ b/src/plugins/discover/public/__mocks__/discover_state.mock.ts @@ -23,6 +23,10 @@ export function getDiscoverStateMock({ const container = getDiscoverStateContainer({ services: discoverServiceMock, history, + customizationContext: { + displayMode: 'standalone', + showLogExplorerTabs: false, + }, }); container.savedSearchState.set( savedSearch ? savedSearch : isTimeBased ? savedSearchMockWithTimeField : savedSearchMock diff --git a/src/plugins/discover/public/application/discover_router.test.tsx b/src/plugins/discover/public/application/discover_router.test.tsx index d151963ce921a1a..3d58d065129697b 100644 --- a/src/plugins/discover/public/application/discover_router.test.tsx +++ b/src/plugins/discover/public/application/discover_router.test.tsx @@ -11,13 +11,19 @@ import { Redirect, RouteProps } from 'react-router-dom'; import { Route } from '@kbn/shared-ux-router'; import { createSearchSessionMock } from '../__mocks__/search_session'; import { discoverServiceMock as mockDiscoverServices } from '../__mocks__/services'; -import { CustomDiscoverRoutes, DiscoverRouter, DiscoverRoutes } from './discover_router'; +import { + CustomDiscoverRoutes, + DiscoverRouter, + DiscoverRoutes, + DiscoverRoutesProps, +} from './discover_router'; import { DiscoverMainRoute } from './main'; import { SingleDocRoute } from './doc'; import { ContextAppRoute } from './context'; import { createProfileRegistry } from '../customizations/profile_registry'; import { addProfile } from '../../common/customizations'; import { NotFoundRoute } from './not_found'; +import type { DiscoverCustomizationContext } from './types'; let mockProfile: string | undefined; @@ -43,9 +49,15 @@ const gatherRoutes = (wrapper: ShallowWrapper) => { }); }; -const props = { +const customizationContext: DiscoverCustomizationContext = { + displayMode: 'standalone', + showLogExplorerTabs: false, +}; + +const props: DiscoverRoutesProps = { isDev: false, customizationCallbacks: [], + customizationContext, }; describe('DiscoverRoutes', () => { @@ -147,12 +159,17 @@ describe('CustomDiscoverRoutes', () => { it('should show DiscoverRoutes for a valid profile', () => { mockProfile = 'test'; const component = shallow( - + ); expect(component.find(DiscoverRoutes).getElement()).toMatchObject( ); @@ -161,7 +178,11 @@ describe('CustomDiscoverRoutes', () => { it('should show NotFoundRoute for an invalid profile', () => { mockProfile = 'invalid'; const component = shallow( - + ); expect(component.find(NotFoundRoute).getElement()).toMatchObject(); }); @@ -178,6 +199,7 @@ describe('DiscoverRouter', () => { services={mockDiscoverServices} history={history} profileRegistry={profileRegistry} + customizationContext={customizationContext} isDev={props.isDev} /> ); @@ -186,13 +208,21 @@ describe('DiscoverRouter', () => { it('should show DiscoverRoutes component for / route', () => { expect(pathMap['/']).toMatchObject( - + ); }); it(`should show CustomDiscoverRoutes component for ${profilePath} route`, () => { expect(pathMap[profilePath]).toMatchObject( - + ); }); }); diff --git a/src/plugins/discover/public/application/discover_router.tsx b/src/plugins/discover/public/application/discover_router.tsx index d6deda6ce5c6fa1..5e146a768baa117 100644 --- a/src/plugins/discover/public/application/discover_router.tsx +++ b/src/plugins/discover/public/application/discover_router.tsx @@ -23,7 +23,7 @@ import type { DiscoverProfileRegistry } from '../customizations/profile_registry import { addProfile } from '../../common/customizations'; import type { DiscoverCustomizationContext } from './types'; -interface DiscoverRoutesProps { +export interface DiscoverRoutesProps { prefix?: string; customizationCallbacks: CustomizationCallback[]; customizationContext: DiscoverCustomizationContext; diff --git a/src/plugins/discover/public/application/main/components/layout/__stories__/get_layout_props.ts b/src/plugins/discover/public/application/main/components/layout/__stories__/get_layout_props.ts index 5a5c2bb0396835f..54d2dc5da0084d6 100644 --- a/src/plugins/discover/public/application/main/components/layout/__stories__/get_layout_props.ts +++ b/src/plugins/discover/public/application/main/components/layout/__stories__/get_layout_props.ts @@ -15,7 +15,7 @@ import { createHashHistory } from 'history'; import { SavedSearch } from '@kbn/saved-search-plugin/public'; import { buildDataTableRecordList } from '@kbn/discover-utils'; import { esHitsMock } from '@kbn/discover-utils/src/__mocks__'; -import { FetchStatus } from '../../../../types'; +import { DiscoverCustomizationContext, FetchStatus } from '../../../../types'; import { AvailableFields$, DataDocuments$, @@ -124,11 +124,17 @@ function getSavedSearch(dataView: DataView) { } as unknown as SavedSearch; } +const customizationContext: DiscoverCustomizationContext = { + displayMode: 'standalone', + showLogExplorerTabs: false, +}; + export function getDocumentsLayoutProps(dataView: DataView) { const stateContainer = getDiscoverStateContainer({ history: createHashHistory(), savedSearch: getSavedSearch(dataView), services, + customizationContext, }); stateContainer.appState.set({ columns: ['name', 'message', 'bytes'], @@ -153,6 +159,7 @@ export const getPlainRecordLayoutProps = (dataView: DataView) => { history: createHashHistory(), savedSearch: getSavedSearch(dataView), services, + customizationContext, }); stateContainer.appState.set({ columns: ['name', 'message', 'bytes'], diff --git a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.test.tsx b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.test.tsx index 50e8b9e16a41877..548470ae8213493 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.test.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.test.tsx @@ -11,7 +11,6 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import { dataViewMock } from '@kbn/discover-utils/src/__mocks__'; import { DiscoverTopNav, DiscoverTopNavProps } from './discover_topnav'; import { TopNavMenu, TopNavMenuData } from '@kbn/navigation-plugin/public'; -import { Query } from '@kbn/es-query'; import { setHeaderActionMenuMounter } from '../../../../kibana_services'; import { discoverServiceMock as mockDiscoverService } from '../../../../__mocks__/services'; import { getDiscoverStateMock } from '../../../../__mocks__/discover_state.mock'; @@ -77,7 +76,6 @@ function getProps( return { stateContainer, - query: {} as Query, savedQuery: '', updateQuery: jest.fn(), onOpenInspector: jest.fn(), diff --git a/src/plugins/discover/public/application/main/components/top_nav/on_save_search.test.tsx b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.test.tsx index 5506010528e05c0..1d422baf238fff9 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/on_save_search.test.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.test.tsx @@ -25,6 +25,10 @@ function getStateContainer({ dataView }: { dataView?: DataView } = {}) { const stateContainer = getDiscoverStateContainer({ services: discoverServiceMock, history, + customizationContext: { + displayMode: 'standalone', + showLogExplorerTabs: false, + }, }); stateContainer.savedSearchState.set(savedSearch); stateContainer.appState.getState = jest.fn(() => ({ diff --git a/src/plugins/discover/public/application/main/discover_main_route.test.tsx b/src/plugins/discover/public/application/main/discover_main_route.test.tsx index 560f998b4bd94e0..251b6dca262c834 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.test.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.test.tsx @@ -11,7 +11,7 @@ import { waitFor } from '@testing-library/react'; import { setHeaderActionMenuMounter, setScopedHistory } from '../../kibana_services'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { discoverServiceMock } from '../../__mocks__/services'; -import { DiscoverMainRoute } from './discover_main_route'; +import { DiscoverMainRoute, MainRouteProps } from './discover_main_route'; import { MemoryRouter } from 'react-router-dom'; import { DiscoverMainApp } from './discover_main_app'; import { findTestSubject } from '@elastic/eui/lib/test'; @@ -101,9 +101,13 @@ describe('DiscoverMainRoute', () => { }); const mountComponent = (hasESData = true, hasUserDataView = true) => { - const props = { + const props: MainRouteProps = { isDev: false, customizationCallbacks: [], + customizationContext: { + displayMode: 'standalone', + showLogExplorerTabs: false, + }, }; return mountWithIntl( diff --git a/src/plugins/discover/public/application/main/services/discover_state.test.ts b/src/plugins/discover/public/application/main/services/discover_state.test.ts index 5e230894fa4ceeb..a14a7d3b797c670 100644 --- a/src/plugins/discover/public/application/main/services/discover_state.test.ts +++ b/src/plugins/discover/public/application/main/services/discover_state.test.ts @@ -22,9 +22,9 @@ import { } from '../../../__mocks__/saved_search'; import { discoverServiceMock } from '../../../__mocks__/services'; import { dataViewMock } from '@kbn/discover-utils/src/__mocks__'; -import { DiscoverAppStateContainer } from './discover_app_state_container'; +import type { DiscoverAppStateContainer } from './discover_app_state_container'; import { waitFor } from '@testing-library/react'; -import { FetchStatus } from '../../types'; +import { DiscoverCustomizationContext, FetchStatus } from '../../types'; import { dataViewAdHoc, dataViewComplexMock } from '../../../__mocks__/data_view_complex'; import { copySavedSearch } from './discover_saved_search_container'; @@ -34,6 +34,11 @@ const startSync = (appState: DiscoverAppStateContainer) => { return stop; }; +const customizationContext: DiscoverCustomizationContext = { + displayMode: 'standalone', + showLogExplorerTabs: false, +}; + async function getState( url: string = '/', { savedSearch, isEmptyUrl }: { savedSearch?: SavedSearch; isEmptyUrl?: boolean } = {} @@ -51,6 +56,7 @@ async function getState( const nextState = getDiscoverStateContainer({ services: discoverServiceMock, history: nextHistory, + customizationContext, }); nextState.appState.isEmptyURL = jest.fn(() => isEmptyUrl ?? true); jest.spyOn(nextState.dataState, 'fetch'); @@ -87,9 +93,10 @@ describe('Test discover state', () => { state = getDiscoverStateContainer({ services: discoverServiceMock, history, + customizationContext, }); state.savedSearchState.set(savedSearchMock); - await state.appState.update({}, true); + state.appState.update({}, true); stopSync = startSync(state.appState); }); afterEach(() => { @@ -137,7 +144,10 @@ describe('Test discover state', () => { test('pauseAutoRefreshInterval sets refreshInterval.pause to true', async () => { history.push('/#?_g=(refreshInterval:(pause:!f,value:5000))'); expect(getCurrentUrl()).toBe('/#?_g=(refreshInterval:(pause:!f,value:5000))'); - await state.actions.setDataView(dataViewMock); + // TODO: state.actions.setDataView should be async because it calls pauseAutoRefreshInterval which is async. + // I found this bug while removing unnecessary awaits, but it will need to be fixed in a follow up PR. + state.actions.setDataView(dataViewMock); + await new Promise(process.nextTick); expect(getCurrentUrl()).toBe('/#?_g=(refreshInterval:(pause:!t,value:5000))'); }); }); @@ -190,6 +200,7 @@ describe('Test createSearchSessionRestorationDataProvider', () => { const discoverStateContainer = getDiscoverStateContainer({ services: discoverServiceMock, history, + customizationContext, }); discoverStateContainer.appState.update({ index: savedSearchMock.searchSource.getField('index')!.id, @@ -661,9 +672,9 @@ describe('Test discover state actions', () => { const { state } = await getState('/', { savedSearch: savedSearchMock }); const unsubscribe = state.actions.initializeAndSync(); await state.actions.loadSavedSearch({ savedSearchId: savedSearchMock.id }); - await state.savedSearchState.update({ nextState: { hideChart: true } }); + state.savedSearchState.update({ nextState: { hideChart: true } }); expect(state.savedSearchState.getState().hideChart).toBe(true); - await state.actions.onOpenSavedSearch(savedSearchMock.id!); + state.actions.onOpenSavedSearch(savedSearchMock.id!); expect(state.savedSearchState.getState().hideChart).toBe(undefined); unsubscribe(); }); @@ -756,16 +767,21 @@ describe('Test discover state with embedded mode', () => { state = getDiscoverStateContainer({ services: discoverServiceMock, history, - displayMode: 'embedded', + customizationContext: { + ...customizationContext, + displayMode: 'embedded', + }, }); state.savedSearchState.set(savedSearchMock); - await state.appState.update({}, true); + state.appState.update({}, true); stopSync = startSync(state.appState); }); + afterEach(() => { stopSync(); stopSync = () => {}; }); + test('setting app state and syncing to URL', async () => { state.appState.update({ index: 'modified' }); await new Promise(process.nextTick); diff --git a/src/plugins/discover/public/mocks.tsx b/src/plugins/discover/public/mocks.tsx index e97c8f5a841a24d..bef23a464a793ce 100644 --- a/src/plugins/discover/public/mocks.tsx +++ b/src/plugins/discover/public/mocks.tsx @@ -17,6 +17,7 @@ export type Start = jest.Mocked; const createSetupContract = (): Setup => { const setupContract: Setup = { locator: sharePluginMock.createLocator(), + showLogExplorerTabs: jest.fn(), }; return setupContract; }; diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index e41baa572dfbcf3..dc4e92e45d0bf4a 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -168,7 +168,6 @@ export interface DiscoverSetupPlugins { data: DataPublicPluginSetup; expressions: ExpressionsSetup; globalSearch?: GlobalSearchPluginSetup; - serverless?: ServerlessPluginStart; } /** @@ -200,6 +199,7 @@ export interface DiscoverStartPlugins { lens: LensPublicStart; contentManagement: ContentManagementPublicStart; noDataPage?: NoDataPagePluginStart; + serverless?: ServerlessPluginStart; } /** diff --git a/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx b/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx index 218c620519cf2cb..f7d17f68a00962e 100644 --- a/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx +++ b/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx @@ -12,7 +12,7 @@ import { act } from 'react-dom/test-utils'; import { MountPoint } from '@kbn/core/public'; import { TopNavMenu, TopNavMenuBadgeProps } from './top_nav_menu'; import { TopNavMenuData } from './top_nav_menu_data'; -import { shallowWithIntl, mountWithIntl } from '@kbn/test-jest-helpers'; +import { findTestSubject, mountWithIntl } from '@kbn/test-jest-helpers'; import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { EuiToolTipProps } from '@elastic/eui'; @@ -66,35 +66,35 @@ describe('TopNavMenu', () => { ]; it('Should render nothing when no config is provided', () => { - const component = shallowWithIntl(); + const component = mountWithIntl(); expect(component.find(WRAPPER_SELECTOR).length).toBe(0); expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(0); expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0); }); it('Should not render menu items when config is empty', () => { - const component = shallowWithIntl(); + const component = mountWithIntl(); expect(component.find(WRAPPER_SELECTOR).length).toBe(0); expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(0); expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0); }); it('Should render 1 menu item', () => { - const component = shallowWithIntl(); + const component = mountWithIntl(); expect(component.find(WRAPPER_SELECTOR).length).toBe(1); expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(1); expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0); }); it('Should render multiple menu items', () => { - const component = shallowWithIntl(); + const component = mountWithIntl(); expect(component.find(WRAPPER_SELECTOR).length).toBe(1); expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(menuItems.length); expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0); }); it('Should render search bar', () => { - const component = shallowWithIntl( + const component = mountWithIntl( ); expect(component.find(WRAPPER_SELECTOR).length).toBe(1); @@ -103,7 +103,7 @@ describe('TopNavMenu', () => { }); it('Should render menu items and search bar', () => { - const component = shallowWithIntl( + const component = mountWithIntl( { }); it('Should render with a class name', () => { - const component = shallowWithIntl( + const component = mountWithIntl( { className={'myCoolClass'} /> ); - expect(component.find('.kbnTopNavMenu').length).toBe(1); + expect(findTestSubject(component, 'top-nav').hasClass('kbnTopNavMenu')).toBe(true); expect(component.find('.myCoolClass').length).toBeTruthy(); }); diff --git a/x-pack/plugins/log_explorer/common/locators/log_explorer/log_explorer_locator.test.ts b/x-pack/plugins/log_explorer/common/locators/log_explorer/log_explorer_locator.test.ts index 2785def1f2927aa..ccac7cccd6dc131 100644 --- a/x-pack/plugins/log_explorer/common/locators/log_explorer/log_explorer_locator.test.ts +++ b/x-pack/plugins/log_explorer/common/locators/log_explorer/log_explorer_locator.test.ts @@ -13,6 +13,7 @@ const setup = async () => { const discoverSetupContract: LogExplorerLocatorDependencies = { discover: { locator: sharePluginMock.createLocator(), + showLogExplorerTabs: jest.fn(), }, }; const logExplorerLocator = new LogExplorerLocatorDefinition(discoverSetupContract);