Navigation: fix navigation when appSubUrl is configured (#42863)
* Navigation: fix navigation when appSubUrl is configured * Update public/app/core/components/NavBar/NavBarItem.tsx Co-authored-by: Torkel Ödegaard <torkel@grafana.org> * Chore: changes after PR comments Co-authored-by: Torkel Ödegaard <torkel@grafana.org>
This commit is contained in:
co-authored by
Torkel Ödegaard
parent
bb17193ce5
commit
a0333c1545
@@ -1,8 +1,11 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import NavBarItem, { Props } from './NavBarItem';
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { locationUtil } from '@grafana/data';
|
||||
import { config, setLocationService } from '@grafana/runtime';
|
||||
|
||||
import NavBarItem, { Props } from './NavBarItem';
|
||||
|
||||
const onClickMock = jest.fn();
|
||||
const defaults: Props = {
|
||||
@@ -17,8 +20,13 @@ const defaults: Props = {
|
||||
},
|
||||
};
|
||||
|
||||
function getTestContext(overrides: Partial<Props> = {}) {
|
||||
function getTestContext(overrides: Partial<Props> = {}, subUrl = '') {
|
||||
jest.clearAllMocks();
|
||||
config.appSubUrl = subUrl;
|
||||
locationUtil.initialize({ config, getTimeRangeForUrl: jest.fn(), getVariablesUrlParams: jest.fn() });
|
||||
const pushMock = jest.fn();
|
||||
const locationService: any = { push: pushMock };
|
||||
setLocationService(locationService);
|
||||
const props = { ...defaults, ...overrides };
|
||||
|
||||
const { rerender } = render(
|
||||
@@ -27,7 +35,7 @@ function getTestContext(overrides: Partial<Props> = {}) {
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
||||
return { rerender };
|
||||
return { rerender, pushMock };
|
||||
}
|
||||
|
||||
describe('NavBarItem', () => {
|
||||
@@ -140,5 +148,56 @@ describe('NavBarItem', () => {
|
||||
expect(screen.getAllByRole('menuitem')[2]).toHaveAttribute('tabIndex', '-1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when appSubUrl is configured and user clicks on menuitem link', () => {
|
||||
it('then location service should be called with correct url', async () => {
|
||||
const { pushMock } = getTestContext(
|
||||
{
|
||||
link: {
|
||||
...defaults.link,
|
||||
url: 'https://www.grafana.com',
|
||||
children: [{ text: 'New', url: '/grafana/dashboard/new', children: [] }],
|
||||
},
|
||||
},
|
||||
'/grafana'
|
||||
);
|
||||
|
||||
userEvent.hover(screen.getByRole('link'));
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
||||
expect(screen.getByText('New')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
userEvent.click(screen.getByText('New'));
|
||||
await waitFor(() => {
|
||||
expect(pushMock).toHaveBeenCalledTimes(1);
|
||||
expect(pushMock).toHaveBeenCalledWith('/dashboard/new');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when appSubUrl is not configured and user clicks on menuitem link', () => {
|
||||
it('then location service should be called with correct url', async () => {
|
||||
const { pushMock } = getTestContext({
|
||||
link: {
|
||||
...defaults.link,
|
||||
url: 'https://www.grafana.com',
|
||||
children: [{ text: 'New', url: '/grafana/dashboard/new', children: [] }],
|
||||
},
|
||||
});
|
||||
|
||||
userEvent.hover(screen.getByRole('link'));
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
||||
expect(screen.getByText('New')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
userEvent.click(screen.getByText('New'));
|
||||
await waitFor(() => {
|
||||
expect(pushMock).toHaveBeenCalledTimes(1);
|
||||
expect(pushMock).toHaveBeenCalledWith('/grafana/dashboard/new');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { Item } from '@react-stately/collections';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { GrafanaTheme2, NavMenuItemType, NavModelItem } from '@grafana/data';
|
||||
import { GrafanaTheme2, locationUtil, NavMenuItemType, NavModelItem } from '@grafana/data';
|
||||
import { IconName, useTheme2 } from '@grafana/ui';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
|
||||
@@ -50,7 +50,7 @@ const NavBarItem = ({
|
||||
}
|
||||
|
||||
if (!target && url.startsWith('/')) {
|
||||
locationService.push(url);
|
||||
locationService.push(locationUtil.stripBaseFromUrl(url));
|
||||
} else {
|
||||
window.open(url, target);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user