Skip to content

Commit a186c7a

Browse files
committed
test: 💍 add tests for factory stats
1 parent a25e6b1 commit a186c7a

File tree

2 files changed

+139
-1
lines changed

2 files changed

+139
-1
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
/* eslint-disable @typescript-eslint/naming-convention */
8+
9+
import { dynamicActionFactoriesCollector } from './dynamic_action_factories_collector';
10+
import { DynamicActionsState } from '../../common';
11+
import { ActionFactory } from '../types';
12+
13+
type GetActionFactory = (id: string) => undefined | ActionFactory;
14+
15+
const factories: Record<string, ActionFactory> = {
16+
FACTORY_ID_1: ({
17+
id: 'FACTORY_ID_1',
18+
telemetry: jest.fn((state: DynamicActionsState, stats: Record<string, any>) => {
19+
stats.myStat_1 = 1;
20+
stats.myStat_2 = 123;
21+
return stats;
22+
}),
23+
} as unknown) as ActionFactory,
24+
FACTORY_ID_2: ({
25+
id: 'FACTORY_ID_2',
26+
telemetry: jest.fn((state: DynamicActionsState, stats: Record<string, any>) => stats),
27+
} as unknown) as ActionFactory,
28+
FACTORY_ID_3: ({
29+
id: 'FACTORY_ID_3',
30+
telemetry: jest.fn((state: DynamicActionsState, stats: Record<string, any>) => {
31+
stats.myStat_1 = 2;
32+
stats.stringStat = 'abc';
33+
return stats;
34+
}),
35+
} as unknown) as ActionFactory,
36+
};
37+
38+
const getActionFactory: GetActionFactory = (id: string) => factories[id];
39+
40+
const state: DynamicActionsState = {
41+
events: [
42+
{
43+
eventId: 'eventId-1',
44+
triggers: ['TRIGGER_1'],
45+
action: {
46+
factoryId: 'FACTORY_ID_1',
47+
name: 'Click me!',
48+
config: {},
49+
},
50+
},
51+
{
52+
eventId: 'eventId-2',
53+
triggers: ['TRIGGER_2', 'TRIGGER_3'],
54+
action: {
55+
factoryId: 'FACTORY_ID_2',
56+
name: 'Click me, too!',
57+
config: {
58+
doCleanup: true,
59+
},
60+
},
61+
},
62+
{
63+
eventId: 'eventId-3',
64+
triggers: ['TRIGGER_4', 'TRIGGER_1'],
65+
action: {
66+
factoryId: 'FACTORY_ID_3',
67+
name: 'Go to documentation',
68+
config: {
69+
url: 'http://google.com',
70+
iamFeelingLucky: true,
71+
},
72+
},
73+
},
74+
],
75+
};
76+
77+
beforeEach(() => {
78+
Object.values(factories).forEach((factory) => {
79+
((factory.telemetry as unknown) as jest.SpyInstance).mockClear();
80+
});
81+
});
82+
83+
describe('dynamicActionFactoriesCollector', () => {
84+
test('returns empty stats when there are not dynamic actions', () => {
85+
const stats = dynamicActionFactoriesCollector(getActionFactory, {
86+
events: [],
87+
});
88+
89+
expect(stats).toEqual({});
90+
});
91+
92+
test('calls .telemetry() method of a supplied factory', () => {
93+
const currentState = {
94+
events: [state.events[0]],
95+
};
96+
dynamicActionFactoriesCollector(getActionFactory, currentState);
97+
98+
const spy1 = (factories.FACTORY_ID_1.telemetry as unknown) as jest.SpyInstance;
99+
const spy2 = (factories.FACTORY_ID_2.telemetry as unknown) as jest.SpyInstance;
100+
101+
expect(spy1).toHaveBeenCalledTimes(1);
102+
expect(spy2).toHaveBeenCalledTimes(0);
103+
104+
expect(spy1.mock.calls[0][0]).toEqual(currentState.events[0]);
105+
expect(typeof spy1.mock.calls[0][1]).toBe('object');
106+
expect(!!spy1.mock.calls[0][1]).toBe(true);
107+
});
108+
109+
test('returns namespaced stats received from factory', () => {
110+
const currentState = {
111+
events: [state.events[0]],
112+
};
113+
const stats = dynamicActionFactoriesCollector(getActionFactory, currentState);
114+
115+
expect(stats).toEqual({
116+
'dynamicActions.factories.FACTORY_ID_1.myStat_1': 1,
117+
'dynamicActions.factories.FACTORY_ID_1.myStat_2': 123,
118+
});
119+
});
120+
121+
test('aggregates stats from all factories', () => {
122+
const currentState = {
123+
events: [state.events[0], state.events[1], state.events[2]],
124+
};
125+
const stats = dynamicActionFactoriesCollector(getActionFactory, currentState);
126+
127+
expect(stats).toEqual({
128+
'dynamicActions.factories.FACTORY_ID_1.myStat_1': 1,
129+
'dynamicActions.factories.FACTORY_ID_1.myStat_2': 123,
130+
131+
'dynamicActions.factories.FACTORY_ID_3.myStat_1': 2,
132+
'dynamicActions.factories.FACTORY_ID_3.stringStat': 'abc',
133+
});
134+
});
135+
});

x-pack/plugins/ui_actions_enhanced/server/telemetry/dynamic_action_factories_collector.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import { DynamicActionsState } from '../../common';
88
import { ActionFactory } from '../types';
9+
import { getMetricKey } from './get_metric_key';
910

1011
export const dynamicActionFactoriesCollector = (
1112
getActionFactory: (id: string) => undefined | ActionFactory,
@@ -21,7 +22,9 @@ export const dynamicActionFactoriesCollector = (
2122

2223
factoryStats = factory.telemetry(event, factoryStats);
2324
for (const [stat, value] of Object.entries(factoryStats)) {
24-
stats[`dynamicActions.factories.${factory.id}.${stat}`] = value;
25+
const key = getMetricKey(`factories.${factory.id}.${stat}`);
26+
27+
stats[key] = value;
2528
}
2629
}
2730
}

0 commit comments

Comments
 (0)