@webex/internal-plugin-metrics 3.0.0-beta.4 → 3.0.0-beta.400
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/README.md +1 -3
- package/dist/batcher.js +42 -22
- package/dist/batcher.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js +65 -0
- package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -0
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +508 -0
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -0
- package/dist/call-diagnostic/call-diagnostic-metrics.js +860 -0
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -0
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +367 -0
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -0
- package/dist/call-diagnostic/config.js +627 -0
- package/dist/call-diagnostic/config.js.map +1 -0
- package/dist/client-metrics-batcher.js +3 -8
- package/dist/client-metrics-batcher.js.map +1 -1
- package/dist/config.js +23 -6
- package/dist/config.js.map +1 -1
- package/dist/index.js +46 -10
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +47 -80
- package/dist/metrics.js.map +1 -1
- package/dist/metrics.types.js +7 -0
- package/dist/metrics.types.js.map +1 -0
- package/dist/new-metrics.js +300 -0
- package/dist/new-metrics.js.map +1 -0
- package/dist/prelogin-metrics-batcher.js +82 -0
- package/dist/prelogin-metrics-batcher.js.map +1 -0
- package/dist/types/batcher.d.ts +7 -0
- package/dist/types/call-diagnostic/call-diagnostic-metrics-batcher.d.ts +2 -0
- package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +218 -0
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +421 -0
- package/dist/types/call-diagnostic/call-diagnostic-metrics.util.d.ts +103 -0
- package/dist/types/call-diagnostic/config.d.ts +178 -0
- package/dist/types/client-metrics-batcher.d.ts +2 -0
- package/dist/types/config.d.ts +36 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/metrics.d.ts +3 -0
- package/dist/types/metrics.types.d.ts +105 -0
- package/dist/types/new-metrics.d.ts +131 -0
- package/dist/types/prelogin-metrics-batcher.d.ts +2 -0
- package/dist/types/utils.d.ts +6 -0
- package/dist/utils.js +27 -0
- package/dist/utils.js.map +1 -0
- package/package.json +16 -8
- package/src/batcher.js +71 -26
- package/src/call-diagnostic/call-diagnostic-metrics-batcher.ts +72 -0
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +467 -0
- package/src/call-diagnostic/call-diagnostic-metrics.ts +919 -0
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +395 -0
- package/src/call-diagnostic/config.ts +685 -0
- package/src/client-metrics-batcher.js +4 -4
- package/src/config.js +26 -5
- package/src/index.ts +56 -0
- package/src/metrics.js +47 -58
- package/src/metrics.types.ts +170 -0
- package/src/new-metrics.ts +278 -0
- package/src/prelogin-metrics-batcher.ts +95 -0
- package/src/utils.ts +17 -0
- package/test/unit/spec/batcher.js +28 -15
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +457 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +657 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +2303 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +634 -0
- package/test/unit/spec/client-metrics-batcher.js +28 -15
- package/test/unit/spec/metrics.js +94 -116
- package/test/unit/spec/new-metrics.ts +231 -0
- package/test/unit/spec/prelogin-metrics-batcher.ts +250 -0
- package/test/unit/spec/utils.ts +22 -0
- package/tsconfig.json +6 -0
- package/dist/call-diagnostic-events-batcher.js +0 -70
- package/dist/call-diagnostic-events-batcher.js.map +0 -1
- package/src/call-diagnostic-events-batcher.js +0 -62
- package/src/index.js +0 -17
- package/test/unit/spec/call-diagnostic-events-batcher.js +0 -180
|
@@ -27,8 +27,8 @@ describe('plugin-metrics', () => {
|
|
|
27
27
|
beforeEach(() => {
|
|
28
28
|
webex = new MockWebex({
|
|
29
29
|
children: {
|
|
30
|
-
metrics: Metrics
|
|
31
|
-
}
|
|
30
|
+
metrics: Metrics,
|
|
31
|
+
},
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
webex.config.metrics = config.metrics;
|
|
@@ -37,7 +37,8 @@ describe('plugin-metrics', () => {
|
|
|
37
37
|
return Promise.resolve({
|
|
38
38
|
statusCode: 204,
|
|
39
39
|
body: undefined,
|
|
40
|
-
|
|
40
|
+
waitForServiceTimeout: 30,
|
|
41
|
+
options,
|
|
41
42
|
});
|
|
42
43
|
};
|
|
43
44
|
sinon.spy(webex, 'request');
|
|
@@ -58,9 +59,10 @@ describe('plugin-metrics', () => {
|
|
|
58
59
|
it('clears the queue', () => {
|
|
59
60
|
clock.uninstall();
|
|
60
61
|
|
|
61
|
-
return webex.internal.metrics.clientMetricsBatcher
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
return webex.internal.metrics.clientMetricsBatcher
|
|
63
|
+
.request({
|
|
64
|
+
key: 'testMetric',
|
|
65
|
+
})
|
|
64
66
|
.then(() => {
|
|
65
67
|
assert.calledOnce(webex.request);
|
|
66
68
|
assert.lengthOf(webex.internal.metrics.clientMetricsBatcher.queue, 0);
|
|
@@ -80,26 +82,29 @@ describe('plugin-metrics', () => {
|
|
|
80
82
|
|
|
81
83
|
sinon.stub(webex, 'request').callsFake((options) => {
|
|
82
84
|
options.headers = {
|
|
83
|
-
trackingid: count
|
|
85
|
+
trackingid: count,
|
|
84
86
|
};
|
|
85
87
|
|
|
86
88
|
count += 1;
|
|
87
89
|
if (count < 9) {
|
|
88
|
-
return Promise.reject(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
return Promise.reject(
|
|
91
|
+
new WebexHttpError.NetworkOrCORSError({
|
|
92
|
+
statusCode: 0,
|
|
93
|
+
options,
|
|
94
|
+
})
|
|
95
|
+
);
|
|
92
96
|
}
|
|
93
97
|
|
|
94
98
|
return Promise.resolve({
|
|
95
99
|
statusCode: 204,
|
|
96
100
|
body: undefined,
|
|
97
|
-
|
|
101
|
+
waitForServiceTimeout: 30,
|
|
102
|
+
options,
|
|
98
103
|
});
|
|
99
104
|
});
|
|
100
105
|
|
|
101
106
|
const promise = webex.internal.metrics.clientMetricsBatcher.request({
|
|
102
|
-
key: 'testMetric'
|
|
107
|
+
key: 'testMetric',
|
|
103
108
|
});
|
|
104
109
|
|
|
105
110
|
return promiseTick(50)
|
|
@@ -159,8 +164,16 @@ describe('plugin-metrics', () => {
|
|
|
159
164
|
.then(() => assert.lengthOf(webex.internal.metrics.clientMetricsBatcher.queue, 0))
|
|
160
165
|
.then(() => promise)
|
|
161
166
|
.then(() => {
|
|
162
|
-
assert.lengthOf(
|
|
163
|
-
|
|
167
|
+
assert.lengthOf(
|
|
168
|
+
webex.request.args[1][0].body.metrics,
|
|
169
|
+
1,
|
|
170
|
+
'Reenqueuing the metric once did not increase the number of metrics to be submitted'
|
|
171
|
+
);
|
|
172
|
+
assert.lengthOf(
|
|
173
|
+
webex.request.args[2][0].body.metrics,
|
|
174
|
+
1,
|
|
175
|
+
'Reenqueuing the metric twice did not increase the number of metrics to be submitted'
|
|
176
|
+
);
|
|
164
177
|
assert.lengthOf(webex.internal.metrics.clientMetricsBatcher.queue, 0);
|
|
165
178
|
});
|
|
166
179
|
});
|
|
@@ -8,6 +8,9 @@ import {Token, Credentials} from '@webex/webex-core';
|
|
|
8
8
|
import FakeTimers from '@sinonjs/fake-timers';
|
|
9
9
|
import sinon from 'sinon';
|
|
10
10
|
import Metrics, {config} from '@webex/internal-plugin-metrics';
|
|
11
|
+
import {BrowserDetection} from '@webex/common';
|
|
12
|
+
|
|
13
|
+
const {getOSVersion} = BrowserDetection();
|
|
11
14
|
|
|
12
15
|
function promiseTick(count) {
|
|
13
16
|
let promise = Promise.resolve();
|
|
@@ -29,35 +32,35 @@ describe('plugin-metrics', () => {
|
|
|
29
32
|
const eventName = 'test_event';
|
|
30
33
|
const mockPayload = {
|
|
31
34
|
fields: {
|
|
32
|
-
testField: 123
|
|
35
|
+
testField: 123,
|
|
33
36
|
},
|
|
34
37
|
tags: {
|
|
35
|
-
testTag: 'tag value'
|
|
38
|
+
testTag: 'tag value',
|
|
36
39
|
},
|
|
37
40
|
metricName: eventName,
|
|
38
41
|
test: 'this field should not be included in final payload',
|
|
39
42
|
type: 'behavioral',
|
|
40
|
-
eventPayload: {value: 'splunk business metric payload'}
|
|
43
|
+
eventPayload: {value: 'splunk business metric payload'},
|
|
41
44
|
};
|
|
42
45
|
const transformedProps = {
|
|
43
46
|
fields: {
|
|
44
|
-
testField: 123
|
|
47
|
+
testField: 123,
|
|
45
48
|
},
|
|
46
49
|
tags: {
|
|
47
|
-
testTag: 'tag value'
|
|
50
|
+
testTag: 'tag value',
|
|
48
51
|
},
|
|
49
52
|
metricName: eventName,
|
|
50
53
|
type: 'behavioral',
|
|
51
|
-
timestamp: Date.now()
|
|
54
|
+
timestamp: Date.now(),
|
|
52
55
|
};
|
|
53
56
|
const preLoginId = '1b90cf5e-27a6-41aa-a208-1f6eb6b9e6b6';
|
|
54
57
|
const preLoginProps = {
|
|
55
|
-
metrics: [transformedProps]
|
|
58
|
+
metrics: [transformedProps],
|
|
56
59
|
};
|
|
57
60
|
const mockCallDiagnosticEvent = {
|
|
58
61
|
originTime: {
|
|
59
|
-
triggered: 'mock triggered timestamp'
|
|
60
|
-
}
|
|
62
|
+
triggered: 'mock triggered timestamp',
|
|
63
|
+
},
|
|
61
64
|
};
|
|
62
65
|
|
|
63
66
|
beforeEach(() => {
|
|
@@ -71,8 +74,8 @@ describe('plugin-metrics', () => {
|
|
|
71
74
|
beforeEach(() => {
|
|
72
75
|
webex = new MockWebex({
|
|
73
76
|
children: {
|
|
74
|
-
metrics: Metrics
|
|
75
|
-
}
|
|
77
|
+
metrics: Metrics,
|
|
78
|
+
},
|
|
76
79
|
});
|
|
77
80
|
|
|
78
81
|
webex.config.metrics = config.metrics;
|
|
@@ -82,7 +85,8 @@ describe('plugin-metrics', () => {
|
|
|
82
85
|
return Promise.resolve({
|
|
83
86
|
statusCode: 204,
|
|
84
87
|
body: undefined,
|
|
85
|
-
|
|
88
|
+
waitForServiceTimeout: 30,
|
|
89
|
+
options,
|
|
86
90
|
});
|
|
87
91
|
};
|
|
88
92
|
|
|
@@ -94,16 +98,21 @@ describe('plugin-metrics', () => {
|
|
|
94
98
|
...webex.config,
|
|
95
99
|
appName: 'appName',
|
|
96
100
|
appPlatform: 'appPlatform',
|
|
97
|
-
appVersion: 'appVersion'
|
|
98
|
-
|
|
101
|
+
appVersion: 'appVersion',
|
|
99
102
|
};
|
|
100
103
|
webex.config.metrics.type = ['operational'];
|
|
101
104
|
webex.config.metrics.appType = 'sdk';
|
|
105
|
+
webex.meetings = {
|
|
106
|
+
config: {
|
|
107
|
+
metrics: {
|
|
108
|
+
clientVersion: '43.0.105'
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
102
112
|
|
|
103
113
|
sinon.spy(webex, 'request');
|
|
104
114
|
sinon.spy(metrics, 'postPreLoginMetric');
|
|
105
115
|
sinon.spy(metrics, 'aliasUser');
|
|
106
|
-
sinon.spy(metrics, 'submitCallDiagnosticEvents');
|
|
107
116
|
});
|
|
108
117
|
|
|
109
118
|
describe('#submit()', () => {
|
|
@@ -132,6 +141,68 @@ describe('plugin-metrics', () => {
|
|
|
132
141
|
});
|
|
133
142
|
});
|
|
134
143
|
|
|
144
|
+
describe('#getClientMetricsPayload()', () => {
|
|
145
|
+
it('returns the expected payload', () => {
|
|
146
|
+
webex.credentials.supertoken = new Token(
|
|
147
|
+
{
|
|
148
|
+
access_token: 'a_b_orgid',
|
|
149
|
+
},
|
|
150
|
+
{parent: webex}
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const testPayload = {
|
|
154
|
+
tags: {success: true},
|
|
155
|
+
fields: {perceivedDurationInMillis: 314},
|
|
156
|
+
context: {},
|
|
157
|
+
eventPayload: {value: 'splunk business metric payload'},
|
|
158
|
+
};
|
|
159
|
+
const date = clock.now;
|
|
160
|
+
|
|
161
|
+
const result = metrics.getClientMetricsPayload('test', testPayload);
|
|
162
|
+
|
|
163
|
+
assert.deepEqual(result, {
|
|
164
|
+
context: {
|
|
165
|
+
app: {
|
|
166
|
+
version: undefined,
|
|
167
|
+
},
|
|
168
|
+
locale: 'en-US',
|
|
169
|
+
os: {
|
|
170
|
+
name: 'other',
|
|
171
|
+
version: getOSVersion(),
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
eventPayload: {
|
|
175
|
+
value: 'splunk business metric payload',
|
|
176
|
+
},
|
|
177
|
+
fields: {
|
|
178
|
+
browser_version: '',
|
|
179
|
+
client_id: 'fake',
|
|
180
|
+
os_version: getOSVersion(),
|
|
181
|
+
perceivedDurationInMillis: 314,
|
|
182
|
+
platform: 'Web',
|
|
183
|
+
sdk_version: undefined,
|
|
184
|
+
spark_user_agent: 'webex-js-sdk appName/appVersion appPlatform',
|
|
185
|
+
},
|
|
186
|
+
metricName: 'test',
|
|
187
|
+
tags: {
|
|
188
|
+
appVersion: '43.0.105',
|
|
189
|
+
browser: '',
|
|
190
|
+
domain: 'whatever',
|
|
191
|
+
os: 'other',
|
|
192
|
+
success: true,
|
|
193
|
+
},
|
|
194
|
+
timestamp: 0,
|
|
195
|
+
type: ['operational'],
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('throws when no event name is specified', () => {
|
|
200
|
+
assert.throws(() => {
|
|
201
|
+
metrics.getClientMetricsPayload();
|
|
202
|
+
}, 'Missing behavioral metric name. Please provide one');
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
135
206
|
describe('#submitClientMetrics()', () => {
|
|
136
207
|
describe('before login', () => {
|
|
137
208
|
it('posts pre-login metric', () => {
|
|
@@ -167,15 +238,18 @@ describe('plugin-metrics', () => {
|
|
|
167
238
|
});
|
|
168
239
|
describe('after login', () => {
|
|
169
240
|
it('submits a metric to clientmetrics', () => {
|
|
170
|
-
webex.credentials.supertoken = new Token(
|
|
171
|
-
|
|
172
|
-
|
|
241
|
+
webex.credentials.supertoken = new Token(
|
|
242
|
+
{
|
|
243
|
+
access_token: 'a_b_orgid',
|
|
244
|
+
},
|
|
245
|
+
{parent: webex}
|
|
246
|
+
);
|
|
173
247
|
|
|
174
248
|
const testPayload = {
|
|
175
249
|
tags: {success: true},
|
|
176
250
|
fields: {perceivedDurationInMillis: 314},
|
|
177
251
|
context: {},
|
|
178
|
-
eventPayload: {value: 'splunk business metric payload'}
|
|
252
|
+
eventPayload: {value: 'splunk business metric payload'},
|
|
179
253
|
};
|
|
180
254
|
const date = clock.now;
|
|
181
255
|
|
|
@@ -197,23 +271,20 @@ describe('plugin-metrics', () => {
|
|
|
197
271
|
assert.property(metric, 'eventPayload');
|
|
198
272
|
|
|
199
273
|
assert.property(metric.tags, 'browser');
|
|
200
|
-
assert.property(metric.tags, 'org_id');
|
|
201
274
|
assert.property(metric.tags, 'os');
|
|
202
275
|
assert.property(metric.tags, 'domain');
|
|
203
|
-
assert.property(metric.tags, 'client_id');
|
|
204
|
-
assert.property(metric.tags, 'user_id');
|
|
205
276
|
|
|
206
277
|
assert.property(metric.fields, 'browser_version');
|
|
207
278
|
assert.property(metric.fields, 'os_version');
|
|
208
279
|
assert.property(metric.fields, 'sdk_version');
|
|
209
280
|
assert.property(metric.fields, 'platform');
|
|
210
281
|
assert.property(metric.fields, 'spark_user_agent');
|
|
282
|
+
assert.property(metric.fields, 'client_id');
|
|
211
283
|
|
|
212
284
|
assert.property(metric.context, 'app');
|
|
213
285
|
assert.property(metric.context, 'locale');
|
|
214
286
|
assert.property(metric.context, 'os');
|
|
215
287
|
|
|
216
|
-
|
|
217
288
|
assert.equal(metric.timestamp, date);
|
|
218
289
|
assert.equal(metric.metricName, 'test');
|
|
219
290
|
assert.equal(metric.tags.success, true);
|
|
@@ -268,98 +339,5 @@ describe('plugin-metrics', () => {
|
|
|
268
339
|
assert.match(params, {alias: true});
|
|
269
340
|
}));
|
|
270
341
|
});
|
|
271
|
-
|
|
272
|
-
describe('#submitCallDiagnosticEvents()', () => {
|
|
273
|
-
it('submits a call diagnostic event', () => {
|
|
274
|
-
const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
|
|
275
|
-
|
|
276
|
-
return promiseTick(50)
|
|
277
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
278
|
-
.then(() => promise)
|
|
279
|
-
.then(() => {
|
|
280
|
-
assert.calledOnce(webex.request);
|
|
281
|
-
const req = webex.request.args[0][0];
|
|
282
|
-
const metric = req.body.metrics[0];
|
|
283
|
-
|
|
284
|
-
assert.property(metric.eventPayload, 'origin');
|
|
285
|
-
assert.property(metric.eventPayload, 'originTime');
|
|
286
|
-
assert.property(metric.eventPayload.origin, 'buildType');
|
|
287
|
-
assert.property(metric.eventPayload.origin, 'networkType');
|
|
288
|
-
assert.property(metric.eventPayload.originTime, 'sent');
|
|
289
|
-
assert.equal(metric.eventPayload.origin.buildType, 'test');
|
|
290
|
-
});
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
it('submits a call diagnostic event with buildType set in the payload', () => {
|
|
294
|
-
const promise = metrics.submitCallDiagnosticEvents({
|
|
295
|
-
...mockCallDiagnosticEvent,
|
|
296
|
-
origin: {
|
|
297
|
-
buildType: 'prod'
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
return promiseTick(50)
|
|
302
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
303
|
-
.then(() => promise)
|
|
304
|
-
.then(() => {
|
|
305
|
-
assert.calledOnce(webex.request);
|
|
306
|
-
const req = webex.request.args[0][0];
|
|
307
|
-
const metric = req.body.metrics[0];
|
|
308
|
-
|
|
309
|
-
assert.property(metric.eventPayload, 'origin');
|
|
310
|
-
assert.property(metric.eventPayload, 'originTime');
|
|
311
|
-
assert.property(metric.eventPayload.origin, 'buildType');
|
|
312
|
-
assert.property(metric.eventPayload.origin, 'networkType');
|
|
313
|
-
assert.property(metric.eventPayload.originTime, 'sent');
|
|
314
|
-
assert.equal(metric.eventPayload.origin.buildType, 'prod');
|
|
315
|
-
});
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
xit('submits a call diagnostic event with a test domain', () => {
|
|
319
|
-
global.window.location.hostname = 'test.webex.com';
|
|
320
|
-
|
|
321
|
-
const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
|
|
322
|
-
|
|
323
|
-
return promiseTick(50)
|
|
324
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
325
|
-
.then(() => promise)
|
|
326
|
-
.then(() => {
|
|
327
|
-
assert.calledOnce(webex.request);
|
|
328
|
-
const req = webex.request.args[0][0];
|
|
329
|
-
const metric = req.body.metrics[0];
|
|
330
|
-
|
|
331
|
-
assert.property(metric.eventPayload, 'origin');
|
|
332
|
-
assert.property(metric.eventPayload, 'originTime');
|
|
333
|
-
assert.property(metric.eventPayload.origin, 'buildType');
|
|
334
|
-
assert.property(metric.eventPayload.origin, 'networkType');
|
|
335
|
-
assert.property(metric.eventPayload.originTime, 'sent');
|
|
336
|
-
assert.equal(metric.eventPayload.origin.buildType, 'test');
|
|
337
|
-
});
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
// Skip because it's current unable to overwrite NODE_ENV
|
|
341
|
-
// However doing `NODE_ENV=test npm run test ...` will get this test case to pass
|
|
342
|
-
xit('submits a call diagnostic event with a NODE_ENV=production', () => {
|
|
343
|
-
process.env.NODE_ENV = 'production';
|
|
344
|
-
|
|
345
|
-
const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
|
|
346
|
-
|
|
347
|
-
return promiseTick(50)
|
|
348
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
349
|
-
.then(() => promise)
|
|
350
|
-
.then(() => {
|
|
351
|
-
assert.calledOnce(webex.request);
|
|
352
|
-
const req = webex.request.args[0][0];
|
|
353
|
-
const metric = req.body.metrics[0];
|
|
354
|
-
|
|
355
|
-
assert.property(metric.eventPayload, 'origin');
|
|
356
|
-
assert.property(metric.eventPayload, 'originTime');
|
|
357
|
-
assert.property(metric.eventPayload.origin, 'buildType');
|
|
358
|
-
assert.property(metric.eventPayload.origin, 'networkType');
|
|
359
|
-
assert.property(metric.eventPayload.originTime, 'sent');
|
|
360
|
-
assert.equal(metric.eventPayload.origin.buildType, 'prod');
|
|
361
|
-
});
|
|
362
|
-
});
|
|
363
|
-
});
|
|
364
342
|
});
|
|
365
343
|
});
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import {assert} from '@webex/test-helper-chai';
|
|
2
|
+
import {NewMetrics, CallDiagnosticLatencies} from '@webex/internal-plugin-metrics';
|
|
3
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
4
|
+
import sinon from 'sinon';
|
|
5
|
+
import {Utils} from '@webex/internal-plugin-metrics';
|
|
6
|
+
|
|
7
|
+
describe('internal-plugin-metrics', () => {
|
|
8
|
+
|
|
9
|
+
const mockWebex = () => new MockWebex({
|
|
10
|
+
children: {
|
|
11
|
+
newMetrics: NewMetrics,
|
|
12
|
+
},
|
|
13
|
+
meetings: {
|
|
14
|
+
meetingCollection: {
|
|
15
|
+
get: sinon.stub(),
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
request: sinon.stub().resolves({}),
|
|
19
|
+
logger: {
|
|
20
|
+
log: sinon.stub(),
|
|
21
|
+
error: sinon.stub(),
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('check submitClientEvent when webex is not ready', () => {
|
|
26
|
+
let webex;
|
|
27
|
+
//@ts-ignore
|
|
28
|
+
webex = mockWebex();
|
|
29
|
+
|
|
30
|
+
it('checks the log', () => {
|
|
31
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
32
|
+
name: 'client.alert.displayed',
|
|
33
|
+
options: {
|
|
34
|
+
meetingId: '123',
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
assert.calledWith(
|
|
38
|
+
webex.logger.log,
|
|
39
|
+
'NewMetrics: @submitClientEvent. Attempted to submit before webex.ready. Event name: client.alert.displayed'
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('new-metrics contstructor', () => {
|
|
45
|
+
it('checks callDiagnosticLatencies is defined before ready emit', () => {
|
|
46
|
+
|
|
47
|
+
const webex = mockWebex();
|
|
48
|
+
|
|
49
|
+
assert.instanceOf(webex.internal.newMetrics.callDiagnosticLatencies, CallDiagnosticLatencies);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('new-metrics', () => {
|
|
54
|
+
let webex;
|
|
55
|
+
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
//@ts-ignore
|
|
58
|
+
webex = mockWebex();
|
|
59
|
+
|
|
60
|
+
webex.emit('ready');
|
|
61
|
+
|
|
62
|
+
webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp = sinon.stub();
|
|
63
|
+
webex.internal.newMetrics.callDiagnosticLatencies.clearTimestamps = sinon.stub();
|
|
64
|
+
webex.internal.newMetrics.callDiagnosticMetrics.submitClientEvent = sinon.stub();
|
|
65
|
+
webex.internal.newMetrics.callDiagnosticMetrics.submitMQE = sinon.stub();
|
|
66
|
+
webex.internal.newMetrics.callDiagnosticMetrics.clientMetricsAliasUser = sinon.stub();
|
|
67
|
+
webex.internal.newMetrics.callDiagnosticMetrics.buildClientEventFetchRequestOptions =
|
|
68
|
+
sinon.stub();
|
|
69
|
+
webex.setTimingsAndFetch = sinon.stub();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
sinon.restore();
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('submits Client Event successfully', () => {
|
|
77
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
78
|
+
name: 'client.alert.displayed',
|
|
79
|
+
options: {
|
|
80
|
+
meetingId: '123',
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
|
|
85
|
+
key: 'client.alert.displayed',
|
|
86
|
+
options: {meetingId: '123'},
|
|
87
|
+
});
|
|
88
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticMetrics.submitClientEvent, {
|
|
89
|
+
name: 'client.alert.displayed',
|
|
90
|
+
payload: undefined,
|
|
91
|
+
options: {meetingId: '123'},
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
it('submits MQE successfully', () => {
|
|
97
|
+
webex.internal.newMetrics.submitMQE({
|
|
98
|
+
name: 'client.mediaquality.event',
|
|
99
|
+
//@ts-ignore
|
|
100
|
+
payload: {intervals: [{}]},
|
|
101
|
+
options: {
|
|
102
|
+
meetingId: '123',
|
|
103
|
+
networkType: 'wifi',
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
|
|
108
|
+
key: 'client.mediaquality.event',
|
|
109
|
+
});
|
|
110
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticMetrics.submitMQE, {
|
|
111
|
+
name: 'client.mediaquality.event',
|
|
112
|
+
//@ts-ignore
|
|
113
|
+
payload: {intervals: [{}]},
|
|
114
|
+
options: {
|
|
115
|
+
meetingId: '123',
|
|
116
|
+
networkType: 'wifi',
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('submits Internal Event successfully', () => {
|
|
122
|
+
webex.internal.newMetrics.submitInternalEvent({
|
|
123
|
+
name: 'client.mediaquality.event',
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
|
|
127
|
+
key: 'client.mediaquality.event',
|
|
128
|
+
});
|
|
129
|
+
assert.notCalled(webex.internal.newMetrics.callDiagnosticLatencies.clearTimestamps);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('submits Internal Event successfully for clearing the join latencies', () => {
|
|
133
|
+
webex.internal.newMetrics.submitInternalEvent({
|
|
134
|
+
name: 'internal.reset.join.latencies',
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
assert.notCalled(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp);
|
|
138
|
+
assert.calledOnce(webex.internal.newMetrics.callDiagnosticLatencies.clearTimestamps);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe('#clientMetricsAliasUser', () => {
|
|
142
|
+
it('aliases the user correctly', async () => {
|
|
143
|
+
webex.request.resolves({response: 'abc'});
|
|
144
|
+
await webex.internal.newMetrics.clientMetricsAliasUser('my-id');
|
|
145
|
+
assert.calledWith(webex.request, {
|
|
146
|
+
method: 'POST',
|
|
147
|
+
api: 'metrics',
|
|
148
|
+
resource: 'clientmetrics',
|
|
149
|
+
headers: { 'x-prelogin-userid': 'my-id' },
|
|
150
|
+
body: {},
|
|
151
|
+
qs: { alias: true },
|
|
152
|
+
});
|
|
153
|
+
assert.calledWith(
|
|
154
|
+
webex.logger.log,
|
|
155
|
+
'NewMetrics: @clientMetricsAliasUser. Request successful.'
|
|
156
|
+
);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('handles failed request correctly', async () => {
|
|
160
|
+
webex.request.rejects(new Error("test error"));
|
|
161
|
+
sinon.stub(Utils, 'generateCommonErrorMetadata').returns('formattedError')
|
|
162
|
+
try {
|
|
163
|
+
await webex.internal.newMetrics.clientMetricsAliasUser({event: 'test'}, 'my-id');
|
|
164
|
+
} catch (err) {
|
|
165
|
+
assert.calledWith(
|
|
166
|
+
webex.logger.error,
|
|
167
|
+
'NewMetrics: @clientMetricsAliasUser. Request failed:',
|
|
168
|
+
`err: formattedError`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe('#buildClientEventFetchRequestOptions', () => {
|
|
175
|
+
it('builds client event fetch options successfully', () => {
|
|
176
|
+
webex.internal.newMetrics.buildClientEventFetchRequestOptions({
|
|
177
|
+
name: 'client.alert.displayed',
|
|
178
|
+
options: {
|
|
179
|
+
meetingId: '123',
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
assert.calledWith(
|
|
184
|
+
webex.internal.newMetrics.callDiagnosticMetrics.buildClientEventFetchRequestOptions,
|
|
185
|
+
{
|
|
186
|
+
name: 'client.alert.displayed',
|
|
187
|
+
payload: undefined,
|
|
188
|
+
options: {meetingId: '123'},
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
describe('#setMetricTimingsAndFetch', () => {
|
|
195
|
+
beforeEach(() => {
|
|
196
|
+
global.fetch = sinon.stub();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('calls fetch with the expected options', () => {
|
|
200
|
+
const now = new Date();
|
|
201
|
+
sinon.useFakeTimers(now.getTime());
|
|
202
|
+
|
|
203
|
+
webex.internal.newMetrics.setMetricTimingsAndFetch({
|
|
204
|
+
json: true,
|
|
205
|
+
body: JSON.stringify({metrics: [{eventPayload: {}}]}),
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
const expected = {
|
|
209
|
+
json: true,
|
|
210
|
+
body: JSON.stringify({
|
|
211
|
+
metrics: [
|
|
212
|
+
{
|
|
213
|
+
eventPayload: {
|
|
214
|
+
originTime: {
|
|
215
|
+
triggered: now.toISOString(),
|
|
216
|
+
sent: now.toISOString(),
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
}),
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
sinon.assert.calledOnce(webex.setTimingsAndFetch);
|
|
225
|
+
sinon.assert.calledWith(webex.setTimingsAndFetch, expected);
|
|
226
|
+
|
|
227
|
+
sinon.restore();
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
});
|