From 601654766fbfa1c384c036a3b2a6032f10400882 Mon Sep 17 00:00:00 2001 From: Kawika Avilla Date: Sun, 9 Jul 2023 07:02:02 +0000 Subject: [PATCH] add more tests Signed-off-by: Kawika Avilla --- .../public/application/utils/index.ts | 2 +- .../utils/use/use_dashboard_app_state.test.ts | 7 +- .../utils/use/use_editor_updates.test.ts | 13 +--- .../utils/use/use_editor_updates.ts | 2 +- .../use/use_saved_dashboard_instance.test.ts | 73 ++++++++++++++++++ .../utils/use/use_saved_dashboard_instance.ts | 72 +++-------------- .../utils/{breadcrumbs.ts => utils.ts} | 77 +++++++++++++++++-- 7 files changed, 161 insertions(+), 85 deletions(-) create mode 100644 src/plugins/dashboard/public/application/utils/use/use_saved_dashboard_instance.test.ts rename src/plugins/dashboard/public/application/utils/{breadcrumbs.ts => utils.ts} (50%) diff --git a/src/plugins/dashboard/public/application/utils/index.ts b/src/plugins/dashboard/public/application/utils/index.ts index 3f96a94264bb..d25368890fb5 100644 --- a/src/plugins/dashboard/public/application/utils/index.ts +++ b/src/plugins/dashboard/public/application/utils/index.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -export * from './breadcrumbs'; +export * from './utils'; export * from './get_nav_actions'; export * from './get_no_items_message'; export * from './get_table_columns'; diff --git a/src/plugins/dashboard/public/application/utils/use/use_dashboard_app_state.test.ts b/src/plugins/dashboard/public/application/utils/use/use_dashboard_app_state.test.ts index 3b4840893de1..1d2c661876e2 100644 --- a/src/plugins/dashboard/public/application/utils/use/use_dashboard_app_state.test.ts +++ b/src/plugins/dashboard/public/application/utils/use/use_dashboard_app_state.test.ts @@ -12,6 +12,8 @@ import { DashboardServices } from '../../../types'; import { SavedObjectDashboard } from '../../../saved_dashboards'; import { dashboardAppStateStub } from '../stubs'; import { createDashboardServicesMock } from '../mocks'; +import { Dashboard } from '../../../dashboard'; +import { convertToSerializedDashboard } from '../../../saved_dashboards/_saved_dashboard'; jest.mock('../create_dashboard_app_state'); jest.mock('../create_dashboard_container.tsx'); @@ -28,7 +30,6 @@ describe('useDashboardAppAndGlobalState', () => { getState: stateContainerGetStateMock, state$: new Observable(), transitions: { - updateVisState: jest.fn(), set: jest.fn(), }, }; @@ -49,6 +50,8 @@ describe('useDashboardAppAndGlobalState', () => { optionsJSON: JSON.stringify(dashboardAppStateStub.options), }, } as unknown) as SavedObjectDashboard; + const dashboard = new Dashboard(convertToSerializedDashboard(savedDashboardInstance)); + let mockServices: jest.Mocked; beforeEach(() => { @@ -77,6 +80,7 @@ describe('useDashboardAppAndGlobalState', () => { services: mockServices, eventEmitter, savedDashboardInstance, + dashboard, }) ); @@ -106,6 +110,7 @@ describe('useDashboardAppAndGlobalState', () => { services: mockServices, eventEmitter, savedDashboardInstance, + dashboard, }) ); diff --git a/src/plugins/dashboard/public/application/utils/use/use_editor_updates.test.ts b/src/plugins/dashboard/public/application/utils/use/use_editor_updates.test.ts index 0faf9589a4f2..fe5554dc2407 100644 --- a/src/plugins/dashboard/public/application/utils/use/use_editor_updates.test.ts +++ b/src/plugins/dashboard/public/application/utils/use/use_editor_updates.test.ts @@ -13,7 +13,7 @@ import { dashboardAppStateStub } from '../stubs'; import { createDashboardServicesMock } from '../mocks'; import { Dashboard } from '../../../dashboard'; import { convertToSerializedDashboard } from '../../../saved_dashboards/_saved_dashboard'; -import { setBreadcrumbsForExistingDashboard, setBreadcrumbsForNewDashboard } from '../breadcrumbs'; +import { setBreadcrumbsForExistingDashboard, setBreadcrumbsForNewDashboard } from '../utils'; import { ViewMode } from '../../../embeddable_plugin'; describe('useEditorUpdates', () => { @@ -75,8 +75,6 @@ describe('useEditorUpdates', () => { let appState: DashboardAppStateContainer; let savedDashboardInstance: SavedObjectDashboard; let dashboard: Dashboard; - let timeRange: any; - let mockFilters: any; beforeEach(() => { unsubscribeStateUpdatesMock = jest.fn(); @@ -98,15 +96,6 @@ describe('useEditorUpdates', () => { }, } as unknown) as SavedObjectDashboard; dashboard = new Dashboard(convertToSerializedDashboard(savedDashboardInstance)); - timeRange = { - from: 'now-15m', - to: 'now', - }; - mockFilters = ['mockFilters']; - const mockQuery = { - query: '', - language: 'kuery', - }; }); test('should set up current app state and render the editor', () => { diff --git a/src/plugins/dashboard/public/application/utils/use/use_editor_updates.ts b/src/plugins/dashboard/public/application/utils/use/use_editor_updates.ts index fa6ea95b5f7c..58a31713435e 100644 --- a/src/plugins/dashboard/public/application/utils/use/use_editor_updates.ts +++ b/src/plugins/dashboard/public/application/utils/use/use_editor_updates.ts @@ -9,7 +9,7 @@ import { DashboardAppState, DashboardAppStateContainer, DashboardServices } from import { DashboardContainer } from '../../embeddable'; import { Dashboard } from '../../../dashboard'; import { SavedObjectDashboard } from '../../../saved_dashboards'; -import { setBreadcrumbsForExistingDashboard, setBreadcrumbsForNewDashboard } from '../breadcrumbs'; +import { setBreadcrumbsForExistingDashboard, setBreadcrumbsForNewDashboard } from '../utils'; export const useEditorUpdates = ({ eventEmitter, diff --git a/src/plugins/dashboard/public/application/utils/use/use_saved_dashboard_instance.test.ts b/src/plugins/dashboard/public/application/utils/use/use_saved_dashboard_instance.test.ts new file mode 100644 index 000000000000..74ad3b74dc47 --- /dev/null +++ b/src/plugins/dashboard/public/application/utils/use/use_saved_dashboard_instance.test.ts @@ -0,0 +1,73 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { renderHook } from '@testing-library/react-hooks'; +import { EventEmitter } from 'events'; + +import { useSavedDashboardInstance } from './use_saved_dashboard_instance'; +import { DashboardServices } from '../../../types'; +import { SavedObjectDashboard } from '../../../saved_dashboards'; +import { dashboardAppStateStub } from '../stubs'; +import { createDashboardServicesMock } from '../mocks'; +import { Dashboard } from '../../../dashboard'; +import { convertToSerializedDashboard } from '../../../saved_dashboards/_saved_dashboard'; + +// TODO: needs more setState tests on update +describe('useSavedDashboardInstance', () => { + const eventEmitter = new EventEmitter(); + let mockServices: jest.Mocked; + let isChromeVisible: boolean | undefined; + let dashboardIdFromUrl: string | undefined; + let savedDashboardInstance: SavedObjectDashboard; + let dashboard: Dashboard; + + beforeEach(() => { + mockServices = createDashboardServicesMock(); + isChromeVisible = true; + dashboardIdFromUrl = '1234'; + + savedDashboardInstance = ({ + ...dashboardAppStateStub, + ...{ + getQuery: () => dashboardAppStateStub.query, + getFilters: () => dashboardAppStateStub.filters, + optionsJSON: JSON.stringify(dashboardAppStateStub.options), + }, + } as unknown) as SavedObjectDashboard; + dashboard = new Dashboard(convertToSerializedDashboard(savedDashboardInstance)); + }); + + describe('should not set saved dashboard instance', () => { + test('if id ref is blank and dashboardIdFromUrl not updated', () => { + dashboardIdFromUrl = undefined; + + const { result } = renderHook(() => + useSavedDashboardInstance({ + services: mockServices, + eventEmitter, + isChromeVisible, + dashboardIdFromUrl, + }) + ); + + expect(result.current).toEqual({}); + }); + + test('if chrome is not visible', () => { + isChromeVisible = undefined; + + const { result } = renderHook(() => + useSavedDashboardInstance({ + services: mockServices, + eventEmitter, + isChromeVisible, + dashboardIdFromUrl, + }) + ); + + expect(result.current).toEqual({}); + }); + }); +}); diff --git a/src/plugins/dashboard/public/application/utils/use/use_saved_dashboard_instance.ts b/src/plugins/dashboard/public/application/utils/use/use_saved_dashboard_instance.ts index 1f09dc72c476..144c907aec3e 100644 --- a/src/plugins/dashboard/public/application/utils/use/use_saved_dashboard_instance.ts +++ b/src/plugins/dashboard/public/application/utils/use/use_saved_dashboard_instance.ts @@ -3,18 +3,17 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { i18n } from '@osd/i18n'; import { EventEmitter } from 'events'; import { useEffect, useRef, useState } from 'react'; -import { - redirectWhenMissing, - SavedObjectNotFound, -} from '../../../../../opensearch_dashboards_utils/public'; -import { DashboardConstants } from '../../../dashboard_constants'; import { DashboardServices } from '../../../types'; import { getDashboardInstance } from '../get_dashboard_instance'; import { SavedObjectDashboard } from '../../../saved_dashboards'; import { Dashboard, DashboardParams } from '../../../dashboard'; +import { + handleErrorFromDashboard, + handleErrorFromCreateDashboard, + handleErrorFromSavedDashboard, +} from '../utils'; /** * This effect is responsible for instantiating a saved dashboard or creating a new one @@ -38,60 +37,7 @@ export const useSavedDashboardInstance = ({ const dashboardId = useRef(''); useEffect(() => { - const { - application: { navigateToApp }, - chrome, - history, - http: { basePath }, - notifications, - toastNotifications, - data, - } = services; - - const handleErrorFromSavedDashboard = (error: any) => { - // Preserve BWC of v5.3.0 links for new, unsaved dashboards. - // See https://github.com/elastic/kibana/issues/10951 for more context. - if (error instanceof SavedObjectNotFound && dashboardIdFromUrl === 'create') { - // Note preserve querystring part is necessary so the state is preserved through the redirect. - history.replace({ - ...history.location, // preserve query, - pathname: DashboardConstants.CREATE_NEW_DASHBOARD_URL, - }); - - notifications.toasts.addWarning( - i18n.translate('dashboard.urlWasRemovedInSixZeroWarningMessage', { - defaultMessage: - 'The url "dashboard/create" was removed in 6.0. Please update your bookmarks.', - }) - ); - } else { - // E.g. a corrupt or deleted dashboard - notifications.toasts.addDanger(error.message); - history.replace(DashboardConstants.LANDING_PAGE_PATH); - } - return new Promise(() => {}); - }; - - const handleErrorFromCreateDashboard = () => { - redirectWhenMissing({ - history, - basePath, - navigateToApp, - mapping: { - dashboard: DashboardConstants.LANDING_PAGE_PATH, - }, - toastNotifications: notifications.toasts, - }); - }; - - const handleError = () => { - toastNotifications.addWarning({ - title: i18n.translate('dashboard.createDashboard.failedToLoadErrorMessage', { - defaultMessage: 'Failed to load the dashboard', - }), - }); - history.replace(DashboardConstants.LANDING_PAGE_PATH); - }; + const { chrome, history, data } = services; const getSavedDashboardInstance = async () => { try { @@ -104,7 +50,7 @@ export const useSavedDashboardInstance = ({ dashboardInstance = await getDashboardInstance(services); setSavedDashboardInstance(dashboardInstance); } catch { - handleErrorFromCreateDashboard(); + handleErrorFromCreateDashboard({ services }); } } else if (dashboardIdFromUrl) { try { @@ -131,11 +77,11 @@ export const useSavedDashboardInstance = ({ ); setSavedDashboardInstance(dashboardInstance); } catch (error: any) { - return handleErrorFromSavedDashboard(error); + return handleErrorFromSavedDashboard({ error, dashboardIdFromUrl, services }); } } } catch (error: any) { - handleError(); + handleErrorFromDashboard({ services }); } }; diff --git a/src/plugins/dashboard/public/application/utils/breadcrumbs.ts b/src/plugins/dashboard/public/application/utils/utils.ts similarity index 50% rename from src/plugins/dashboard/public/application/utils/breadcrumbs.ts rename to src/plugins/dashboard/public/application/utils/utils.ts index dbedf389b07c..29e489fd7dc4 100644 --- a/src/plugins/dashboard/public/application/utils/breadcrumbs.ts +++ b/src/plugins/dashboard/public/application/utils/utils.ts @@ -1,17 +1,16 @@ /* + * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Any modifications Copyright OpenSearch Contributors. See - * GitHub history for details. */ import { i18n } from '@osd/i18n'; import { DashboardConstants } from '../../dashboard_constants'; import { ViewMode } from '../../embeddable_plugin'; +import { + redirectWhenMissing, + SavedObjectNotFound, +} from '../../../../opensearch_dashboards_utils/public'; +import { DashboardServices } from '../../types'; export function getLandingBreadcrumbs() { return [ @@ -96,3 +95,67 @@ export const setBreadcrumbsForExistingDashboard = ( } } }; + +export const handleErrorFromSavedDashboard = ({ + error, + dashboardIdFromUrl, + services, +}: { + error: any; + dashboardIdFromUrl: string; + services: DashboardServices; +}) => { + const { history, notifications } = services; + + // Preserve BWC of v5.3.0 links for new, unsaved dashboards. + // See https://github.com/elastic/kibana/issues/10951 for more context. + if (error instanceof SavedObjectNotFound && dashboardIdFromUrl === 'create') { + // Note preserve querystring part is necessary so the state is preserved through the redirect. + history.replace({ + ...history.location, // preserve query, + pathname: DashboardConstants.CREATE_NEW_DASHBOARD_URL, + }); + + notifications.toasts.addWarning( + i18n.translate('dashboard.urlWasRemovedInSixZeroWarningMessage', { + defaultMessage: + 'The url "dashboard/create" was removed in 6.0. Please update your bookmarks.', + }) + ); + } else { + // E.g. a corrupt or deleted dashboard + notifications.toasts.addDanger(error.message); + history.replace(DashboardConstants.LANDING_PAGE_PATH); + } + return new Promise(() => {}); +}; + +export const handleErrorFromCreateDashboard = ({ services }: { services: DashboardServices }) => { + const { + application: { navigateToApp }, + history, + http: { basePath }, + notifications, + } = services; + + redirectWhenMissing({ + history, + basePath, + navigateToApp, + mapping: { + dashboard: DashboardConstants.LANDING_PAGE_PATH, + }, + toastNotifications: notifications.toasts, + }); +}; + +export const handleErrorFromDashboard = ({ services }: { services: DashboardServices }) => { + const { history, toastNotifications } = services; + + toastNotifications.addWarning({ + title: i18n.translate('dashboard.createDashboard.failedToLoadErrorMessage', { + defaultMessage: 'Failed to load the dashboard', + }), + }); + history.replace(DashboardConstants.LANDING_PAGE_PATH); +};