Skip to content

Commit 211d59e

Browse files
committed
PR feedback
1 parent 6fb09ae commit 211d59e

6 files changed

Lines changed: 461 additions & 657 deletions

File tree

x-pack/platform/plugins/shared/alerting_v2/server/lib/director/strategies/basic_strategy.test.ts

Lines changed: 91 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
import { BasicTransitionStrategy } from './basic_strategy';
9+
import type { AlertEpisodeStatus, AlertEventStatus } from '../../../resources/alert_events';
910
import { alertEpisodeStatus, alertEventStatus } from '../../../resources/alert_events';
1011
import { createRuleResponse } from '../../test_utils';
1112
import { buildLatestAlertEvent, buildStrategyStateTransitionContext } from '../test_utils';
@@ -17,6 +18,33 @@ describe('BasicTransitionStrategy', () => {
1718
strategy = new BasicTransitionStrategy();
1819
});
1920

21+
const getNextState = (...args: Parameters<typeof buildStrategyStateTransitionContext>) =>
22+
strategy.getNextState(buildStrategyStateTransitionContext(...args));
23+
24+
const expectTransition = ({
25+
from,
26+
on,
27+
to,
28+
}: {
29+
from?: AlertEpisodeStatus | null;
30+
on: AlertEventStatus;
31+
to: AlertEpisodeStatus;
32+
}) => {
33+
const result = getNextState({
34+
eventStatus: on,
35+
...(from !== undefined
36+
? {
37+
previousEpisode: buildLatestAlertEvent({
38+
episodeStatus: from,
39+
eventStatus: on,
40+
}),
41+
}
42+
: {}),
43+
});
44+
45+
expect(result).toEqual({ status: to });
46+
};
47+
2048
it('has name "basic"', () => {
2149
expect(strategy.name).toBe('basic');
2250
});
@@ -32,246 +60,101 @@ describe('BasicTransitionStrategy', () => {
3260

3361
describe('no previous episode', () => {
3462
it('returns pending when there is no previous episode', () => {
35-
const result = strategy.getNextState(
36-
buildStrategyStateTransitionContext({
37-
eventStatus: alertEventStatus.breached,
38-
})
39-
);
40-
expect(result).toEqual({ status: alertEpisodeStatus.pending });
63+
expectTransition({
64+
on: alertEventStatus.breached,
65+
to: alertEpisodeStatus.pending,
66+
});
4167
});
4268

4369
it('returns pending when previous episode status is null', () => {
44-
const result = strategy.getNextState(
45-
buildStrategyStateTransitionContext({
46-
eventStatus: alertEventStatus.breached,
47-
previousEpisode: buildLatestAlertEvent({
48-
episodeStatus: null,
49-
eventStatus: alertEventStatus.breached,
50-
}),
51-
})
52-
);
53-
expect(result).toEqual({ status: alertEpisodeStatus.pending });
70+
expectTransition({
71+
from: null,
72+
on: alertEventStatus.breached,
73+
to: alertEpisodeStatus.pending,
74+
});
5475
});
5576

5677
it('returns pending when the current state is unknown', () => {
57-
const result = strategy.getNextState(
58-
buildStrategyStateTransitionContext({
59-
eventStatus: alertEventStatus.breached,
60-
previousEpisode: {
61-
...buildLatestAlertEvent({
62-
episodeStatus: alertEpisodeStatus.pending,
63-
eventStatus: alertEventStatus.breached,
64-
}),
65-
// @ts-expect-error - unknown state testing
66-
last_episode_status: 'unknown_state',
67-
},
68-
})
69-
);
70-
expect(result).toEqual({ status: alertEpisodeStatus.pending });
71-
});
72-
});
73-
74-
describe('state transitions from inactive', () => {
75-
const currentState = alertEpisodeStatus.inactive;
76-
77-
it('transitions to pending on breached event', () => {
78-
const result = strategy.getNextState(
79-
buildStrategyStateTransitionContext({
80-
eventStatus: alertEventStatus.breached,
81-
previousEpisode: buildLatestAlertEvent({
82-
episodeStatus: currentState,
78+
const result = getNextState({
79+
eventStatus: alertEventStatus.breached,
80+
previousEpisode: {
81+
...buildLatestAlertEvent({
82+
episodeStatus: alertEpisodeStatus.pending,
8383
eventStatus: alertEventStatus.breached,
8484
}),
85-
})
86-
);
85+
// @ts-expect-error - unknown state testing
86+
last_episode_status: 'unknown_state',
87+
},
88+
});
8789
expect(result).toEqual({ status: alertEpisodeStatus.pending });
8890
});
91+
});
8992

90-
it('stays inactive on recovered event', () => {
91-
const result = strategy.getNextState(
92-
buildStrategyStateTransitionContext({
93-
eventStatus: alertEventStatus.recovered,
94-
previousEpisode: buildLatestAlertEvent({
95-
episodeStatus: currentState,
96-
eventStatus: alertEventStatus.recovered,
97-
}),
98-
})
99-
);
100-
expect(result).toEqual({ status: alertEpisodeStatus.inactive });
101-
});
102-
103-
it('stays inactive on no_data event', () => {
104-
const result = strategy.getNextState(
105-
buildStrategyStateTransitionContext({
106-
eventStatus: alertEventStatus.no_data,
107-
previousEpisode: buildLatestAlertEvent({
108-
episodeStatus: currentState,
109-
eventStatus: alertEventStatus.no_data,
110-
}),
111-
})
112-
);
113-
expect(result).toEqual({ status: alertEpisodeStatus.inactive });
93+
describe('state transitions from inactive', () => {
94+
it.each<[string, AlertEventStatus, AlertEpisodeStatus]>([
95+
['pending', alertEventStatus.breached, alertEpisodeStatus.pending],
96+
['inactive', alertEventStatus.recovered, alertEpisodeStatus.inactive],
97+
['inactive', alertEventStatus.no_data, alertEpisodeStatus.inactive],
98+
])('transitions to %s on %s event', (_label, on, to) => {
99+
expectTransition({ from: alertEpisodeStatus.inactive, on, to });
114100
});
115101
});
116102

117103
describe('state transitions from pending', () => {
118-
const currentState = alertEpisodeStatus.pending;
119-
120-
it('transitions to active on breached event', () => {
121-
const result = strategy.getNextState(
122-
buildStrategyStateTransitionContext({
123-
eventStatus: alertEventStatus.breached,
124-
previousEpisode: buildLatestAlertEvent({
125-
episodeStatus: currentState,
126-
eventStatus: alertEventStatus.breached,
127-
}),
128-
})
129-
);
130-
expect(result).toEqual({ status: alertEpisodeStatus.active });
131-
});
132-
133-
it('transitions to inactive on recovered event', () => {
134-
const result = strategy.getNextState(
135-
buildStrategyStateTransitionContext({
136-
eventStatus: alertEventStatus.recovered,
137-
previousEpisode: buildLatestAlertEvent({
138-
episodeStatus: currentState,
139-
eventStatus: alertEventStatus.recovered,
140-
}),
141-
})
142-
);
143-
expect(result).toEqual({ status: alertEpisodeStatus.inactive });
144-
});
145-
146-
it('stays pending on no_data event', () => {
147-
const result = strategy.getNextState(
148-
buildStrategyStateTransitionContext({
149-
eventStatus: alertEventStatus.no_data,
150-
previousEpisode: buildLatestAlertEvent({
151-
episodeStatus: currentState,
152-
eventStatus: alertEventStatus.no_data,
153-
}),
154-
})
155-
);
156-
expect(result).toEqual({ status: alertEpisodeStatus.pending });
104+
it.each<[string, AlertEventStatus, AlertEpisodeStatus]>([
105+
['active', alertEventStatus.breached, alertEpisodeStatus.active],
106+
['inactive', alertEventStatus.recovered, alertEpisodeStatus.inactive],
107+
['pending', alertEventStatus.no_data, alertEpisodeStatus.pending],
108+
])('transitions to %s on %s event', (_label, on, to) => {
109+
expectTransition({ from: alertEpisodeStatus.pending, on, to });
157110
});
158111
});
159112

160113
describe('state transitions from active', () => {
161-
const currentState = alertEpisodeStatus.active;
162-
163-
it('stays active on breached event', () => {
164-
const result = strategy.getNextState(
165-
buildStrategyStateTransitionContext({
166-
eventStatus: alertEventStatus.breached,
167-
previousEpisode: buildLatestAlertEvent({
168-
episodeStatus: currentState,
169-
eventStatus: alertEventStatus.breached,
170-
}),
171-
})
172-
);
173-
expect(result).toEqual({ status: alertEpisodeStatus.active });
174-
});
175-
176-
it('transitions to recovering on recovered event', () => {
177-
const result = strategy.getNextState(
178-
buildStrategyStateTransitionContext({
179-
eventStatus: alertEventStatus.recovered,
180-
previousEpisode: buildLatestAlertEvent({
181-
episodeStatus: currentState,
182-
eventStatus: alertEventStatus.recovered,
183-
}),
184-
})
185-
);
186-
expect(result).toEqual({ status: alertEpisodeStatus.recovering });
187-
});
188-
189-
it('stays active on no_data event', () => {
190-
const result = strategy.getNextState(
191-
buildStrategyStateTransitionContext({
192-
eventStatus: alertEventStatus.no_data,
193-
previousEpisode: buildLatestAlertEvent({
194-
episodeStatus: currentState,
195-
eventStatus: alertEventStatus.no_data,
196-
}),
197-
})
198-
);
199-
expect(result).toEqual({ status: alertEpisodeStatus.active });
114+
it.each<[string, AlertEventStatus, AlertEpisodeStatus]>([
115+
['active', alertEventStatus.breached, alertEpisodeStatus.active],
116+
['recovering', alertEventStatus.recovered, alertEpisodeStatus.recovering],
117+
['active', alertEventStatus.no_data, alertEpisodeStatus.active],
118+
])('transitions to %s on %s event', (_label, on, to) => {
119+
expectTransition({ from: alertEpisodeStatus.active, on, to });
200120
});
201121
});
202122

203123
describe('state transitions from recovering', () => {
204-
const currentState = alertEpisodeStatus.recovering;
205-
206-
it('transitions to active on breached event', () => {
207-
const result = strategy.getNextState(
208-
buildStrategyStateTransitionContext({
209-
eventStatus: alertEventStatus.breached,
210-
previousEpisode: buildLatestAlertEvent({
211-
episodeStatus: currentState,
212-
eventStatus: alertEventStatus.breached,
213-
}),
214-
})
215-
);
216-
expect(result).toEqual({ status: alertEpisodeStatus.active });
217-
});
218-
219-
it('transitions to inactive on recovered event', () => {
220-
const result = strategy.getNextState(
221-
buildStrategyStateTransitionContext({
222-
eventStatus: alertEventStatus.recovered,
223-
previousEpisode: buildLatestAlertEvent({
224-
episodeStatus: currentState,
225-
eventStatus: alertEventStatus.recovered,
226-
}),
227-
})
228-
);
229-
expect(result).toEqual({ status: alertEpisodeStatus.inactive });
230-
});
231-
232-
it('stays recovering on no_data event', () => {
233-
const result = strategy.getNextState(
234-
buildStrategyStateTransitionContext({
235-
eventStatus: alertEventStatus.no_data,
236-
previousEpisode: buildLatestAlertEvent({
237-
episodeStatus: currentState,
238-
eventStatus: alertEventStatus.no_data,
239-
}),
240-
})
241-
);
242-
expect(result).toEqual({ status: alertEpisodeStatus.recovering });
124+
it.each<[string, AlertEventStatus, AlertEpisodeStatus]>([
125+
['active', alertEventStatus.breached, alertEpisodeStatus.active],
126+
['inactive', alertEventStatus.recovered, alertEpisodeStatus.inactive],
127+
['recovering', alertEventStatus.no_data, alertEpisodeStatus.recovering],
128+
])('transitions to %s on %s event', (_label, on, to) => {
129+
expectTransition({ from: alertEpisodeStatus.recovering, on, to });
243130
});
244131
});
245132

246133
describe('defensive fallbacks', () => {
247134
it('returns pending for unknown current state', () => {
248-
const result = strategy.getNextState(
249-
buildStrategyStateTransitionContext({
250-
eventStatus: alertEventStatus.breached,
251-
previousEpisode: {
252-
...buildLatestAlertEvent({
253-
episodeStatus: alertEpisodeStatus.pending,
254-
eventStatus: alertEventStatus.breached,
255-
}),
256-
// @ts-expect-error - unknown state testing
257-
last_episode_status: 'unknown_state',
258-
},
259-
})
260-
);
135+
const result = getNextState({
136+
eventStatus: alertEventStatus.breached,
137+
previousEpisode: {
138+
...buildLatestAlertEvent({
139+
episodeStatus: alertEpisodeStatus.pending,
140+
eventStatus: alertEventStatus.breached,
141+
}),
142+
// @ts-expect-error - unknown state testing
143+
last_episode_status: 'unknown_state',
144+
},
145+
});
261146
expect(result).toEqual({ status: alertEpisodeStatus.pending });
262147
});
263148

264149
it('returns current state for unknown event status', () => {
265-
const result = strategy.getNextState(
266-
buildStrategyStateTransitionContext({
267-
// @ts-expect-error - unknown event status testing
268-
eventStatus: 'unknown_event',
269-
previousEpisode: buildLatestAlertEvent({
270-
episodeStatus: alertEpisodeStatus.active,
271-
eventStatus: alertEventStatus.breached,
272-
}),
273-
})
274-
);
150+
const result = getNextState({
151+
// @ts-expect-error - unknown event status testing
152+
eventStatus: 'unknown_event',
153+
previousEpisode: buildLatestAlertEvent({
154+
episodeStatus: alertEpisodeStatus.active,
155+
eventStatus: alertEventStatus.breached,
156+
}),
157+
});
275158
expect(result).toEqual({ status: alertEpisodeStatus.active });
276159
});
277160
});

0 commit comments

Comments
 (0)