@webex/internal-plugin-metrics 3.5.0-next.3 → 3.5.0-next.5
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/dist/call-diagnostic/call-diagnostic-metrics.js +8 -3
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/rtcMetrics/constants.js +11 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +202 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +71 -0
- package/package.json +11 -11
- package/src/call-diagnostic/call-diagnostic-metrics.ts +6 -3
- package/src/index.ts +2 -0
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +186 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +214 -26
- package/test/unit/spec/rtcMetrics/index.ts +155 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import sinon from 'sinon';
|
|
2
|
+
import bowser from 'bowser';
|
|
2
3
|
import {assert} from '@webex/test-helper-chai';
|
|
3
4
|
import {WebexHttpError} from '@webex/webex-core';
|
|
4
5
|
import {BrowserDetection} from '@webex/common';
|
|
6
|
+
import window from 'global/window';
|
|
5
7
|
import {
|
|
6
8
|
CallDiagnosticLatencies,
|
|
7
9
|
CallDiagnosticMetrics,
|
|
@@ -30,7 +32,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
30
32
|
const fakeMeeting = {
|
|
31
33
|
id: '1',
|
|
32
34
|
correlationId: 'correlationId',
|
|
33
|
-
sessionCorrelationId: undefined,
|
|
34
35
|
callStateForMetrics: {},
|
|
35
36
|
environment: 'meeting_evn',
|
|
36
37
|
locusUrl: 'locus/url',
|
|
@@ -53,9 +54,17 @@ describe('internal-plugin-metrics', () => {
|
|
|
53
54
|
callStateForMetrics: {loginType: 'fakeLoginType'},
|
|
54
55
|
};
|
|
55
56
|
|
|
57
|
+
const fakeMeeting3 = {
|
|
58
|
+
...fakeMeeting,
|
|
59
|
+
id: '3',
|
|
60
|
+
correlationId: 'correlationId3',
|
|
61
|
+
sessionCorrelationId: 'sessionCorrelationId3',
|
|
62
|
+
}
|
|
63
|
+
|
|
56
64
|
const fakeMeetings = {
|
|
57
65
|
1: fakeMeeting,
|
|
58
66
|
2: fakeMeeting2,
|
|
67
|
+
3: fakeMeeting3,
|
|
59
68
|
};
|
|
60
69
|
|
|
61
70
|
let webex;
|
|
@@ -355,7 +364,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
355
364
|
|
|
356
365
|
assert.deepEqual(res, {
|
|
357
366
|
correlationId: 'correlationId',
|
|
358
|
-
sessionCorrelationId: undefined,
|
|
359
367
|
deviceId: 'deviceUrl',
|
|
360
368
|
locusId: 'url',
|
|
361
369
|
locusStartTime: 'lastActive',
|
|
@@ -368,7 +376,37 @@ describe('internal-plugin-metrics', () => {
|
|
|
368
376
|
});
|
|
369
377
|
});
|
|
370
378
|
|
|
371
|
-
|
|
379
|
+
[undefined, null, '', false, 0].forEach((sessionCorrelationId) => {
|
|
380
|
+
it(`should build identifiers correctly and not add session correlation id if it is falsy: ${sessionCorrelationId}`, () => {
|
|
381
|
+
cd.device = {
|
|
382
|
+
...cd.device,
|
|
383
|
+
config: {installationId: 'installationId'},
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
const res = cd.getIdentifiers({
|
|
387
|
+
mediaConnections: [
|
|
388
|
+
{mediaAgentAlias: 'mediaAgentAlias', mediaAgentGroupId: 'mediaAgentGroupId'},
|
|
389
|
+
],
|
|
390
|
+
meeting: {...fakeMeeting, sessionCorrelationId},
|
|
391
|
+
sessionCorrelationId: sessionCorrelationId as any,
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
assert.deepEqual(res, {
|
|
395
|
+
correlationId: 'correlationId',
|
|
396
|
+
deviceId: 'deviceUrl',
|
|
397
|
+
locusId: 'url',
|
|
398
|
+
locusStartTime: 'lastActive',
|
|
399
|
+
locusUrl: 'locus/url',
|
|
400
|
+
machineId: 'installationId',
|
|
401
|
+
mediaAgentAlias: 'mediaAgentAlias',
|
|
402
|
+
mediaAgentGroupId: 'mediaAgentGroupId',
|
|
403
|
+
orgId: 'orgId',
|
|
404
|
+
userId: 'userId',
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
it('should build identifiers correctly with sessionCorrelationID as a param', () => {
|
|
372
410
|
cd.device = {
|
|
373
411
|
...cd.device,
|
|
374
412
|
config: {installationId: 'installationId'},
|
|
@@ -397,6 +435,35 @@ describe('internal-plugin-metrics', () => {
|
|
|
397
435
|
});
|
|
398
436
|
});
|
|
399
437
|
|
|
438
|
+
it('should build identifiers correctly with sessionCorrelationID as a param and a meeting with session correlation id, and the param should take precedence', () => {
|
|
439
|
+
cd.device = {
|
|
440
|
+
...cd.device,
|
|
441
|
+
config: {installationId: 'installationId'},
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
const res = cd.getIdentifiers({
|
|
445
|
+
mediaConnections: [
|
|
446
|
+
{mediaAgentAlias: 'mediaAgentAlias', mediaAgentGroupId: 'mediaAgentGroupId'},
|
|
447
|
+
],
|
|
448
|
+
meeting: {...fakeMeeting, sessionCorrelationId: 'sessionCorrelationId1'},
|
|
449
|
+
sessionCorrelationId: 'sessionCorrelationId',
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
assert.deepEqual(res, {
|
|
453
|
+
correlationId: 'correlationId',
|
|
454
|
+
sessionCorrelationId: 'sessionCorrelationId',
|
|
455
|
+
deviceId: 'deviceUrl',
|
|
456
|
+
locusId: 'url',
|
|
457
|
+
locusStartTime: 'lastActive',
|
|
458
|
+
locusUrl: 'locus/url',
|
|
459
|
+
machineId: 'installationId',
|
|
460
|
+
mediaAgentAlias: 'mediaAgentAlias',
|
|
461
|
+
mediaAgentGroupId: 'mediaAgentGroupId',
|
|
462
|
+
orgId: 'orgId',
|
|
463
|
+
userId: 'userId',
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
|
|
400
467
|
it('should build identifiers correctly with a meeting that has meetingInfo with a webexConferenceIdStr and globalMeetingId, and that should take precedence over the options passed to it', () => {
|
|
401
468
|
const res = cd.getIdentifiers({
|
|
402
469
|
mediaConnections: [
|
|
@@ -450,7 +517,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
450
517
|
|
|
451
518
|
assert.deepEqual(res, {
|
|
452
519
|
correlationId: 'correlationId',
|
|
453
|
-
sessionCorrelationId: undefined,
|
|
454
520
|
webexConferenceIdStr: 'webexConferenceIdStr1',
|
|
455
521
|
globalMeetingId: 'globalMeetingId1',
|
|
456
522
|
deviceId: 'deviceUrl',
|
|
@@ -484,7 +550,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
484
550
|
|
|
485
551
|
assert.deepEqual(res, {
|
|
486
552
|
correlationId: 'correlationId',
|
|
487
|
-
sessionCorrelationId: undefined,
|
|
488
553
|
webexConferenceIdStr: 'webexConferenceIdStr1',
|
|
489
554
|
globalMeetingId: 'globalMeetingId1',
|
|
490
555
|
deviceId: 'deviceUrl',
|
|
@@ -543,7 +608,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
543
608
|
|
|
544
609
|
assert.deepEqual(res, {
|
|
545
610
|
correlationId: 'correlationId',
|
|
546
|
-
sessionCorrelationId: 'unknown',
|
|
547
611
|
webexConferenceIdStr: 'webexConferenceIdStr1',
|
|
548
612
|
deviceId: 'deviceUrl',
|
|
549
613
|
locusUrl: 'locus-url',
|
|
@@ -560,7 +624,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
560
624
|
|
|
561
625
|
assert.deepEqual(res, {
|
|
562
626
|
correlationId: 'correlationId',
|
|
563
|
-
sessionCorrelationId: 'unknown',
|
|
564
627
|
globalMeetingId: 'globalMeetingId1',
|
|
565
628
|
deviceId: 'deviceUrl',
|
|
566
629
|
locusUrl: 'locus-url',
|
|
@@ -576,7 +639,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
576
639
|
|
|
577
640
|
assert.deepEqual(res, {
|
|
578
641
|
correlationId: 'correlationId',
|
|
579
|
-
sessionCorrelationId: 'unknown',
|
|
580
642
|
deviceId: 'deviceUrl',
|
|
581
643
|
locusUrl: 'locus-url',
|
|
582
644
|
orgId: 'orgId',
|
|
@@ -621,7 +683,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
621
683
|
|
|
622
684
|
assert.deepEqual(res, {
|
|
623
685
|
correlationId: 'correlationId',
|
|
624
|
-
sessionCorrelationId: 'unknown',
|
|
625
686
|
locusUrl: 'locus-url',
|
|
626
687
|
deviceId: 'deviceUrl',
|
|
627
688
|
orgId: 'orgId',
|
|
@@ -695,12 +756,13 @@ describe('internal-plugin-metrics', () => {
|
|
|
695
756
|
options,
|
|
696
757
|
});
|
|
697
758
|
|
|
759
|
+
assert.called(getIdentifiersSpy);
|
|
698
760
|
assert.calledWith(getIdentifiersSpy, {
|
|
699
761
|
meeting: fakeMeeting,
|
|
700
762
|
mediaConnections: [{mediaAgentAlias: 'alias', mediaAgentGroupId: '1'}],
|
|
701
763
|
webexConferenceIdStr: undefined,
|
|
702
|
-
sessionCorrelationId: undefined,
|
|
703
764
|
globalMeetingId: undefined,
|
|
765
|
+
sessionCorrelationId: undefined,
|
|
704
766
|
});
|
|
705
767
|
assert.notCalled(generateClientEventErrorPayloadSpy);
|
|
706
768
|
assert.calledWith(
|
|
@@ -712,7 +774,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
712
774
|
},
|
|
713
775
|
identifiers: {
|
|
714
776
|
correlationId: 'correlationId',
|
|
715
|
-
sessionCorrelationId: undefined,
|
|
716
777
|
deviceId: 'deviceUrl',
|
|
717
778
|
locusId: 'url',
|
|
718
779
|
locusStartTime: 'lastActive',
|
|
@@ -738,7 +799,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
738
799
|
},
|
|
739
800
|
identifiers: {
|
|
740
801
|
correlationId: 'correlationId',
|
|
741
|
-
sessionCorrelationId: undefined,
|
|
742
802
|
deviceId: 'deviceUrl',
|
|
743
803
|
locusId: 'url',
|
|
744
804
|
locusStartTime: 'lastActive',
|
|
@@ -775,7 +835,142 @@ describe('internal-plugin-metrics', () => {
|
|
|
775
835
|
},
|
|
776
836
|
identifiers: {
|
|
777
837
|
correlationId: 'correlationId',
|
|
778
|
-
|
|
838
|
+
deviceId: 'deviceUrl',
|
|
839
|
+
locusId: 'url',
|
|
840
|
+
locusStartTime: 'lastActive',
|
|
841
|
+
locusUrl: 'locus/url',
|
|
842
|
+
mediaAgentAlias: 'alias',
|
|
843
|
+
mediaAgentGroupId: '1',
|
|
844
|
+
orgId: 'orgId',
|
|
845
|
+
userId: 'userId',
|
|
846
|
+
},
|
|
847
|
+
loginType: 'login-ci',
|
|
848
|
+
name: 'client.alert.displayed',
|
|
849
|
+
userType: 'host',
|
|
850
|
+
isConvergedArchitectureEnabled: undefined,
|
|
851
|
+
webexSubServiceType: undefined,
|
|
852
|
+
},
|
|
853
|
+
eventId: 'my-fake-id',
|
|
854
|
+
origin: {
|
|
855
|
+
origin: 'fake-origin',
|
|
856
|
+
},
|
|
857
|
+
originTime: {
|
|
858
|
+
sent: 'not_defined_yet',
|
|
859
|
+
triggered: now.toISOString(),
|
|
860
|
+
},
|
|
861
|
+
senderCountryCode: 'UK',
|
|
862
|
+
version: 1,
|
|
863
|
+
},
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
867
|
+
assert.deepEqual(webexLoggerLogCalls[1].args, [
|
|
868
|
+
'call-diagnostic-events -> ',
|
|
869
|
+
'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
|
|
870
|
+
`name: client.alert.displayed`,
|
|
871
|
+
]);
|
|
872
|
+
});
|
|
873
|
+
|
|
874
|
+
it('should submit client event successfully with meetingId which has a sessionCorrelationId', () => {
|
|
875
|
+
const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
|
|
876
|
+
const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
|
|
877
|
+
const generateClientEventErrorPayloadSpy = sinon.spy(cd, 'generateClientEventErrorPayload');
|
|
878
|
+
const getIdentifiersSpy = sinon.spy(cd, 'getIdentifiers');
|
|
879
|
+
const getSubServiceTypeSpy = sinon.spy(cd, 'getSubServiceType');
|
|
880
|
+
sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
|
|
881
|
+
const validatorSpy = sinon.spy(cd, 'validator');
|
|
882
|
+
const options = {
|
|
883
|
+
meetingId: fakeMeeting3.id,
|
|
884
|
+
mediaConnections: [{mediaAgentAlias: 'alias', mediaAgentGroupId: '1'}],
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
cd.submitClientEvent({
|
|
888
|
+
name: 'client.alert.displayed',
|
|
889
|
+
options,
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
assert.called(getIdentifiersSpy);
|
|
893
|
+
assert.calledWith(getIdentifiersSpy, {
|
|
894
|
+
meeting: {...fakeMeeting3, sessionCorrelationId: 'sessionCorrelationId3'},
|
|
895
|
+
mediaConnections: [{mediaAgentAlias: 'alias', mediaAgentGroupId: '1'}],
|
|
896
|
+
webexConferenceIdStr: undefined,
|
|
897
|
+
globalMeetingId: undefined,
|
|
898
|
+
sessionCorrelationId: undefined,
|
|
899
|
+
});
|
|
900
|
+
assert.notCalled(generateClientEventErrorPayloadSpy);
|
|
901
|
+
assert.calledWith(
|
|
902
|
+
prepareDiagnosticEventSpy,
|
|
903
|
+
{
|
|
904
|
+
canProceed: true,
|
|
905
|
+
eventData: {
|
|
906
|
+
webClientDomain: 'whatever',
|
|
907
|
+
},
|
|
908
|
+
identifiers: {
|
|
909
|
+
correlationId: 'correlationId3',
|
|
910
|
+
sessionCorrelationId: 'sessionCorrelationId3',
|
|
911
|
+
deviceId: 'deviceUrl',
|
|
912
|
+
locusId: 'url',
|
|
913
|
+
locusStartTime: 'lastActive',
|
|
914
|
+
locusUrl: 'locus/url',
|
|
915
|
+
mediaAgentAlias: 'alias',
|
|
916
|
+
mediaAgentGroupId: '1',
|
|
917
|
+
orgId: 'orgId',
|
|
918
|
+
userId: 'userId',
|
|
919
|
+
},
|
|
920
|
+
loginType: 'login-ci',
|
|
921
|
+
name: 'client.alert.displayed',
|
|
922
|
+
userType: 'host',
|
|
923
|
+
isConvergedArchitectureEnabled: undefined,
|
|
924
|
+
webexSubServiceType: undefined,
|
|
925
|
+
},
|
|
926
|
+
options
|
|
927
|
+
);
|
|
928
|
+
assert.calledWith(submitToCallDiagnosticsSpy, {
|
|
929
|
+
event: {
|
|
930
|
+
canProceed: true,
|
|
931
|
+
eventData: {
|
|
932
|
+
webClientDomain: 'whatever',
|
|
933
|
+
},
|
|
934
|
+
identifiers: {
|
|
935
|
+
correlationId: 'correlationId3',
|
|
936
|
+
sessionCorrelationId: 'sessionCorrelationId3',
|
|
937
|
+
deviceId: 'deviceUrl',
|
|
938
|
+
locusId: 'url',
|
|
939
|
+
locusStartTime: 'lastActive',
|
|
940
|
+
locusUrl: 'locus/url',
|
|
941
|
+
mediaAgentAlias: 'alias',
|
|
942
|
+
mediaAgentGroupId: '1',
|
|
943
|
+
orgId: 'orgId',
|
|
944
|
+
userId: 'userId',
|
|
945
|
+
},
|
|
946
|
+
loginType: 'login-ci',
|
|
947
|
+
name: 'client.alert.displayed',
|
|
948
|
+
userType: 'host',
|
|
949
|
+
isConvergedArchitectureEnabled: undefined,
|
|
950
|
+
webexSubServiceType: undefined,
|
|
951
|
+
},
|
|
952
|
+
eventId: 'my-fake-id',
|
|
953
|
+
origin: {
|
|
954
|
+
origin: 'fake-origin',
|
|
955
|
+
},
|
|
956
|
+
originTime: {
|
|
957
|
+
sent: 'not_defined_yet',
|
|
958
|
+
triggered: now.toISOString(),
|
|
959
|
+
},
|
|
960
|
+
senderCountryCode: 'UK',
|
|
961
|
+
version: 1,
|
|
962
|
+
});
|
|
963
|
+
assert.calledWith(validatorSpy, {
|
|
964
|
+
type: 'ce',
|
|
965
|
+
event: {
|
|
966
|
+
event: {
|
|
967
|
+
canProceed: true,
|
|
968
|
+
eventData: {
|
|
969
|
+
webClientDomain: 'whatever',
|
|
970
|
+
},
|
|
971
|
+
identifiers: {
|
|
972
|
+
correlationId: 'correlationId3',
|
|
973
|
+
sessionCorrelationId: 'sessionCorrelationId3',
|
|
779
974
|
deviceId: 'deviceUrl',
|
|
780
975
|
locusId: 'url',
|
|
781
976
|
locusStartTime: 'lastActive',
|
|
@@ -819,6 +1014,9 @@ describe('internal-plugin-metrics', () => {
|
|
|
819
1014
|
const getIdentifiersSpy = sinon.spy(cd, 'getIdentifiers');
|
|
820
1015
|
const getSubServiceTypeSpy = sinon.spy(cd, 'getSubServiceType');
|
|
821
1016
|
const validatorSpy = sinon.spy(cd, 'validator');
|
|
1017
|
+
sinon.stub(window.navigator, 'userAgent').get(() => userAgent);
|
|
1018
|
+
sinon.stub(bowser, 'getParser').returns(userAgent);
|
|
1019
|
+
|
|
822
1020
|
const options = {
|
|
823
1021
|
meetingId: fakeMeeting.id,
|
|
824
1022
|
mediaConnections: [{mediaAgentAlias: 'alias', mediaAgentGroupId: '1'}],
|
|
@@ -847,7 +1045,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
847
1045
|
assert.deepEqual(webexLoggerLogCalls[2].args, [
|
|
848
1046
|
'call-diagnostic-events -> ',
|
|
849
1047
|
'CallDiagnosticMetrics: @createClientEventObjectInMeeting => collected browser data',
|
|
850
|
-
|
|
1048
|
+
`${JSON.stringify(userAgent)}`,
|
|
851
1049
|
]);
|
|
852
1050
|
|
|
853
1051
|
assert.deepEqual(webexLoggerLogCalls[3].args, [
|
|
@@ -1052,7 +1250,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
1052
1250
|
},
|
|
1053
1251
|
identifiers: {
|
|
1054
1252
|
correlationId: 'correlationId2',
|
|
1055
|
-
sessionCorrelationId: undefined,
|
|
1056
1253
|
deviceId: 'deviceUrl',
|
|
1057
1254
|
locusId: 'url',
|
|
1058
1255
|
locusStartTime: 'lastActive',
|
|
@@ -1161,7 +1358,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
1161
1358
|
},
|
|
1162
1359
|
identifiers: {
|
|
1163
1360
|
correlationId: 'correlationId',
|
|
1164
|
-
sessionCorrelationId: undefined,
|
|
1165
1361
|
webexConferenceIdStr: 'webexConferenceIdStr1',
|
|
1166
1362
|
globalMeetingId: 'globalMeetingId1',
|
|
1167
1363
|
deviceId: 'deviceUrl',
|
|
@@ -1240,7 +1436,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
1240
1436
|
},
|
|
1241
1437
|
identifiers: {
|
|
1242
1438
|
correlationId: 'correlationId',
|
|
1243
|
-
sessionCorrelationId: undefined,
|
|
1244
1439
|
deviceId: 'deviceUrl',
|
|
1245
1440
|
locusId: 'url',
|
|
1246
1441
|
locusStartTime: 'lastActive',
|
|
@@ -1316,7 +1511,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
1316
1511
|
},
|
|
1317
1512
|
identifiers: {
|
|
1318
1513
|
correlationId: 'correlationId',
|
|
1319
|
-
sessionCorrelationId: 'unknown',
|
|
1320
1514
|
deviceId: 'deviceUrl',
|
|
1321
1515
|
locusUrl: 'locus-url',
|
|
1322
1516
|
orgId: 'orgId',
|
|
@@ -1390,7 +1584,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
1390
1584
|
},
|
|
1391
1585
|
identifiers: {
|
|
1392
1586
|
correlationId: 'correlationId',
|
|
1393
|
-
sessionCorrelationId: 'unknown',
|
|
1394
1587
|
deviceId: 'deviceUrl',
|
|
1395
1588
|
locusUrl: 'locus-url',
|
|
1396
1589
|
orgId: 'orgId',
|
|
@@ -1470,7 +1663,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
1470
1663
|
},
|
|
1471
1664
|
identifiers: {
|
|
1472
1665
|
correlationId: 'correlationId',
|
|
1473
|
-
sessionCorrelationId: undefined,
|
|
1474
1666
|
deviceId: 'deviceUrl',
|
|
1475
1667
|
locusId: 'url',
|
|
1476
1668
|
locusStartTime: 'lastActive',
|
|
@@ -1603,7 +1795,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
1603
1795
|
canProceed: true,
|
|
1604
1796
|
identifiers: {
|
|
1605
1797
|
correlationId: 'correlationId',
|
|
1606
|
-
sessionCorrelationId: undefined,
|
|
1607
1798
|
webexConferenceIdStr: 'webexConferenceIdStr1',
|
|
1608
1799
|
globalMeetingId: 'globalMeetingId1',
|
|
1609
1800
|
userId: 'userId',
|
|
@@ -1643,7 +1834,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
1643
1834
|
canProceed: true,
|
|
1644
1835
|
identifiers: {
|
|
1645
1836
|
correlationId: 'correlationId',
|
|
1646
|
-
sessionCorrelationId: undefined,
|
|
1647
1837
|
webexConferenceIdStr: 'webexConferenceIdStr1',
|
|
1648
1838
|
globalMeetingId: 'globalMeetingId1',
|
|
1649
1839
|
userId: 'userId',
|
|
@@ -1689,7 +1879,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
1689
1879
|
locusUrl: 'locus/url',
|
|
1690
1880
|
locusId: 'url',
|
|
1691
1881
|
locusStartTime: 'lastActive',
|
|
1692
|
-
sessionCorrelationId: undefined,
|
|
1693
1882
|
},
|
|
1694
1883
|
eventData: {webClientDomain: 'whatever'},
|
|
1695
1884
|
intervals: [{}],
|
|
@@ -2477,7 +2666,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
2477
2666
|
locusUrl: 'locus/url',
|
|
2478
2667
|
orgId: 'orgId',
|
|
2479
2668
|
userId: 'userId',
|
|
2480
|
-
sessionCorrelationId: undefined,
|
|
2481
2669
|
},
|
|
2482
2670
|
loginType: 'login-ci',
|
|
2483
2671
|
name: 'client.exit.app',
|
|
@@ -2585,11 +2773,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
2585
2773
|
// The method is called in beforeEach itself. We are just testing it here
|
|
2586
2774
|
it('sets the received deviceInfo to call-diagnostics', () => {
|
|
2587
2775
|
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
2588
|
-
const device = {
|
|
2776
|
+
const device = {userId: 'userId', url: 'deviceUrl', orgId: 'orgId'};
|
|
2589
2777
|
|
|
2590
2778
|
assert.deepEqual(webexLoggerLogCalls[0].args, [
|
|
2591
2779
|
'CallDiagnosticMetrics: @setDeviceInfo called',
|
|
2592
|
-
device
|
|
2780
|
+
device,
|
|
2593
2781
|
]);
|
|
2594
2782
|
|
|
2595
2783
|
assert.deepEqual(cd.device, device);
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import 'jsdom-global/register';
|
|
2
|
+
import RtcMetrics from '../../../../src/rtcMetrics';
|
|
3
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
4
|
+
import {assert} from '@webex/test-helper-chai';
|
|
5
|
+
import sinon from 'sinon';
|
|
6
|
+
import RTC_METRICS from '../../../../src/rtcMetrics/constants';
|
|
7
|
+
|
|
8
|
+
const FAKE_METRICS_ITEM = {payload: ['{"type":"string","value":"fake-metrics","id":""}']};
|
|
9
|
+
const FAILURE_METRICS_ITEM = {
|
|
10
|
+
name: "onconnectionstatechange",
|
|
11
|
+
payload: ['{"type":"string","value":"failed","id":""}'],
|
|
12
|
+
timestamp: 1707929986667
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const STATS_WITH_IP = '{"id":"RTCIceCandidate_/kQs0ZNU","type":"remote-candidate","transportId":"RTCTransport_0_1","isRemote":true,"ip":"11.22.111.255","address":"11.22.111.255","port":5004,"protocol":"udp","candidateType":"host","priority":2130706431}';
|
|
16
|
+
const STATS_WITH_IP_RESULT = '{"id":"RTCIceCandidate_/kQs0ZNU","type":"remote-candidate","transportId":"RTCTransport_0_1","isRemote":true,"ip":"11.22.111.240","address":"11.22.111.240","port":5004,"protocol":"udp","candidateType":"host","priority":2130706431}';
|
|
17
|
+
|
|
18
|
+
describe('RtcMetrics', () => {
|
|
19
|
+
let metrics: RtcMetrics;
|
|
20
|
+
let webex: MockWebex;
|
|
21
|
+
let clock;
|
|
22
|
+
let anonymizeIpSpy;
|
|
23
|
+
|
|
24
|
+
const sandbox = sinon.createSandbox();
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
clock = sinon.useFakeTimers();
|
|
28
|
+
window.setInterval = setInterval;
|
|
29
|
+
webex = new MockWebex();
|
|
30
|
+
metrics = new RtcMetrics(webex, 'mock-meeting-id', 'mock-correlation-id');
|
|
31
|
+
anonymizeIpSpy = sandbox.spy(metrics, 'anonymizeIp');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
sandbox.restore();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('sendMetrics should send a webex request', () => {
|
|
39
|
+
assert.notCalled(webex.request);
|
|
40
|
+
|
|
41
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
42
|
+
(metrics as any).sendMetrics();
|
|
43
|
+
|
|
44
|
+
assert.callCount(webex.request, 1);
|
|
45
|
+
assert.calledWithMatch(webex.request, sinon.match.has('headers', {
|
|
46
|
+
type: 'webrtcMedia',
|
|
47
|
+
appId: RTC_METRICS.APP_ID,
|
|
48
|
+
}));
|
|
49
|
+
assert.calledWithMatch(webex.request, sinon.match.hasNested('body.metrics[0].data[0].payload', FAKE_METRICS_ITEM.payload));
|
|
50
|
+
assert.calledWithMatch(webex.request, sinon.match.hasNested('body.metrics[0].meetingId', 'mock-meeting-id'));
|
|
51
|
+
assert.calledWithMatch(webex.request, sinon.match.hasNested('body.metrics[0].correlationId', 'mock-correlation-id'));
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should have a defined sendMetricsInQueue function which is public', () => {
|
|
55
|
+
assert.isDefined(metrics.sendMetricsInQueue);
|
|
56
|
+
assert.isFunction(metrics.sendMetricsInQueue);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should send metrics requests over time', () => {
|
|
60
|
+
assert.notCalled(webex.request);
|
|
61
|
+
|
|
62
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
63
|
+
assert.deepEqual(metrics.metricsQueue, [FAKE_METRICS_ITEM]);
|
|
64
|
+
clock.tick(60 * 1000);
|
|
65
|
+
|
|
66
|
+
assert.callCount(webex.request, 1);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should not send requests with no items in the queue', () => {
|
|
70
|
+
clock.tick(60 * 1000);
|
|
71
|
+
assert.notCalled(webex.request);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('sendMetricsInQueue should send metrics if any exist in the queue', () => {
|
|
75
|
+
assert.notCalled(webex.request);
|
|
76
|
+
|
|
77
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
78
|
+
(metrics as any).sendMetricsInQueue();
|
|
79
|
+
|
|
80
|
+
assert.callCount(webex.request, 1);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should clear out metrics on close', () => {
|
|
84
|
+
assert.notCalled(webex.request);
|
|
85
|
+
|
|
86
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
87
|
+
metrics.closeMetrics();
|
|
88
|
+
|
|
89
|
+
assert.callCount(webex.request, 1);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should clear out metrics on failure', () => {
|
|
93
|
+
assert.notCalled(webex.request);
|
|
94
|
+
|
|
95
|
+
metrics.addMetrics(FAILURE_METRICS_ITEM);
|
|
96
|
+
|
|
97
|
+
assert.callCount(webex.request, 1);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should have the same connectionId on success', () => {
|
|
101
|
+
const originalId = metrics.connectionId;
|
|
102
|
+
|
|
103
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
104
|
+
|
|
105
|
+
assert.strictEqual(originalId, metrics.connectionId);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should have a new connectionId on failure', () => {
|
|
109
|
+
const originalId = metrics.connectionId;
|
|
110
|
+
|
|
111
|
+
metrics.addMetrics(FAILURE_METRICS_ITEM);
|
|
112
|
+
|
|
113
|
+
assert.notEqual(originalId, metrics.connectionId);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should anonymize IP addresses', () => {
|
|
117
|
+
assert.strictEqual(metrics.anonymizeIp(STATS_WITH_IP), STATS_WITH_IP_RESULT);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should call anonymizeIp', () => {
|
|
121
|
+
metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
|
|
122
|
+
assert.calledOnce(anonymizeIpSpy);
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('should send metrics on first stats-report', () => {
|
|
126
|
+
assert.callCount(webex.request, 0);
|
|
127
|
+
|
|
128
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
129
|
+
assert.callCount(webex.request, 0);
|
|
130
|
+
|
|
131
|
+
// first stats-report should trigger a call to webex.request
|
|
132
|
+
metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
|
|
133
|
+
assert.callCount(webex.request, 1);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should send metrics on first stats-report after a new connection', () => {
|
|
137
|
+
assert.callCount(webex.request, 0);
|
|
138
|
+
|
|
139
|
+
// first stats-report should trigger a call to webex.request
|
|
140
|
+
metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
|
|
141
|
+
assert.callCount(webex.request, 1);
|
|
142
|
+
|
|
143
|
+
// subsequent stats-report doesn't trigger it
|
|
144
|
+
metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
|
|
145
|
+
assert.callCount(webex.request, 1);
|
|
146
|
+
|
|
147
|
+
// now, simulate a failure - that triggers a new connection and upload of the metrics
|
|
148
|
+
metrics.addMetrics(FAILURE_METRICS_ITEM);
|
|
149
|
+
assert.callCount(webex.request, 2);
|
|
150
|
+
|
|
151
|
+
// and another stats-report should trigger another upload of the metrics
|
|
152
|
+
metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
|
|
153
|
+
assert.callCount(webex.request, 3);
|
|
154
|
+
});
|
|
155
|
+
});
|