@webex/internal-plugin-metrics 2.59.1 → 2.59.3-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +6 -6
- package/README.md +42 -42
- package/babel.config.js +3 -3
- package/dist/batcher.js +2 -2
- package/dist/batcher.js.map +1 -1
- package/dist/call-diagnostic-events-batcher.js +5 -5
- package/dist/call-diagnostic-events-batcher.js.map +1 -1
- package/dist/client-metrics-batcher.js +2 -2
- package/dist/client-metrics-batcher.js.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +11 -11
- package/dist/metrics.js.map +1 -1
- package/jest.config.js +3 -3
- package/package.json +17 -16
- package/process +1 -1
- package/src/batcher.js +99 -99
- package/src/call-diagnostic-events-batcher.js +62 -62
- package/src/client-metrics-batcher.js +31 -31
- package/src/config.js +42 -42
- package/src/index.js +15 -15
- package/src/metrics.js +165 -165
- package/test/unit/spec/batcher.js +181 -181
- package/test/unit/spec/call-diagnostic-events-batcher.js +195 -195
- package/test/unit/spec/client-metrics-batcher.js +181 -181
- package/test/unit/spec/metrics.js +364 -364
|
@@ -1,364 +1,364 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {assert} from '@webex/test-helper-chai';
|
|
6
|
-
import MockWebex from '@webex/test-helper-mock-webex';
|
|
7
|
-
import {Token, Credentials} from '@webex/webex-core';
|
|
8
|
-
import FakeTimers from '@sinonjs/fake-timers';
|
|
9
|
-
import sinon from 'sinon';
|
|
10
|
-
import Metrics, {config} from '@webex/internal-plugin-metrics';
|
|
11
|
-
|
|
12
|
-
function promiseTick(count) {
|
|
13
|
-
let promise = Promise.resolve();
|
|
14
|
-
|
|
15
|
-
while (count > 1) {
|
|
16
|
-
promise = promise.then(() => promiseTick(1));
|
|
17
|
-
count -= 1;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return promise;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
describe('plugin-metrics', () => {
|
|
24
|
-
describe('Metrics', () => {
|
|
25
|
-
let webex;
|
|
26
|
-
let metrics;
|
|
27
|
-
let clock;
|
|
28
|
-
|
|
29
|
-
const eventName = 'test_event';
|
|
30
|
-
const mockPayload = {
|
|
31
|
-
fields: {
|
|
32
|
-
testField: 123,
|
|
33
|
-
},
|
|
34
|
-
tags: {
|
|
35
|
-
testTag: 'tag value',
|
|
36
|
-
},
|
|
37
|
-
metricName: eventName,
|
|
38
|
-
test: 'this field should not be included in final payload',
|
|
39
|
-
type: 'behavioral',
|
|
40
|
-
eventPayload: {value: 'splunk business metric payload'},
|
|
41
|
-
};
|
|
42
|
-
const transformedProps = {
|
|
43
|
-
fields: {
|
|
44
|
-
testField: 123,
|
|
45
|
-
},
|
|
46
|
-
tags: {
|
|
47
|
-
testTag: 'tag value',
|
|
48
|
-
},
|
|
49
|
-
metricName: eventName,
|
|
50
|
-
type: 'behavioral',
|
|
51
|
-
timestamp: Date.now(),
|
|
52
|
-
};
|
|
53
|
-
const preLoginId = '1b90cf5e-27a6-41aa-a208-1f6eb6b9e6b6';
|
|
54
|
-
const preLoginProps = {
|
|
55
|
-
metrics: [transformedProps],
|
|
56
|
-
};
|
|
57
|
-
const mockCallDiagnosticEvent = {
|
|
58
|
-
originTime: {
|
|
59
|
-
triggered: 'mock triggered timestamp',
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
beforeEach(() => {
|
|
64
|
-
clock = FakeTimers.install({now: 0});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
afterEach(() => {
|
|
68
|
-
clock.uninstall();
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
beforeEach(() => {
|
|
72
|
-
webex = new MockWebex({
|
|
73
|
-
children: {
|
|
74
|
-
metrics: Metrics,
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
webex.config.metrics = config.metrics;
|
|
79
|
-
metrics = webex.internal.metrics;
|
|
80
|
-
|
|
81
|
-
webex.request = function (options) {
|
|
82
|
-
return Promise.resolve({
|
|
83
|
-
statusCode: 204,
|
|
84
|
-
body: undefined,
|
|
85
|
-
options,
|
|
86
|
-
});
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
webex.credentials = new Credentials(undefined, {parent: webex});
|
|
90
|
-
sinon.stub(webex.credentials, 'getClientToken').returns(Promise.resolve('token'));
|
|
91
|
-
|
|
92
|
-
webex.internal = {...webex.internal};
|
|
93
|
-
webex.config = {
|
|
94
|
-
...webex.config,
|
|
95
|
-
appName: 'appName',
|
|
96
|
-
appPlatform: 'appPlatform',
|
|
97
|
-
appVersion: 'appVersion',
|
|
98
|
-
};
|
|
99
|
-
webex.config.metrics.type = ['operational'];
|
|
100
|
-
webex.config.metrics.appType = 'sdk';
|
|
101
|
-
|
|
102
|
-
sinon.spy(webex, 'request');
|
|
103
|
-
sinon.spy(metrics, 'postPreLoginMetric');
|
|
104
|
-
sinon.spy(metrics, 'aliasUser');
|
|
105
|
-
sinon.spy(metrics, 'submitCallDiagnosticEvents');
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
describe('#submit()', () => {
|
|
109
|
-
it('submits a metric', () => {
|
|
110
|
-
const promise = metrics.submit('testMetric');
|
|
111
|
-
|
|
112
|
-
return promiseTick(50)
|
|
113
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
114
|
-
.then(() => promise)
|
|
115
|
-
.then(() => {
|
|
116
|
-
assert.calledOnce(webex.request);
|
|
117
|
-
const req = webex.request.args[0][0];
|
|
118
|
-
const metric = req.body.metrics[0];
|
|
119
|
-
|
|
120
|
-
assert.property(metric, 'key');
|
|
121
|
-
assert.property(metric, 'version');
|
|
122
|
-
assert.property(metric, 'appType');
|
|
123
|
-
assert.property(metric, 'env');
|
|
124
|
-
assert.property(metric, 'time');
|
|
125
|
-
assert.property(metric, 'version');
|
|
126
|
-
|
|
127
|
-
assert.equal(metric.key, 'testMetric');
|
|
128
|
-
assert.equal(metric.version, webex.version);
|
|
129
|
-
assert.equal(metric.env, 'TEST');
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
describe('#submitClientMetrics()', () => {
|
|
135
|
-
describe('before login', () => {
|
|
136
|
-
it('posts pre-login metric', () => {
|
|
137
|
-
const date = clock.now;
|
|
138
|
-
const promise = metrics.submitClientMetrics(eventName, mockPayload, preLoginId);
|
|
139
|
-
|
|
140
|
-
return promiseTick(50)
|
|
141
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
142
|
-
.then(() => promise)
|
|
143
|
-
.then(() => {
|
|
144
|
-
assert.called(metrics.postPreLoginMetric);
|
|
145
|
-
assert.calledOnce(webex.credentials.getClientToken);
|
|
146
|
-
assert.calledOnce(webex.request);
|
|
147
|
-
const req = webex.request.args[0][0];
|
|
148
|
-
const metric = req.body.metrics[0];
|
|
149
|
-
|
|
150
|
-
assert.property(metric, 'metricName');
|
|
151
|
-
assert.property(metric, 'tags');
|
|
152
|
-
assert.property(metric, 'fields');
|
|
153
|
-
assert.property(metric, 'timestamp');
|
|
154
|
-
assert.property(metric, 'type');
|
|
155
|
-
assert.property(metric, 'eventPayload');
|
|
156
|
-
assert.notProperty(metric.tags, 'org_id');
|
|
157
|
-
|
|
158
|
-
assert.equal(metric.timestamp, date);
|
|
159
|
-
assert.equal(metric.metricName, 'test_event');
|
|
160
|
-
assert.equal(metric.type, 'behavioral');
|
|
161
|
-
assert.equal(metric.fields.testField, 123);
|
|
162
|
-
assert.equal(metric.tags.testTag, 'tag value');
|
|
163
|
-
assert.equal(metric.eventPayload.value, 'splunk business metric payload');
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
describe('after login', () => {
|
|
168
|
-
it('submits a metric to clientmetrics', () => {
|
|
169
|
-
webex.credentials.supertoken = new Token(
|
|
170
|
-
{
|
|
171
|
-
access_token: 'a_b_orgid',
|
|
172
|
-
},
|
|
173
|
-
{parent: webex}
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
const testPayload = {
|
|
177
|
-
tags: {success: true},
|
|
178
|
-
fields: {perceivedDurationInMillis: 314},
|
|
179
|
-
context: {},
|
|
180
|
-
eventPayload: {value: 'splunk business metric payload'},
|
|
181
|
-
};
|
|
182
|
-
const date = clock.now;
|
|
183
|
-
|
|
184
|
-
const promise = metrics.submitClientMetrics('test', testPayload);
|
|
185
|
-
|
|
186
|
-
return promiseTick(50)
|
|
187
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
188
|
-
.then(() => promise)
|
|
189
|
-
.then(() => {
|
|
190
|
-
assert.calledOnce(webex.request);
|
|
191
|
-
const req = webex.request.args[0][0];
|
|
192
|
-
const metric = req.body.metrics[0];
|
|
193
|
-
|
|
194
|
-
assert.property(metric, 'metricName');
|
|
195
|
-
assert.property(metric, 'tags');
|
|
196
|
-
assert.property(metric, 'fields');
|
|
197
|
-
assert.property(metric, 'timestamp');
|
|
198
|
-
assert.property(metric, 'context');
|
|
199
|
-
assert.property(metric, 'eventPayload');
|
|
200
|
-
|
|
201
|
-
assert.property(metric.tags, 'browser');
|
|
202
|
-
assert.property(metric.tags, 'os');
|
|
203
|
-
assert.property(metric.tags, 'domain');
|
|
204
|
-
|
|
205
|
-
assert.property(metric.fields, 'browser_version');
|
|
206
|
-
assert.property(metric.fields, 'os_version');
|
|
207
|
-
assert.property(metric.fields, 'sdk_version');
|
|
208
|
-
assert.property(metric.fields, 'platform');
|
|
209
|
-
assert.property(metric.fields, 'spark_user_agent');
|
|
210
|
-
assert.property(metric.fields, 'client_id');
|
|
211
|
-
|
|
212
|
-
assert.property(metric.context, 'app');
|
|
213
|
-
assert.property(metric.context, 'locale');
|
|
214
|
-
assert.property(metric.context, 'os');
|
|
215
|
-
|
|
216
|
-
assert.equal(metric.timestamp, date);
|
|
217
|
-
assert.equal(metric.metricName, 'test');
|
|
218
|
-
assert.equal(metric.tags.success, true);
|
|
219
|
-
assert.equal(metric.fields.perceivedDurationInMillis, 314);
|
|
220
|
-
assert.equal(metric.eventPayload.value, 'splunk business metric payload');
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
it('throws error if no metric name is given', () => {
|
|
225
|
-
assert.throws(
|
|
226
|
-
() => metrics.submitClientMetrics(),
|
|
227
|
-
'Missing behavioral metric name. Please provide one'
|
|
228
|
-
);
|
|
229
|
-
});
|
|
230
|
-
});
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
describe('#postPreLoginMetric()', () => {
|
|
234
|
-
it('returns an HttpResponse object', () => {
|
|
235
|
-
const promise = metrics.postPreLoginMetric(preLoginProps, preLoginId);
|
|
236
|
-
|
|
237
|
-
return promiseTick(50)
|
|
238
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
239
|
-
.then(() => promise)
|
|
240
|
-
.then(() => {
|
|
241
|
-
assert.calledOnce(webex.request);
|
|
242
|
-
const req = webex.request.args[0][0];
|
|
243
|
-
const metric = req.body.metrics[0];
|
|
244
|
-
const {headers} = req;
|
|
245
|
-
|
|
246
|
-
assert.property(headers, 'x-prelogin-userid');
|
|
247
|
-
assert.property(metric, 'metricName');
|
|
248
|
-
assert.property(metric, 'tags');
|
|
249
|
-
assert.property(metric, 'fields');
|
|
250
|
-
assert.property(metric, 'timestamp');
|
|
251
|
-
|
|
252
|
-
assert.equal(metric.timestamp, transformedProps.timestamp);
|
|
253
|
-
assert.equal(metric.metricName, eventName);
|
|
254
|
-
assert.equal(metric.tags.testTag, 'tag value');
|
|
255
|
-
assert.equal(metric.fields.testField, 123);
|
|
256
|
-
});
|
|
257
|
-
});
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
describe('#aliasUser()', () => {
|
|
261
|
-
it('returns an HttpResponse object', () =>
|
|
262
|
-
metrics.aliasUser(preLoginId).then(() => {
|
|
263
|
-
assert.calledOnce(webex.request);
|
|
264
|
-
const req = webex.request.args[0][0];
|
|
265
|
-
const params = req.qs;
|
|
266
|
-
|
|
267
|
-
assert.match(params, {alias: true});
|
|
268
|
-
}));
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
describe('#submitCallDiagnosticEvents()', () => {
|
|
272
|
-
it('submits a call diagnostic event', () => {
|
|
273
|
-
const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
|
|
274
|
-
|
|
275
|
-
return promiseTick(50)
|
|
276
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
277
|
-
.then(() => promise)
|
|
278
|
-
.then(() => {
|
|
279
|
-
assert.calledOnce(webex.request);
|
|
280
|
-
const req = webex.request.args[0][0];
|
|
281
|
-
const metric = req.body.metrics[0];
|
|
282
|
-
|
|
283
|
-
assert.property(metric.eventPayload, 'origin');
|
|
284
|
-
assert.property(metric.eventPayload, 'originTime');
|
|
285
|
-
assert.property(metric.eventPayload.origin, 'buildType');
|
|
286
|
-
assert.property(metric.eventPayload.origin, 'networkType');
|
|
287
|
-
assert.property(metric.eventPayload.originTime, 'sent');
|
|
288
|
-
assert.equal(metric.eventPayload.origin.buildType, 'test');
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
it('submits a call diagnostic event with buildType set in the payload', () => {
|
|
293
|
-
const promise = metrics.submitCallDiagnosticEvents({
|
|
294
|
-
...mockCallDiagnosticEvent,
|
|
295
|
-
origin: {
|
|
296
|
-
buildType: 'prod',
|
|
297
|
-
},
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
return promiseTick(50)
|
|
301
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
302
|
-
.then(() => promise)
|
|
303
|
-
.then(() => {
|
|
304
|
-
assert.calledOnce(webex.request);
|
|
305
|
-
const req = webex.request.args[0][0];
|
|
306
|
-
const metric = req.body.metrics[0];
|
|
307
|
-
|
|
308
|
-
assert.property(metric.eventPayload, 'origin');
|
|
309
|
-
assert.property(metric.eventPayload, 'originTime');
|
|
310
|
-
assert.property(metric.eventPayload.origin, 'buildType');
|
|
311
|
-
assert.property(metric.eventPayload.origin, 'networkType');
|
|
312
|
-
assert.property(metric.eventPayload.originTime, 'sent');
|
|
313
|
-
assert.equal(metric.eventPayload.origin.buildType, 'prod');
|
|
314
|
-
});
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
xit('submits a call diagnostic event with a test domain', () => {
|
|
318
|
-
global.window.location.hostname = 'test.webex.com';
|
|
319
|
-
|
|
320
|
-
const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
|
|
321
|
-
|
|
322
|
-
return promiseTick(50)
|
|
323
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
324
|
-
.then(() => promise)
|
|
325
|
-
.then(() => {
|
|
326
|
-
assert.calledOnce(webex.request);
|
|
327
|
-
const req = webex.request.args[0][0];
|
|
328
|
-
const metric = req.body.metrics[0];
|
|
329
|
-
|
|
330
|
-
assert.property(metric.eventPayload, 'origin');
|
|
331
|
-
assert.property(metric.eventPayload, 'originTime');
|
|
332
|
-
assert.property(metric.eventPayload.origin, 'buildType');
|
|
333
|
-
assert.property(metric.eventPayload.origin, 'networkType');
|
|
334
|
-
assert.property(metric.eventPayload.originTime, 'sent');
|
|
335
|
-
assert.equal(metric.eventPayload.origin.buildType, 'test');
|
|
336
|
-
});
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
// Skip because it's current unable to overwrite NODE_ENV
|
|
340
|
-
// However doing `NODE_ENV=test npm run test ...` will get this test case to pass
|
|
341
|
-
xit('submits a call diagnostic event with a NODE_ENV=production', () => {
|
|
342
|
-
process.env.NODE_ENV = 'production';
|
|
343
|
-
|
|
344
|
-
const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
|
|
345
|
-
|
|
346
|
-
return promiseTick(50)
|
|
347
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
348
|
-
.then(() => promise)
|
|
349
|
-
.then(() => {
|
|
350
|
-
assert.calledOnce(webex.request);
|
|
351
|
-
const req = webex.request.args[0][0];
|
|
352
|
-
const metric = req.body.metrics[0];
|
|
353
|
-
|
|
354
|
-
assert.property(metric.eventPayload, 'origin');
|
|
355
|
-
assert.property(metric.eventPayload, 'originTime');
|
|
356
|
-
assert.property(metric.eventPayload.origin, 'buildType');
|
|
357
|
-
assert.property(metric.eventPayload.origin, 'networkType');
|
|
358
|
-
assert.property(metric.eventPayload.originTime, 'sent');
|
|
359
|
-
assert.equal(metric.eventPayload.origin.buildType, 'prod');
|
|
360
|
-
});
|
|
361
|
-
});
|
|
362
|
-
});
|
|
363
|
-
});
|
|
364
|
-
});
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {assert} from '@webex/test-helper-chai';
|
|
6
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
7
|
+
import {Token, Credentials} from '@webex/webex-core';
|
|
8
|
+
import FakeTimers from '@sinonjs/fake-timers';
|
|
9
|
+
import sinon from 'sinon';
|
|
10
|
+
import Metrics, {config} from '@webex/internal-plugin-metrics';
|
|
11
|
+
|
|
12
|
+
function promiseTick(count) {
|
|
13
|
+
let promise = Promise.resolve();
|
|
14
|
+
|
|
15
|
+
while (count > 1) {
|
|
16
|
+
promise = promise.then(() => promiseTick(1));
|
|
17
|
+
count -= 1;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return promise;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe('plugin-metrics', () => {
|
|
24
|
+
describe('Metrics', () => {
|
|
25
|
+
let webex;
|
|
26
|
+
let metrics;
|
|
27
|
+
let clock;
|
|
28
|
+
|
|
29
|
+
const eventName = 'test_event';
|
|
30
|
+
const mockPayload = {
|
|
31
|
+
fields: {
|
|
32
|
+
testField: 123,
|
|
33
|
+
},
|
|
34
|
+
tags: {
|
|
35
|
+
testTag: 'tag value',
|
|
36
|
+
},
|
|
37
|
+
metricName: eventName,
|
|
38
|
+
test: 'this field should not be included in final payload',
|
|
39
|
+
type: 'behavioral',
|
|
40
|
+
eventPayload: {value: 'splunk business metric payload'},
|
|
41
|
+
};
|
|
42
|
+
const transformedProps = {
|
|
43
|
+
fields: {
|
|
44
|
+
testField: 123,
|
|
45
|
+
},
|
|
46
|
+
tags: {
|
|
47
|
+
testTag: 'tag value',
|
|
48
|
+
},
|
|
49
|
+
metricName: eventName,
|
|
50
|
+
type: 'behavioral',
|
|
51
|
+
timestamp: Date.now(),
|
|
52
|
+
};
|
|
53
|
+
const preLoginId = '1b90cf5e-27a6-41aa-a208-1f6eb6b9e6b6';
|
|
54
|
+
const preLoginProps = {
|
|
55
|
+
metrics: [transformedProps],
|
|
56
|
+
};
|
|
57
|
+
const mockCallDiagnosticEvent = {
|
|
58
|
+
originTime: {
|
|
59
|
+
triggered: 'mock triggered timestamp',
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
beforeEach(() => {
|
|
64
|
+
clock = FakeTimers.install({now: 0});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
afterEach(() => {
|
|
68
|
+
clock.uninstall();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
beforeEach(() => {
|
|
72
|
+
webex = new MockWebex({
|
|
73
|
+
children: {
|
|
74
|
+
metrics: Metrics,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
webex.config.metrics = config.metrics;
|
|
79
|
+
metrics = webex.internal.metrics;
|
|
80
|
+
|
|
81
|
+
webex.request = function (options) {
|
|
82
|
+
return Promise.resolve({
|
|
83
|
+
statusCode: 204,
|
|
84
|
+
body: undefined,
|
|
85
|
+
options,
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
webex.credentials = new Credentials(undefined, {parent: webex});
|
|
90
|
+
sinon.stub(webex.credentials, 'getClientToken').returns(Promise.resolve('token'));
|
|
91
|
+
|
|
92
|
+
webex.internal = {...webex.internal};
|
|
93
|
+
webex.config = {
|
|
94
|
+
...webex.config,
|
|
95
|
+
appName: 'appName',
|
|
96
|
+
appPlatform: 'appPlatform',
|
|
97
|
+
appVersion: 'appVersion',
|
|
98
|
+
};
|
|
99
|
+
webex.config.metrics.type = ['operational'];
|
|
100
|
+
webex.config.metrics.appType = 'sdk';
|
|
101
|
+
|
|
102
|
+
sinon.spy(webex, 'request');
|
|
103
|
+
sinon.spy(metrics, 'postPreLoginMetric');
|
|
104
|
+
sinon.spy(metrics, 'aliasUser');
|
|
105
|
+
sinon.spy(metrics, 'submitCallDiagnosticEvents');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('#submit()', () => {
|
|
109
|
+
it('submits a metric', () => {
|
|
110
|
+
const promise = metrics.submit('testMetric');
|
|
111
|
+
|
|
112
|
+
return promiseTick(50)
|
|
113
|
+
.then(() => clock.tick(config.metrics.batcherWait))
|
|
114
|
+
.then(() => promise)
|
|
115
|
+
.then(() => {
|
|
116
|
+
assert.calledOnce(webex.request);
|
|
117
|
+
const req = webex.request.args[0][0];
|
|
118
|
+
const metric = req.body.metrics[0];
|
|
119
|
+
|
|
120
|
+
assert.property(metric, 'key');
|
|
121
|
+
assert.property(metric, 'version');
|
|
122
|
+
assert.property(metric, 'appType');
|
|
123
|
+
assert.property(metric, 'env');
|
|
124
|
+
assert.property(metric, 'time');
|
|
125
|
+
assert.property(metric, 'version');
|
|
126
|
+
|
|
127
|
+
assert.equal(metric.key, 'testMetric');
|
|
128
|
+
assert.equal(metric.version, webex.version);
|
|
129
|
+
assert.equal(metric.env, 'TEST');
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('#submitClientMetrics()', () => {
|
|
135
|
+
describe('before login', () => {
|
|
136
|
+
it('posts pre-login metric', () => {
|
|
137
|
+
const date = clock.now;
|
|
138
|
+
const promise = metrics.submitClientMetrics(eventName, mockPayload, preLoginId);
|
|
139
|
+
|
|
140
|
+
return promiseTick(50)
|
|
141
|
+
.then(() => clock.tick(config.metrics.batcherWait))
|
|
142
|
+
.then(() => promise)
|
|
143
|
+
.then(() => {
|
|
144
|
+
assert.called(metrics.postPreLoginMetric);
|
|
145
|
+
assert.calledOnce(webex.credentials.getClientToken);
|
|
146
|
+
assert.calledOnce(webex.request);
|
|
147
|
+
const req = webex.request.args[0][0];
|
|
148
|
+
const metric = req.body.metrics[0];
|
|
149
|
+
|
|
150
|
+
assert.property(metric, 'metricName');
|
|
151
|
+
assert.property(metric, 'tags');
|
|
152
|
+
assert.property(metric, 'fields');
|
|
153
|
+
assert.property(metric, 'timestamp');
|
|
154
|
+
assert.property(metric, 'type');
|
|
155
|
+
assert.property(metric, 'eventPayload');
|
|
156
|
+
assert.notProperty(metric.tags, 'org_id');
|
|
157
|
+
|
|
158
|
+
assert.equal(metric.timestamp, date);
|
|
159
|
+
assert.equal(metric.metricName, 'test_event');
|
|
160
|
+
assert.equal(metric.type, 'behavioral');
|
|
161
|
+
assert.equal(metric.fields.testField, 123);
|
|
162
|
+
assert.equal(metric.tags.testTag, 'tag value');
|
|
163
|
+
assert.equal(metric.eventPayload.value, 'splunk business metric payload');
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
describe('after login', () => {
|
|
168
|
+
it('submits a metric to clientmetrics', () => {
|
|
169
|
+
webex.credentials.supertoken = new Token(
|
|
170
|
+
{
|
|
171
|
+
access_token: 'a_b_orgid',
|
|
172
|
+
},
|
|
173
|
+
{parent: webex}
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const testPayload = {
|
|
177
|
+
tags: {success: true},
|
|
178
|
+
fields: {perceivedDurationInMillis: 314},
|
|
179
|
+
context: {},
|
|
180
|
+
eventPayload: {value: 'splunk business metric payload'},
|
|
181
|
+
};
|
|
182
|
+
const date = clock.now;
|
|
183
|
+
|
|
184
|
+
const promise = metrics.submitClientMetrics('test', testPayload);
|
|
185
|
+
|
|
186
|
+
return promiseTick(50)
|
|
187
|
+
.then(() => clock.tick(config.metrics.batcherWait))
|
|
188
|
+
.then(() => promise)
|
|
189
|
+
.then(() => {
|
|
190
|
+
assert.calledOnce(webex.request);
|
|
191
|
+
const req = webex.request.args[0][0];
|
|
192
|
+
const metric = req.body.metrics[0];
|
|
193
|
+
|
|
194
|
+
assert.property(metric, 'metricName');
|
|
195
|
+
assert.property(metric, 'tags');
|
|
196
|
+
assert.property(metric, 'fields');
|
|
197
|
+
assert.property(metric, 'timestamp');
|
|
198
|
+
assert.property(metric, 'context');
|
|
199
|
+
assert.property(metric, 'eventPayload');
|
|
200
|
+
|
|
201
|
+
assert.property(metric.tags, 'browser');
|
|
202
|
+
assert.property(metric.tags, 'os');
|
|
203
|
+
assert.property(metric.tags, 'domain');
|
|
204
|
+
|
|
205
|
+
assert.property(metric.fields, 'browser_version');
|
|
206
|
+
assert.property(metric.fields, 'os_version');
|
|
207
|
+
assert.property(metric.fields, 'sdk_version');
|
|
208
|
+
assert.property(metric.fields, 'platform');
|
|
209
|
+
assert.property(metric.fields, 'spark_user_agent');
|
|
210
|
+
assert.property(metric.fields, 'client_id');
|
|
211
|
+
|
|
212
|
+
assert.property(metric.context, 'app');
|
|
213
|
+
assert.property(metric.context, 'locale');
|
|
214
|
+
assert.property(metric.context, 'os');
|
|
215
|
+
|
|
216
|
+
assert.equal(metric.timestamp, date);
|
|
217
|
+
assert.equal(metric.metricName, 'test');
|
|
218
|
+
assert.equal(metric.tags.success, true);
|
|
219
|
+
assert.equal(metric.fields.perceivedDurationInMillis, 314);
|
|
220
|
+
assert.equal(metric.eventPayload.value, 'splunk business metric payload');
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('throws error if no metric name is given', () => {
|
|
225
|
+
assert.throws(
|
|
226
|
+
() => metrics.submitClientMetrics(),
|
|
227
|
+
'Missing behavioral metric name. Please provide one'
|
|
228
|
+
);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
describe('#postPreLoginMetric()', () => {
|
|
234
|
+
it('returns an HttpResponse object', () => {
|
|
235
|
+
const promise = metrics.postPreLoginMetric(preLoginProps, preLoginId);
|
|
236
|
+
|
|
237
|
+
return promiseTick(50)
|
|
238
|
+
.then(() => clock.tick(config.metrics.batcherWait))
|
|
239
|
+
.then(() => promise)
|
|
240
|
+
.then(() => {
|
|
241
|
+
assert.calledOnce(webex.request);
|
|
242
|
+
const req = webex.request.args[0][0];
|
|
243
|
+
const metric = req.body.metrics[0];
|
|
244
|
+
const {headers} = req;
|
|
245
|
+
|
|
246
|
+
assert.property(headers, 'x-prelogin-userid');
|
|
247
|
+
assert.property(metric, 'metricName');
|
|
248
|
+
assert.property(metric, 'tags');
|
|
249
|
+
assert.property(metric, 'fields');
|
|
250
|
+
assert.property(metric, 'timestamp');
|
|
251
|
+
|
|
252
|
+
assert.equal(metric.timestamp, transformedProps.timestamp);
|
|
253
|
+
assert.equal(metric.metricName, eventName);
|
|
254
|
+
assert.equal(metric.tags.testTag, 'tag value');
|
|
255
|
+
assert.equal(metric.fields.testField, 123);
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
describe('#aliasUser()', () => {
|
|
261
|
+
it('returns an HttpResponse object', () =>
|
|
262
|
+
metrics.aliasUser(preLoginId).then(() => {
|
|
263
|
+
assert.calledOnce(webex.request);
|
|
264
|
+
const req = webex.request.args[0][0];
|
|
265
|
+
const params = req.qs;
|
|
266
|
+
|
|
267
|
+
assert.match(params, {alias: true});
|
|
268
|
+
}));
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
describe('#submitCallDiagnosticEvents()', () => {
|
|
272
|
+
it('submits a call diagnostic event', () => {
|
|
273
|
+
const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
|
|
274
|
+
|
|
275
|
+
return promiseTick(50)
|
|
276
|
+
.then(() => clock.tick(config.metrics.batcherWait))
|
|
277
|
+
.then(() => promise)
|
|
278
|
+
.then(() => {
|
|
279
|
+
assert.calledOnce(webex.request);
|
|
280
|
+
const req = webex.request.args[0][0];
|
|
281
|
+
const metric = req.body.metrics[0];
|
|
282
|
+
|
|
283
|
+
assert.property(metric.eventPayload, 'origin');
|
|
284
|
+
assert.property(metric.eventPayload, 'originTime');
|
|
285
|
+
assert.property(metric.eventPayload.origin, 'buildType');
|
|
286
|
+
assert.property(metric.eventPayload.origin, 'networkType');
|
|
287
|
+
assert.property(metric.eventPayload.originTime, 'sent');
|
|
288
|
+
assert.equal(metric.eventPayload.origin.buildType, 'test');
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
it('submits a call diagnostic event with buildType set in the payload', () => {
|
|
293
|
+
const promise = metrics.submitCallDiagnosticEvents({
|
|
294
|
+
...mockCallDiagnosticEvent,
|
|
295
|
+
origin: {
|
|
296
|
+
buildType: 'prod',
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
return promiseTick(50)
|
|
301
|
+
.then(() => clock.tick(config.metrics.batcherWait))
|
|
302
|
+
.then(() => promise)
|
|
303
|
+
.then(() => {
|
|
304
|
+
assert.calledOnce(webex.request);
|
|
305
|
+
const req = webex.request.args[0][0];
|
|
306
|
+
const metric = req.body.metrics[0];
|
|
307
|
+
|
|
308
|
+
assert.property(metric.eventPayload, 'origin');
|
|
309
|
+
assert.property(metric.eventPayload, 'originTime');
|
|
310
|
+
assert.property(metric.eventPayload.origin, 'buildType');
|
|
311
|
+
assert.property(metric.eventPayload.origin, 'networkType');
|
|
312
|
+
assert.property(metric.eventPayload.originTime, 'sent');
|
|
313
|
+
assert.equal(metric.eventPayload.origin.buildType, 'prod');
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
xit('submits a call diagnostic event with a test domain', () => {
|
|
318
|
+
global.window.location.hostname = 'test.webex.com';
|
|
319
|
+
|
|
320
|
+
const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
|
|
321
|
+
|
|
322
|
+
return promiseTick(50)
|
|
323
|
+
.then(() => clock.tick(config.metrics.batcherWait))
|
|
324
|
+
.then(() => promise)
|
|
325
|
+
.then(() => {
|
|
326
|
+
assert.calledOnce(webex.request);
|
|
327
|
+
const req = webex.request.args[0][0];
|
|
328
|
+
const metric = req.body.metrics[0];
|
|
329
|
+
|
|
330
|
+
assert.property(metric.eventPayload, 'origin');
|
|
331
|
+
assert.property(metric.eventPayload, 'originTime');
|
|
332
|
+
assert.property(metric.eventPayload.origin, 'buildType');
|
|
333
|
+
assert.property(metric.eventPayload.origin, 'networkType');
|
|
334
|
+
assert.property(metric.eventPayload.originTime, 'sent');
|
|
335
|
+
assert.equal(metric.eventPayload.origin.buildType, 'test');
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// Skip because it's current unable to overwrite NODE_ENV
|
|
340
|
+
// However doing `NODE_ENV=test npm run test ...` will get this test case to pass
|
|
341
|
+
xit('submits a call diagnostic event with a NODE_ENV=production', () => {
|
|
342
|
+
process.env.NODE_ENV = 'production';
|
|
343
|
+
|
|
344
|
+
const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
|
|
345
|
+
|
|
346
|
+
return promiseTick(50)
|
|
347
|
+
.then(() => clock.tick(config.metrics.batcherWait))
|
|
348
|
+
.then(() => promise)
|
|
349
|
+
.then(() => {
|
|
350
|
+
assert.calledOnce(webex.request);
|
|
351
|
+
const req = webex.request.args[0][0];
|
|
352
|
+
const metric = req.body.metrics[0];
|
|
353
|
+
|
|
354
|
+
assert.property(metric.eventPayload, 'origin');
|
|
355
|
+
assert.property(metric.eventPayload, 'originTime');
|
|
356
|
+
assert.property(metric.eventPayload.origin, 'buildType');
|
|
357
|
+
assert.property(metric.eventPayload.origin, 'networkType');
|
|
358
|
+
assert.property(metric.eventPayload.originTime, 'sent');
|
|
359
|
+
assert.equal(metric.eventPayload.origin.buildType, 'prod');
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
});
|