@webex/plugin-meetings 3.12.0-next.9 → 3.12.0-task-refactor.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/dist/annotation/index.js +5 -14
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.js +2 -8
- package/dist/config.js.map +1 -1
- package/dist/constants.js +6 -29
- package/dist/constants.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +29 -1563
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/types.js +3 -13
- package/dist/hashTree/types.js.map +1 -1
- package/dist/index.js +2 -11
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +0 -7
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/locusRouteToken.js +5 -27
- package/dist/interceptors/locusRouteToken.js.map +1 -1
- package/dist/interpretation/index.js +2 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +3 -7
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +247 -642
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +0 -1
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +1 -57
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/properties.js +2 -4
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +1 -7
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +1036 -1481
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +0 -50
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +3 -133
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +59 -142
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +7 -11
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +0 -10
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +0 -10
- package/dist/member/util.js.map +1 -1
- package/dist/metrics/constants.js +1 -7
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +60 -9
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +0 -11
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +2 -116
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/reachability/clusterReachability.js +18 -171
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +11 -21
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/reachabilityPeerConnection.js +1 -1
- package/dist/reachability/reachabilityPeerConnection.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +1 -0
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/types/common/browser-detection.d.ts +0 -1
- package/dist/types/common/events/events-scope.d.ts +0 -1
- package/dist/types/common/events/events.d.ts +0 -1
- package/dist/types/config.d.ts +0 -5
- package/dist/types/constants.d.ts +1 -24
- package/dist/types/hashTree/hashTreeParser.d.ts +11 -260
- package/dist/types/hashTree/types.d.ts +0 -20
- package/dist/types/index.d.ts +0 -1
- package/dist/types/interceptors/index.d.ts +1 -2
- package/dist/types/interceptors/locusRouteToken.d.ts +0 -2
- package/dist/types/locus-info/index.d.ts +47 -68
- package/dist/types/locus-info/types.d.ts +12 -28
- package/dist/types/media/MediaConnectionAwaiter.d.ts +1 -10
- package/dist/types/media/properties.d.ts +1 -2
- package/dist/types/meeting/in-meeting-actions.d.ts +0 -6
- package/dist/types/meeting/index.d.ts +7 -86
- package/dist/types/meeting/request.d.ts +1 -16
- package/dist/types/meeting/request.type.d.ts +0 -5
- package/dist/types/meeting/util.d.ts +0 -31
- package/dist/types/meeting-info/util.d.ts +0 -1
- package/dist/types/meeting-info/utilv2.d.ts +0 -1
- package/dist/types/meetings/index.d.ts +2 -4
- package/dist/types/member/index.d.ts +0 -1
- package/dist/types/member/types.d.ts +4 -4
- package/dist/types/member/util.d.ts +0 -5
- package/dist/types/metrics/constants.d.ts +0 -6
- package/dist/types/multistream/mediaRequestManager.d.ts +23 -0
- package/dist/types/multistream/sendSlotManager.d.ts +1 -23
- package/dist/types/reachability/clusterReachability.d.ts +3 -30
- package/dist/types/reactions/reactions.type.d.ts +0 -1
- package/dist/types/recording-controller/util.d.ts +5 -5
- package/dist/types/roap/index.d.ts +1 -1
- package/dist/webinar/index.js +163 -438
- package/dist/webinar/index.js.map +1 -1
- package/package.json +24 -26
- package/src/annotation/index.ts +7 -27
- package/src/config.ts +0 -5
- package/src/constants.ts +1 -30
- package/src/hashTree/hashTreeParser.ts +25 -1523
- package/src/hashTree/types.ts +1 -24
- package/src/index.ts +1 -8
- package/src/interceptors/index.ts +1 -2
- package/src/interceptors/locusRouteToken.ts +5 -22
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/controlsUtils.ts +0 -17
- package/src/locus-info/index.ts +213 -707
- package/src/locus-info/selfUtils.ts +0 -1
- package/src/locus-info/types.ts +12 -27
- package/src/media/MediaConnectionAwaiter.ts +1 -41
- package/src/media/properties.ts +1 -3
- package/src/meeting/in-meeting-actions.ts +0 -12
- package/src/meeting/index.ts +84 -461
- package/src/meeting/request.ts +0 -42
- package/src/meeting/request.type.ts +0 -6
- package/src/meeting/util.ts +2 -160
- package/src/meetings/index.ts +60 -180
- package/src/meetings/util.ts +9 -10
- package/src/member/index.ts +0 -10
- package/src/member/util.ts +0 -12
- package/src/metrics/constants.ts +0 -7
- package/src/multistream/mediaRequestManager.ts +54 -4
- package/src/multistream/remoteMediaManager.ts +0 -13
- package/src/multistream/sendSlotManager.ts +3 -97
- package/src/reachability/clusterReachability.ts +27 -153
- package/src/reachability/index.ts +1 -15
- package/src/reachability/reachabilityPeerConnection.ts +1 -3
- package/src/reactions/reactions.type.ts +0 -1
- package/src/reconnection-manager/index.ts +1 -0
- package/src/webinar/index.ts +6 -265
- package/test/unit/spec/annotation/index.ts +7 -69
- package/test/unit/spec/interceptors/locusRouteToken.ts +0 -44
- package/test/unit/spec/locus-info/controlsUtils.js +1 -56
- package/test/unit/spec/locus-info/index.js +90 -1457
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +1 -41
- package/test/unit/spec/media/properties.ts +3 -12
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -8
- package/test/unit/spec/meeting/index.js +128 -981
- package/test/unit/spec/meeting/request.js +0 -70
- package/test/unit/spec/meeting/utils.js +26 -438
- package/test/unit/spec/meetings/index.js +33 -845
- package/test/unit/spec/meetings/utils.js +1 -51
- package/test/unit/spec/member/index.js +4 -28
- package/test/unit/spec/member/util.js +27 -65
- package/test/unit/spec/multistream/mediaRequestManager.ts +85 -2
- package/test/unit/spec/multistream/remoteMediaManager.ts +0 -30
- package/test/unit/spec/multistream/sendSlotManager.ts +36 -135
- package/test/unit/spec/reachability/clusterReachability.ts +1 -125
- package/test/unit/spec/reachability/index.ts +3 -26
- package/test/unit/spec/reconnection-manager/index.js +8 -4
- package/test/unit/spec/webinar/index.ts +37 -534
- package/dist/aiEnableRequest/index.js +0 -184
- package/dist/aiEnableRequest/index.js.map +0 -1
- package/dist/aiEnableRequest/utils.js +0 -36
- package/dist/aiEnableRequest/utils.js.map +0 -1
- package/dist/hashTree/constants.js +0 -22
- package/dist/hashTree/constants.js.map +0 -1
- package/dist/hashTree/hashTree.js +0 -533
- package/dist/hashTree/hashTree.js.map +0 -1
- package/dist/hashTree/utils.js +0 -69
- package/dist/hashTree/utils.js.map +0 -1
- package/dist/interceptors/constant.js +0 -12
- package/dist/interceptors/constant.js.map +0 -1
- package/dist/interceptors/dataChannelAuthToken.js +0 -290
- package/dist/interceptors/dataChannelAuthToken.js.map +0 -1
- package/dist/interceptors/utils.js +0 -27
- package/dist/interceptors/utils.js.map +0 -1
- package/dist/types/aiEnableRequest/index.d.ts +0 -5
- package/dist/types/aiEnableRequest/utils.d.ts +0 -2
- package/dist/types/hashTree/constants.d.ts +0 -9
- package/dist/types/hashTree/hashTree.d.ts +0 -136
- package/dist/types/hashTree/utils.d.ts +0 -22
- package/dist/types/interceptors/constant.d.ts +0 -5
- package/dist/types/interceptors/dataChannelAuthToken.d.ts +0 -43
- package/dist/types/interceptors/utils.d.ts +0 -1
- package/dist/types/webinar/utils.d.ts +0 -6
- package/dist/webinar/utils.js +0 -25
- package/dist/webinar/utils.js.map +0 -1
- package/src/aiEnableRequest/README.md +0 -84
- package/src/aiEnableRequest/index.ts +0 -170
- package/src/aiEnableRequest/utils.ts +0 -25
- package/src/hashTree/constants.ts +0 -10
- package/src/hashTree/hashTree.ts +0 -480
- package/src/hashTree/utils.ts +0 -62
- package/src/interceptors/constant.ts +0 -6
- package/src/interceptors/dataChannelAuthToken.ts +0 -170
- package/src/interceptors/utils.ts +0 -16
- package/src/webinar/utils.ts +0 -16
- package/test/unit/spec/aiEnableRequest/index.ts +0 -981
- package/test/unit/spec/aiEnableRequest/utils.ts +0 -130
- package/test/unit/spec/hashTree/hashTree.ts +0 -721
- package/test/unit/spec/hashTree/hashTreeParser.ts +0 -3670
- package/test/unit/spec/hashTree/utils.ts +0 -140
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +0 -210
- package/test/unit/spec/interceptors/utils.ts +0 -75
- package/test/unit/spec/webinar/utils.ts +0 -39
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import {HashTreeObject, ObjectType} from '../../../../src/hashTree/types';
|
|
2
|
-
import {deleteNestedObjectsWithHtMeta, isSelf} from '../../../../src/hashTree/utils';
|
|
3
|
-
|
|
4
|
-
import {assert} from '@webex/test-helper-chai';
|
|
5
|
-
|
|
6
|
-
describe('Hash Tree Utils', () => {
|
|
7
|
-
describe('#deleteNestedObjectsWithHtMeta', () => {
|
|
8
|
-
it('should delete nested objects with htMeta', () => {
|
|
9
|
-
const locusPart = {
|
|
10
|
-
a: {
|
|
11
|
-
htMeta: {
|
|
12
|
-
id: '1',
|
|
13
|
-
},
|
|
14
|
-
value: 'to be deleted',
|
|
15
|
-
},
|
|
16
|
-
b: {
|
|
17
|
-
c: {
|
|
18
|
-
htMeta: {
|
|
19
|
-
id: '2',
|
|
20
|
-
},
|
|
21
|
-
value: 'to be deleted',
|
|
22
|
-
},
|
|
23
|
-
d: 'to be kept',
|
|
24
|
-
},
|
|
25
|
-
e: [
|
|
26
|
-
{
|
|
27
|
-
htMeta: {
|
|
28
|
-
id: '3',
|
|
29
|
-
},
|
|
30
|
-
value: 'to be deleted',
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
f: 'to be kept',
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
htMeta: {
|
|
37
|
-
id: '4',
|
|
38
|
-
},
|
|
39
|
-
value: 'to be deleted',
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
g: 'to be kept',
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
deleteNestedObjectsWithHtMeta(locusPart);
|
|
48
|
-
|
|
49
|
-
assert.deepEqual(locusPart, {
|
|
50
|
-
b: {
|
|
51
|
-
d: 'to be kept',
|
|
52
|
-
},
|
|
53
|
-
e: [
|
|
54
|
-
{
|
|
55
|
-
f: 'to be kept',
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
g: 'to be kept',
|
|
59
|
-
},
|
|
60
|
-
],
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should handle arrays correctly', () => {
|
|
65
|
-
const locusPart = {
|
|
66
|
-
htMeta: {
|
|
67
|
-
id: '0', // this should not be deleted
|
|
68
|
-
},
|
|
69
|
-
participants: [
|
|
70
|
-
{
|
|
71
|
-
htMeta: {
|
|
72
|
-
id: '1',
|
|
73
|
-
},
|
|
74
|
-
id: 'participant1',
|
|
75
|
-
value: 'to be deleted',
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
htMeta: {
|
|
79
|
-
id: '2',
|
|
80
|
-
},
|
|
81
|
-
id: 'participant2',
|
|
82
|
-
value: 'to be deleted',
|
|
83
|
-
},
|
|
84
|
-
],
|
|
85
|
-
self: {
|
|
86
|
-
htMeta: {
|
|
87
|
-
id: '3',
|
|
88
|
-
},
|
|
89
|
-
id: 'self1',
|
|
90
|
-
value: 'to be deleted',
|
|
91
|
-
},
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
deleteNestedObjectsWithHtMeta(locusPart);
|
|
95
|
-
|
|
96
|
-
assert.deepEqual(locusPart, {
|
|
97
|
-
htMeta: {
|
|
98
|
-
id: '0',
|
|
99
|
-
},
|
|
100
|
-
participants: [],
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
describe('#isSelf', () => {
|
|
106
|
-
['self', 'SELF', 'Self'].forEach((type) => {
|
|
107
|
-
it(`should return true for object with type="${type}"`, () => {
|
|
108
|
-
const selfObject = {
|
|
109
|
-
htMeta: {
|
|
110
|
-
elementId: {
|
|
111
|
-
type,
|
|
112
|
-
id: 1,
|
|
113
|
-
version: 1,
|
|
114
|
-
},
|
|
115
|
-
dataSetNames: [],
|
|
116
|
-
},
|
|
117
|
-
data: {},
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
assert.isTrue(isSelf(selfObject as HashTreeObject));
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('should return false for non-self object', () => {
|
|
125
|
-
const participantObject = {
|
|
126
|
-
htMeta: {
|
|
127
|
-
elementId: {
|
|
128
|
-
type: ObjectType.participant,
|
|
129
|
-
id: 2,
|
|
130
|
-
version: 1,
|
|
131
|
-
},
|
|
132
|
-
dataSetNames: [],
|
|
133
|
-
},
|
|
134
|
-
data: {},
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
assert.isFalse(isSelf(participantObject));
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
});
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
import 'jsdom-global/register';
|
|
2
|
-
import {assert, expect} from '@webex/test-helper-chai';
|
|
3
|
-
import sinon from 'sinon';
|
|
4
|
-
import MockWebex from '@webex/test-helper-mock-webex';
|
|
5
|
-
import {WebexHttpError} from '@webex/webex-core';
|
|
6
|
-
import DataChannelAuthTokenInterceptor from '@webex/plugin-meetings/src/interceptors/dataChannelAuthToken';
|
|
7
|
-
import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
|
|
8
|
-
import * as utils from '@webex/plugin-meetings/src/interceptors/utils';
|
|
9
|
-
import {DATA_CHANNEL_AUTH_HEADER, MAX_RETRY} from '@webex/plugin-meetings/src/interceptors/constant';
|
|
10
|
-
|
|
11
|
-
describe('plugin-meetings', () => {
|
|
12
|
-
describe('Interceptors', () => {
|
|
13
|
-
describe('DataChannelAuthTokenInterceptor', () => {
|
|
14
|
-
let interceptor, webex, clock;
|
|
15
|
-
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
clock = sinon.useFakeTimers();
|
|
18
|
-
sinon.stub(LoggerProxy, 'logger').value({
|
|
19
|
-
error: sinon.stub(),
|
|
20
|
-
warn: sinon.stub(),
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
webex = new MockWebex({children: {}});
|
|
24
|
-
webex.request = sinon.stub().resolves({});
|
|
25
|
-
|
|
26
|
-
interceptor = Reflect.apply(DataChannelAuthTokenInterceptor.create, webex, []);
|
|
27
|
-
|
|
28
|
-
interceptor._refreshDataChannelToken = sinon.stub();
|
|
29
|
-
interceptor._isDataChannelTokenEnabled = sinon.stub().resolves(true);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
afterEach(() => {
|
|
33
|
-
sinon.restore();
|
|
34
|
-
clock.restore();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const makeReason = (statusCode) =>
|
|
38
|
-
new WebexHttpError({
|
|
39
|
-
statusCode,
|
|
40
|
-
options: {headers: {}, uri: 'https://example.com'},
|
|
41
|
-
body: {},
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe('#onResponseError', () => {
|
|
45
|
-
it('rejects when no Data-Channel-Auth-Token header exists', async () => {
|
|
46
|
-
const options = {headers: {}};
|
|
47
|
-
const reason = makeReason(401);
|
|
48
|
-
|
|
49
|
-
await assert.isRejected(interceptor.onResponseError(options, reason), reason);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('rejects when statusCode is not 401/403', async () => {
|
|
53
|
-
const options = {headers: {[DATA_CHANNEL_AUTH_HEADER]: 'abc'}};
|
|
54
|
-
const reason = makeReason(500);
|
|
55
|
-
|
|
56
|
-
await assert.isRejected(interceptor.onResponseError(options, reason), reason);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('rejects when retry count exceeds MAX_RETRY', async () => {
|
|
60
|
-
const options = {headers: {[DATA_CHANNEL_AUTH_HEADER]: 'abc'}};
|
|
61
|
-
const reason = makeReason(401);
|
|
62
|
-
|
|
63
|
-
for (let i = 0; i < MAX_RETRY; i++) {
|
|
64
|
-
interceptor.onResponseError(options, reason).catch(() => {});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
await assert.isRejected(interceptor.onResponseError(options, reason), reason);
|
|
68
|
-
|
|
69
|
-
sinon.assert.calledOnce(LoggerProxy.logger.error);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('calls refreshTokenAndRetryWithDelay when eligible', async () => {
|
|
73
|
-
const options = {headers: {[DATA_CHANNEL_AUTH_HEADER]: 'abc'}};
|
|
74
|
-
const reason = makeReason(401);
|
|
75
|
-
|
|
76
|
-
interceptor._isDataChannelTokenEnabled.resolves(true);
|
|
77
|
-
|
|
78
|
-
const stub = sinon.stub(interceptor, 'refreshTokenAndRetryWithDelay').resolves('ok');
|
|
79
|
-
|
|
80
|
-
await interceptor.onResponseError(options, reason);
|
|
81
|
-
|
|
82
|
-
sinon.assert.calledOnceWithExactly(stub, options);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('rejects when isDataChannelTokenEnabled is false', async () => {
|
|
86
|
-
const options = {headers: {[DATA_CHANNEL_AUTH_HEADER]: 'abc'}};
|
|
87
|
-
const reason = makeReason(401);
|
|
88
|
-
|
|
89
|
-
interceptor._isDataChannelTokenEnabled.resolves(false);
|
|
90
|
-
|
|
91
|
-
await assert.isRejected(interceptor.onResponseError(options, reason), reason);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
describe('#onRequest', () => {
|
|
96
|
-
let isJwtTokenExpiredStub;
|
|
97
|
-
|
|
98
|
-
beforeEach(() => {
|
|
99
|
-
isJwtTokenExpiredStub = sinon.stub(utils, 'isJwtTokenExpired').returns(false);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('does nothing when token is missing', async () => {
|
|
103
|
-
const options = {headers: {}};
|
|
104
|
-
|
|
105
|
-
const res = await interceptor.onRequest(options);
|
|
106
|
-
|
|
107
|
-
expect(res).to.equal(options);
|
|
108
|
-
sinon.assert.notCalled(isJwtTokenExpiredStub);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('does nothing when feature is disabled', async () => {
|
|
112
|
-
interceptor._isDataChannelTokenEnabled.resolves(false);
|
|
113
|
-
|
|
114
|
-
const options = {headers: {[DATA_CHANNEL_AUTH_HEADER]: 'old-token'}};
|
|
115
|
-
const res = await interceptor.onRequest(options);
|
|
116
|
-
|
|
117
|
-
expect(res).to.equal(options);
|
|
118
|
-
sinon.assert.notCalled(isJwtTokenExpiredStub);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('does not refresh when token is not expired', async () => {
|
|
122
|
-
interceptor._isDataChannelTokenEnabled.resolves(true);
|
|
123
|
-
isJwtTokenExpiredStub.returns(false);
|
|
124
|
-
|
|
125
|
-
const options = {headers: {[DATA_CHANNEL_AUTH_HEADER]: 'old-token'}};
|
|
126
|
-
const res = await interceptor.onRequest(options);
|
|
127
|
-
|
|
128
|
-
sinon.assert.notCalled(interceptor._refreshDataChannelToken);
|
|
129
|
-
expect(res.headers[DATA_CHANNEL_AUTH_HEADER]).to.equal('old-token');
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it('refreshes token when expired', async () => {
|
|
133
|
-
interceptor._isDataChannelTokenEnabled.resolves(true);
|
|
134
|
-
isJwtTokenExpiredStub.returns(true);
|
|
135
|
-
|
|
136
|
-
interceptor._refreshDataChannelToken.resolves('new-token');
|
|
137
|
-
|
|
138
|
-
const options = {headers: {[DATA_CHANNEL_AUTH_HEADER]: 'old-token'}};
|
|
139
|
-
const res = await interceptor.onRequest(options);
|
|
140
|
-
|
|
141
|
-
sinon.assert.calledOnce(interceptor._refreshDataChannelToken);
|
|
142
|
-
expect(res.headers[DATA_CHANNEL_AUTH_HEADER]).to.equal('new-token');
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it('continues request when refresh fails', async () => {
|
|
146
|
-
interceptor._isDataChannelTokenEnabled.resolves(true);
|
|
147
|
-
isJwtTokenExpiredStub.returns(true);
|
|
148
|
-
|
|
149
|
-
interceptor._refreshDataChannelToken.rejects(new Error('refresh failed'));
|
|
150
|
-
|
|
151
|
-
const options = {headers: {[DATA_CHANNEL_AUTH_HEADER]: 'old-token'}};
|
|
152
|
-
const res = await interceptor.onRequest(options);
|
|
153
|
-
|
|
154
|
-
expect(res.headers[DATA_CHANNEL_AUTH_HEADER]).to.equal('old-token');
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
describe('#refreshTokenAndRetryWithDelay', () => {
|
|
159
|
-
const options = {
|
|
160
|
-
headers: {[DATA_CHANNEL_AUTH_HEADER]: 'old-token'},
|
|
161
|
-
method: 'GET',
|
|
162
|
-
uri: 'https://example.com',
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
it('refreshes token and retries request successfully', async () => {
|
|
166
|
-
interceptor._refreshDataChannelToken.resolves('new-token');
|
|
167
|
-
webex.request.resolves('mock-response');
|
|
168
|
-
|
|
169
|
-
const promise = interceptor.refreshTokenAndRetryWithDelay(options);
|
|
170
|
-
|
|
171
|
-
clock.tick(2000);
|
|
172
|
-
|
|
173
|
-
const result = await promise;
|
|
174
|
-
|
|
175
|
-
expect(interceptor._refreshDataChannelToken.calledOnce).to.be.true;
|
|
176
|
-
expect(options.headers[DATA_CHANNEL_AUTH_HEADER]).to.equal('new-token');
|
|
177
|
-
expect(webex.request.calledOnceWith(options)).to.be.true;
|
|
178
|
-
expect(result).to.equal('mock-response');
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it('rejects when refreshDataChannelToken fails', async () => {
|
|
182
|
-
interceptor._refreshDataChannelToken.rejects(new Error('refresh failed'));
|
|
183
|
-
|
|
184
|
-
const promise = interceptor.refreshTokenAndRetryWithDelay(options);
|
|
185
|
-
|
|
186
|
-
clock.tick(2000);
|
|
187
|
-
|
|
188
|
-
await assert.isRejected(
|
|
189
|
-
promise,
|
|
190
|
-
/DataChannel token refresh failed: refresh failed/
|
|
191
|
-
);
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it('rejects when retry request fails', async () => {
|
|
195
|
-
interceptor._refreshDataChannelToken.resolves('new-token');
|
|
196
|
-
webex.request.rejects(new Error('request failed'));
|
|
197
|
-
|
|
198
|
-
const promise = interceptor.refreshTokenAndRetryWithDelay(options);
|
|
199
|
-
|
|
200
|
-
clock.tick(2000);
|
|
201
|
-
|
|
202
|
-
await assert.isRejected(
|
|
203
|
-
promise,
|
|
204
|
-
/DataChannel token refresh failed: request failed/
|
|
205
|
-
);
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
});
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import 'jsdom-global/register';
|
|
2
|
-
import {expect} from '@webex/test-helper-chai';
|
|
3
|
-
import sinon from 'sinon';
|
|
4
|
-
import {isJwtTokenExpired} from '@webex/plugin-meetings/src/interceptors/utils';
|
|
5
|
-
|
|
6
|
-
const makeJwt = (payload) =>
|
|
7
|
-
[
|
|
8
|
-
Buffer.from(JSON.stringify({alg: 'none', typ: 'JWT'})).toString('base64url'),
|
|
9
|
-
Buffer.from(JSON.stringify(payload)).toString('base64url'),
|
|
10
|
-
''
|
|
11
|
-
].join('.');
|
|
12
|
-
|
|
13
|
-
describe('plugin-meetings', () => {
|
|
14
|
-
describe('Interceptors', () => {
|
|
15
|
-
describe('utils - isJwtTokenExpired', () => {
|
|
16
|
-
let clock;
|
|
17
|
-
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
clock = sinon.useFakeTimers();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
afterEach(() => {
|
|
23
|
-
sinon.restore();
|
|
24
|
-
clock.restore();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('returns false when token has no exp', () => {
|
|
28
|
-
const token = makeJwt({}); // no exp
|
|
29
|
-
|
|
30
|
-
const result = isJwtTokenExpired(token);
|
|
31
|
-
|
|
32
|
-
expect(result).to.equal(false);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('returns false when token is not expired', () => {
|
|
36
|
-
const now = Date.now();
|
|
37
|
-
const futureExp = Math.floor((now + 60 * 1000) / 1000);
|
|
38
|
-
|
|
39
|
-
const token = makeJwt({exp: futureExp});
|
|
40
|
-
|
|
41
|
-
const result = isJwtTokenExpired(token);
|
|
42
|
-
|
|
43
|
-
expect(result).to.equal(false);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('returns true when token is expired', () => {
|
|
47
|
-
const now = Date.now();
|
|
48
|
-
const pastExp = Math.floor((now - 60 * 1000) / 1000);
|
|
49
|
-
|
|
50
|
-
const token = makeJwt({exp: pastExp});
|
|
51
|
-
|
|
52
|
-
const result = isJwtTokenExpired(token);
|
|
53
|
-
|
|
54
|
-
expect(result).to.equal(true);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('returns true when token expires within EXPIRY_BUFFER', () => {
|
|
58
|
-
const now = Date.now();
|
|
59
|
-
const expSoon = Math.floor((now + 10 * 1000) / 1000);
|
|
60
|
-
|
|
61
|
-
const token = makeJwt({exp: expSoon});
|
|
62
|
-
|
|
63
|
-
const result = isJwtTokenExpired(token);
|
|
64
|
-
|
|
65
|
-
expect(result).to.equal(true);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('returns true when token is invalid', () => {
|
|
69
|
-
const result = isJwtTokenExpired('not-a-jwt');
|
|
70
|
-
|
|
71
|
-
expect(result).to.equal(true);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
});
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import chai from 'chai';
|
|
2
|
-
import {sanitizeParams} from '@webex/plugin-meetings/src/webinar/utils';
|
|
3
|
-
|
|
4
|
-
const {assert} = chai;
|
|
5
|
-
|
|
6
|
-
describe('plugin-meetings', () => {
|
|
7
|
-
describe('webinar utils', () => {
|
|
8
|
-
describe('#sanitizeParams', () => {
|
|
9
|
-
it('sanitizes params by removing undefined, "", or null values', () => {
|
|
10
|
-
const input = {
|
|
11
|
-
a: 1,
|
|
12
|
-
b: undefined,
|
|
13
|
-
c: null,
|
|
14
|
-
d: 'test',
|
|
15
|
-
e: false,
|
|
16
|
-
f: '',
|
|
17
|
-
};
|
|
18
|
-
const expectedOutput = {
|
|
19
|
-
a: 1,
|
|
20
|
-
d: 'test',
|
|
21
|
-
e: false,
|
|
22
|
-
};
|
|
23
|
-
const result = sanitizeParams(input);
|
|
24
|
-
assert.deepEqual(result, expectedOutput);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('returns an empty object when all values are invalid', () => {
|
|
28
|
-
const input = {
|
|
29
|
-
a: undefined,
|
|
30
|
-
b: null,
|
|
31
|
-
c: '',
|
|
32
|
-
};
|
|
33
|
-
const expectedOutput = {};
|
|
34
|
-
const result = sanitizeParams(input);
|
|
35
|
-
assert.deepEqual(result, expectedOutput);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
});
|