@webex/internal-plugin-metrics 3.11.0-webex-services-ready.1 → 3.12.0-auth-prejoin-fetch.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/README.md +36 -0
- package/dist/automated-user.js +19 -0
- package/dist/automated-user.js.map +1 -0
- package/dist/batcher.js +3 -0
- package/dist/batcher.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +639 -65
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +168 -76
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +11 -3
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/call-diagnostic/config.js +16 -3
- package/dist/call-diagnostic/config.js.map +1 -1
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/generic-metrics.js +8 -6
- package/dist/generic-metrics.js.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js +4 -0
- package/dist/metrics.types.js.map +1 -1
- package/dist/new-metrics.js +108 -26
- package/dist/new-metrics.js.map +1 -1
- package/dist/prelogin-metrics.js +106 -0
- package/dist/prelogin-metrics.js.map +1 -0
- package/dist/privacy-and-security-permission-enricher/constants.js +18 -0
- package/dist/privacy-and-security-permission-enricher/constants.js.map +1 -0
- package/dist/privacy-and-security-permission-enricher/index.js +143 -0
- package/dist/privacy-and-security-permission-enricher/index.js.map +1 -0
- package/dist/privacy-and-security-permission-enricher/types.js +7 -0
- package/dist/privacy-and-security-permission-enricher/types.js.map +1 -0
- package/dist/privacy-and-security-permission-enricher/utils.js +71 -0
- package/dist/privacy-and-security-permission-enricher/utils.js.map +1 -0
- package/dist/types/automated-user.d.ts +2 -0
- package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +208 -5
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +79 -15
- package/dist/types/call-diagnostic/config.d.ts +4 -0
- package/dist/types/config.d.ts +4 -0
- package/dist/types/index.d.ts +6 -3
- package/dist/types/metrics.types.d.ts +9 -4
- package/dist/types/new-metrics.d.ts +29 -1
- package/dist/types/prelogin-metrics.d.ts +47 -0
- package/dist/types/privacy-and-security-permission-enricher/constants.d.ts +6 -0
- package/dist/types/privacy-and-security-permission-enricher/index.d.ts +40 -0
- package/dist/types/privacy-and-security-permission-enricher/types.d.ts +14 -0
- package/dist/types/privacy-and-security-permission-enricher/utils.d.ts +5 -0
- package/dist/types/unhandled-exception-telemetry/index.d.ts +60 -0
- package/dist/types/unhandled-exception-telemetry/utils.d.ts +6 -0
- package/dist/unhandled-exception-telemetry/index.js +330 -0
- package/dist/unhandled-exception-telemetry/index.js.map +1 -0
- package/dist/unhandled-exception-telemetry/utils.js +105 -0
- package/dist/unhandled-exception-telemetry/utils.js.map +1 -0
- package/package.json +12 -11
- package/src/automated-user.ts +16 -0
- package/src/batcher.js +4 -0
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +800 -75
- package/src/call-diagnostic/call-diagnostic-metrics.ts +102 -15
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +12 -2
- package/src/call-diagnostic/config.ts +14 -0
- package/src/config.js +4 -0
- package/src/generic-metrics.ts +6 -6
- package/src/index.ts +9 -0
- package/src/metrics.types.ts +27 -5
- package/src/new-metrics.ts +98 -6
- package/src/prelogin-metrics.ts +94 -0
- package/src/privacy-and-security-permission-enricher/constants.ts +33 -0
- package/src/privacy-and-security-permission-enricher/index.ts +142 -0
- package/src/privacy-and-security-permission-enricher/types.ts +21 -0
- package/src/privacy-and-security-permission-enricher/utils.ts +82 -0
- package/src/unhandled-exception-telemetry/index.ts +403 -0
- package/src/unhandled-exception-telemetry/utils.ts +101 -0
- package/test/unit/spec/automated-user.ts +43 -0
- package/test/unit/spec/batcher.js +43 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +47 -11
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +1550 -416
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +887 -159
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +37 -3
- package/test/unit/spec/new-metrics.ts +203 -50
- package/test/unit/spec/prelogin-metrics-batcher.ts +71 -36
- package/test/unit/spec/prelogin-metrics.ts +132 -0
- package/test/unit/spec/privacy-and-security-permission-enricher.ts +318 -0
- package/test/unit/spec/unhandled-exception-telemetry/utils.ts +109 -0
- package/test/unit/spec/unhandled-exception-telemetry.ts +688 -0
|
@@ -311,7 +311,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
311
311
|
origin: {
|
|
312
312
|
buildType: 'prod',
|
|
313
313
|
networkType: 'unknown',
|
|
314
|
-
upgradeChannel: expectedUpgradeChannel
|
|
314
|
+
upgradeChannel: expectedUpgradeChannel,
|
|
315
315
|
},
|
|
316
316
|
event: {name: eventName, ...expectedEvent},
|
|
317
317
|
},
|
|
@@ -393,7 +393,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
393
393
|
totalJmt: undefined,
|
|
394
394
|
clientJmt: undefined,
|
|
395
395
|
downloadTime: undefined,
|
|
396
|
-
clickToInterstitialWithUserDelay:
|
|
396
|
+
clickToInterstitialWithUserDelay: undefined,
|
|
397
397
|
totalJMTWithUserDelay: undefined,
|
|
398
398
|
},
|
|
399
399
|
},
|
|
@@ -430,7 +430,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
430
430
|
totalMediaJMT: undefined,
|
|
431
431
|
interstitialToMediaOKJMT: undefined,
|
|
432
432
|
callInitMediaEngineReady: undefined,
|
|
433
|
-
stayLobbyTime: undefined,
|
|
434
433
|
totalMediaJMTWithUserDelay: undefined,
|
|
435
434
|
totalJMTWithUserDelay: undefined,
|
|
436
435
|
},
|
|
@@ -447,12 +446,47 @@ describe('internal-plugin-metrics', () => {
|
|
|
447
446
|
},
|
|
448
447
|
},
|
|
449
448
|
],
|
|
449
|
+
[
|
|
450
|
+
'client.lobby.exited',
|
|
451
|
+
{
|
|
452
|
+
joinTimes: {
|
|
453
|
+
stayLobbyTime: undefined,
|
|
454
|
+
},
|
|
455
|
+
},
|
|
456
|
+
],
|
|
450
457
|
].forEach(([eventName, expectedEvent]) => {
|
|
451
458
|
it(`returns expected result for ${eventName}`, () => {
|
|
452
459
|
check(eventName as string, expectedEvent, 'gold');
|
|
453
460
|
});
|
|
454
461
|
});
|
|
455
462
|
|
|
463
|
+
it('logs a Milestone entry when event name is present', () => {
|
|
464
|
+
const logSpy = sinon.spy(webex.logger, 'log');
|
|
465
|
+
const eventName = 'client.call.initiated';
|
|
466
|
+
const eventPayload = {event: {name: eventName}};
|
|
467
|
+
|
|
468
|
+
prepareDiagnosticMetricItem(webex, {eventPayload, type: ['diagnostic-event']});
|
|
469
|
+
|
|
470
|
+
assert.isTrue(
|
|
471
|
+
logSpy.calledWith('Milestone,CallDiagnostic', eventName),
|
|
472
|
+
'expected logger.log to be called with Milestone,CallDiagnostic and the event name'
|
|
473
|
+
);
|
|
474
|
+
sinon.restore();
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it('does not log a Milestone entry when event name is absent', () => {
|
|
478
|
+
const logSpy = sinon.spy(webex.logger, 'log');
|
|
479
|
+
const eventPayload = {event: {}};
|
|
480
|
+
|
|
481
|
+
prepareDiagnosticMetricItem(webex, {eventPayload, type: ['diagnostic-event']});
|
|
482
|
+
|
|
483
|
+
assert.isFalse(
|
|
484
|
+
logSpy.calledWith('Milestone,CallDiagnostic', sinon.match.any),
|
|
485
|
+
'expected logger.log not to be called with Milestone,CallDiagnostic when event name is absent'
|
|
486
|
+
);
|
|
487
|
+
sinon.restore();
|
|
488
|
+
});
|
|
489
|
+
|
|
456
490
|
it('sets buildType and upgradeChannel correctly', () => {
|
|
457
491
|
const item: any = {
|
|
458
492
|
eventPayload: {
|
|
@@ -1,23 +1,34 @@
|
|
|
1
1
|
import {assert} from '@webex/test-helper-chai';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
NewMetrics,
|
|
4
|
+
CallDiagnosticLatencies,
|
|
5
|
+
AutomatedUserUtils,
|
|
6
|
+
Utils,
|
|
7
|
+
} from '@webex/internal-plugin-metrics';
|
|
3
8
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
4
9
|
import sinon from 'sinon';
|
|
5
|
-
import {Utils} from '@webex/internal-plugin-metrics';
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
import SourceNewMetrics from '@webex/internal-plugin-metrics/src/new-metrics';
|
|
12
|
+
import * as Telemetry from '@webex/internal-plugin-metrics/src/unhandled-exception-telemetry';
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
describe('internal-plugin-metrics', () => {
|
|
15
|
+
const mockWebex = (NewMetricsPlugin = NewMetrics) =>
|
|
16
|
+
new MockWebex({
|
|
17
|
+
children: {
|
|
18
|
+
newMetrics: NewMetricsPlugin,
|
|
19
|
+
},
|
|
20
|
+
meetings: {
|
|
21
|
+
getBasicMeetingInformation: sinon.stub().callsFake((meetingId) => ({
|
|
22
|
+
id: meetingId,
|
|
23
|
+
correlationId: `correlation-${meetingId}`,
|
|
24
|
+
})),
|
|
25
|
+
},
|
|
26
|
+
request: sinon.stub().resolves({}),
|
|
27
|
+
logger: {
|
|
28
|
+
log: sinon.stub(),
|
|
29
|
+
error: sinon.stub(),
|
|
30
|
+
},
|
|
31
|
+
});
|
|
21
32
|
|
|
22
33
|
describe('check submitClientEvent, submitFeatureEvent when webex is not ready', () => {
|
|
23
34
|
let webex;
|
|
@@ -46,12 +57,14 @@ describe('internal-plugin-metrics', () => {
|
|
|
46
57
|
payload: {
|
|
47
58
|
meetingSummaryInfo: {
|
|
48
59
|
featureName: 'syncSystemMuteStatus',
|
|
49
|
-
featureActions: [
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
featureActions: [
|
|
61
|
+
{
|
|
62
|
+
actionName: 'syncMeetingMicUnmuteStatusToSystem',
|
|
63
|
+
actionId: '14200',
|
|
64
|
+
isInitialValue: false,
|
|
65
|
+
clickCount: '1',
|
|
66
|
+
},
|
|
67
|
+
],
|
|
55
68
|
},
|
|
56
69
|
},
|
|
57
70
|
});
|
|
@@ -63,12 +76,54 @@ describe('internal-plugin-metrics', () => {
|
|
|
63
76
|
});
|
|
64
77
|
|
|
65
78
|
describe('new-metrics contstructor', () => {
|
|
66
|
-
|
|
79
|
+
afterEach(() => {
|
|
80
|
+
sinon.restore();
|
|
81
|
+
});
|
|
67
82
|
|
|
83
|
+
it('checks callDiagnosticLatencies is defined before ready emit', () => {
|
|
68
84
|
const webex = mockWebex();
|
|
69
85
|
|
|
70
86
|
assert.instanceOf(webex.internal.newMetrics.callDiagnosticLatencies, CallDiagnosticLatencies);
|
|
71
87
|
});
|
|
88
|
+
|
|
89
|
+
it('checks callDiagnosticMetrics is defined before ready emit', () => {
|
|
90
|
+
const webex = mockWebex();
|
|
91
|
+
|
|
92
|
+
assert.isDefined(webex.internal.newMetrics.callDiagnosticMetrics);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('can call buildClientEventFetchRequestOptions before ready', async () => {
|
|
96
|
+
const webex = mockWebex();
|
|
97
|
+
const stub = sinon
|
|
98
|
+
.stub(
|
|
99
|
+
webex.internal.newMetrics.callDiagnosticMetrics,
|
|
100
|
+
'buildClientEventFetchRequestOptions'
|
|
101
|
+
)
|
|
102
|
+
.resolves({url: 'https://metrics.example.com'});
|
|
103
|
+
|
|
104
|
+
const result = await webex.internal.newMetrics.buildClientEventFetchRequestOptions({
|
|
105
|
+
name: 'client.alert.displayed',
|
|
106
|
+
options: {correlationId: 'test-id'},
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
assert.calledOnceWithExactly(stub, {
|
|
110
|
+
name: 'client.alert.displayed',
|
|
111
|
+
payload: undefined,
|
|
112
|
+
options: {correlationId: 'test-id'},
|
|
113
|
+
});
|
|
114
|
+
assert.deepEqual(result, {url: 'https://metrics.example.com'});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('starts unhandled exception telemetry when webex is ready', () => {
|
|
118
|
+
const start = sinon.stub(Telemetry, 'startUnhandledExceptionTelemetry');
|
|
119
|
+
const webex = mockWebex(SourceNewMetrics);
|
|
120
|
+
|
|
121
|
+
assert.notCalled(start);
|
|
122
|
+
|
|
123
|
+
webex.emit('ready');
|
|
124
|
+
|
|
125
|
+
assert.calledOnceWithExactly(start, webex);
|
|
126
|
+
});
|
|
72
127
|
});
|
|
73
128
|
|
|
74
129
|
describe('new-metrics', () => {
|
|
@@ -94,7 +149,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
94
149
|
|
|
95
150
|
afterEach(() => {
|
|
96
151
|
sinon.restore();
|
|
97
|
-
})
|
|
152
|
+
});
|
|
98
153
|
|
|
99
154
|
it('lazy metrics backend initialization when checking if backend ready', () => {
|
|
100
155
|
assert.isUndefined(webex.internal.newMetrics.behavioralMetrics);
|
|
@@ -105,13 +160,20 @@ describe('internal-plugin-metrics', () => {
|
|
|
105
160
|
webex.internal.newMetrics.isReadyToSubmitOperationalEvents();
|
|
106
161
|
assert.isDefined(webex.internal.newMetrics.operationalMetrics);
|
|
107
162
|
|
|
108
|
-
assert.isUndefined(webex.internal.newMetrics.businessMetrics)
|
|
163
|
+
assert.isUndefined(webex.internal.newMetrics.businessMetrics);
|
|
109
164
|
webex.internal.newMetrics.isReadyToSubmitBusinessEvents();
|
|
110
165
|
assert.isDefined(webex.internal.newMetrics.businessMetrics);
|
|
111
|
-
})
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('returns the automated user classification', () => {
|
|
169
|
+
assert.strictEqual(
|
|
170
|
+
webex.internal.newMetrics.isAutomatedUser(),
|
|
171
|
+
AutomatedUserUtils.isAutomatedUser()
|
|
172
|
+
);
|
|
173
|
+
});
|
|
112
174
|
|
|
113
175
|
it('passes the table through to the business metrics', () => {
|
|
114
|
-
assert.isUndefined(webex.internal.newMetrics.businessMetrics)
|
|
176
|
+
assert.isUndefined(webex.internal.newMetrics.businessMetrics);
|
|
115
177
|
webex.internal.newMetrics.isReadyToSubmitBusinessEvents();
|
|
116
178
|
assert.isDefined(webex.internal.newMetrics.businessMetrics);
|
|
117
179
|
webex.internal.newMetrics.businessMetrics.submitBusinessEvent = sinon.stub();
|
|
@@ -119,14 +181,14 @@ describe('internal-plugin-metrics', () => {
|
|
|
119
181
|
name: 'foobar',
|
|
120
182
|
payload: {},
|
|
121
183
|
table: 'test',
|
|
122
|
-
metadata: {
|
|
184
|
+
metadata: {foo: 'bar'},
|
|
123
185
|
});
|
|
124
186
|
|
|
125
187
|
assert.calledWith(webex.internal.newMetrics.businessMetrics.submitBusinessEvent, {
|
|
126
188
|
name: 'foobar',
|
|
127
189
|
payload: {},
|
|
128
190
|
table: 'test',
|
|
129
|
-
metadata: {
|
|
191
|
+
metadata: {foo: 'bar'},
|
|
130
192
|
});
|
|
131
193
|
});
|
|
132
194
|
|
|
@@ -150,6 +212,87 @@ describe('internal-plugin-metrics', () => {
|
|
|
150
212
|
});
|
|
151
213
|
});
|
|
152
214
|
|
|
215
|
+
describe('privacy and security permission enrichment', () => {
|
|
216
|
+
const permission = {
|
|
217
|
+
camera: {status: 'GRANTED' as const},
|
|
218
|
+
microphone: {status: 'DENIED' as const, reason: 'DENIED_BY_USER' as const},
|
|
219
|
+
contentShare: {status: 'REQUESTING' as const},
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
it('enriches an eligible client event through the public metrics API', () => {
|
|
223
|
+
webex.internal.newMetrics.setPrivacyAndSecurityPermission(permission);
|
|
224
|
+
webex.internal.newMetrics.submitClientEvent({name: 'client.call.initiated'});
|
|
225
|
+
|
|
226
|
+
const submittedPayload =
|
|
227
|
+
webex.internal.newMetrics.callDiagnosticMetrics.submitClientEvent.firstCall.args[0]
|
|
228
|
+
.payload;
|
|
229
|
+
|
|
230
|
+
assert.deepEqual(submittedPayload.privacyAndSecurityPermission, {
|
|
231
|
+
camera: permission.camera,
|
|
232
|
+
microphone: permission.microphone,
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it('uses the meeting correlation id to preserve history across identifier transitions', () => {
|
|
237
|
+
webex.meetings.getBasicMeetingInformation
|
|
238
|
+
.withArgs('meeting-1')
|
|
239
|
+
.returns({id: 'meeting-1', correlationId: 'correlation-1'});
|
|
240
|
+
webex.internal.newMetrics.setPrivacyAndSecurityPermission(permission);
|
|
241
|
+
|
|
242
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
243
|
+
name: 'client.call.initiated',
|
|
244
|
+
options: {correlationId: 'correlation-1'},
|
|
245
|
+
});
|
|
246
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
247
|
+
name: 'client.ice.end',
|
|
248
|
+
payload: {},
|
|
249
|
+
options: {meetingId: 'meeting-1'},
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
const submissions = webex.internal.newMetrics.callDiagnosticMetrics.submitClientEvent.args;
|
|
253
|
+
|
|
254
|
+
assert.property(submissions[0][0].payload, 'privacyAndSecurityPermission');
|
|
255
|
+
assert.notProperty(submissions[1][0].payload, 'privacyAndSecurityPermission');
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it('uses the default scope when no correlation id can be resolved', () => {
|
|
259
|
+
webex.internal.newMetrics.setPrivacyAndSecurityPermission(permission);
|
|
260
|
+
|
|
261
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
262
|
+
name: 'client.call.initiated',
|
|
263
|
+
options: {sessionCorrelationId: 'session-1'},
|
|
264
|
+
});
|
|
265
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
266
|
+
name: 'client.ice.end',
|
|
267
|
+
payload: {},
|
|
268
|
+
options: {sessionCorrelationId: 'session-2'},
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
const submissions = webex.internal.newMetrics.callDiagnosticMetrics.submitClientEvent.args;
|
|
272
|
+
|
|
273
|
+
assert.property(submissions[0][0].payload, 'privacyAndSecurityPermission');
|
|
274
|
+
assert.notProperty(submissions[1][0].payload, 'privacyAndSecurityPermission');
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('captures the permission snapshot before a delayed event is queued', () => {
|
|
278
|
+
webex.internal.newMetrics.setPrivacyAndSecurityPermission(permission);
|
|
279
|
+
webex.internal.newMetrics.setDelaySubmitClientEvents({shouldDelay: true});
|
|
280
|
+
webex.internal.newMetrics.submitClientEvent({name: 'client.call.initiated'});
|
|
281
|
+
webex.internal.newMetrics.setPrivacyAndSecurityPermission({
|
|
282
|
+
camera: {status: 'DENIED' as const},
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const submission =
|
|
286
|
+
webex.internal.newMetrics.callDiagnosticMetrics.submitClientEvent.firstCall.args[0];
|
|
287
|
+
|
|
288
|
+
assert.isTrue(submission.delaySubmitEvent);
|
|
289
|
+
assert.deepEqual(submission.payload.privacyAndSecurityPermission, {
|
|
290
|
+
camera: permission.camera,
|
|
291
|
+
microphone: permission.microphone,
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
|
|
153
296
|
it('submits feature Event successfully', () => {
|
|
154
297
|
webex.internal.newMetrics.submitFeatureEvent({
|
|
155
298
|
name: 'client.feature.meeting.summary',
|
|
@@ -159,12 +302,14 @@ describe('internal-plugin-metrics', () => {
|
|
|
159
302
|
payload: {
|
|
160
303
|
meetingSummaryInfo: {
|
|
161
304
|
featureName: 'syncSystemMuteStatus',
|
|
162
|
-
featureActions: [
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
305
|
+
featureActions: [
|
|
306
|
+
{
|
|
307
|
+
actionName: 'syncMeetingMicUnmuteStatusToSystem',
|
|
308
|
+
actionId: '14200',
|
|
309
|
+
isInitialValue: false,
|
|
310
|
+
clickCount: '1',
|
|
311
|
+
},
|
|
312
|
+
],
|
|
168
313
|
},
|
|
169
314
|
},
|
|
170
315
|
});
|
|
@@ -178,12 +323,14 @@ describe('internal-plugin-metrics', () => {
|
|
|
178
323
|
payload: {
|
|
179
324
|
meetingSummaryInfo: {
|
|
180
325
|
featureName: 'syncSystemMuteStatus',
|
|
181
|
-
featureActions: [
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
326
|
+
featureActions: [
|
|
327
|
+
{
|
|
328
|
+
actionName: 'syncMeetingMicUnmuteStatusToSystem',
|
|
329
|
+
actionId: '14200',
|
|
330
|
+
isInitialValue: false,
|
|
331
|
+
clickCount: '1',
|
|
332
|
+
},
|
|
333
|
+
],
|
|
187
334
|
},
|
|
188
335
|
},
|
|
189
336
|
options: {meetingId: '123'},
|
|
@@ -244,9 +391,9 @@ describe('internal-plugin-metrics', () => {
|
|
|
244
391
|
method: 'POST',
|
|
245
392
|
api: 'metrics',
|
|
246
393
|
resource: 'clientmetrics',
|
|
247
|
-
headers: {
|
|
394
|
+
headers: {'x-prelogin-userid': 'my-id'},
|
|
248
395
|
body: {},
|
|
249
|
-
qs: {
|
|
396
|
+
qs: {alias: true},
|
|
250
397
|
});
|
|
251
398
|
assert.calledWith(
|
|
252
399
|
webex.logger.log,
|
|
@@ -255,8 +402,8 @@ describe('internal-plugin-metrics', () => {
|
|
|
255
402
|
});
|
|
256
403
|
|
|
257
404
|
it('handles failed request correctly', async () => {
|
|
258
|
-
webex.request.rejects(new Error(
|
|
259
|
-
sinon.stub(Utils, 'generateCommonErrorMetadata').returns('formattedError')
|
|
405
|
+
webex.request.rejects(new Error('test error'));
|
|
406
|
+
sinon.stub(Utils, 'generateCommonErrorMetadata').returns('formattedError');
|
|
260
407
|
try {
|
|
261
408
|
await webex.internal.newMetrics.clientMetricsAliasUser({event: 'test'}, 'my-id');
|
|
262
409
|
} catch (err) {
|
|
@@ -338,19 +485,26 @@ describe('internal-plugin-metrics', () => {
|
|
|
338
485
|
sinon.assert.match(webex.internal.newMetrics.delaySubmitClientEvents, true);
|
|
339
486
|
sinon.assert.match(webex.internal.newMetrics.delayedClientEventsOverrides, {});
|
|
340
487
|
|
|
341
|
-
webex.internal.newMetrics.setDelaySubmitClientEvents({
|
|
488
|
+
webex.internal.newMetrics.setDelaySubmitClientEvents({
|
|
489
|
+
shouldDelay: false,
|
|
490
|
+
overrides: {foo: 'bar'},
|
|
491
|
+
});
|
|
342
492
|
|
|
343
|
-
assert.calledOnce(
|
|
344
|
-
|
|
493
|
+
assert.calledOnce(
|
|
494
|
+
webex.internal.newMetrics.callDiagnosticMetrics.submitDelayedClientEvents
|
|
495
|
+
);
|
|
496
|
+
assert.calledWith(
|
|
497
|
+
webex.internal.newMetrics.callDiagnosticMetrics.submitDelayedClientEvents,
|
|
498
|
+
{foo: 'bar'}
|
|
499
|
+
);
|
|
345
500
|
|
|
346
501
|
sinon.assert.match(webex.internal.newMetrics.delaySubmitClientEvents, false);
|
|
347
502
|
sinon.assert.match(webex.internal.newMetrics.delayedClientEventsOverrides, {foo: 'bar'});
|
|
348
503
|
});
|
|
349
504
|
|
|
350
505
|
it('should not fail when called before webex is ready', () => {
|
|
351
|
-
|
|
352
506
|
// Create mock
|
|
353
|
-
webex = mockWebex()
|
|
507
|
+
webex = mockWebex();
|
|
354
508
|
|
|
355
509
|
webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp = sinon.stub();
|
|
356
510
|
webex.internal.newMetrics.callDiagnosticLatencies.clearTimestamps = sinon.stub();
|
|
@@ -365,7 +519,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
365
519
|
webex.internal.newMetrics.setDelaySubmitClientEvents({shouldDelay: false});
|
|
366
520
|
// Webex is ready
|
|
367
521
|
webex.emit('ready');
|
|
368
|
-
|
|
369
522
|
});
|
|
370
523
|
});
|
|
371
524
|
});
|
|
@@ -64,45 +64,36 @@ describe('internal-plugin-metrics', () => {
|
|
|
64
64
|
//@ts-ignore
|
|
65
65
|
assert.calledOnce(webex.request);
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
networkType: 'unknown',
|
|
87
|
-
upgradeChannel: 'test',
|
|
88
|
-
},
|
|
89
|
-
originTime: {
|
|
90
|
-
sent: dateAfterBatcherWait.toISOString(),
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
type: ['diagnostic-event'],
|
|
94
|
-
},
|
|
95
|
-
],
|
|
67
|
+
assert.deepEqual(webexRequestArgs.headers, {
|
|
68
|
+
authorization: false,
|
|
69
|
+
'x-prelogin-userid': preLoginId,
|
|
70
|
+
});
|
|
71
|
+
assert.equal(webexRequestArgs.method, 'POST');
|
|
72
|
+
assert.equal(webexRequestArgs.resource, 'clientmetrics-prelogin');
|
|
73
|
+
assert.equal(webexRequestArgs.service, 'metrics');
|
|
74
|
+
assert.equal(webexRequestArgs.waitForServiceTimeout, 30);
|
|
75
|
+
|
|
76
|
+
assert.deepEqual(webexRequestArgs.body.metrics[0].eventPayload, {
|
|
77
|
+
event: {
|
|
78
|
+
joinTimes: {
|
|
79
|
+
meetingInfoReqResp: undefined,
|
|
80
|
+
clickToInterstitial: undefined,
|
|
81
|
+
refreshCaptchaServiceReqResp: undefined,
|
|
82
|
+
downloadIntelligenceModelsReqResp: undefined,
|
|
83
|
+
clickToInterstitialWithUserDelay: undefined,
|
|
84
|
+
},
|
|
85
|
+
name: 'client.interstitial-window.launched',
|
|
96
86
|
},
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
'
|
|
87
|
+
origin: {
|
|
88
|
+
buildType: 'test',
|
|
89
|
+
networkType: 'unknown',
|
|
90
|
+
upgradeChannel: 'test',
|
|
91
|
+
},
|
|
92
|
+
originTime: {
|
|
93
|
+
sent: dateAfterBatcherWait.toISOString(),
|
|
100
94
|
},
|
|
101
|
-
method: 'POST',
|
|
102
|
-
resource: 'clientmetrics-prelogin',
|
|
103
|
-
service: 'metrics',
|
|
104
|
-
waitForServiceTimeout: 30,
|
|
105
95
|
});
|
|
96
|
+
assert.deepEqual(webexRequestArgs.body.metrics[0].type, ['diagnostic-event']);
|
|
106
97
|
assert.lengthOf(
|
|
107
98
|
webex.internal.newMetrics.callDiagnosticMetrics.preLoginMetricsBatcher.queue,
|
|
108
99
|
0
|
|
@@ -320,5 +311,49 @@ describe('internal-plugin-metrics', () => {
|
|
|
320
311
|
);
|
|
321
312
|
});
|
|
322
313
|
});
|
|
314
|
+
|
|
315
|
+
describe('#submitHttpRequest', () => {
|
|
316
|
+
it('calls webex.request with the correct parameters', async () => {
|
|
317
|
+
const payload = [
|
|
318
|
+
{
|
|
319
|
+
eventPayload: {event: 'my.event'},
|
|
320
|
+
type: ['diagnostic-event'],
|
|
321
|
+
},
|
|
322
|
+
];
|
|
323
|
+
|
|
324
|
+
webex.internal.newMetrics.callDiagnosticMetrics.preLoginMetricsBatcher.savePreLoginId(
|
|
325
|
+
preLoginId
|
|
326
|
+
);
|
|
327
|
+
webex.request = sinon.stub().resolves({statusCode: 200});
|
|
328
|
+
|
|
329
|
+
const promise =
|
|
330
|
+
webex.internal.newMetrics.callDiagnosticMetrics.preLoginMetricsBatcher.submitHttpRequest(
|
|
331
|
+
payload
|
|
332
|
+
);
|
|
333
|
+
|
|
334
|
+
await flushPromises();
|
|
335
|
+
|
|
336
|
+
clock.tick(config.metrics.batcherWait);
|
|
337
|
+
|
|
338
|
+
await promise;
|
|
339
|
+
|
|
340
|
+
const webexRequestArgs = webex.request.args[0][0];
|
|
341
|
+
|
|
342
|
+
assert.match(webexRequestArgs, {
|
|
343
|
+
//@ts-ignore
|
|
344
|
+
body: {
|
|
345
|
+
metrics: payload,
|
|
346
|
+
},
|
|
347
|
+
headers: {
|
|
348
|
+
authorization: false,
|
|
349
|
+
'x-prelogin-userid': preLoginId,
|
|
350
|
+
},
|
|
351
|
+
method: 'POST',
|
|
352
|
+
resource: 'clientmetrics-prelogin',
|
|
353
|
+
service: 'metrics',
|
|
354
|
+
waitForServiceTimeout: 30,
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
});
|
|
323
358
|
});
|
|
324
359
|
});
|