diff --git a/public/app/AppWrapper.tsx b/public/app/AppWrapper.tsx index 109a4e9d81f..879c4c5ad7d 100644 --- a/public/app/AppWrapper.tsx +++ b/public/app/AppWrapper.tsx @@ -5,7 +5,6 @@ import { Router, Route, Redirect, Switch } from 'react-router-dom'; import { config, locationService, navigationLogger, reportInteraction } from '@grafana/runtime'; import { ErrorBoundaryAlert, GlobalStyles, ModalRoot, ModalsProvider, PortalContainer } from '@grafana/ui'; -import { SearchWrapper } from 'app/features/search'; import { getAppRoutes } from 'app/routes/routes'; import { store } from 'app/store/store'; @@ -14,13 +13,11 @@ import { loadAndInitAngularIfEnabled } from './angular/loadAndInitAngularIfEnabl import { GrafanaApp } from './app'; import { AppChrome } from './core/components/AppChrome/AppChrome'; import { AppNotificationList } from './core/components/AppNotifications/AppNotificationList'; -import { NavBar } from './core/components/NavBar/NavBar'; import { GrafanaContext } from './core/context/GrafanaContext'; import { GrafanaRoute } from './core/navigation/GrafanaRoute'; import { RouteDescriptor } from './core/navigation/types'; import { contextSrv } from './core/services/context_srv'; import { ThemeProvider } from './core/utils/ConfigProvider'; -import { CommandPalette } from './features/commandPalette/CommandPalette'; import { LiveConnectionWarning } from './features/live/LiveConnectionWarning'; interface AppWrapperProps { @@ -82,23 +79,6 @@ export class AppWrapper extends React.Component{getAppRoutes().map((r) => this.renderRoute(r))}; } - renderNavBar() { - if (config.isPublicDashboardView || !this.state.ready || config.featureToggles.topnav) { - return null; - } - - return ; - } - - commandPaletteEnabled() { - const isLoginPage = locationService.getLocation().pathname === '/login'; - return config.featureToggles.commandPalette && !config.isPublicDashboardView && !isLoginPage; - } - - searchBarEnabled() { - return !config.isPublicDashboardView; - } - render() { const { app } = this.props; const { ready } = this.state; @@ -124,18 +104,14 @@ export class AppWrapper extends React.Component - {this.commandPaletteEnabled() && }
- {this.renderNavBar()} {pageBanners.map((Banner, index) => ( ))} - - {this.searchBarEnabled() && } {ready && this.renderRoutes()} {bodyRenderHooks.map((Hook, index) => ( diff --git a/public/app/angular/GrafanaCtrl.ts b/public/app/angular/GrafanaCtrl.ts index 3be2ee41e0c..edac9ec1961 100644 --- a/public/app/angular/GrafanaCtrl.ts +++ b/public/app/angular/GrafanaCtrl.ts @@ -11,7 +11,7 @@ import appEvents from 'app/core/app_events'; import config from 'app/core/config'; import { ContextSrv } from 'app/core/services/context_srv'; import { initGrafanaLive } from 'app/features/live'; -import { CoreEvents, AppEventEmitter, AppEventConsumer } from 'app/types'; +import { AppEventEmitter, AppEventConsumer } from 'app/types'; import { UtilSrv } from './services/UtilSrv'; @@ -89,10 +89,6 @@ export function grafanaAppDirective() { // see https://github.com/zenorocha/clipboard.js/issues/155 $.fn.modal.Constructor.prototype.enforceFocus = () => {}; - appEvents.on(CoreEvents.toggleSidemenuHidden, () => { - body.toggleClass('sidemenu-hidden'); - }); - // handle in active view state class let lastActivity = new Date().getTime(); let activeUser = true; diff --git a/public/app/core/components/AppChrome/AppChrome.tsx b/public/app/core/components/AppChrome/AppChrome.tsx index aefa8d54f21..39d15857da1 100644 --- a/public/app/core/components/AppChrome/AppChrome.tsx +++ b/public/app/core/components/AppChrome/AppChrome.tsx @@ -5,9 +5,12 @@ import { GrafanaTheme2 } from '@grafana/data'; import { config } from '@grafana/runtime'; import { useStyles2 } from '@grafana/ui'; import { useGrafana } from 'app/core/context/GrafanaContext'; +import { CommandPalette } from 'app/features/commandPalette/CommandPalette'; +import { SearchWrapper } from 'app/features/search'; import { KioskMode } from 'app/types'; import { MegaMenu } from '../MegaMenu/MegaMenu'; +import { NavBar } from '../NavBar/NavBar'; import { NavToolbar } from './NavToolbar'; import { TopSearchBar } from './TopSearchBar'; @@ -19,9 +22,21 @@ export function AppChrome({ children }: Props) { const styles = useStyles2(getStyles); const { chrome } = useGrafana(); const state = chrome.useState(); + const featureToggles = config.featureToggles; if (!config.featureToggles.topnav) { - return
{children}
; + return ( + <> + {!state.chromeless && ( + <> + + + {featureToggles.commandPalette && } + + )} +
{children}
+ + ); } const searchBarHidden = state.searchBarHidden || state.kioskMode === KioskMode.TV; @@ -32,24 +47,33 @@ export function AppChrome({ children }: Props) { [styles.contentChromeless]: state.chromeless, }); + // Chromeless routes are without topNav, mega menu, search & command palette + if (state.chromeless) { + return ( +
+
{children}
+
+ ); + } + return (
- {!state.chromeless && ( -
- {!searchBarHidden && } - -
- )} +
+ {!searchBarHidden && } + +
{children}
- {!state.chromeless && chrome.setMegaMenu(false)} />} + chrome.setMegaMenu(false)} /> + {featureToggles.commandPalette && } + {!featureToggles.topNavCommandPalette && }
); } diff --git a/public/app/core/components/AppChrome/NavLandingPage.test.tsx b/public/app/core/components/AppChrome/NavLandingPage.test.tsx index ca54b24a845..f327f0b1463 100644 --- a/public/app/core/components/AppChrome/NavLandingPage.test.tsx +++ b/public/app/core/components/AppChrome/NavLandingPage.test.tsx @@ -1,9 +1,8 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { config } from '@grafana/runtime'; -import { configureStore } from 'app/store/configureStore'; import { NavLandingPage } from './NavLandingPage'; @@ -51,11 +50,10 @@ describe('NavLandingPage', () => { }, ]; - const store = configureStore(); return render( - + - + ); }; diff --git a/public/app/core/components/AppChrome/Organization/OrganizationSwitcher.test.tsx b/public/app/core/components/AppChrome/Organization/OrganizationSwitcher.test.tsx index dcc7a6b3d77..b256dbd1331 100644 --- a/public/app/core/components/AppChrome/Organization/OrganizationSwitcher.test.tsx +++ b/public/app/core/components/AppChrome/Organization/OrganizationSwitcher.test.tsx @@ -1,11 +1,10 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { OrgRole } from '@grafana/data'; import { ContextSrv, setContextSrv } from 'app/core/services/context_srv'; import { getUserOrganizations } from 'app/features/org/state/actions'; -import { configureStore } from 'app/store/configureStore'; import * as appTypes from 'app/types'; import { OrganizationSwitcher } from './OrganizationSwitcher'; @@ -22,12 +21,10 @@ jest.mock('app/types', () => ({ })); const renderWithProvider = ({ initialState }: { initialState?: Partial }) => { - const store = configureStore(initialState); - render( - + - + ); }; diff --git a/public/app/core/components/AppChrome/QuickAdd/QuickAdd.test.tsx b/public/app/core/components/AppChrome/QuickAdd/QuickAdd.test.tsx index 568ec4af0d8..2bbcc388bf8 100644 --- a/public/app/core/components/AppChrome/QuickAdd/QuickAdd.test.tsx +++ b/public/app/core/components/AppChrome/QuickAdd/QuickAdd.test.tsx @@ -1,11 +1,10 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { NavModelItem, NavSection } from '@grafana/data'; import { reportInteraction } from '@grafana/runtime'; -import { configureStore } from 'app/store/configureStore'; import { QuickAdd } from './QuickAdd'; @@ -37,12 +36,10 @@ const setup = () => { }, ]; - const store = configureStore({ navBarTree }); - return render( - + - + ); }; diff --git a/public/app/core/components/MegaMenu/MegaMenu.test.tsx b/public/app/core/components/MegaMenu/MegaMenu.test.tsx index f06ae94136a..b88f7f087c9 100644 --- a/public/app/core/components/MegaMenu/MegaMenu.test.tsx +++ b/public/app/core/components/MegaMenu/MegaMenu.test.tsx @@ -1,15 +1,12 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock'; import { NavModelItem, NavSection } from '@grafana/data'; import { locationService } from '@grafana/runtime'; -import { GrafanaContext } from 'app/core/context/GrafanaContext'; -import { configureStore } from 'app/store/configureStore'; -import TestProvider from '../../../../test/helpers/TestProvider'; +import { TestProvider } from '../../../../test/helpers/TestProvider'; import { MegaMenu } from './MegaMenu'; @@ -33,21 +30,15 @@ const setup = () => { }, ]; - const context = getGrafanaContextMock(); - const store = configureStore({ navBarTree }); - - context.chrome.onToggleMegaMenu(); + const grafanaContext = getGrafanaContextMock(); + grafanaContext.chrome.onToggleMegaMenu(); return render( - - - - - {}} /> - - - - + + + {}} /> + + ); }; diff --git a/public/app/core/components/NavBar/NavBar.test.tsx b/public/app/core/components/NavBar/NavBar.test.tsx index 39e2949a651..62ae0280d88 100644 --- a/public/app/core/components/NavBar/NavBar.test.tsx +++ b/public/app/core/components/NavBar/NavBar.test.tsx @@ -1,12 +1,9 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; import { locationService } from '@grafana/runtime'; -import { configureStore } from 'app/store/configureStore'; -import TestProvider from '../../../../test/helpers/TestProvider'; +import { TestProvider } from '../../../../test/helpers/TestProvider'; import { NavBar } from './NavBar'; @@ -22,16 +19,10 @@ jest.mock('app/core/services/context_srv', () => ({ })); const setup = () => { - const store = configureStore(); - return render( - - - - - - - + + + ); }; diff --git a/public/app/core/components/NavBar/NavBar.tsx b/public/app/core/components/NavBar/NavBar.tsx index d0a5e58ac86..32dcd416788 100644 --- a/public/app/core/components/NavBar/NavBar.tsx +++ b/public/app/core/components/NavBar/NavBar.tsx @@ -192,10 +192,6 @@ const getStyles = (theme: GrafanaTheme2) => ({ navWrapper: css({ position: 'relative', display: 'flex', - - '.sidemenu-hidden &': { - display: 'none', - }, }), sidemenu: css({ label: 'sidemenu', diff --git a/public/app/core/components/NavBar/NavBarItem.test.tsx b/public/app/core/components/NavBar/NavBarItem.test.tsx index 86b0eca5fae..840b61b7a85 100644 --- a/public/app/core/components/NavBar/NavBarItem.test.tsx +++ b/public/app/core/components/NavBar/NavBarItem.test.tsx @@ -6,8 +6,6 @@ import { BrowserRouter } from 'react-router-dom'; import { locationUtil } from '@grafana/data'; import { config, setLocationService } from '@grafana/runtime'; -import TestProvider from '../../../../test/helpers/TestProvider'; - // Need to mock createBrowserHistory here to avoid errors jest.mock('history', () => ({ ...jest.requireActual('history'), @@ -45,18 +43,16 @@ async function getTestContext(overrides: Partial = {}, subUrl = '', isMen const props = { ...defaults, ...overrides }; const { rerender } = render( - - - - - - - + + + + + ); // Need to click this first to set the correct selection range diff --git a/public/app/core/components/Page/Page.test.tsx b/public/app/core/components/Page/Page.test.tsx index 3ac2e7edcff..afa5e7b99c8 100644 --- a/public/app/core/components/Page/Page.test.tsx +++ b/public/app/core/components/Page/Page.test.tsx @@ -1,10 +1,9 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { NavModelItem } from '@grafana/data'; import { config } from '@grafana/runtime'; -import { configureStore } from 'app/store/configureStore'; import { Page } from './Page'; import { PageProps } from './types'; @@ -30,14 +29,12 @@ const setup = (props: Partial) => { }, ]; - const store = configureStore(); - return render( - +
Children
-
+ ); }; diff --git a/public/app/core/components/Page/Page.tsx b/public/app/core/components/Page/Page.tsx index a8e620942df..3e55466782a 100644 --- a/public/app/core/components/Page/Page.tsx +++ b/public/app/core/components/Page/Page.tsx @@ -1,10 +1,11 @@ // Libraries import { css, cx } from '@emotion/css'; -import React from 'react'; +import React, { useEffect } from 'react'; import { GrafanaTheme2, PageLayoutType } from '@grafana/data'; import { config } from '@grafana/runtime'; import { CustomScrollbar, useStyles2 } from '@grafana/ui'; +import { useGrafana } from 'app/core/context/GrafanaContext'; import { Footer } from '../Footer/Footer'; import { PageHeader } from '../PageHeader/PageHeader'; @@ -34,11 +35,21 @@ export const OldPage: PageType = ({ }) => { const styles = useStyles2(getStyles); const navModel = usePageNav(navId, oldNavProp); + const { chrome } = useGrafana(); usePageTitle(navModel, pageNav); const pageHeaderNav = pageNav ?? navModel?.main; + useEffect(() => { + if (navModel) { + // This is needed for chrome to update it's chromeless state + chrome.update({ + sectionNav: navModel.node, + }); + } + }, [navModel, chrome]); + return (
{layout === PageLayoutType.Standard && ( diff --git a/public/app/core/components/PageNew/Page.test.tsx b/public/app/core/components/PageNew/Page.test.tsx index 66556318fa1..2492edf45e6 100644 --- a/public/app/core/components/PageNew/Page.test.tsx +++ b/public/app/core/components/PageNew/Page.test.tsx @@ -1,13 +1,11 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock'; import { NavModelItem } from '@grafana/data'; import { config } from '@grafana/runtime'; -import { GrafanaContext } from 'app/core/context/GrafanaContext'; import { HOME_NAV_ID } from 'app/core/reducers/navModel'; -import { configureStore } from 'app/store/configureStore'; import { PageProps } from '../Page/types'; @@ -38,16 +36,13 @@ const setup = (props: Partial) => { ]; const context = getGrafanaContextMock(); - const store = configureStore(); const renderResult = render( - - - -
Children
-
-
-
+ + +
Children
+
+
); return { renderResult, context }; diff --git a/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx b/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx index a1ea4c4ff0d..90bfeb72397 100644 --- a/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx +++ b/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx @@ -1,7 +1,6 @@ import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import TestProvider from 'test/helpers/TestProvider'; import { assertInstanceOf } from 'test/helpers/asserts'; import { getSelectParent, selectOptionInTest } from 'test/helpers/selectOptionInTest'; @@ -124,11 +123,7 @@ describe('SharedPreferences', () => { mockReload.mockReset(); mockPrefsUpdate.mockReset(); - render( - - - - ); + render(); await waitFor(() => expect(mockPrefsLoad).toHaveBeenCalled()); }); diff --git a/public/app/core/navigation/GrafanaRoute.test.tsx b/public/app/core/navigation/GrafanaRoute.test.tsx index 396fe7e802a..accd7e09086 100644 --- a/public/app/core/navigation/GrafanaRoute.test.tsx +++ b/public/app/core/navigation/GrafanaRoute.test.tsx @@ -1,19 +1,14 @@ import { render, screen } from '@testing-library/react'; import React, { ComponentType } from 'react'; -import { Provider } from 'react-redux'; -import { BrowserRouter } from 'react-router-dom'; -import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock'; +import { TestProvider } from 'test/helpers/TestProvider'; import { setEchoSrv } from '@grafana/runtime'; -import { configureStore } from '../../store/configureStore'; -import { GrafanaContext } from '../context/GrafanaContext'; import { Echo } from '../services/echo/Echo'; import { GrafanaRoute, Props } from './GrafanaRoute'; function setup(overrides: Partial) { - const store = configureStore(); const props: Props = { location: { search: '?query=hello&test=asd' } as any, history: {} as any, @@ -26,13 +21,9 @@ function setup(overrides: Partial) { }; render( - - - - - - - + + + ); } diff --git a/public/app/core/navigation/GrafanaRoute.tsx b/public/app/core/navigation/GrafanaRoute.tsx index 1bfe2765013..7b40ea06d0f 100644 --- a/public/app/core/navigation/GrafanaRoute.tsx +++ b/public/app/core/navigation/GrafanaRoute.tsx @@ -19,8 +19,8 @@ export function GrafanaRoute(props: Props) { chrome.setMatchedRoute(props.route); useLayoutEffect(() => { - keybindings.clearAndInitGlobalBindings(); - }, [keybindings]); + keybindings.clearAndInitGlobalBindings(props.route); + }, [keybindings, props.route]); useEffect(() => { updateBodyClassNames(props.route); diff --git a/public/app/core/services/keybindingSrv.ts b/public/app/core/services/keybindingSrv.ts index 51b7518e9d2..4ed2a9e5fcb 100644 --- a/public/app/core/services/keybindingSrv.ts +++ b/public/app/core/services/keybindingSrv.ts @@ -23,6 +23,7 @@ import { import { AppChromeService } from '../components/AppChrome/AppChromeService'; import { HelpModal } from '../components/help/HelpModal'; import { contextSrv } from '../core'; +import { RouteDescriptor } from '../navigation/types'; import { toggleTheme } from './theme'; import { withFocusedPanel } from './withFocusedPanelId'; @@ -30,10 +31,11 @@ import { withFocusedPanel } from './withFocusedPanelId'; export class KeybindingSrv { constructor(private locationService: LocationService, private chromeService: AppChromeService) {} - clearAndInitGlobalBindings() { + clearAndInitGlobalBindings(route: RouteDescriptor) { Mousetrap.reset(); - if (this.locationService.getLocation().pathname !== '/login') { + // Chromeless pages like login and signup page don't get any global bindings + if (!route.chromeless) { this.bind(['?', 'h'], this.showHelpModal); this.bind('g h', this.goToHome); this.bind('g a', this.openAlerting); diff --git a/public/app/features/alerting/AlertRuleList.test.tsx b/public/app/features/alerting/AlertRuleList.test.tsx index 2589b5f4cd6..df8f7c795de 100644 --- a/public/app/features/alerting/AlertRuleList.test.tsx +++ b/public/app/features/alerting/AlertRuleList.test.tsx @@ -1,15 +1,14 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; import { openMenu } from 'react-select-event'; import { mockToolkitActionCreator } from 'test/core/redux/mocks'; +import { TestProvider } from 'test/helpers/TestProvider'; import { locationService } from '@grafana/runtime'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; import appEvents from '../../core/app_events'; -import { configureStore } from '../../store/configureStore'; import { ShowModalReactEvent } from '../../types/events'; import { AlertHowToModal } from './AlertHowToModal'; @@ -31,20 +30,19 @@ const defaultProps: Props = { }; const setup = (propOverrides?: object) => { - const store = configureStore(); const props: Props = { ...defaultProps, ...propOverrides, }; const { rerender } = render( - + - + ); return { - rerender: (element: JSX.Element) => rerender({element}), + rerender: (element: JSX.Element) => rerender({element}), }; }; diff --git a/public/app/features/alerting/unified/AlertGroups.test.tsx b/public/app/features/alerting/unified/AlertGroups.test.tsx index 0c46f97e58d..e71d29fa39e 100644 --- a/public/app/features/alerting/unified/AlertGroups.test.tsx +++ b/public/app/features/alerting/unified/AlertGroups.test.tsx @@ -1,12 +1,10 @@ import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { byRole, byTestId, byText } from 'testing-library-selector'; -import { locationService, setDataSourceSrv } from '@grafana/runtime'; -import { configureStore } from 'app/store/configureStore'; +import { setDataSourceSrv } from '@grafana/runtime'; import AlertGroups from './AlertGroups'; import { fetchAlertGroups } from './api/alertmanager'; @@ -28,14 +26,10 @@ const mocks = { }; const renderAmNotifications = () => { - const store = configureStore(); - return render( - - - - - + + + ); }; diff --git a/public/app/features/alerting/unified/AlertsFolderView.test.tsx b/public/app/features/alerting/unified/AlertsFolderView.test.tsx index e588e306178..7c09245f377 100644 --- a/public/app/features/alerting/unified/AlertsFolderView.test.tsx +++ b/public/app/features/alerting/unified/AlertsFolderView.test.tsx @@ -1,11 +1,9 @@ import { render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; -import { MemoryRouter } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { byTestId } from 'testing-library-selector'; -import { configureStore } from 'app/store/configureStore'; import { FolderState } from 'app/types'; import { CombinedRuleNamespace } from 'app/types/unified-alerting'; @@ -47,7 +45,6 @@ const mockFolder = (folderOverride: Partial = {}): FolderState => { describe('AlertsFolderView tests', () => { it('Should display grafana alert rules when the namespace name matches the folder name', () => { // Arrange - const store = configureStore(); const folder = mockFolder(); const grafanaNamespace: CombinedRuleNamespace = { @@ -77,11 +74,9 @@ describe('AlertsFolderView tests', () => { // Act render( - - - - - + + + ); // Assert @@ -97,7 +92,6 @@ describe('AlertsFolderView tests', () => { it('Should not display alert rules when the namespace name does not match the folder name', () => { // Arrange - const store = configureStore(); const folder = mockFolder(); const grafanaNamespace: CombinedRuleNamespace = { @@ -118,11 +112,9 @@ describe('AlertsFolderView tests', () => { // Act render( - - - - - + + + ); // Assert @@ -131,7 +123,6 @@ describe('AlertsFolderView tests', () => { it('Should filter alert rules by the name, case insensitive', async () => { // Arrange - const store = configureStore(); const folder = mockFolder(); const grafanaNamespace: CombinedRuleNamespace = { @@ -149,11 +140,9 @@ describe('AlertsFolderView tests', () => { // Act render( - - - - - + + + ); await userEvent.type(ui.filter.name.get(), 'cpu'); @@ -165,7 +154,6 @@ describe('AlertsFolderView tests', () => { it('Should filter alert rule by labels', async () => { // Arrange - const store = configureStore(); const folder = mockFolder(); const grafanaNamespace: CombinedRuleNamespace = { @@ -186,11 +174,9 @@ describe('AlertsFolderView tests', () => { // Act render( - - - - - + + + ); await userEvent.type(ui.filter.label.get(), 'severity=critical'); diff --git a/public/app/features/alerting/unified/AmRoutes.test.tsx b/public/app/features/alerting/unified/AmRoutes.test.tsx index c4a30208147..d1a70e3ff21 100644 --- a/public/app/features/alerting/unified/AmRoutes.test.tsx +++ b/public/app/features/alerting/unified/AmRoutes.test.tsx @@ -1,8 +1,7 @@ import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { selectOptionInTest } from 'test/helpers/selectOptionInTest'; import { byLabelText, byRole, byTestId, byText } from 'testing-library-selector'; @@ -15,7 +14,6 @@ import { MuteTimeInterval, Route, } from 'app/plugins/datasource/alertmanager/types'; -import { configureStore } from 'app/store/configureStore'; import { AccessControlAction } from 'app/types'; import AmRoutes from './AmRoutes'; @@ -47,19 +45,15 @@ const mocks = { const useGetGrafanaReceiverTypeCheckerMock = jest.spyOn(grafanaApp, 'useGetGrafanaReceiverTypeChecker'); const renderAmRoutes = (alertManagerSourceName?: string) => { - const store = configureStore(); locationService.push(location); - locationService.push( '/alerting/routes' + (alertManagerSourceName ? `?${ALERTMANAGER_NAME_QUERY_KEY}=${alertManagerSourceName}` : '') ); return render( - - - - - + + + ); }; diff --git a/public/app/features/alerting/unified/CloneRuleEditor.test.tsx b/public/app/features/alerting/unified/CloneRuleEditor.test.tsx index aa91a0c7910..408898d6566 100644 --- a/public/app/features/alerting/unified/CloneRuleEditor.test.tsx +++ b/public/app/features/alerting/unified/CloneRuleEditor.test.tsx @@ -2,8 +2,7 @@ import { render, waitFor, waitForElementToBeRemoved } from '@testing-library/rea import { setupServer } from 'msw/node'; import React from 'react'; import { FormProvider, useForm } from 'react-hook-form'; -import { Provider } from 'react-redux'; -import { MemoryRouter } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { byRole, byTestId, byText } from 'testing-library-selector'; import { selectors } from '@grafana/e2e-selectors/src'; @@ -91,11 +90,9 @@ function getProvidersWrapper() { const formApi = useForm({ defaultValues: getDefaultFormValues() }); return ( - - - {children} - - + + {children} + ); }; } diff --git a/public/app/features/alerting/unified/MuteTimings.test.tsx b/public/app/features/alerting/unified/MuteTimings.test.tsx index 040b6b6594a..369fee9a77b 100644 --- a/public/app/features/alerting/unified/MuteTimings.test.tsx +++ b/public/app/features/alerting/unified/MuteTimings.test.tsx @@ -1,13 +1,11 @@ import { render, waitFor, fireEvent } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { byRole, byTestId, byText } from 'testing-library-selector'; import { locationService, setDataSourceSrv } from '@grafana/runtime'; import { AlertManagerCortexConfig, MuteTimeInterval } from 'app/plugins/datasource/alertmanager/types'; -import { configureStore } from 'app/store/configureStore'; import MuteTimings from './MuteTimings'; import { fetchAlertManagerConfig, updateAlertManagerConfig } from './api/alertmanager'; @@ -24,15 +22,12 @@ const mocks = { }; const renderMuteTimings = (location = '/alerting/routes/mute-timing/new') => { - const store = configureStore(); locationService.push(location); return render( - - - - - + + + ); }; diff --git a/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx b/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx index fcd4005f0e1..37f226adbaa 100644 --- a/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx +++ b/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx @@ -1,11 +1,10 @@ import { render, act, waitFor } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { byTestId } from 'testing-library-selector'; import { DataSourceApi } from '@grafana/data'; -import { locationService, setDataSourceSrv } from '@grafana/runtime'; +import { setDataSourceSrv } from '@grafana/runtime'; import * as ruleActionButtons from 'app/features/alerting/unified/components/rules/RuleActionsButtons'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; @@ -69,15 +68,11 @@ const renderAlertTabContent = ( panel: PanelModel, initialStore?: ReturnType ) => { - const store = initialStore ?? configureStore(); - return act(async () => { render( - - - - - + + + ); }); }; diff --git a/public/app/features/alerting/unified/Receivers.test.tsx b/public/app/features/alerting/unified/Receivers.test.tsx index e91f53b6067..0877c1ff128 100644 --- a/public/app/features/alerting/unified/Receivers.test.tsx +++ b/public/app/features/alerting/unified/Receivers.test.tsx @@ -2,8 +2,7 @@ import { render, waitFor, within, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { setupServer } from 'msw/node'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { selectOptionInTest } from 'test/helpers/selectOptionInTest'; import { byLabelText, byPlaceholderText, byRole, byTestId, byText } from 'testing-library-selector'; @@ -17,7 +16,6 @@ import { AlertManagerDataSourceJsonData, AlertManagerImplementation, } from 'app/plugins/datasource/alertmanager/types'; -import { configureStore } from 'app/store/configureStore'; import { AccessControlAction, ContactPointsState } from 'app/types'; import 'whatwg-fetch'; @@ -70,19 +68,15 @@ const alertmanagerChoiceMockedResponse: AlertmanagersChoiceResponse = { }; const renderReceivers = (alertManagerSourceName?: string) => { - const store = configureStore(); - locationService.push( '/alerting/notifications' + (alertManagerSourceName ? `?${ALERTMANAGER_NAME_QUERY_KEY}=${alertManagerSourceName}` : '') ); return render( - - - - - + + + ); }; diff --git a/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx b/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx index ce6bcba3e5f..2dcbcf1a381 100644 --- a/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx +++ b/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx @@ -1,11 +1,10 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; -import { MemoryRouter } from 'react-router-dom'; import { useLocation } from 'react-use'; +import { TestProvider } from 'test/helpers/TestProvider'; import { DataSourceJsonData, PluginMeta } from '@grafana/data'; -import { configureStore } from 'app/store/configureStore'; +import { locationService } from '@grafana/runtime'; import { CombinedRule, Rule } from '../../../types/unified-alerting'; import { PromRuleType } from '../../../types/unified-alerting-dto'; @@ -24,16 +23,15 @@ jest.mock('react-router-dom', () => ({ jest.mock('react-use'); -const store = configureStore(); const renderRedirectToRuleViewer = (pathname: string) => { jest.mocked(useLocation).mockReturnValue({ pathname, trigger: '' }); + locationService.push(pathname); + return render( - - - - - + + + ); }; diff --git a/public/app/features/alerting/unified/RuleEditorExisting.test.tsx b/public/app/features/alerting/unified/RuleEditorExisting.test.tsx index 9862a96baa5..ebb6b894b44 100644 --- a/public/app/features/alerting/unified/RuleEditorExisting.test.tsx +++ b/public/app/features/alerting/unified/RuleEditorExisting.test.tsx @@ -1,8 +1,8 @@ import { render, waitFor, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Route, Router } from 'react-router-dom'; +import { Route } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { ui } from 'test/helpers/alertingRuleEditor'; import { clickSelectOptionMatch } from 'test/helpers/selectOptionInTest'; import { byRole } from 'testing-library-selector'; @@ -11,7 +11,6 @@ import { locationService, setDataSourceSrv } from '@grafana/runtime'; import { ADD_NEW_FOLER_OPTION } from 'app/core/components/Select/FolderPicker'; import { contextSrv } from 'app/core/services/context_srv'; import { DashboardSearchHit } from 'app/features/search/types'; -import { configureStore } from 'app/store/configureStore'; import { GrafanaAlertStateDecision } from 'app/types/unified-alerting-dto'; import { searchFolders } from '../../../../app/features/manage-dashboards/state/actions'; @@ -64,16 +63,12 @@ const mocks = { }; function renderRuleEditor(identifier?: string) { - const store = configureStore(); - locationService.push(identifier ? `/alerting/${identifier}/edit` : `/alerting/new`); return render( - - - - - + + + ); } diff --git a/public/app/features/alerting/unified/RuleList.test.tsx b/public/app/features/alerting/unified/RuleList.test.tsx index fccb1899192..14fc8c4495c 100644 --- a/public/app/features/alerting/unified/RuleList.test.tsx +++ b/public/app/features/alerting/unified/RuleList.test.tsx @@ -2,8 +2,7 @@ import { SerializedError } from '@reduxjs/toolkit'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { byRole, byTestId, byText } from 'testing-library-selector'; import { locationService, logInfo, setBackendSrv, setDataSourceSrv } from '@grafana/runtime'; @@ -11,7 +10,6 @@ import { backendSrv } from 'app/core/services/backend_srv'; import { contextSrv } from 'app/core/services/context_srv'; import * as ruleActionButtons from 'app/features/alerting/unified/components/rules/RuleActionsButtons'; import * as actions from 'app/features/alerting/unified/state/actions'; -import { configureStore } from 'app/store/configureStore'; import { AccessControlAction } from 'app/types'; import { PromAlertingRuleState, PromApplication } from 'app/types/unified-alerting-dto'; @@ -76,15 +74,12 @@ const mocks = { }; const renderRuleList = () => { - const store = configureStore(); locationService.push('/'); return render( - - - - - + + + ); }; diff --git a/public/app/features/alerting/unified/RuleViewer.test.tsx b/public/app/features/alerting/unified/RuleViewer.test.tsx index f0efa02ecd2..11bd03bb774 100644 --- a/public/app/features/alerting/unified/RuleViewer.test.tsx +++ b/public/app/features/alerting/unified/RuleViewer.test.tsx @@ -1,14 +1,12 @@ import { act, render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { byRole } from 'testing-library-selector'; import { locationService, setBackendSrv } from '@grafana/runtime'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { backendSrv } from 'app/core/services/backend_srv'; import { contextSrv } from 'app/core/services/context_srv'; -import { configureStore } from 'app/store/configureStore'; import { AccessControlAction } from 'app/types'; import { CombinedRule } from 'app/types/unified-alerting'; @@ -45,15 +43,12 @@ jest.mock('@grafana/runtime', () => ({ }, })); -const store = configureStore(); const renderRuleViewer = () => { return act(async () => { render( - - - - - + + + ); }); }; diff --git a/public/app/features/alerting/unified/Silences.test.tsx b/public/app/features/alerting/unified/Silences.test.tsx index 648f790a4f0..4c333b57825 100644 --- a/public/app/features/alerting/unified/Silences.test.tsx +++ b/public/app/features/alerting/unified/Silences.test.tsx @@ -1,15 +1,13 @@ import { render, waitFor } from '@testing-library/react'; import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { byLabelText, byPlaceholderText, byRole, byTestId, byText } from 'testing-library-selector'; import { dateTime } from '@grafana/data'; import { locationService, setDataSourceSrv, config } from '@grafana/runtime'; import { contextSrv } from 'app/core/services/context_srv'; import { AlertState, MatcherOperator } from 'app/plugins/datasource/alertmanager/types'; -import { configureStore } from 'app/store/configureStore'; import { AccessControlAction } from 'app/types'; import Silences from './Silences'; @@ -33,15 +31,12 @@ const mocks = { }; const renderSilences = (location = '/alerting/silences/') => { - const store = configureStore(); locationService.push(location); return render( - - - - - + + + ); }; diff --git a/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx b/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx index 4ba59ea2926..a9bebf53196 100644 --- a/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx +++ b/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx @@ -1,8 +1,7 @@ import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { byLabelText, byRole, byTestId } from 'testing-library-selector'; import { locationService, setDataSourceSrv } from '@grafana/runtime'; @@ -13,7 +12,6 @@ import { AlertManagerDataSourceJsonData, AlertManagerImplementation, } from 'app/plugins/datasource/alertmanager/types'; -import { configureStore } from 'app/store/configureStore'; import { fetchAlertManagerConfig, @@ -50,19 +48,15 @@ const mocks = { }; const renderAdminPage = (alertManagerSourceName?: string) => { - const store = configureStore(); - locationService.push( '/alerting/notifications' + (alertManagerSourceName ? `?${ALERTMANAGER_NAME_QUERY_KEY}=${alertManagerSourceName}` : '') ); return render( - - - - - + + + ); }; diff --git a/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx b/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx index 6ade4ead637..99ec8e3066a 100644 --- a/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx +++ b/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx @@ -1,9 +1,7 @@ import { screen, render, within } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; -import { locationService } from '@grafana/runtime'; import { AlertManagerCortexConfig, GrafanaManagedReceiverConfig, @@ -31,11 +29,9 @@ const renderReceieversTable = async (receivers: Receiver[], notifiers: NotifierD await store.dispatch(fetchGrafanaNotifiersAction.fulfilled(notifiers, 'initial')); return render( - - - - - + + + ); }; diff --git a/public/app/features/alerting/unified/components/rule-editor/AnnotationsField.test.tsx b/public/app/features/alerting/unified/components/rule-editor/AnnotationsField.test.tsx index a5645d048cf..15258340ccd 100644 --- a/public/app/features/alerting/unified/components/rule-editor/AnnotationsField.test.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/AnnotationsField.test.tsx @@ -4,7 +4,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; import React from 'react'; import { FormProvider, useForm } from 'react-hook-form'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { byRole, byTestId } from 'testing-library-selector'; import { setBackendSrv } from '@grafana/runtime'; @@ -63,11 +63,11 @@ function FormWrapper({ formValues }: { formValues?: Partial }) { const formApi = useForm({ defaultValues: { ...getDefaultFormValues(), ...formValues } }); return ( - + - + ); } diff --git a/public/app/features/api-keys/ApiKeysPage.test.tsx b/public/app/features/api-keys/ApiKeysPage.test.tsx index f1bcc796342..df8cf679c4c 100644 --- a/public/app/features/api-keys/ApiKeysPage.test.tsx +++ b/public/app/features/api-keys/ApiKeysPage.test.tsx @@ -1,14 +1,13 @@ import { render, screen, within } from '@testing-library/react'; import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { selectors } from '@grafana/e2e-selectors'; import { ApiKey, OrgRole } from 'app/types'; import { mockToolkitActionCreator } from '../../../test/core/redux/mocks'; import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput'; -import { configureStore } from '../../store/configureStore'; import { ApiKeysPageUnconnected, Props } from './ApiKeysPage'; import { getMultipleMockKeys } from './__mocks__/apiKeysMock'; @@ -24,7 +23,6 @@ jest.mock('app/core/core', () => { }); const setup = (propOverrides: Partial) => { - const store = configureStore(); const loadApiKeysMock = jest.fn(); const deleteApiKeyMock = jest.fn(); const migrateApiKeyMock = jest.fn(); @@ -58,12 +56,12 @@ const setup = (propOverrides: Partial) => { Object.assign(props, propOverrides); const { rerender } = render( - + - + ); return { - rerender: (element: JSX.Element) => rerender({element}), + rerender: (element: JSX.Element) => rerender({element}), props, loadApiKeysMock, setSearchQueryMock, diff --git a/public/app/features/commandPalette/CommandPalette.tsx b/public/app/features/commandPalette/CommandPalette.tsx index 9b19cf667dd..66d5b94f472 100644 --- a/public/app/features/commandPalette/CommandPalette.tsx +++ b/public/app/features/commandPalette/CommandPalette.tsx @@ -26,7 +26,7 @@ import useActions from './actions/useActions'; import { CommandPaletteAction } from './types'; import { useMatches } from './useMatches'; -export const CommandPalette = () => { +export function CommandPalette() { const styles = useStyles2(getSearchStyles); const { query, showing, searchQuery } = useKBar((state) => ({ @@ -43,6 +43,7 @@ export const CommandPalette = () => { { isOpen: showing, onClose: () => query.setVisualState(VisualState.animatingOut) }, ref ); + const { dialogProps } = useDialog({}, ref); // Report interaction when opened @@ -72,7 +73,7 @@ export const CommandPalette = () => { ) : null; -}; +} interface RenderResultsProps { dashboardResults: CommandPaletteAction[]; diff --git a/public/app/features/connections/Connections.test.tsx b/public/app/features/connections/Connections.test.tsx index 6877f010b6d..15c5ee2b2de 100644 --- a/public/app/features/connections/Connections.test.tsx +++ b/public/app/features/connections/Connections.test.tsx @@ -1,7 +1,6 @@ import { render, RenderResult, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { locationService } from '@grafana/runtime'; import { contextSrv } from 'app/core/services/context_srv'; @@ -25,11 +24,9 @@ const renderPage = ( locationService.push(path); return render( - - - - - + + + ); }; @@ -86,6 +83,7 @@ describe('Connections', () => { url: '/connections/connect-data', pluginId: 'grafana-easystart-app', }; + const connections = { ...navIndex.connections, children: navIndex.connections.children?.map((child) => { @@ -96,6 +94,7 @@ describe('Connections', () => { return child; }), }; + const store = configureStore({ navIndex: { ...navIndex, connections, [standalonePluginPage.id]: standalonePluginPage }, plugins: getPluginsStateMock([]), diff --git a/public/app/features/correlations/CorrelationsPage.test.tsx b/public/app/features/correlations/CorrelationsPage.test.tsx index 8ad54c9bfae..31d18864ec4 100644 --- a/public/app/features/correlations/CorrelationsPage.test.tsx +++ b/public/app/features/correlations/CorrelationsPage.test.tsx @@ -11,8 +11,8 @@ import { import { merge, uniqueId } from 'lodash'; import React from 'react'; import { DeepPartial } from 'react-hook-form'; -import { Provider } from 'react-redux'; import { Observable } from 'rxjs'; +import { TestProvider } from 'test/helpers/TestProvider'; import { MockDataSourceApi } from 'test/mocks/datasource_srv'; import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock'; @@ -25,7 +25,6 @@ import { BackendSrvRequest, reportInteraction, } from '@grafana/runtime'; -import { GrafanaContext } from 'app/core/context/GrafanaContext'; import { contextSrv } from 'app/core/services/context_srv'; import { configureStore } from 'app/store/configureStore'; @@ -150,11 +149,9 @@ const renderWithContext = async ( setDataSourceSrv(dsServer); const renderResult = render( - - - - - , + + + , { queries: { /** diff --git a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx index 349576f5374..98174a431dd 100644 --- a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx @@ -2,23 +2,18 @@ import { within } from '@testing-library/dom'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; -import { BrowserRouter } from 'react-router-dom'; -import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock'; +import { TestProvider } from 'test/helpers/TestProvider'; import { selectors } from '@grafana/e2e-selectors'; import { locationService, setAngularLoader, setDataSourceSrv } from '@grafana/runtime'; -import { GrafanaContext } from 'app/core/context/GrafanaContext'; import { mockDataSource, MockDataSourceSrv } from 'app/features/alerting/unified/mocks'; -import { configureStore } from '../../../../store/configureStore'; import { DashboardModel } from '../../state/DashboardModel'; import { createDashboardModelFixture } from '../../state/__fixtures__/dashboardFixtures'; import { AnnotationsSettings } from './AnnotationsSettings'; function setup(dashboard: DashboardModel, editIndex?: number) { - const store = configureStore(); const sectionNav = { main: { text: 'Dashboard' }, node: { @@ -27,13 +22,9 @@ function setup(dashboard: DashboardModel, editIndex?: number) { }; return render( - - - - - - - + + + ); } diff --git a/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.test.tsx index 2dfb2b0817e..4dcb106fb0e 100644 --- a/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.test.tsx @@ -1,26 +1,14 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; -import { BrowserRouter } from 'react-router-dom'; -import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock'; +import { TestProvider } from 'test/helpers/TestProvider'; import { NavModel, NavModelItem } from '@grafana/data'; import { BackendSrv, setBackendSrv } from '@grafana/runtime'; -import { GrafanaContext } from 'app/core/context/GrafanaContext'; -import { configureStore } from 'app/store/configureStore'; import { createDashboardModelFixture } from '../../state/__fixtures__/dashboardFixtures'; import { DashboardSettings } from './DashboardSettings'; -jest.mock('@grafana/runtime', () => ({ - ...jest.requireActual('@grafana/runtime'), - locationService: { - getSearchObject: jest.fn().mockResolvedValue({}), - partial: jest.fn(), - }, -})); - setBackendSrv({ get: jest.fn().mockResolvedValue([]), } as unknown as BackendSrv); @@ -36,19 +24,13 @@ describe('DashboardSettings', () => { } ); - const store = configureStore(); - const context = getGrafanaContextMock(); const sectionNav: NavModel = { main: { text: 'Dashboards' }, node: { text: 'Dashboards' } }; const pageNav: NavModelItem = { text: 'My cool dashboard' }; render( - - - - - - - + + + ); expect(await screen.findByRole('tab', { name: 'Tab Settings' })).toBeInTheDocument(); diff --git a/public/app/features/datasources/components/EmptyStateNoDatasource.test.tsx b/public/app/features/datasources/components/EmptyStateNoDatasource.test.tsx index e0fd8ce982f..49d7cfa9fae 100644 --- a/public/app/features/datasources/components/EmptyStateNoDatasource.test.tsx +++ b/public/app/features/datasources/components/EmptyStateNoDatasource.test.tsx @@ -3,13 +3,12 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; import React from 'react'; import { DeepPartial } from 'react-hook-form'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { DataSourcePluginMeta } from '@grafana/data'; import * as runtime from '@grafana/runtime'; import { backendSrv } from 'app/core/services/backend_srv'; import { contextSrv } from 'app/core/services/context_srv'; -import { configureStore } from 'app/store/configureStore'; import 'whatwg-fetch'; import { EmptyStateNoDatasource } from './EmptyStateNoDatasource'; @@ -60,9 +59,9 @@ describe('EmptyStateNoDatasource', () => { }) ); render( - + - + ); await waitFor(() => { diff --git a/public/app/features/datasources/pages/DataSourceDashboardsPage.test.tsx b/public/app/features/datasources/pages/DataSourceDashboardsPage.test.tsx index 861f8154da2..81abac95ef9 100644 --- a/public/app/features/datasources/pages/DataSourceDashboardsPage.test.tsx +++ b/public/app/features/datasources/pages/DataSourceDashboardsPage.test.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; import { Store } from 'redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { setAngularLoader } from '@grafana/runtime'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; @@ -23,7 +23,7 @@ jest.mock('app/core/services/context_srv', () => ({ const setup = (uid: string, store: Store) => render( - + }, })} /> - + ); describe('', () => { diff --git a/public/app/features/datasources/pages/DataSourcesListPage.test.tsx b/public/app/features/datasources/pages/DataSourcesListPage.test.tsx index 3dc46e2f709..50aa5e0c259 100644 --- a/public/app/features/datasources/pages/DataSourcesListPage.test.tsx +++ b/public/app/features/datasources/pages/DataSourcesListPage.test.tsx @@ -1,10 +1,9 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { LayoutModes } from '@grafana/data'; import { contextSrv } from 'app/core/services/context_srv'; -import { configureStore } from 'app/store/configureStore'; import { navIndex, getMockDataSources } from '../__mocks__'; import { getDataSources } from '../api'; @@ -21,19 +20,19 @@ jest.mock('../api', () => ({ const getDataSourcesMock = getDataSources as jest.Mock; const setup = (options: { isSortAscending: boolean }) => { - const store = configureStore({ + const storeState = { dataSources: { ...initialState, layoutMode: LayoutModes.Grid, isSortAscending: options.isSortAscending, }, navIndex, - }); + }; return render( - + - + ); }; diff --git a/public/app/features/datasources/pages/EditDataSourcePage.test.tsx b/public/app/features/datasources/pages/EditDataSourcePage.test.tsx index 646a8741792..ad9ac025879 100644 --- a/public/app/features/datasources/pages/EditDataSourcePage.test.tsx +++ b/public/app/features/datasources/pages/EditDataSourcePage.test.tsx @@ -1,7 +1,7 @@ import { screen, render } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; import { Store } from 'redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { LayoutModes } from '@grafana/data'; import { setAngularLoader } from '@grafana/runtime'; @@ -36,7 +36,7 @@ jest.mock('@grafana/runtime', () => { const setup = (uid: string, store: Store) => render( - + }, })} /> - + ); describe('', () => { diff --git a/public/app/features/folders/FolderSettingsPage.test.tsx b/public/app/features/folders/FolderSettingsPage.test.tsx index 6855a2f0547..21c1dbd3f2d 100644 --- a/public/app/features/folders/FolderSettingsPage.test.tsx +++ b/public/app/features/folders/FolderSettingsPage.test.tsx @@ -1,13 +1,12 @@ import { render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; import { mockToolkitActionCreator } from 'test/core/redux/mocks'; +import { TestProvider } from 'test/helpers/TestProvider'; import { NavModel } from '@grafana/data'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; import { ModalManager } from 'app/core/services/ModalManager'; -import { configureStore } from 'app/store/configureStore'; import { FolderSettingsPage, Props } from './FolderSettingsPage'; import { setFolderTitle } from './state/reducers'; @@ -38,9 +37,9 @@ const setup = (propOverrides?: object) => { Object.assign(props, propOverrides); render( - + - + ); }; diff --git a/public/app/features/invites/SignupInvited.test.tsx b/public/app/features/invites/SignupInvited.test.tsx index 693ff41b0e2..41f76d4ddb7 100644 --- a/public/app/features/invites/SignupInvited.test.tsx +++ b/public/app/features/invites/SignupInvited.test.tsx @@ -1,12 +1,11 @@ import { render, screen, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; import { backendSrv } from '../../core/services/backend_srv'; -import { configureStore } from '../../store/configureStore'; import { SignupInvitedPage, Props } from './SignupInvited'; @@ -30,7 +29,6 @@ const defaultGet = { async function setupTestContext({ get = defaultGet }: { get?: typeof defaultGet | null } = {}) { jest.clearAllMocks(); - const store = configureStore(); const getSpy = jest.spyOn(backendSrv, 'get'); getSpy.mockResolvedValue(get); @@ -47,9 +45,9 @@ async function setupTestContext({ get = defaultGet }: { get?: typeof defaultGet }; render( - + - + ); await waitFor(() => expect(getSpy).toHaveBeenCalled()); diff --git a/public/app/features/org/OrgDetailsPage.test.tsx b/public/app/features/org/OrgDetailsPage.test.tsx index 50c086d81e9..1bb4b8920c1 100644 --- a/public/app/features/org/OrgDetailsPage.test.tsx +++ b/public/app/features/org/OrgDetailsPage.test.tsx @@ -1,14 +1,13 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; import { mockToolkitActionCreator } from 'test/core/redux/mocks'; +import { TestProvider } from 'test/helpers/TestProvider'; import { NavModel } from '@grafana/data'; import { ModalManager } from 'app/core/services/ModalManager'; import { backendSrv } from '../../core/services/backend_srv'; -import { configureStore } from '../../store/configureStore'; import { Organization } from '../../types'; import { OrgDetailsPage, Props } from './OrgDetailsPage'; @@ -37,7 +36,6 @@ jest.mock('@grafana/runtime', () => { }); const setup = (propOverrides?: object) => { - const store = configureStore(); jest.clearAllMocks(); // needed because SharedPreferences is rendered in the test jest.spyOn(backendSrv, 'put'); @@ -63,9 +61,9 @@ const setup = (propOverrides?: object) => { Object.assign(props, propOverrides); render( - + - + ); }; diff --git a/public/app/features/playlist/PlaylistEditPage.test.tsx b/public/app/features/playlist/PlaylistEditPage.test.tsx index a64bab76278..ac0e0e8ba03 100644 --- a/public/app/features/playlist/PlaylistEditPage.test.tsx +++ b/public/app/features/playlist/PlaylistEditPage.test.tsx @@ -1,13 +1,11 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { locationService } from '@grafana/runtime'; import { backendSrv } from 'app/core/services/backend_srv'; -import { configureStore } from '../../store/configureStore'; - import { PlaylistEditPage } from './PlaylistEditPage'; import { Playlist } from './types'; @@ -24,7 +22,6 @@ jest.mock('app/core/components/TagFilter/TagFilter', () => ({ async function getTestContext({ name, interval, items, uid }: Partial = {}) { jest.clearAllMocks(); - const store = configureStore(); const playlist = { name, items, interval, uid } as unknown as Playlist; const queryParams = {}; const route: any = {}; @@ -33,16 +30,18 @@ async function getTestContext({ name, interval, items, uid }: Partial const history: any = {}; const getMock = jest.spyOn(backendSrv, 'get'); const putMock = jest.spyOn(backendSrv, 'put'); + getMock.mockResolvedValue({ name: 'Test Playlist', interval: '5s', items: [{ title: 'First item', type: 'dashboard_by_uid', order: 1, value: '1' }], uid: 'foo', }); + const { rerender } = render( - + - + ); await waitFor(() => expect(getMock).toHaveBeenCalledTimes(1)); diff --git a/public/app/features/playlist/PlaylistNewPage.test.tsx b/public/app/features/playlist/PlaylistNewPage.test.tsx index 69cabd81048..9034ca2059f 100644 --- a/public/app/features/playlist/PlaylistNewPage.test.tsx +++ b/public/app/features/playlist/PlaylistNewPage.test.tsx @@ -1,13 +1,12 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { selectors } from '@grafana/e2e-selectors'; import { locationService } from '@grafana/runtime'; import { backendSrv } from '../../core/services/backend_srv'; -import { configureStore } from '../../store/configureStore'; import { PlaylistNewPage } from './PlaylistNewPage'; import { Playlist } from './types'; @@ -24,15 +23,14 @@ jest.mock('app/core/components/TagFilter/TagFilter', () => ({ })); function getTestContext({ name, interval, items }: Partial = {}) { - const store = configureStore(); jest.clearAllMocks(); const playlist = { name, items, interval } as unknown as Playlist; const backendSrvMock = jest.spyOn(backendSrv, 'post'); const { rerender } = render( - + - + ); return { playlist, rerender, backendSrvMock }; diff --git a/public/app/features/playlist/PlaylistPage.test.tsx b/public/app/features/playlist/PlaylistPage.test.tsx index 70f1b6924b0..51af4e47ad4 100644 --- a/public/app/features/playlist/PlaylistPage.test.tsx +++ b/public/app/features/playlist/PlaylistPage.test.tsx @@ -1,11 +1,9 @@ import { render, waitFor } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { contextSrv } from 'app/core/services/context_srv'; -import { configureStore } from '../../store/configureStore'; - import { PlaylistPage } from './PlaylistPage'; const fnMock = jest.fn(); @@ -24,11 +22,10 @@ jest.mock('app/core/services/context_srv', () => ({ })); function getTestContext() { - const store = configureStore(); return render( - + - + ); } diff --git a/public/app/features/plugins/admin/pages/Browse.test.tsx b/public/app/features/plugins/admin/pages/Browse.test.tsx index 632d8bcfb18..687b0a057bc 100644 --- a/public/app/features/plugins/admin/pages/Browse.test.tsx +++ b/public/app/features/plugins/admin/pages/Browse.test.tsx @@ -1,8 +1,7 @@ import { render, RenderResult, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { PluginType, escapeStringForRegex } from '@grafana/data'; import { locationService } from '@grafana/runtime'; @@ -37,11 +36,9 @@ const renderBrowse = ( }); return render( - - - - - + + + ); }; diff --git a/public/app/features/plugins/admin/pages/PluginDetails.test.tsx b/public/app/features/plugins/admin/pages/PluginDetails.test.tsx index 16892cb07b4..139a38c9ad9 100644 --- a/public/app/features/plugins/admin/pages/PluginDetails.test.tsx +++ b/public/app/features/plugins/admin/pages/PluginDetails.test.tsx @@ -1,8 +1,8 @@ import { getDefaultNormalizer, render, RenderResult, SelectorMatcherOptions, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; -import { MemoryRouter, Route } from 'react-router-dom'; +import { Route } from 'react-router-dom'; +import { TestProvider } from 'test/helpers/TestProvider'; import { PluginErrorCode, @@ -12,7 +12,7 @@ import { WithAccessControlMetadata, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { config } from '@grafana/runtime'; +import { config, locationService } from '@grafana/runtime'; import { configureStore } from 'app/store/configureStore'; import { mockPluginApis, getCatalogPluginMock, getPluginsStateMock, mockUserPermissions } from '../__mocks__'; @@ -73,12 +73,12 @@ const renderPluginDetails = ( plugins: pluginsStateOverride || getPluginsStateMock([plugin]), }); + locationService.push({ pathname: `/plugins/${id}`, search: pageId ? `?page=${pageId}` : '' }); + return render( - - - - - + + + ); }; diff --git a/public/app/features/profile/ChangePasswordPage.test.tsx b/public/app/features/profile/ChangePasswordPage.test.tsx index dcef679b234..cc3bedbac83 100644 --- a/public/app/features/profile/ChangePasswordPage.test.tsx +++ b/public/app/features/profile/ChangePasswordPage.test.tsx @@ -1,12 +1,11 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import config from 'app/core/config'; import { backendSrv } from '../../core/services/backend_srv'; -import { configureStore } from '../../store/configureStore'; import { Props, ChangePasswordPage } from './ChangePasswordPage'; import { initialUserState } from './state/reducers'; @@ -28,7 +27,6 @@ const defaultProps: Props = { }; async function getTestContext(overrides: Partial = {}) { - const store = configureStore(); jest.clearAllMocks(); jest.spyOn(backendSrv, 'get').mockResolvedValue({ id: 1, @@ -42,9 +40,9 @@ async function getTestContext(overrides: Partial = {}) { const props = { ...defaultProps, ...overrides }; const { rerender } = render( - + - + ); await waitFor(() => expect(props.loadUser).toHaveBeenCalledTimes(1)); diff --git a/public/app/features/profile/UserProfileEditPage.test.tsx b/public/app/features/profile/UserProfileEditPage.test.tsx index d767e793eb3..0c92be131ab 100644 --- a/public/app/features/profile/UserProfileEditPage.test.tsx +++ b/public/app/features/profile/UserProfileEditPage.test.tsx @@ -2,14 +2,12 @@ import { within } from '@testing-library/dom'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; import { OrgRole } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import TestProvider from '../../../test/helpers/TestProvider'; +import { TestProvider } from '../../../test/helpers/TestProvider'; import { backendSrv } from '../../core/services/backend_srv'; -import { configureStore } from '../../store/configureStore'; import { TeamPermissionLevel } from '../../types'; import { getMockTeam } from '../teams/__mocks__/teamMocks'; @@ -98,7 +96,6 @@ function getSelectors() { } async function getTestContext(overrides: Partial = {}) { - const store = configureStore(); jest.clearAllMocks(); const putSpy = jest.spyOn(backendSrv, 'put'); const getSpy = jest @@ -108,11 +105,9 @@ async function getTestContext(overrides: Partial = {}) { const props = { ...defaultProps, ...overrides }; const { rerender } = render( - - - - - + + + ); await waitFor(() => expect(props.initUserProfilePage).toHaveBeenCalledTimes(1)); diff --git a/public/app/features/serviceaccounts/ServiceAccountCreatePage.test.tsx b/public/app/features/serviceaccounts/ServiceAccountCreatePage.test.tsx index e9dfe18c306..7d53a87ffa2 100644 --- a/public/app/features/serviceaccounts/ServiceAccountCreatePage.test.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountCreatePage.test.tsx @@ -1,9 +1,7 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; - -import { configureStore } from '../../store/configureStore'; +import { TestProvider } from 'test/helpers/TestProvider'; import { ServiceAccountCreatePage, Props } from './ServiceAccountCreatePage'; @@ -45,7 +43,6 @@ jest.mock('app/core/core', () => ({ })); const setup = (propOverrides: Partial) => { - const store = configureStore(); const props: Props = { navModel: { main: { @@ -60,9 +57,9 @@ const setup = (propOverrides: Partial) => { Object.assign(props, propOverrides); render( - + - + ); }; diff --git a/public/app/features/serviceaccounts/ServiceAccountPage.test.tsx b/public/app/features/serviceaccounts/ServiceAccountPage.test.tsx index 9a3e5800c70..6cf3d35903a 100644 --- a/public/app/features/serviceaccounts/ServiceAccountPage.test.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountPage.test.tsx @@ -1,12 +1,10 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { ApiKey, OrgRole, ServiceAccountDTO } from 'app/types'; -import { configureStore } from '../../store/configureStore'; - import { ServiceAccountPageUnconnected, Props } from './ServiceAccountPage'; jest.mock('app/core/core', () => ({ @@ -19,7 +17,6 @@ jest.mock('app/core/core', () => ({ })); const setup = (propOverrides: Partial) => { - const store = configureStore(); const createServiceAccountTokenMock = jest.fn(); const deleteServiceAccountMock = jest.fn(); const deleteServiceAccountTokenMock = jest.fn(); @@ -54,9 +51,9 @@ const setup = (propOverrides: Partial) => { Object.assign(props, propOverrides); const { rerender } = render( - + - + ); return { rerender, diff --git a/public/app/features/serviceaccounts/ServiceAccountsListPage.test.tsx b/public/app/features/serviceaccounts/ServiceAccountsListPage.test.tsx index 4e4d74ec145..bd459659dbe 100644 --- a/public/app/features/serviceaccounts/ServiceAccountsListPage.test.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountsListPage.test.tsx @@ -1,12 +1,10 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { OrgRole, ServiceAccountDTO, ServiceAccountStateFilter } from 'app/types'; -import { configureStore } from '../../store/configureStore'; - import { Props, ServiceAccountsListPageUnconnected } from './ServiceAccountsListPage'; jest.mock('app/core/core', () => ({ @@ -18,7 +16,6 @@ jest.mock('app/core/core', () => ({ })); const setup = (propOverrides: Partial) => { - const store = configureStore(); const changeQueryMock = jest.fn(); const fetchACOptionsMock = jest.fn(); const fetchServiceAccountsMock = jest.fn(); @@ -56,12 +53,12 @@ const setup = (propOverrides: Partial) => { Object.assign(props, propOverrides); const { rerender } = render( - + - + ); return { - rerender: (element: JSX.Element) => rerender({element}), + rerender: (element: JSX.Element) => rerender({element}), props, changeQueryMock, fetchACOptionsMock, diff --git a/public/app/features/teams/CreateTeam.test.tsx b/public/app/features/teams/CreateTeam.test.tsx index 3cfdbb310ee..dfa891519ba 100644 --- a/public/app/features/teams/CreateTeam.test.tsx +++ b/public/app/features/teams/CreateTeam.test.tsx @@ -1,12 +1,10 @@ import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { BackendSrv, setBackendSrv } from '@grafana/runtime'; -import { configureStore } from '../../store/configureStore'; - import { CreateTeam } from './CreateTeam'; beforeEach(() => { @@ -35,11 +33,10 @@ setBackendSrv({ } as unknown as BackendSrv); const setup = () => { - const store = configureStore(); return render( - + - + ); }; diff --git a/public/app/features/teams/TeamList.test.tsx b/public/app/features/teams/TeamList.test.tsx index 5adaa2a8722..85d1636e367 100644 --- a/public/app/features/teams/TeamList.test.tsx +++ b/public/app/features/teams/TeamList.test.tsx @@ -1,11 +1,10 @@ import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { contextSrv, User } from 'app/core/services/context_srv'; -import { configureStore } from '../../store/configureStore'; import { OrgRole, Team } from '../../types'; import { Props, TeamList } from './TeamList'; @@ -17,7 +16,6 @@ jest.mock('app/core/config', () => ({ })); const setup = (propOverrides?: object) => { - const store = configureStore(); const props: Props = { teams: [] as Team[], noTeams: false, @@ -41,9 +39,9 @@ const setup = (propOverrides?: object) => { contextSrv.user = props.signedInUser; render( - + - + ); }; diff --git a/public/app/features/teams/TeamPages.test.tsx b/public/app/features/teams/TeamPages.test.tsx index 2e165284c12..fab1b3b90ab 100644 --- a/public/app/features/teams/TeamPages.test.tsx +++ b/public/app/features/teams/TeamPages.test.tsx @@ -1,11 +1,10 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; +import { TestProvider } from 'test/helpers/TestProvider'; import { createTheme } from '@grafana/data'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; import { User } from 'app/core/services/context_srv'; -import { configureStore } from 'app/store/configureStore'; import { OrgRole, Team, TeamMember } from '../../types'; @@ -64,7 +63,6 @@ jest.mock('./TeamGroupSync', () => { }); const setup = (propOverrides?: object) => { - const store = configureStore(); const props: Props = { ...getRouteComponentProps({ match: { @@ -93,9 +91,9 @@ const setup = (propOverrides?: object) => { Object.assign(props, propOverrides); render( - + - + ); }; diff --git a/public/app/routes/routes.tsx b/public/app/routes/routes.tsx index 0973b7420c6..3b087e59c81 100644 --- a/public/app/routes/routes.tsx +++ b/public/app/routes/routes.tsx @@ -401,7 +401,7 @@ export function getAppRoutes(): RouteDescriptor[] { { path: '/login', component: LoginPage, - pageClass: 'login-page sidemenu-hidden', + pageClass: 'login-page', chromeless: true, }, { @@ -409,7 +409,6 @@ export function getAppRoutes(): RouteDescriptor[] { component: SafeDynamicImport( () => import(/* webpackChunkName: "SignupInvited" */ 'app/features/invites/SignupInvited') ), - pageClass: 'sidemenu-hidden', chromeless: true, }, { @@ -419,7 +418,7 @@ export function getAppRoutes(): RouteDescriptor[] { : SafeDynamicImport( () => import(/* webpackChunkName "VerifyEmailPage"*/ 'app/core/components/Signup/VerifyEmailPage') ), - pageClass: 'login-page sidemenu-hidden', + pageClass: 'login-page', chromeless: true, }, { @@ -427,12 +426,11 @@ export function getAppRoutes(): RouteDescriptor[] { component: config.disableUserSignUp ? () => : SafeDynamicImport(() => import(/* webpackChunkName "SignupPage"*/ 'app/core/components/Signup/SignupPage')), - pageClass: 'sidemenu-hidden login-page', + pageClass: 'login-page', chromeless: true, }, { path: '/user/password/send-reset-email', - pageClass: 'sidemenu-hidden', chromeless: true, component: SafeDynamicImport( () => @@ -447,7 +445,7 @@ export function getAppRoutes(): RouteDescriptor[] { /* webpackChunkName: "ChangePasswordPage" */ 'app/core/components/ForgottenPassword/ChangePasswordPage' ) ), - pageClass: 'sidemenu-hidden login-page', + pageClass: 'login-page', chromeless: true, }, { diff --git a/public/app/types/events.ts b/public/app/types/events.ts index 8501bcc0f26..882cd3df12f 100644 --- a/public/app/types/events.ts +++ b/public/app/types/events.ts @@ -87,7 +87,6 @@ export interface PanelChangeViewPayload {} export const dsRequestResponse = eventFactory('ds-request-response'); export const dsRequestError = eventFactory('ds-request-error'); -export const toggleSidemenuHidden = eventFactory('toggle-sidemenu-hidden'); export const templateVariableValueUpdated = eventFactory('template-variable-value-updated'); export const graphClicked = eventFactory('graph-click'); diff --git a/public/test/helpers/TestProvider.tsx b/public/test/helpers/TestProvider.tsx index c808eefd048..739af4c454d 100644 --- a/public/test/helpers/TestProvider.tsx +++ b/public/test/helpers/TestProvider.tsx @@ -1,7 +1,32 @@ +import { ToolkitStore } from '@reduxjs/toolkit/dist/configureStore'; import React from 'react'; +import { Provider } from 'react-redux'; +import { Router } from 'react-router-dom'; +import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock'; -const TestProvider = ({ children }: React.PropsWithChildren<{}>) => { - return <>{children}; -}; +import { locationService } from '@grafana/runtime'; +import { GrafanaContext, GrafanaContextType } from 'app/core/context/GrafanaContext'; +import { configureStore } from 'app/store/configureStore'; +import { StoreState } from 'app/types/store'; -export default TestProvider; +export interface Props { + storeState?: Partial; + store?: ToolkitStore; + children: React.ReactNode; + grafanaContext?: GrafanaContextType; +} + +/** + * Wrapps component in redux store provider, Router and GrafanaContext + */ +export function TestProvider(props: Props) { + const { store = configureStore(props.storeState), grafanaContext = getGrafanaContextMock(), children } = props; + + return ( + + + {children} + + + ); +} diff --git a/public/test/helpers/alertingRuleEditor.tsx b/public/test/helpers/alertingRuleEditor.tsx index eac7a02fc57..02b57153da0 100644 --- a/public/test/helpers/alertingRuleEditor.tsx +++ b/public/test/helpers/alertingRuleEditor.tsx @@ -1,13 +1,13 @@ import { render } from '@testing-library/react'; import React from 'react'; -import { Provider } from 'react-redux'; -import { Router, Route } from 'react-router-dom'; +import { Route } from 'react-router-dom'; import { byRole, byTestId } from 'testing-library-selector'; import { selectors } from '@grafana/e2e-selectors'; import { locationService } from '@grafana/runtime'; import RuleEditor from 'app/features/alerting/unified/RuleEditor'; -import { configureStore } from 'app/store/configureStore'; + +import { TestProvider } from './TestProvider'; export const ui = { inputs: { @@ -36,15 +36,11 @@ export const ui = { }; export function renderRuleEditor(identifier?: string) { - const store = configureStore(); - locationService.push(identifier ? `/alerting/${identifier}/edit` : `/alerting/new`); return render( - - - - - + + + ); }