Alerting: Remove unneeded uses of setBackendSrv in alerting tests (#90380)

This commit is contained in:
Tom Ratcliffe 2024-07-15 09:09:24 +01:00 committed by GitHub
parent c77015b329
commit 0547a9ed88
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 40 additions and 234 deletions

View File

@ -1,30 +1,24 @@
import { SerializedError } from '@reduxjs/toolkit';
import userEvent from '@testing-library/user-event';
import { setupServer } from 'msw/node';
import { SetupServer } from 'msw/node';
import { TestProvider } from 'test/helpers/TestProvider';
import { prettyDOM, render, screen, waitFor, within } from 'test/test-utils';
import { byRole, byTestId, byText } from 'testing-library-selector';
import { PluginExtensionTypes, PluginMeta } from '@grafana/data';
import { PluginExtensionTypes } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import {
DataSourceSrv,
getPluginLinkExtensions,
locationService,
setBackendSrv,
setAppEvents,
setDataSourceSrv,
usePluginLinkExtensions,
} from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import appEvents from 'app/core/app_events';
import * as ruleActionButtons from 'app/features/alerting/unified/components/rules/RuleActionsButtons';
import {
mockAlertRuleApi,
mockApi,
mockFolderApi,
mockSearchApi,
mockUserApi,
} from 'app/features/alerting/unified/mockApi';
import { mockAlertmanagerChoiceResponse } from 'app/features/alerting/unified/mocks/alertmanagerApi';
import { mockSearchApi, mockUserApi, setupMswServer } from 'app/features/alerting/unified/mockApi';
import { setAlertmanagerChoices } from 'app/features/alerting/unified/mocks/server/configure';
import * as actions from 'app/features/alerting/unified/state/actions';
import { getMockUser } from 'app/features/users/__mocks__/userMocks';
import { AlertmanagerChoice } from 'app/plugins/datasource/alertmanager/types';
@ -42,13 +36,11 @@ import {
getPotentiallyPausedRulerRules,
grantUserPermissions,
mockDataSource,
mockFolder,
mockPromAlert,
mockPromAlertingRule,
mockPromRecordingRule,
mockPromRuleGroup,
mockPromRuleNamespace,
mockRulerGrafanaRule,
pausedPromRules,
somePromRules,
someRulerRules,
@ -67,22 +59,14 @@ jest.mock('./api/buildInfo');
jest.mock('./api/prometheus');
jest.mock('./api/ruler');
jest.mock('../../../core/hooks/useMediaQueryChange');
jest.spyOn(ruleActionButtons, 'matchesWidth').mockReturnValue(false);
jest.mock('app/core/core', () => ({
...jest.requireActual('app/core/core'),
appEvents: {
subscribe: () => {
return { unsubscribe: () => {} };
},
emit: () => {},
},
}));
jest.spyOn(ruleActionButtons, 'matchesWidth').mockReturnValue(false);
jest.spyOn(analytics, 'logInfo');
jest.spyOn(config, 'getAllDataSources');
jest.spyOn(actions, 'rulesInSameGroupHaveInvalidFor').mockReturnValue([]);
jest.spyOn(apiRuler, 'rulerUrlBuilder');
setAppEvents(appEvents);
setupPluginsExtensionsHook();
const mocks = {
@ -169,45 +153,17 @@ const ui = {
},
};
const server = setupServer();
const server = setupMswServer();
const configureMockServer = () => {
const configureMockServer = (server: SetupServer) => {
mockSearchApi(server).search([]);
mockUserApi(server).user(getMockUser());
mockFolderApi(server).folder(
'NAMESPACE_UID',
mockFolder({
accessControl: { [AccessControlAction.AlertingRuleUpdate]: true },
})
);
mockApi(server).plugins.getPluginSettings(
// We aren't particularly concerned with the plugin response in these tests
// at the time of writing, so we can go unknown -> PluginMeta to get the bare minimum
{ id: 'grafana-incident-app' } as unknown as PluginMeta
);
mockAlertmanagerChoiceResponse(server, {
alertmanagersChoice: AlertmanagerChoice.All,
numExternalAlertmanagers: 1,
});
mockAlertRuleApi(server).updateRule('grafana', {
message: 'rule group updated successfully',
updated: ['foo', 'bar', 'baz'],
});
mockAlertRuleApi(server).rulerRuleGroup(GRAFANA_RULES_SOURCE_NAME, 'NAMESPACE_UID', 'groupPaused', {
name: 'group-1',
interval: '1m',
rules: [mockRulerGrafanaRule()],
});
setAlertmanagerChoices(AlertmanagerChoice.All, 1);
};
beforeAll(() => {
setBackendSrv(backendSrv);
});
describe('RuleList', () => {
beforeEach(() => {
server.listen({ onUnhandledRequest: 'error' });
configureMockServer();
configureMockServer(server);
grantUserPermissions([
AccessControlAction.AlertingRuleRead,
AccessControlAction.AlertingRuleUpdate,
@ -232,15 +188,10 @@ describe('RuleList', () => {
});
afterEach(() => {
server.resetHandlers();
jest.resetAllMocks();
setDataSourceSrv(undefined as unknown as DataSourceSrv);
});
afterAll(() => {
server.close();
});
it('load & show rule groups from multiple cloud data sources', async () => {
mocks.getAllDataSourcesMock.mockReturnValue(Object.values(dataSources));

View File

@ -1,24 +0,0 @@
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import { SupportedPlugin } from '../types/pluginBridges';
export const NON_EXISTING_PLUGIN = '__does_not_exist__';
const server = setupServer(
http.get(`/api/plugins/${NON_EXISTING_PLUGIN}/settings`, async () =>
HttpResponse.json(
{},
{
status: 404,
}
)
),
http.get(`/api/plugins/${SupportedPlugin.Incident}/settings`, async () => {
return HttpResponse.json({
enabled: true,
});
})
);
export { server };

View File

@ -1,19 +1,12 @@
import { screen, render } from '@testing-library/react';
import { screen, render } from 'test/test-utils';
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { setupMswServer } from 'app/features/alerting/unified/mockApi';
import { SupportedPlugin } from '../types/pluginBridges';
import { createBridgeURL, PluginBridge } from './PluginBridge';
import { server, NON_EXISTING_PLUGIN } from './PluginBridge.mock';
beforeAll(() => {
setBackendSrv(backendSrv);
server.listen({ onUnhandledRequest: 'error' });
});
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
const NON_EXISTING_PLUGIN = '__does_not_exist__';
setupMswServer();
describe('createBridgeURL', () => {
it('should work with path', () => {

View File

@ -1,5 +1,5 @@
import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/lib/node';
import { SetupServer } from 'msw/node';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';

View File

@ -1,5 +1,5 @@
import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/lib/node';
import { SetupServer } from 'msw/node';
import { AlertmanagerStatus } from 'app/plugins/datasource/alertmanager/types';

View File

@ -1,13 +1,11 @@
import { screen, render, waitFor } from '@testing-library/react';
import { setupServer } from 'msw/node';
import { default as React } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { Provider } from 'react-redux';
import { screen, render, waitFor } from 'test/test-utils';
import { byRole } from 'testing-library-selector';
import { Components } from '@grafana/e2e-selectors';
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { setupMswServer } from 'app/features/alerting/unified/mockApi';
import { configureStore } from 'app/store/configureStore';
import { TemplatePreviewResponse } from '../../api/templateApi';
@ -39,20 +37,7 @@ const getProviderWraper = () => {
};
};
const server = setupServer();
beforeAll(() => {
setBackendSrv(backendSrv);
server.listen({ onUnhandledRequest: 'error' });
});
beforeEach(() => {
server.resetHandlers();
});
afterAll(() => {
server.close();
});
const server = setupMswServer();
const ui = {
errorAlert: byRole('alert', { name: /error/i }),

View File

@ -1,17 +1,13 @@
import { findByRole, findByText, findByTitle, getByTestId, queryByText, render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { setupServer } from 'msw/node';
import { FormProvider, useForm } from 'react-hook-form';
import { TestProvider } from 'test/helpers/TestProvider';
import { findByRole, findByText, findByTitle, getByTestId, queryByText, render } from 'test/test-utils';
import { byRole, byTestId } from 'testing-library-selector';
import 'core-js/stable/structured-clone';
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { DashboardSearchItemType } from '../../../../search/types';
import { mockDashboardApi } from '../../mockApi';
import { mockDashboardDto, mockDashboardSearchItem, mockStore } from '../../mocks';
import { mockDashboardApi, setupMswServer } from '../../mockApi';
import { mockDashboardDto, mockDashboardSearchItem } from '../../mocks';
import { RuleFormValues } from '../../types/rule-form';
import { Annotation } from '../../utils/constants';
import { getDefaultFormValues } from '../../utils/rule-form';
@ -40,31 +36,15 @@ const ui = {
},
} as const;
const server = setupServer();
beforeAll(() => {
setBackendSrv(backendSrv);
server.listen({ onUnhandledRequest: 'error' });
});
beforeEach(() => {
server.resetHandlers();
});
afterAll(() => {
server.close();
});
const server = setupMswServer();
function FormWrapper({ formValues }: { formValues?: Partial<RuleFormValues> }) {
const store = mockStore(() => null);
const formApi = useForm<RuleFormValues>({ defaultValues: { ...getDefaultFormValues(), ...formValues } });
return (
<TestProvider store={store}>
<FormProvider {...formApi}>
<AnnotationsStep />
</FormProvider>
</TestProvider>
<FormProvider {...formApi}>
<AnnotationsStep />
</FormProvider>
);
}

View File

@ -2,8 +2,7 @@ import { within } from '@testing-library/react';
import { render, waitFor, screen, userEvent } from 'test/test-utils';
import { byText, byRole } from 'testing-library-selector';
import { setBackendSrv, setPluginExtensionsHook } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { setPluginExtensionsHook } from '@grafana/runtime';
import { setupMswServer } from 'app/features/alerting/unified/mockApi';
import { setFolderAccessControl } from 'app/features/alerting/unified/mocks/server/configure';
import { AlertManagerDataSourceJsonData } from 'app/plugins/datasource/alertmanager/types';
@ -95,7 +94,6 @@ beforeAll(() => {
AccessControlAction.AlertingRuleDelete,
AccessControlAction.AlertingInstanceCreate,
]);
setBackendSrv(backendSrv);
});
describe('RuleViewer', () => {

View File

@ -1,41 +0,0 @@
import { http, HttpResponse, RequestHandler } from 'msw';
import { setupServer } from 'msw/node';
import { GrafanaAlertingConfigurationStatusResponse } from 'app/features/alerting/unified/api/alertmanagerApi';
import { grafanaAlertingConfigurationStatusHandler } from 'app/features/alerting/unified/mocks/server/handlers/alertmanagers';
import { AlertmanagerChoice } from 'app/plugins/datasource/alertmanager/types';
import { AccessControlAction } from 'app/types';
const grafanaAlertingConfigurationMockedResponse: GrafanaAlertingConfigurationStatusResponse = {
alertmanagersChoice: AlertmanagerChoice.Internal,
numExternalAlertmanagers: 0,
};
const folderAccess = {
[AccessControlAction.AlertingRuleCreate]: true,
[AccessControlAction.AlertingRuleRead]: true,
[AccessControlAction.AlertingRuleUpdate]: true,
[AccessControlAction.AlertingRuleDelete]: true,
};
export function createMockGrafanaServer(...handlers: RequestHandler[]) {
const folderHandler = mockFolderAccess(folderAccess);
const amChoiceHandler = grafanaAlertingConfigurationStatusHandler(grafanaAlertingConfigurationMockedResponse);
return setupServer(folderHandler, amChoiceHandler, ...handlers);
}
// this endpoint is used to determine of we have edit / delete permissions for the Grafana managed alert rule
// a user must alsso have permissions for the folder (namespace) in which the alert rule is stored
function mockFolderAccess(accessControl: Partial<Record<AccessControlAction, boolean>>) {
return http.get('/api/folders/:uid', ({ request }) => {
const url = new URL(request.url);
const uid = url.searchParams.get('uid');
return HttpResponse.json({
title: 'My Folder',
uid,
accessControl,
});
});
}

View File

@ -2,8 +2,7 @@ import { render } from 'test/test-utils';
import { byRole } from 'testing-library-selector';
import { PluginExtensionTypes } from '@grafana/data';
import { usePluginLinkExtensions, setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { usePluginLinkExtensions } from '@grafana/runtime';
import { setupMswServer } from 'app/features/alerting/unified/mockApi';
import { useIsRuleEditable } from '../../hooks/useIsRuleEditable';
@ -34,7 +33,6 @@ const ui = {
setupMswServer();
beforeAll(() => {
setBackendSrv(backendSrv);
jest.clearAllMocks();
});

View File

@ -1,18 +1,14 @@
import { render, waitFor } from '@testing-library/react';
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import { Props } from 'react-virtualized-auto-sizer';
import { render, waitFor } from 'test/test-utils';
import { byRole, byTestId, byText } from 'testing-library-selector';
import { DataFrameJSON } from '@grafana/data';
import { setBackendSrv } from '@grafana/runtime';
import { TestProvider } from '../../../../../../../test/helpers/TestProvider';
import { backendSrv } from '../../../../../../core/services/backend_srv';
import { setupMswServer } from 'app/features/alerting/unified/mockApi';
import LokiStateHistory from './LokiStateHistory';
const server = setupServer();
const server = setupMswServer();
jest.mock('react-virtualized-auto-sizer', () => {
return ({ children }: Props) =>
@ -25,9 +21,6 @@ jest.mock('react-virtualized-auto-sizer', () => {
});
beforeAll(() => {
setBackendSrv(backendSrv);
server.listen({ onUnhandledRequest: 'error' });
server.use(
http.get('/api/v1/rules/history', () =>
HttpResponse.json<DataFrameJSON>({
@ -78,10 +71,6 @@ beforeAll(() => {
);
});
afterAll(() => {
server.close();
});
window.HTMLElement.prototype.scrollIntoView = jest.fn();
const ui = {
@ -94,7 +83,7 @@ const ui = {
describe('LokiStateHistory', () => {
it('should render history records', async () => {
render(<LokiStateHistory ruleUID="ABC123" />, { wrapper: TestProvider });
render(<LokiStateHistory ruleUID="ABC123" />);
await waitFor(() => expect(ui.loadingIndicator.query()).not.toBeInTheDocument());
@ -107,7 +96,7 @@ describe('LokiStateHistory', () => {
});
it('should render timeline chart', async () => {
render(<LokiStateHistory ruleUID="ABC123" />, { wrapper: TestProvider });
render(<LokiStateHistory ruleUID="ABC123" />);
await waitFor(() => expect(ui.loadingIndicator.query()).not.toBeInTheDocument());
@ -121,7 +110,7 @@ describe('LokiStateHistory', () => {
)
);
render(<LokiStateHistory ruleUID="abcd" />, { wrapper: TestProvider });
render(<LokiStateHistory ruleUID="abcd" />);
await waitFor(() => expect(ui.loadingIndicator.query()).not.toBeInTheDocument());

View File

@ -1,5 +1,5 @@
import { delay, http, HttpResponse } from 'msw';
import { SetupServerApi } from 'msw/lib/node';
import { SetupServerApi } from 'msw/node';
import { setDataSourceSrv } from '@grafana/runtime';
import {

View File

@ -3,8 +3,6 @@ import { HttpResponse } from 'msw';
import { render } from 'test/test-utils';
import { byRole, byText } from 'testing-library-selector';
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { AccessControlAction } from 'app/types';
import { CombinedRule } from 'app/types/unified-alerting';
@ -29,7 +27,6 @@ import { useDeleteRuleFromGroup } from './useDeleteRuleFromGroup';
setupMswServer();
beforeAll(() => {
setBackendSrv(backendSrv);
grantUserPermissions([AccessControlAction.AlertingRuleExternalRead, AccessControlAction.AlertingRuleRead]);
});

View File

@ -3,8 +3,6 @@ import { HttpResponse } from 'msw';
import { render } from 'test/test-utils';
import { byText, byRole } from 'testing-library-selector';
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { AccessControlAction } from 'app/types';
import { RulerGrafanaRuleDTO } from 'app/types/unified-alerting-dto';
@ -21,7 +19,6 @@ import { usePauseRuleInGroup } from './usePauseAlertRule';
setupMswServer();
beforeAll(() => {
setBackendSrv(backendSrv);
grantUserPermissions([AccessControlAction.AlertingRuleExternalRead, AccessControlAction.AlertingRuleRead]);
});

View File

@ -2,8 +2,6 @@ import userEvent from '@testing-library/user-event';
import { render } from 'test/test-utils';
import { byRole, byText } from 'testing-library-selector';
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { AccessControlAction } from 'app/types';
import { RuleGroupIdentifier } from 'app/types/unified-alerting';
@ -22,7 +20,6 @@ import { useMoveRuleGroup, useRenameRuleGroup, useUpdateRuleGroupConfiguration }
setupMswServer();
beforeAll(() => {
setBackendSrv(backendSrv);
grantUserPermissions([AccessControlAction.AlertingRuleExternalRead, AccessControlAction.AlertingRuleRead]);
});

View File

@ -1,31 +1,17 @@
import { renderHook, waitFor } from '@testing-library/react';
import { http, HttpResponse } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
import { SetupServer } from 'msw/node';
import { TestProvider } from 'test/helpers/TestProvider';
import { DataSourceSettings } from '@grafana/data';
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { setupMswServer } from 'app/features/alerting/unified/mockApi';
import { AlertManagerDataSourceJsonData } from 'app/plugins/datasource/alertmanager/types';
import { mockAlertmanagersResponse } from '../mocks/alertmanagerApi';
import { normalizeDataSourceURL, useExternalDataSourceAlertmanagers } from './useExternalAmSelector';
const server = setupServer();
beforeAll(() => {
setBackendSrv(backendSrv);
server.listen({ onUnhandledRequest: 'error' });
});
beforeEach(() => {
server.resetHandlers();
});
afterAll(() => {
server.close();
});
const server = setupMswServer();
describe('useExternalDataSourceAlertmanagers', () => {
it('Should get the correct data source settings', async () => {