Skip to content

Commit d2265d9

Browse files
committed
added alert services mock and use it in siem
1 parent c2f2a79 commit d2265d9

File tree

3 files changed

+75
-102
lines changed

3 files changed

+75
-102
lines changed

x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/rules_notification_alert_type.test.ts

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,27 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import { savedObjectsClientMock } from 'src/core/server/mocks';
87
import { loggerMock } from 'src/core/server/logging/logger.mock';
98
import { getResult } from '../routes/__mocks__/request_responses';
109
import { rulesNotificationAlertType } from './rules_notification_alert_type';
1110
import { buildSignalsSearchQuery } from './build_signals_query';
12-
import { AlertInstance } from '../../../../../../../plugins/alerting/server';
11+
import { alertsMock, AlertServicesMock } from '../../../../../../../plugins/alerting/server/mocks';
1312
import { NotificationExecutorOptions } from './types';
1413
jest.mock('./build_signals_query');
1514

1615
describe('rules_notification_alert_type', () => {
1716
let payload: NotificationExecutorOptions;
1817
let alert: ReturnType<typeof rulesNotificationAlertType>;
19-
let alertInstanceMock: Record<string, jest.Mock>;
20-
let alertInstanceFactoryMock: () => AlertInstance;
21-
let savedObjectsClient: ReturnType<typeof savedObjectsClientMock.create>;
2218
let logger: ReturnType<typeof loggerMock.create>;
23-
let callClusterMock: jest.Mock;
19+
let alertServices: AlertServicesMock;
2420

2521
beforeEach(() => {
26-
alertInstanceMock = {
27-
scheduleActions: jest.fn(),
28-
replaceState: jest.fn(),
29-
};
30-
alertInstanceMock.replaceState.mockReturnValue(alertInstanceMock);
31-
alertInstanceFactoryMock = jest.fn().mockReturnValue(alertInstanceMock);
32-
callClusterMock = jest.fn();
33-
savedObjectsClient = savedObjectsClientMock.create();
22+
alertServices = alertsMock.createAlertServices();
3423
logger = loggerMock.create();
3524

3625
payload = {
3726
alertId: '1111',
38-
services: {
39-
savedObjectsClient,
40-
alertInstanceFactory: alertInstanceFactoryMock,
41-
callCluster: callClusterMock,
42-
},
27+
services: alertServices,
4328
params: { ruleAlertId: '2222' },
4429
state: {},
4530
spaceId: '',
@@ -58,7 +43,7 @@ describe('rules_notification_alert_type', () => {
5843

5944
describe('executor', () => {
6045
it('throws an error if rule alert was not found', async () => {
61-
savedObjectsClient.get.mockResolvedValue({
46+
alertServices.savedObjectsClient.get.mockResolvedValue({
6247
id: 'id',
6348
attributes: {},
6449
type: 'type',
@@ -72,13 +57,13 @@ describe('rules_notification_alert_type', () => {
7257

7358
it('should call buildSignalsSearchQuery with proper params', async () => {
7459
const ruleAlert = getResult();
75-
savedObjectsClient.get.mockResolvedValue({
60+
alertServices.savedObjectsClient.get.mockResolvedValue({
7661
id: 'id',
7762
type: 'type',
7863
references: [],
7964
attributes: ruleAlert,
8065
});
81-
callClusterMock.mockResolvedValue({
66+
alertServices.callCluster.mockResolvedValue({
8267
count: 0,
8368
});
8469

@@ -96,36 +81,38 @@ describe('rules_notification_alert_type', () => {
9681

9782
it('should not call alertInstanceFactory if signalsCount was 0', async () => {
9883
const ruleAlert = getResult();
99-
savedObjectsClient.get.mockResolvedValue({
84+
alertServices.savedObjectsClient.get.mockResolvedValue({
10085
id: 'id',
10186
type: 'type',
10287
references: [],
10388
attributes: ruleAlert,
10489
});
105-
callClusterMock.mockResolvedValue({
90+
alertServices.callCluster.mockResolvedValue({
10691
count: 0,
10792
});
10893

10994
await alert.executor(payload);
11095

111-
expect(alertInstanceFactoryMock).not.toHaveBeenCalled();
96+
expect(alertServices.alertInstanceFactory).not.toHaveBeenCalled();
11297
});
11398

11499
it('should call scheduleActions if signalsCount was greater than 0', async () => {
115100
const ruleAlert = getResult();
116-
savedObjectsClient.get.mockResolvedValue({
101+
alertServices.savedObjectsClient.get.mockResolvedValue({
117102
id: 'id',
118103
type: 'type',
119104
references: [],
120105
attributes: ruleAlert,
121106
});
122-
callClusterMock.mockResolvedValue({
107+
alertServices.callCluster.mockResolvedValue({
123108
count: 10,
124109
});
125110

126111
await alert.executor(payload);
127112

128-
expect(alertInstanceFactoryMock).toHaveBeenCalled();
113+
expect(alertServices.alertInstanceFactory).toHaveBeenCalled();
114+
115+
const [{ value: alertInstanceMock }] = alertServices.alertInstanceFactory.mock.results;
129116
expect(alertInstanceMock.replaceState).toHaveBeenCalledWith(
130117
expect.objectContaining({ signals_count: 10 })
131118
);

x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.test.ts

Lines changed: 19 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
*/
66

77
import moment from 'moment';
8-
import { savedObjectsClientMock } from 'src/core/server/mocks';
98
import { loggerMock } from 'src/core/server/logging/logger.mock';
109
import { getResult, getMlResult } from '../routes/__mocks__/request_responses';
1110
import { signalRulesAlertType } from './signal_rule_alert_type';
12-
import { AlertInstance } from '../../../../../../../plugins/alerting/server';
11+
import { alertsMock, AlertServicesMock } from '../../../../../../../plugins/alerting/server/mocks';
1312
import { ruleStatusServiceFactory } from './rule_status_service';
1413
import { getGapBetweenRuns } from './utils';
1514
import { RuleExecutorOptions } from './types';
@@ -28,18 +27,9 @@ jest.mock('../notifications/schedule_notification_actions');
2827
jest.mock('./find_ml_signals');
2928
jest.mock('./bulk_create_ml_signals');
3029

31-
const getPayload = (
32-
ruleAlert: RuleAlertType,
33-
alertInstanceFactoryMock: () => AlertInstance,
34-
savedObjectsClient: ReturnType<typeof savedObjectsClientMock.create>,
35-
callClusterMock: jest.Mock
36-
) => ({
30+
const getPayload = (ruleAlert: RuleAlertType, services: AlertServicesMock) => ({
3731
alertId: ruleAlert.id,
38-
services: {
39-
savedObjectsClient,
40-
alertInstanceFactory: alertInstanceFactoryMock,
41-
callCluster: callClusterMock,
42-
},
32+
services,
4333
params: {
4434
...ruleAlert.params,
4535
actions: [],
@@ -78,24 +68,14 @@ describe('rules_notification_alert_type', () => {
7868
modulesProvider: jest.fn(),
7969
resultsServiceProvider: jest.fn(),
8070
};
81-
let payload: RuleExecutorOptions;
71+
let payload: jest.Mocked<RuleExecutorOptions>;
8272
let alert: ReturnType<typeof signalRulesAlertType>;
83-
let alertInstanceMock: Record<string, jest.Mock>;
84-
let alertInstanceFactoryMock: () => AlertInstance;
85-
let savedObjectsClient: ReturnType<typeof savedObjectsClientMock.create>;
8673
let logger: ReturnType<typeof loggerMock.create>;
87-
let callClusterMock: jest.Mock;
74+
let alertServices: AlertServicesMock;
8875
let ruleStatusService: Record<string, jest.Mock>;
8976

9077
beforeEach(() => {
91-
alertInstanceMock = {
92-
scheduleActions: jest.fn(),
93-
replaceState: jest.fn(),
94-
};
95-
alertInstanceMock.replaceState.mockReturnValue(alertInstanceMock);
96-
alertInstanceFactoryMock = jest.fn().mockReturnValue(alertInstanceMock);
97-
callClusterMock = jest.fn();
98-
savedObjectsClient = savedObjectsClientMock.create();
78+
alertServices = alertsMock.createAlertServices();
9979
logger = loggerMock.create();
10080
ruleStatusService = {
10181
success: jest.fn(),
@@ -111,20 +91,20 @@ describe('rules_notification_alert_type', () => {
11191
searchAfterTimes: [],
11292
createdSignalsCount: 10,
11393
});
114-
callClusterMock.mockResolvedValue({
94+
alertServices.callCluster.mockResolvedValue({
11595
hits: {
11696
total: { value: 10 },
11797
},
11898
});
11999
const ruleAlert = getResult();
120-
savedObjectsClient.get.mockResolvedValue({
100+
alertServices.savedObjectsClient.get.mockResolvedValue({
121101
id: 'id',
122102
type: 'type',
123103
references: [],
124104
attributes: ruleAlert,
125105
});
126106

127-
payload = getPayload(ruleAlert, alertInstanceFactoryMock, savedObjectsClient, callClusterMock);
107+
payload = getPayload(ruleAlert, alertServices);
128108

129109
alert = signalRulesAlertType({
130110
logger,
@@ -164,7 +144,7 @@ describe('rules_notification_alert_type', () => {
164144
},
165145
];
166146

167-
savedObjectsClient.get.mockResolvedValue({
147+
alertServices.savedObjectsClient.get.mockResolvedValue({
168148
id: 'id',
169149
type: 'type',
170150
references: [],
@@ -195,7 +175,7 @@ describe('rules_notification_alert_type', () => {
195175
},
196176
];
197177

198-
savedObjectsClient.get.mockResolvedValue({
178+
alertServices.savedObjectsClient.get.mockResolvedValue({
199179
id: 'id',
200180
type: 'type',
201181
references: [],
@@ -214,12 +194,7 @@ describe('rules_notification_alert_type', () => {
214194
describe('ML rule', () => {
215195
it('should throw an error if ML plugin was not available', async () => {
216196
const ruleAlert = getMlResult();
217-
payload = getPayload(
218-
ruleAlert,
219-
alertInstanceFactoryMock,
220-
savedObjectsClient,
221-
callClusterMock
222-
);
197+
payload = getPayload(ruleAlert, alertServices);
223198
alert = signalRulesAlertType({
224199
logger,
225200
version,
@@ -235,12 +210,7 @@ describe('rules_notification_alert_type', () => {
235210
it('should throw an error if machineLearningJobId or anomalyThreshold was not null', async () => {
236211
const ruleAlert = getMlResult();
237212
ruleAlert.params.anomalyThreshold = undefined;
238-
payload = getPayload(
239-
ruleAlert,
240-
alertInstanceFactoryMock,
241-
savedObjectsClient,
242-
callClusterMock
243-
);
213+
payload = getPayload(ruleAlert, alertServices);
244214
await alert.executor(payload);
245215
expect(logger.error).toHaveBeenCalled();
246216
expect(logger.error.mock.calls[0][0]).toContain(
@@ -250,12 +220,7 @@ describe('rules_notification_alert_type', () => {
250220

251221
it('should throw an error if Machine learning job summary was null', async () => {
252222
const ruleAlert = getMlResult();
253-
payload = getPayload(
254-
ruleAlert,
255-
alertInstanceFactoryMock,
256-
savedObjectsClient,
257-
callClusterMock
258-
);
223+
payload = getPayload(ruleAlert, alertServices);
259224
jobsSummaryMock.mockResolvedValue([]);
260225
await alert.executor(payload);
261226
expect(logger.warn).toHaveBeenCalled();
@@ -268,12 +233,7 @@ describe('rules_notification_alert_type', () => {
268233

269234
it('should log an error if Machine learning job was not started', async () => {
270235
const ruleAlert = getMlResult();
271-
payload = getPayload(
272-
ruleAlert,
273-
alertInstanceFactoryMock,
274-
savedObjectsClient,
275-
callClusterMock
276-
);
236+
payload = getPayload(ruleAlert, alertServices);
277237
jobsSummaryMock.mockResolvedValue([
278238
{
279239
id: 'some_job_id',
@@ -297,12 +257,7 @@ describe('rules_notification_alert_type', () => {
297257

298258
it('should not call ruleStatusService.success if no anomalies were found', async () => {
299259
const ruleAlert = getMlResult();
300-
payload = getPayload(
301-
ruleAlert,
302-
alertInstanceFactoryMock,
303-
savedObjectsClient,
304-
callClusterMock
305-
);
260+
payload = getPayload(ruleAlert, alertServices);
306261
jobsSummaryMock.mockResolvedValue([]);
307262
(findMlSignals as jest.Mock).mockResolvedValue({
308263
hits: {
@@ -320,12 +275,7 @@ describe('rules_notification_alert_type', () => {
320275

321276
it('should call ruleStatusService.success if signals were created', async () => {
322277
const ruleAlert = getMlResult();
323-
payload = getPayload(
324-
ruleAlert,
325-
alertInstanceFactoryMock,
326-
savedObjectsClient,
327-
callClusterMock
328-
);
278+
payload = getPayload(ruleAlert, alertServices);
329279
jobsSummaryMock.mockResolvedValue([
330280
{
331281
id: 'some_job_id',
@@ -360,13 +310,8 @@ describe('rules_notification_alert_type', () => {
360310
id: '99403909-ca9b-49ba-9d7a-7e5320e68d05',
361311
},
362312
];
363-
payload = getPayload(
364-
ruleAlert,
365-
alertInstanceFactoryMock,
366-
savedObjectsClient,
367-
callClusterMock
368-
);
369-
savedObjectsClient.get.mockResolvedValue({
313+
payload = getPayload(ruleAlert, alertServices);
314+
alertServices.savedObjectsClient.get.mockResolvedValue({
370315
id: 'id',
371316
type: 'type',
372317
references: [],

x-pack/plugins/alerting/server/mocks.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
import { alertsClientMock } from './alerts_client.mock';
88
import { PluginSetupContract, PluginStartContract } from './plugin';
9+
import { savedObjectsClientMock } from '../../../../src/core/server/mocks';
10+
import { createScopedSeachApiMock } from '../../../../src/plugins/data/server/mocks';
11+
import { AlertInstance } from './alert_instance';
912

1013
export { alertsClientMock };
1114

@@ -24,7 +27,45 @@ const createStartMock = () => {
2427
return mock;
2528
};
2629

30+
const createAlertInstanceFactoryMock = () => {
31+
const mock = {
32+
hasScheduledActions: jest.fn(),
33+
isThrottled: jest.fn(),
34+
getScheduledActionOptions: jest.fn(),
35+
unscheduleActions: jest.fn(),
36+
getState: jest.fn(),
37+
scheduleActions: jest.fn(),
38+
replaceState: jest.fn(),
39+
updateLastScheduledActions: jest.fn(),
40+
toJSON: jest.fn(),
41+
toRaw: jest.fn(),
42+
};
43+
44+
// support chaining
45+
mock.replaceState.mockReturnValue(mock);
46+
mock.unscheduleActions.mockReturnValue(mock);
47+
mock.scheduleActions.mockReturnValue(mock);
48+
49+
return (mock as unknown) as jest.Mocked<AlertInstance>;
50+
};
51+
52+
const createAlertServicesMock = () => {
53+
const alertInstanceFactoryMock = createAlertInstanceFactoryMock();
54+
return {
55+
alertInstanceFactory: jest
56+
.fn<jest.Mocked<AlertInstance>, []>()
57+
.mockReturnValue(alertInstanceFactoryMock),
58+
callCluster: jest.fn(),
59+
savedObjectsClient: savedObjectsClientMock.create(),
60+
search: createScopedSeachApiMock().search,
61+
};
62+
};
63+
64+
export type AlertServicesMock = ReturnType<typeof createAlertServicesMock>;
65+
2766
export const alertsMock = {
67+
createAlertInstanceFactory: createAlertInstanceFactoryMock,
2868
createSetup: createSetupMock,
2969
createStart: createStartMock,
70+
createAlertServices: createAlertServicesMock,
3071
};

0 commit comments

Comments
 (0)