@webex/internal-plugin-metrics 3.0.0-beta.218 → 3.0.0-beta.219
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 +48 -24
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +35 -3
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/call-diagnostic/config.js +142 -23
- package/dist/call-diagnostic/config.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +2 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics.util.d.ts +17 -1
- package/dist/types/call-diagnostic/config.d.ts +31 -2
- package/dist/types/metrics.types.d.ts +1 -0
- package/package.json +8 -8
- package/src/call-diagnostic/call-diagnostic-metrics.ts +51 -19
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +32 -1
- package/src/call-diagnostic/config.ts +143 -20
- package/src/metrics.types.ts +1 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +163 -32
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +49 -0
|
@@ -16,7 +16,7 @@ const userAgent = `webex-js-sdk/test-webex-version client=Cantina; (os=${getOSNa
|
|
|
16
16
|
getOSVersion().split('.')[0]
|
|
17
17
|
})`;
|
|
18
18
|
|
|
19
|
-
describe('internal-plugin-metrics', () => {
|
|
19
|
+
describe.only('internal-plugin-metrics', () => {
|
|
20
20
|
describe('CallDiagnosticMetrics', () => {
|
|
21
21
|
var now = new Date();
|
|
22
22
|
|
|
@@ -412,7 +412,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
412
412
|
});
|
|
413
413
|
});
|
|
414
414
|
|
|
415
|
-
it('it should include errors if provided', () => {
|
|
415
|
+
it('it should include errors if provided with meetingId', () => {
|
|
416
416
|
sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
|
|
417
417
|
const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
|
|
418
418
|
|
|
@@ -477,6 +477,64 @@ describe('internal-plugin-metrics', () => {
|
|
|
477
477
|
});
|
|
478
478
|
});
|
|
479
479
|
|
|
480
|
+
it('it should include errors if provided with correlationId', () => {
|
|
481
|
+
sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
|
|
482
|
+
const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
|
|
483
|
+
|
|
484
|
+
const options = {
|
|
485
|
+
correlationId: 'correlationId',
|
|
486
|
+
rawError: {
|
|
487
|
+
body: {
|
|
488
|
+
errorCode: 2409005,
|
|
489
|
+
},
|
|
490
|
+
},
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
cd.submitClientEvent({
|
|
494
|
+
name: 'client.alert.displayed',
|
|
495
|
+
options,
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
assert.calledWith(submitToCallDiagnosticsSpy, {
|
|
499
|
+
event: {
|
|
500
|
+
canProceed: true,
|
|
501
|
+
eventData: {
|
|
502
|
+
webClientDomain: 'whatever',
|
|
503
|
+
},
|
|
504
|
+
identifiers: {
|
|
505
|
+
correlationId: 'correlationId',
|
|
506
|
+
deviceId: 'deviceUrl',
|
|
507
|
+
locusUrl: 'locus-url',
|
|
508
|
+
orgId: 'orgId',
|
|
509
|
+
userId: 'userId',
|
|
510
|
+
},
|
|
511
|
+
errors: [
|
|
512
|
+
{
|
|
513
|
+
category: 'expected',
|
|
514
|
+
errorDescription: 'StartRecordingFailed',
|
|
515
|
+
fatal: true,
|
|
516
|
+
name: 'other',
|
|
517
|
+
shownToUser: false,
|
|
518
|
+
serviceErrorCode: 2409005,
|
|
519
|
+
errorCode: 4029,
|
|
520
|
+
},
|
|
521
|
+
],
|
|
522
|
+
loginType: 'login-ci',
|
|
523
|
+
name: 'client.alert.displayed',
|
|
524
|
+
},
|
|
525
|
+
eventId: 'my-fake-id',
|
|
526
|
+
origin: {
|
|
527
|
+
origin: 'fake-origin',
|
|
528
|
+
},
|
|
529
|
+
originTime: {
|
|
530
|
+
sent: 'not_defined_yet',
|
|
531
|
+
triggered: now.toISOString(),
|
|
532
|
+
},
|
|
533
|
+
senderCountryCode: 'UK',
|
|
534
|
+
version: 1,
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
|
|
480
538
|
it('should include errors in payload if provided via payload', () => {
|
|
481
539
|
sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
|
|
482
540
|
const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
|
|
@@ -721,22 +779,67 @@ describe('internal-plugin-metrics', () => {
|
|
|
721
779
|
});
|
|
722
780
|
|
|
723
781
|
describe('#generateClientEventErrorPayload', () => {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
782
|
+
const defaultExpectedRes = {
|
|
783
|
+
category: 'expected',
|
|
784
|
+
errorDescription: 'StartRecordingFailed',
|
|
785
|
+
fatal: true,
|
|
786
|
+
name: 'other',
|
|
787
|
+
shownToUser: false,
|
|
788
|
+
errorCode: 4029,
|
|
789
|
+
serviceErrorCode: 2409005,
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
const checkNameError = (payload: any, isExpectedToBeCalled: boolean) => {
|
|
793
|
+
const res = cd.generateClientEventErrorPayload(payload);
|
|
794
|
+
const expectedResult = {
|
|
727
795
|
category: 'expected',
|
|
728
|
-
errorDescription: '
|
|
796
|
+
errorDescription: 'CameraPermissionDenied',
|
|
729
797
|
fatal: true,
|
|
730
798
|
name: 'other',
|
|
731
799
|
shownToUser: false,
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
800
|
+
serviceErrorCode: undefined,
|
|
801
|
+
errorCode: 4032,
|
|
802
|
+
errorData: {errorName: payload.name},
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
if (isExpectedToBeCalled) {
|
|
806
|
+
assert.deepEqual(res, expectedResult);
|
|
807
|
+
} else {
|
|
808
|
+
assert.notDeepEqual(res, expectedResult);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
it('should generate media event error payload if rawError has a media error name', () => {
|
|
813
|
+
checkNameError({name: 'PermissionDeniedError'}, true);
|
|
735
814
|
});
|
|
736
815
|
|
|
737
|
-
it('should
|
|
738
|
-
|
|
739
|
-
|
|
816
|
+
it('should not generate media event error payload if rawError has a name that is not recognized', () => {
|
|
817
|
+
checkNameError({name: 'SomeRandomError'}, false);
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
const checkCodeError = (payload: any, expetedRes: any) => {
|
|
821
|
+
const res = cd.generateClientEventErrorPayload(payload);
|
|
822
|
+
assert.deepEqual(res, expetedRes);
|
|
823
|
+
}
|
|
824
|
+
it('should generate event error payload correctly', () => {
|
|
825
|
+
checkCodeError({body: {errorCode: 2409005}}, defaultExpectedRes)
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
it('should generate event error payload correctly if rawError has body.code', () => {
|
|
829
|
+
checkCodeError({body: {code: 2409005}}, defaultExpectedRes)
|
|
830
|
+
});
|
|
831
|
+
|
|
832
|
+
it('should generate event error payload correctly if rawError has body.reason.reasonCode', () => {
|
|
833
|
+
checkCodeError({body: {reason: {reasonCode: 2409005}}}, defaultExpectedRes);
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
it('should generate event error payload correctly if rawError has error.body.errorCode', () => {
|
|
837
|
+
checkCodeError({error: {body: {errorCode: 2409005}}}, defaultExpectedRes);
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
const checkLocusError = (payload: any, isExpectedToBeCalled: boolean) => {
|
|
841
|
+
const res = cd.generateClientEventErrorPayload(payload);
|
|
842
|
+
const expectedResult = {
|
|
740
843
|
category: 'signaling',
|
|
741
844
|
errorDescription: 'NewLocusError',
|
|
742
845
|
fatal: true,
|
|
@@ -744,38 +847,66 @@ describe('internal-plugin-metrics', () => {
|
|
|
744
847
|
shownToUser: false,
|
|
745
848
|
serviceErrorCode: 2400000,
|
|
746
849
|
errorCode: 4008,
|
|
747
|
-
}
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
if (isExpectedToBeCalled) {
|
|
853
|
+
assert.deepEqual(res, expectedResult);
|
|
854
|
+
} else {
|
|
855
|
+
assert.notDeepEqual(res, expectedResult);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
it('should return default new locus event error payload correctly if locus error is recognized', () => {
|
|
860
|
+
checkLocusError({body: {errorCode: 2400000}}, true);
|
|
748
861
|
});
|
|
749
862
|
|
|
750
|
-
it('should
|
|
751
|
-
|
|
752
|
-
assert.deepEqual(res, {
|
|
753
|
-
category: 'expected',
|
|
754
|
-
errorDescription: 'StartRecordingFailed',
|
|
755
|
-
fatal: true,
|
|
756
|
-
name: 'other',
|
|
757
|
-
shownToUser: false,
|
|
758
|
-
errorCode: 4029,
|
|
759
|
-
serviceErrorCode: 2409005,
|
|
760
|
-
});
|
|
863
|
+
it('should not return default new locus event error payload correctly if locus is not recognized', () => {
|
|
864
|
+
checkLocusError({body: {errorCode: 1400000}}, false);
|
|
761
865
|
});
|
|
762
866
|
|
|
763
|
-
|
|
764
|
-
const res = cd.generateClientEventErrorPayload(
|
|
765
|
-
|
|
867
|
+
const checkMeetingInfoError = (payload: any, isExpectedToBeCalled: boolean) => {
|
|
868
|
+
const res = cd.generateClientEventErrorPayload(payload);
|
|
869
|
+
const expectedResult = {
|
|
766
870
|
category: 'signaling',
|
|
767
871
|
errorDescription: 'MeetingInfoLookupError',
|
|
768
872
|
fatal: true,
|
|
769
873
|
name: 'other',
|
|
770
874
|
shownToUser: false,
|
|
771
|
-
serviceErrorCode:
|
|
875
|
+
serviceErrorCode: undefined,
|
|
772
876
|
errorCode: 4100,
|
|
773
|
-
}
|
|
877
|
+
};
|
|
878
|
+
|
|
879
|
+
if (isExpectedToBeCalled) {
|
|
880
|
+
assert.deepEqual(res, expectedResult);
|
|
881
|
+
} else {
|
|
882
|
+
assert.notDeepEqual(res, expectedResult);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
it('should return default meeting info lookup error payload if data.meetingInfo was found on error body', () => {
|
|
887
|
+
checkMeetingInfoError({body: {data: {meetingInfo: 'something'}}}, true);
|
|
774
888
|
});
|
|
775
889
|
|
|
776
|
-
it('should return
|
|
777
|
-
|
|
778
|
-
|
|
890
|
+
it('should return default meeting info lookup error payload if body.url contains wbxappapi', () => {
|
|
891
|
+
checkMeetingInfoError({body: {url: '1234567-wbxappapiabcdefg'}}, true);
|
|
892
|
+
});
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
it('should not return default meeting info lookup error payload if body.url does not contain wbxappapi and data.meetingInfo was not found on error body', () => {
|
|
896
|
+
checkMeetingInfoError({body: {data: '1234567-wbxappapiabcdefg'}}, false);
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
it('should return unknown error otherwise', () => {
|
|
900
|
+
const res = cd.generateClientEventErrorPayload({somethgin: 'new'});
|
|
901
|
+
assert.deepEqual(res, {
|
|
902
|
+
category: 'other',
|
|
903
|
+
errorDescription: 'UnknownError',
|
|
904
|
+
fatal: true,
|
|
905
|
+
name: 'other',
|
|
906
|
+
shownToUser: false,
|
|
907
|
+
serviceErrorCode: 9999,
|
|
908
|
+
errorCode: 9999,
|
|
909
|
+
});
|
|
779
910
|
});
|
|
780
911
|
});
|
|
781
912
|
|
|
@@ -4,7 +4,9 @@ import {
|
|
|
4
4
|
clearEmptyKeysRecursively,
|
|
5
5
|
extractVersionMetadata,
|
|
6
6
|
getBuildType,
|
|
7
|
+
isBrowserMediaErrorName,
|
|
7
8
|
isLocusServiceErrorCode,
|
|
9
|
+
isMeetingInfoServiceError,
|
|
8
10
|
prepareDiagnosticMetricItem,
|
|
9
11
|
setMetricTimings,
|
|
10
12
|
} from '../../../../src/call-diagnostic/call-diagnostic-metrics.util';
|
|
@@ -80,6 +82,53 @@ describe('internal-plugin-metrics', () => {
|
|
|
80
82
|
});
|
|
81
83
|
});
|
|
82
84
|
|
|
85
|
+
describe('isMeetingInfoServiceError', () => {
|
|
86
|
+
[
|
|
87
|
+
[{body: {data: {meetingInfo: 'something'}}}, true],
|
|
88
|
+
[{body: {url: 'abcde-123-wbxappapi-efgh'}}, true],
|
|
89
|
+
[{body: {data: {meetingInformation: 'something'}}}, false],
|
|
90
|
+
[{body: {uri: 'abcde-123-wbxappap-efgh'}}, false],
|
|
91
|
+
['2400001', false],
|
|
92
|
+
[2400001, false],
|
|
93
|
+
[{}, false],
|
|
94
|
+
].forEach(([rawError, expected]) => {
|
|
95
|
+
it(`for rawError ${rawError} returns the correct result`, () => {
|
|
96
|
+
//@ts-ignore
|
|
97
|
+
assert.deepEqual(isMeetingInfoServiceError(rawError), expected);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
describe('isBrowserMediaErrorName', () => {
|
|
103
|
+
[
|
|
104
|
+
['PermissionDeniedError', true],
|
|
105
|
+
['PermissionDeniedErrors', false],
|
|
106
|
+
['NotAllowedError', true],
|
|
107
|
+
['NotAllowedErrors', false],
|
|
108
|
+
['NotReadableError', true],
|
|
109
|
+
['NotReadableErrors', false],
|
|
110
|
+
['AbortError', true],
|
|
111
|
+
['AbortErrors', false],
|
|
112
|
+
['NotFoundError', true],
|
|
113
|
+
['NotFoundErrors', false],
|
|
114
|
+
['OverconstrainedError', true],
|
|
115
|
+
['OverconstrainedErrors', false],
|
|
116
|
+
['SecurityError', true],
|
|
117
|
+
['SecurityErrors', false],
|
|
118
|
+
['TypeError', true],
|
|
119
|
+
['TypeErrors', false],
|
|
120
|
+
['', false],
|
|
121
|
+
['SomethingElse', false],
|
|
122
|
+
[{name: 'SomethingElse'}, false],
|
|
123
|
+
|
|
124
|
+
].forEach(([errorName, expected]) => {
|
|
125
|
+
it(`for rawError ${errorName} returns the correct result`, () => {
|
|
126
|
+
//@ts-ignore
|
|
127
|
+
assert.deepEqual(isBrowserMediaErrorName(errorName), expected);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
83
132
|
describe('getBuildType', () => {
|
|
84
133
|
beforeEach(() => {
|
|
85
134
|
process.env.NODE_ENV = 'production';
|