Update tests to use existing mock server approach

This commit is contained in:
Tom Ratcliffe
2024-03-26 16:26:50 +00:00
committed by Tom Ratcliffe
parent 5fbca0962e
commit b84962ef3f
4 changed files with 78 additions and 52 deletions

View File

@@ -1,11 +1,12 @@
import { SerializedError } from '@reduxjs/toolkit';
import { prettyDOM, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { setupServer } from 'msw/node';
import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
import { byRole, byTestId, byText } from 'testing-library-selector';
import { PluginExtensionTypes } from '@grafana/data';
import { PluginExtensionTypes, PluginMeta } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import {
DataSourceSrv,
@@ -16,9 +17,17 @@ import {
} from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import * as ruleActionButtons from 'app/features/alerting/unified/components/rules/RuleActionsButtons';
import alertingServer from 'app/features/alerting/unified/mock-server';
import {
mockAlertRuleApi,
mockApi,
mockFolderApi,
mockSearchApi,
mockUserApi,
} from 'app/features/alerting/unified/mockApi';
import { mockAlertmanagerChoiceResponse } from 'app/features/alerting/unified/mocks/alertmanagerApi';
import * as actions from 'app/features/alerting/unified/state/actions';
import { AccessControlAction } from 'app/types';
import { AlertmanagerChoice } from 'app/plugins/datasource/alertmanager/types';
import { AccessControlAction, FolderDTO } from 'app/types';
import { PromAlertingRuleState, PromApplication } from 'app/types/unified-alerting-dto';
import * as analytics from './Analytics';
@@ -39,6 +48,8 @@ import {
getPotentiallyPausedRulerRules,
somePromRules,
someRulerRules,
mockFolder,
mockUser,
} from './mocks';
import * as config from './utils/config';
import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource';
@@ -149,13 +160,40 @@ const ui = {
},
};
const server = setupServer();
const configureMockServer = () => {
mockSearchApi(server).search([]);
mockUserApi(server).user(mockUser());
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'],
});
};
beforeAll(() => {
setBackendSrv(backendSrv);
});
describe('RuleList', () => {
beforeEach(() => {
alertingServer.listen({ onUnhandledRequest: 'error' });
server.listen({ onUnhandledRequest: 'error' });
configureMockServer();
grantUserPermissions([
AccessControlAction.AlertingRuleRead,
AccessControlAction.AlertingRuleUpdate,
@@ -179,13 +217,13 @@ describe('RuleList', () => {
});
afterEach(() => {
alertingServer.resetHandlers();
server.resetHandlers();
jest.resetAllMocks();
setDataSourceSrv(undefined as unknown as DataSourceSrv);
});
afterAll(() => {
alertingServer.close();
server.close();
});
it('load & show rule groups from multiple cloud data sources', async () => {

View File

@@ -1,44 +0,0 @@
import 'whatwg-fetch';
import { HttpResponse, http } from 'msw';
import { setupServer } from 'msw/node';
import { AccessControlAction } from 'app/types';
const alertingServer = setupServer(
// TODO: Scaffold out test behaviour/configuration for search endpoint
http.get('/api/search', () => {
return HttpResponse.json([]);
}),
// TODO: Scaffold out test behaviour/configuration for user endpoint
http.get('/api/user', () => {
return HttpResponse.json({});
}),
// TODO: Scaffold out test behaviour/configuration for alert manager endpoint
http.get('/api/v1/ngalert', () => {
return HttpResponse.json({ alertmanagersChoice: 'all', numExternalAlertmanagers: 1 });
}),
// TODO: Scaffold out test behaviour/configuration for plugins / incident endpoint
http.get('/api/plugins/grafana-incident-app/settings', () => {
return new HttpResponse(null, { status: 200 });
}),
http.get('/api/folders/:folderUid', () => {
return HttpResponse.json({
accessControl: { [AccessControlAction.AlertingRuleUpdate]: true },
});
}),
http.get('/api/prometheus/grafana/api/v1/rules', () => {
return HttpResponse.json([]);
}),
http.get('/api/ruler/grafana/api/v1/rules', () => {
return HttpResponse.json([]);
}),
http.post('/api/ruler/grafana/api/v1/rules/:namespaceUID/', async ({ request }) => {
return HttpResponse.json({
message: 'rule group updated successfully',
updated: ['foo', 'bar', 'baz'],
});
})
);
export default alertingServer;

View File

@@ -5,6 +5,7 @@ import { setupServer, SetupServer } from 'msw/node';
import { DataSourceInstanceSettings, PluginMeta } from '@grafana/data';
import { setBackendSrv } from '@grafana/runtime';
import { AlertRuleUpdated } from 'app/features/alerting/unified/api/alertRuleApi';
import {
PromBuildInfoResponse,
PromRulesResponse,
@@ -22,7 +23,7 @@ import {
MatcherOperator,
Route,
} from '../../../plugins/datasource/alertmanager/types';
import { DashboardDTO, FolderDTO, NotifierDTO } from '../../../types';
import { DashboardDTO, FolderDTO, NotifierDTO, UserDTO } from '../../../types';
import { DashboardSearchItem } from '../../search/types';
import { CreateIntegrationDTO, NewOnCallIntegrationDTO, OnCallIntegrationDTO } from './api/onCallApi';
@@ -278,6 +279,9 @@ export function mockAlertRuleApi(server: SetupServer) {
rulerRules: (dsName: string, response: RulerRulesConfigDTO) => {
server.use(http.get(`/api/ruler/${dsName}/api/v1/rules`, () => HttpResponse.json(response)));
},
updateRule: (dsName: string, response: AlertRuleUpdated) => {
server.use(http.post(`/api/ruler/${dsName}/api/v1/rules/:namespaceUid`, () => HttpResponse.json(response)));
},
rulerRuleGroup: (dsName: string, namespace: string, group: string, response: RulerRuleGroupDTO) => {
server.use(
http.get(`/api/ruler/${dsName}/api/v1/rules/${namespace}/${group}`, () => HttpResponse.json(response))
@@ -398,6 +402,14 @@ export function mockSearchApi(server: SetupServer) {
};
}
export function mockUserApi(server: SetupServer) {
return {
user: (user: UserDTO) => {
server.use(http.get(`/api/user`, () => HttpResponse.json(user)));
},
};
}
export function mockDashboardApi(server: SetupServer) {
return {
search: (results: DashboardSearchItem[]) => {

View File

@@ -31,7 +31,15 @@ import {
SilenceState,
} from 'app/plugins/datasource/alertmanager/types';
import { configureStore } from 'app/store/configureStore';
import { AccessControlAction, DashboardDTO, FolderDTO, NotifiersState, ReceiversState, StoreState } from 'app/types';
import {
AccessControlAction,
DashboardDTO,
FolderDTO,
NotifiersState,
ReceiversState,
StoreState,
UserDTO,
} from 'app/types';
import {
Alert,
AlertingRule,
@@ -611,6 +619,18 @@ export const mockFolder = (partial?: Partial<FolderDTO>): FolderDTO => {
};
};
export const mockUser = (partial?: Partial<UserDTO>): UserDTO => {
return {
id: 1,
login: 'admin',
email: 'admin@grafana.com',
name: 'Admin',
isGrafanaAdmin: true,
isDisabled: false,
...partial,
};
};
export const grantUserPermissions = (permissions: AccessControlAction[]) => {
jest
.spyOn(contextSrv, 'hasPermission')