Refactor tab query param logic and add tests

This commit is contained in:
Tom Ratcliffe 2024-04-08 15:56:56 +01:00 committed by Tom Ratcliffe
parent 800a2e0228
commit d91e1a4e3a
2 changed files with 65 additions and 32 deletions

View File

@ -1,7 +1,7 @@
import { render, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { noop } from 'lodash';
import React, { PropsWithChildren } from 'react';
import React, { ComponentProps, PropsWithChildren } from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
import { selectors } from '@grafana/e2e-selectors';
@ -40,6 +40,18 @@ import setupVanillaAlertmanagerFlavoredServer, {
*/
const server = setupMswServer();
const renderWithProvider = (
providerProps?: Partial<ComponentProps<typeof AlertmanagerProvider>>,
contactPointProps?: Partial<ComponentProps<typeof ContactPoints>>
) =>
render(
<TestProvider>
<AlertmanagerProvider accessType={'notification'} {...providerProps}>
<ContactPoints {...contactPointProps} />
</AlertmanagerProvider>
</TestProvider>
);
describe('contact points', () => {
beforeEach(() => {
// The location service is stateful between tests - `TestProvider` uses the same instance between each test
@ -58,13 +70,37 @@ describe('contact points', () => {
setupGrafanaManagedServer(server);
});
describe('tabs behaviour', () => {
test('loads contact points tab', async () => {
locationService.push('/?tab=contact_points');
renderWithProvider();
expect(await screen.findByText(/add contact point/i)).toBeInTheDocument();
});
test('loads templates tab', async () => {
locationService.push('/?tab=templates');
renderWithProvider();
expect(await screen.findByText(/add notification template/i)).toBeInTheDocument();
});
test('defaults to contact points tab with invalid query param', async () => {
locationService.push('/?tab=foo_bar');
renderWithProvider();
expect(await screen.findByText(/add contact point/i)).toBeInTheDocument();
});
test('defaults to contact points tab with no query param', async () => {
renderWithProvider();
expect(await screen.findByText(/add contact point/i)).toBeInTheDocument();
});
});
it('should show / hide loading states, have all actions enabled', async () => {
render(
<AlertmanagerProvider accessType={'notification'}>
<ContactPoints />
</AlertmanagerProvider>,
{ wrapper: TestProvider }
);
renderWithProvider();
await waitFor(async () => {
expect(screen.getByText('Loading...')).toBeInTheDocument();
@ -103,12 +139,7 @@ describe('contact points', () => {
it('should disable certain actions if the user has no write permissions', async () => {
grantUserPermissions([AccessControlAction.AlertingNotificationsRead]);
render(
<AlertmanagerProvider accessType={'notification'}>
<ContactPoints />
</AlertmanagerProvider>,
{ wrapper: TestProvider }
);
renderWithProvider();
// wait for loading to be done
await waitFor(async () => {
@ -211,12 +242,7 @@ describe('contact points', () => {
});
it('should be able to search', async () => {
render(
<AlertmanagerProvider accessType={'notification'}>
<ContactPoints />
</AlertmanagerProvider>,
{ wrapper: TestProvider }
);
renderWithProvider();
const searchInput = screen.getByRole('textbox', { name: 'search contact points' });
await userEvent.type(searchInput, 'slack');
@ -254,13 +280,7 @@ describe('contact points', () => {
});
it('should show / hide loading states, have the right actions enabled', async () => {
render(
<TestProvider>
<AlertmanagerProvider accessType={'notification'} alertmanagerSourceName={MIMIR_DATASOURCE_UID}>
<ContactPoints />
</AlertmanagerProvider>
</TestProvider>
);
renderWithProvider({ alertmanagerSourceName: MIMIR_DATASOURCE_UID });
await waitFor(async () => {
expect(screen.getByText('Loading...')).toBeInTheDocument();

View File

@ -25,8 +25,8 @@ import {
Tooltip,
useStyles2,
} from '@grafana/ui';
import { useQueryParams } from 'app/core/hooks/useQueryParams';
import ConditionalWrap from 'app/features/alerting/unified/components/ConditionalWrap';
import { useURLSearchParams } from 'app/features/alerting/unified/hooks/useURLSearchParams';
import { receiverTypeNames } from 'app/plugins/datasource/alertmanager/consts';
import { GrafanaManagedReceiverConfig } from 'app/plugins/datasource/alertmanager/types';
import { GrafanaNotifierType, NotifierStatus } from 'app/types/alerting';
@ -69,12 +69,25 @@ export enum ActiveTab {
const DEFAULT_PAGE_SIZE = 10;
const useTabQueryParam = () => {
const [queryParams] = useURLSearchParams();
return useMemo(() => {
const queryParam = queryParams.get('tab');
if (!queryParam || !Object.values(ActiveTab).map(String).includes(queryParam)) {
return ActiveTab.ContactPoints;
}
return queryParam || ActiveTab.ContactPoints;
}, [queryParams]);
};
const ContactPoints = () => {
const { selectedAlertmanager } = useAlertmanager();
const [queryParams, setQueryParams] = useQueryParams();
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const initialActiveTab = queryParams.tab as ActiveTab;
const [activeTab, setActiveTab] = useState<ActiveTab>(initialActiveTab || ActiveTab.ContactPoints);
const [queryParams, setQueryParams] = useURLSearchParams();
const activeTabVal = useTabQueryParam();
const [activeTab, setActiveTab] = useState(activeTabVal);
let { isLoading, error, contactPoints } = useContactPointsWithStatus();
const { deleteTrigger, updateAlertmanagerState } = useDeleteContactPoint(selectedAlertmanager!);
const [addContactPointSupported, addContactPointAllowed] = useAlertmanagerAbility(
@ -90,7 +103,7 @@ const ContactPoints = () => {
const [DeleteModal, showDeleteModal] = useDeleteContactPointModal(deleteTrigger, updateAlertmanagerState.isLoading);
const [ExportDrawer, showExportDrawer] = useExportContactPoint();
const search = String(queryParams.search || '');
const search = queryParams.get('search');
const showingContactPoints = activeTab === ActiveTab.ContactPoints;
const showNotificationTemplates = activeTab === ActiveTab.NotificationTemplates;