diff --git a/public/app/core/navigation/RouterDebugger.tsx b/public/app/core/navigation/RouterDebugger.tsx index abc6f9f66cc..f1e165edc8b 100644 --- a/public/app/core/navigation/RouterDebugger.tsx +++ b/public/app/core/navigation/RouterDebugger.tsx @@ -1,4 +1,4 @@ -import { Link } from 'react-router-dom'; +import { Link } from 'react-router-dom-v5-compat'; import { getAppRoutes } from '../../routes/routes'; import { PageContents } from '../components/Page/PageContents'; diff --git a/public/app/features/alerting/unified/MuteTimings.test.tsx b/public/app/features/alerting/unified/MuteTimings.test.tsx index 6e3eba6611d..ad600a490f5 100644 --- a/public/app/features/alerting/unified/MuteTimings.test.tsx +++ b/public/app/features/alerting/unified/MuteTimings.test.tsx @@ -1,7 +1,6 @@ import { InitialEntry } from 'history'; import { last } from 'lodash'; -import { ReactNode } from 'react'; -import { Route } from 'react-router'; +import { Route, Routes } from 'react-router-dom-v5-compat'; import { render, screen, userEvent, within } from 'test/test-utils'; import { byRole, byTestId, byText } from 'testing-library-selector'; @@ -24,14 +23,16 @@ import { grantUserPermissions, mockDataSource } from './mocks'; import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; const indexPageText = 'redirected routes page'; -const renderMuteTimings = (component: ReactNode, location?: InitialEntry) => { +const Index = () => { + return
{indexPageText}
; +}; +const renderMuteTimings = (location?: InitialEntry) => { render( - <> - - {indexPageText} - - {component} - , + + } /> + } /> + } /> + , { historyOptions: location ? { initialEntries: [location] } : undefined } ); }; @@ -213,7 +214,7 @@ describe('Mute timings', () => { it('creates a new mute timing, with mute_time_intervals in config', async () => { const capture = captureRequests(); - renderMuteTimings(); + renderMuteTimings('/alerting/routes/new'); await screen.findByText(/add mute timing/i); @@ -240,9 +241,7 @@ describe('Mute timings', () => { it('creates a new mute timing, with time_intervals in config', async () => { const capture = captureRequests(); setAlertmanagerConfig(dataSources.am.uid, defaultConfigWithNewTimeIntervalsField); - renderMuteTimings(, { - search: `?alertmanager=${dataSources.am.name}`, - }); + renderMuteTimings({ pathname: '/alerting/routes/new', search: `?alertmanager=${dataSources.am.name}` }); await fillOutForm({ name: 'maintenance period', @@ -264,9 +263,7 @@ describe('Mute timings', () => { it('creates a new mute timing, with time_intervals and mute_time_intervals in config', async () => { setAlertmanagerConfig(dataSources.am.uid, defaultConfigWithBothTimeIntervalsField); - renderMuteTimings(, { - search: `?alertmanager=${dataSources.am.name}`, - }); + renderMuteTimings({ pathname: '/alerting/routes/new', search: `?alertmanager=${dataSources.am.name}` }); expect(ui.nameField.get()).toBeInTheDocument(); @@ -285,7 +282,8 @@ describe('Mute timings', () => { it('prepopulates the form when editing a mute timing', async () => { const capture = captureRequests(); - renderMuteTimings(, { + renderMuteTimings({ + pathname: '/alerting/routes/edit', search: `?muteName=${encodeURIComponent(muteTimeInterval.name)}`, }); @@ -325,7 +323,7 @@ describe('Mute timings', () => { }); it('form is invalid with duplicate mute timing name', async () => { - renderMuteTimings(); + renderMuteTimings('/alerting/routes/new'); await fillOutForm({ name: muteTimeInterval.name, days: '1' }); @@ -335,7 +333,8 @@ describe('Mute timings', () => { }); it('replaces mute timings in routes when the mute timing name is changed', async () => { - renderMuteTimings(, { + renderMuteTimings({ + pathname: '/alerting/routes/edit', search: `?muteName=${encodeURIComponent(muteTimeInterval.name)}`, }); @@ -350,7 +349,8 @@ describe('Mute timings', () => { }); it('shows error when mute timing does not exist', async () => { - renderMuteTimings(, { + renderMuteTimings({ + pathname: '/alerting/routes/edit', search: `?alertmanager=${GRAFANA_RULES_SOURCE_NAME}&muteName=${'does not exist'}`, }); @@ -363,7 +363,7 @@ describe('Mute timings', () => { }); it('allows creation of new mute timings', async () => { - renderMuteTimings(); + renderMuteTimings('/alerting/routes/new'); await fillOutForm({ name: 'a new mute timing' }); @@ -372,7 +372,8 @@ describe('Mute timings', () => { }); it('shows error when mute timing does not exist', async () => { - renderMuteTimings(, { + renderMuteTimings({ + pathname: '/alerting/routes/edit', search: `?alertmanager=${GRAFANA_RULES_SOURCE_NAME}&muteName=${TIME_INTERVAL_NAME_HAPPY_PATH + '_force_breakage'}`, }); @@ -380,7 +381,8 @@ describe('Mute timings', () => { }); it('loads edit form correctly and allows saving', async () => { - renderMuteTimings(, { + renderMuteTimings({ + pathname: '/alerting/routes/edit', search: `?alertmanager=${GRAFANA_RULES_SOURCE_NAME}&muteName=${TIME_INTERVAL_NAME_HAPPY_PATH}`, }); @@ -389,7 +391,8 @@ describe('Mute timings', () => { }); it('loads view form for provisioned interval', async () => { - renderMuteTimings(, { + renderMuteTimings({ + pathname: '/alerting/routes/edit', search: `?muteName=${TIME_INTERVAL_NAME_FILE_PROVISIONED}`, }); diff --git a/public/app/features/alerting/unified/components/receivers/NewReceiverView.test.tsx b/public/app/features/alerting/unified/components/receivers/NewReceiverView.test.tsx index 9f0b8b7620b..b0509065b58 100644 --- a/public/app/features/alerting/unified/components/receivers/NewReceiverView.test.tsx +++ b/public/app/features/alerting/unified/components/receivers/NewReceiverView.test.tsx @@ -1,5 +1,5 @@ import 'core-js/stable/structured-clone'; -import { Route } from 'react-router'; +import { Routes, Route } from 'react-router-dom-v5-compat'; import { render, screen } from 'test/test-utils'; import { byLabelText, byPlaceholderText, byRole, byTestId } from 'testing-library-selector'; @@ -9,23 +9,22 @@ import { AccessControlAction } from 'app/types'; import { setupMswServer } from '../../mockApi'; import { grantUserPermissions } from '../../mocks'; -import { AlertmanagerProvider } from '../../state/AlertmanagerContext'; import { testWithFeatureToggles } from '../../test/test-utils'; import NewReceiverView from './NewReceiverView'; setupMswServer(); +const Index = () => { + return
redirected
; +}; + const renderForm = () => render( - - - - - - redirected - - , + + } /> + } /> + , { historyOptions: { initialEntries: ['/alerting/notifications/new'] }, } diff --git a/public/app/features/dashboard-scene/sharing/ShareDrawer/ShareDrawer.test.tsx b/public/app/features/dashboard-scene/sharing/ShareDrawer/ShareDrawer.test.tsx index b2772d5f856..5e7e71ee6b3 100644 --- a/public/app/features/dashboard-scene/sharing/ShareDrawer/ShareDrawer.test.tsx +++ b/public/app/features/dashboard-scene/sharing/ShareDrawer/ShareDrawer.test.tsx @@ -23,15 +23,6 @@ jest.mock('@grafana/runtime', () => ({ useChromeHeaderHeight: jest.fn(), })); -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useLocation: jest.fn().mockReturnValue({ - pathname: '/d/dash-1', - hash: '', - state: null, - }), -})); - describe('ShareDrawer', () => { it('removes shareView query param from url when it is closed', async () => { const { dashboard } = await buildAndRenderScenario(); diff --git a/public/app/features/dashboard/components/GenAI/GenAIButton.test.tsx b/public/app/features/dashboard/components/GenAI/GenAIButton.test.tsx index b6c94f6fa87..ab003448e23 100644 --- a/public/app/features/dashboard/components/GenAI/GenAIButton.test.tsx +++ b/public/app/features/dashboard/components/GenAI/GenAIButton.test.tsx @@ -1,10 +1,9 @@ -import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { fireEvent, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { Router } from 'react-router-dom'; import { Observable } from 'rxjs'; +import { render } from 'test/test-utils'; import { selectors } from '@grafana/e2e-selectors'; -import { locationService } from '@grafana/runtime'; import { GenAIButton, GenAIButtonProps } from './GenAIButton'; import { StreamStatus, useOpenAIStream } from './hooks'; @@ -33,11 +32,7 @@ describe('GenAIButton', () => { const eventTrackingSrc = EventTrackingSrc.unknown; function setup(props: GenAIButtonProps = { onGenerate, messages: [], eventTrackingSrc }) { - return render( - - - - ); + return render(); } describe('when LLM plugin is not configured', () => { diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.test.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.test.tsx index 374a8fd5e80..2a04e5aa045 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.test.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.test.tsx @@ -28,12 +28,6 @@ standardFieldConfigEditorRegistry.setInit(getAllStandardFieldConfigs); const mockStore = configureMockStore(); const OptionsPaneSelector = selectors.components.PanelEditor.OptionsPane; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useLocation: () => ({ - pathname: 'localhost:3000/example/path', - }), -})); class OptionsPaneOptionsTestScenario { onFieldConfigsChange = jest.fn(); diff --git a/public/app/features/scopes/internal/ScopesDashboardsTreeDashboardItem.tsx b/public/app/features/scopes/internal/ScopesDashboardsTreeDashboardItem.tsx index ce84b86c0cb..5566deebb66 100644 --- a/public/app/features/scopes/internal/ScopesDashboardsTreeDashboardItem.tsx +++ b/public/app/features/scopes/internal/ScopesDashboardsTreeDashboardItem.tsx @@ -1,5 +1,5 @@ import { css } from '@emotion/css'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router-dom-v5-compat'; import { GrafanaTheme2, urlUtil } from '@grafana/data'; import { Icon, useStyles2 } from '@grafana/ui'; diff --git a/public/app/plugins/datasource/alertmanager/ConfigEditor.tsx b/public/app/plugins/datasource/alertmanager/ConfigEditor.tsx index 748fb691ce0..24bc89e9b90 100644 --- a/public/app/plugins/datasource/alertmanager/ConfigEditor.tsx +++ b/public/app/plugins/datasource/alertmanager/ConfigEditor.tsx @@ -1,6 +1,6 @@ import { produce } from 'immer'; import { useEffect } from 'react'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router-dom-v5-compat'; import { SIGV4ConnectionConfig } from '@grafana/aws-sdk'; import { DataSourcePluginOptionsEditorProps, SelectableValue } from '@grafana/data';