@webex/plugin-meetings 1.150.0 → 1.151.2
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/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/meeting/index.js +170 -4
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting-info/utilv2.js +6 -2
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/metrics/index.js +65 -45
- package/dist/metrics/index.js.map +1 -1
- package/dist/peer-connection-manager/index.js +1 -1
- package/dist/peer-connection-manager/index.js.map +1 -1
- package/package.json +6 -5
- package/src/constants.js +2 -0
- package/src/meeting/index.js +171 -10
- package/src/meeting-info/utilv2.js +6 -1
- package/src/metrics/index.js +28 -17
- package/src/peer-connection-manager/index.js +7 -2
- package/test/integration/spec/journey.js +45 -7
- package/test/integration/spec/space-meeting.js +30 -6
- package/test/unit/spec/meeting/index.js +0 -1
- package/test/unit/spec/meeting-info/utilv2.js +1 -0
- package/test/unit/spec/metrics/index.js +42 -1
- package/test/utils/testUtils.js +18 -1
- package/test/utils/webex-test-users.js +2 -0
|
@@ -164,6 +164,41 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
164
164
|
}));
|
|
165
165
|
});
|
|
166
166
|
|
|
167
|
+
// Enabled when config.enableUnifiedMeetings = true
|
|
168
|
+
xdescribe('Conversation URL', () => {
|
|
169
|
+
describe('Successful 1:1 meeting', () => {
|
|
170
|
+
it('Fetch meeting information with a conversation URL for a 1:1 space', async () => {
|
|
171
|
+
assert.equal(Object.keys(bob.webex.meetings.getAllMeetings()), 0);
|
|
172
|
+
assert.equal(Object.keys(chris.webex.meetings.getAllMeetings()), 0);
|
|
173
|
+
|
|
174
|
+
const conversation = await chris.webex.internal.conversation.create({participants: [bob]});
|
|
175
|
+
|
|
176
|
+
await chris.webex.internal.conversation.post(conversation, {displayName: 'hello world how are you '});
|
|
177
|
+
|
|
178
|
+
await Promise.all([
|
|
179
|
+
testUtils.delayedPromise(chris.webex.meetings.create(conversation.url, 'CONVERSATION_URL')),
|
|
180
|
+
testUtils.waitForEvents([{scope: chris.webex.meetings, event: 'meeting:added', user: chris}])
|
|
181
|
+
])
|
|
182
|
+
.then(function chrisJoinsMeeting() {
|
|
183
|
+
return Promise.all([
|
|
184
|
+
testUtils.delayedPromise(chris.meeting.join()),
|
|
185
|
+
testUtils.waitForEvents([{scope: bob.webex.meetings, event: 'meeting:added', user: bob},
|
|
186
|
+
{scope: chris.meeting, event: 'meeting:stateChange', user: chris}])
|
|
187
|
+
.then((response) => {
|
|
188
|
+
assert.equal(response[0].result.payload.currentState, 'ACTIVE');
|
|
189
|
+
})
|
|
190
|
+
]);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('Fetch meeting information with invalid conversation URL and throws error', () => {
|
|
195
|
+
chris.webex.meetings.meetingInfo.fetchMeetingInfo('http://some-invalid.com', 'CONVERSATION_URL').then((response) => {
|
|
196
|
+
assert(response.result === '404');
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
167
202
|
describe('Successful 1:1 meeting (including Guest)', function () {
|
|
168
203
|
before(() => {
|
|
169
204
|
// Workaround since getDisplayMedia requires a user gesture to be activated, and this is a integration tests
|
|
@@ -484,7 +519,10 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
484
519
|
.then((response) => {
|
|
485
520
|
assert.equal(response[0].result.memberId, alice.meeting.selfId);
|
|
486
521
|
}),
|
|
487
|
-
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
522
|
+
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
523
|
+
.then((response) => {
|
|
524
|
+
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
525
|
+
}),
|
|
488
526
|
testUtils.waitForEvents([{scope: alice.meeting, event: 'media:ready'}])
|
|
489
527
|
.then((response) => {
|
|
490
528
|
console.log('MEDIA:READY event ', response[0].result);
|
|
@@ -514,7 +552,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
514
552
|
}),
|
|
515
553
|
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
516
554
|
.then((response) => {
|
|
517
|
-
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response));
|
|
555
|
+
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
518
556
|
}),
|
|
519
557
|
testUtils.waitForEvents([{scope: bob.meeting, event: 'media:ready'}])
|
|
520
558
|
.then((response) => {
|
|
@@ -566,7 +604,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
566
604
|
}),
|
|
567
605
|
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
568
606
|
.then((response) => {
|
|
569
|
-
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
|
|
607
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
570
608
|
})
|
|
571
609
|
])
|
|
572
610
|
.then(() => {
|
|
@@ -589,7 +627,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
589
627
|
}),
|
|
590
628
|
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
591
629
|
.then((response) => {
|
|
592
|
-
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
|
|
630
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
593
631
|
})
|
|
594
632
|
])
|
|
595
633
|
.then(() => {
|
|
@@ -625,7 +663,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
625
663
|
}),
|
|
626
664
|
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
627
665
|
.then((response) => {
|
|
628
|
-
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
|
|
666
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
629
667
|
})
|
|
630
668
|
])
|
|
631
669
|
.then(() => {
|
|
@@ -644,7 +682,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
644
682
|
}),
|
|
645
683
|
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
646
684
|
.then((response) => {
|
|
647
|
-
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response));
|
|
685
|
+
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
648
686
|
}),
|
|
649
687
|
testUtils.waitForEvents([{scope: bob.meeting, event: 'media:ready'}])
|
|
650
688
|
.then((response) => {
|
|
@@ -680,7 +718,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
680
718
|
}),
|
|
681
719
|
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
682
720
|
.then((response) => {
|
|
683
|
-
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
|
|
721
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
684
722
|
})
|
|
685
723
|
])
|
|
686
724
|
.then(() => {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
import {assert} from '@webex/test-helper-chai';
|
|
3
3
|
import {skipInNode, jenkinsOnly} from '@webex/test-helper-mocha';
|
|
4
|
+
import {patterns} from '@webex/common';
|
|
5
|
+
import MeetingInfoUtil from '@webex/plugin-meetings/src/meeting-info/utilv2';
|
|
4
6
|
|
|
5
7
|
import CMR from '../../utils/cmr';
|
|
6
8
|
import testUtils from '../../utils/testUtils';
|
|
@@ -63,18 +65,40 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
63
65
|
testUtils.delayedPromise(alice.meeting.join()),
|
|
64
66
|
testUtils.waitForEvents([
|
|
65
67
|
{scope: bob.webex.meetings, event: 'meeting:added', user: bob},
|
|
66
|
-
{scope: chris.webex.meetings, event: 'meeting:added', user: chris}
|
|
67
|
-
|
|
68
|
+
{scope: chris.webex.meetings, event: 'meeting:added', user: chris}
|
|
69
|
+
])
|
|
70
|
+
]).then(() => {
|
|
71
|
+
// TODO Renenable after unified flag is enabled
|
|
72
|
+
// const {meetingNumber} = bob.meeting.meetingInfo;
|
|
73
|
+
|
|
74
|
+
// assert(meetingNumber === alice.meeting.meetingNumber, 'meetingNumber matches alice meeting number');
|
|
75
|
+
})));
|
|
76
|
+
|
|
77
|
+
xit('Should fetch user info using user hydra id with the new api', () => alice.webex.rooms.create({title: 'sample'})
|
|
78
|
+
.then((room) => MeetingInfoUtil.getDestinationType({
|
|
79
|
+
destination: room.creatorId,
|
|
80
|
+
webex: alice.webex
|
|
81
|
+
}))
|
|
82
|
+
.then((destinationType) => MeetingInfoUtil.getRequestBody(destinationType))
|
|
83
|
+
.then((res) => {
|
|
84
|
+
assert.exists(res.sipUrl, 'sipURL didnt exist');
|
|
85
|
+
assert.match(res.sipUrl, patterns.email); // assert sipURL is email
|
|
86
|
+
}));
|
|
68
87
|
|
|
69
88
|
// Enable this test when we are going to enable the unified space meeeting .
|
|
70
89
|
// We cannot change the config on load as the meetingInfo function loads dynamically
|
|
71
|
-
xit('Should fetch meeting
|
|
72
|
-
alice.webex.meetings.config.experimental.enableUnifiedMeetings = true;
|
|
90
|
+
xit('Should fetch meeting info using space url with the new api', async () => {
|
|
73
91
|
const res = await alice.webex.meetings.meetingInfo.fetchMeetingInfo(space.url, 'CONVERSATION_URL');
|
|
74
92
|
|
|
75
|
-
assert.exists(res.meetingNumber);
|
|
93
|
+
assert.exists(res.body.meetingNumber);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
xit('Bob fetches meeting info with SIP URI before joining', async () => {
|
|
97
|
+
const {sipUri} = alice.meeting;
|
|
98
|
+
const res = await bob.webex.meetings.meetingInfo.fetchMeetingInfo(sipUri, 'SIP_URI');
|
|
99
|
+
const {meetingNumber} = res.body;
|
|
76
100
|
|
|
77
|
-
alice.
|
|
101
|
+
assert(meetingNumber === alice.meeting.meetingNumber, 'meetingNumber matches alice meeting number');
|
|
78
102
|
});
|
|
79
103
|
|
|
80
104
|
it('Bob and chris joins space meeting', () => testUtils.waitForStateChange(alice.meeting, 'JOINED')
|
|
@@ -110,7 +110,6 @@ describe('plugin-meetings', () => {
|
|
|
110
110
|
|
|
111
111
|
|
|
112
112
|
TriggerProxy.trigger = sinon.stub().returns(true);
|
|
113
|
-
Metrics.initPayload = sinon.stub();
|
|
114
113
|
Metrics.postEvent = sinon.stub();
|
|
115
114
|
Metrics.initialSetup(null, webex);
|
|
116
115
|
MediaUtil.createPeerConnection = sinon.stub().returns({});
|
|
@@ -24,6 +24,14 @@ const {
|
|
|
24
24
|
browserOnly(describe)('Meeting metrics', () => {
|
|
25
25
|
let webex, mockSubmitMetric, sandbox;
|
|
26
26
|
|
|
27
|
+
const geoHintInfo = {
|
|
28
|
+
clientAddress: '2001:0db8:0000:08d3:0000:0000:0070:0000',
|
|
29
|
+
clientRegion: 'US-WEST',
|
|
30
|
+
countryCode: 'US',
|
|
31
|
+
regionCode: 'US-WEST',
|
|
32
|
+
timezone: 'America/Los_Angeles'
|
|
33
|
+
};
|
|
34
|
+
|
|
27
35
|
beforeEach(() => {
|
|
28
36
|
sandbox = sinon.createSandbox();
|
|
29
37
|
mockSubmitMetric = sandbox.stub();
|
|
@@ -40,7 +48,6 @@ browserOnly(describe)('Meeting metrics', () => {
|
|
|
40
48
|
clientId: 'mock-client-id'
|
|
41
49
|
}
|
|
42
50
|
};
|
|
43
|
-
|
|
44
51
|
webex.internal.metrics.submitClientMetrics = mockSubmitMetric;
|
|
45
52
|
metrics.initialSetup({}, webex);
|
|
46
53
|
});
|
|
@@ -49,6 +56,40 @@ browserOnly(describe)('Meeting metrics', () => {
|
|
|
49
56
|
sandbox.restore();
|
|
50
57
|
});
|
|
51
58
|
|
|
59
|
+
describe('initPayload / initMediaPayload', () => {
|
|
60
|
+
it('should create payload with masked IPv4', () => {
|
|
61
|
+
geoHintInfo.clientAddress = '128.0.0.1';
|
|
62
|
+
webex.meetings = {
|
|
63
|
+
geoHintInfo
|
|
64
|
+
};
|
|
65
|
+
metrics.initialSetup({}, webex);
|
|
66
|
+
const payload = metrics.initPayload('myMetric', {}, {clientType: 'TEAMS_CLIENT'});
|
|
67
|
+
|
|
68
|
+
assert(payload.origin.clientInfo.localNetworkPrefix === '128.0.0.0');
|
|
69
|
+
assert(payload.event.name === 'myMetric');
|
|
70
|
+
|
|
71
|
+
const payload2 = metrics.initMediaPayload('myMetric', {}, {clientType: 'TEAMS_CLIENT'});
|
|
72
|
+
|
|
73
|
+
assert(payload2.origin.clientInfo.localNetworkPrefix === '128.0.0.0');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should create payload with masked IPv6', () => {
|
|
77
|
+
geoHintInfo.clientAddress = '2001:0db8:0000:08d3:0000:0000:0070:0000';
|
|
78
|
+
webex.meetings = {
|
|
79
|
+
geoHintInfo
|
|
80
|
+
};
|
|
81
|
+
metrics.initialSetup({}, webex);
|
|
82
|
+
const payload = metrics.initPayload('myIPv6Metric', {}, {clientType: 'TEAMS_CLIENT'});
|
|
83
|
+
|
|
84
|
+
assert(payload.origin.clientInfo.localNetworkPrefix === '2001:d00::');
|
|
85
|
+
assert(payload.event.name === 'myIPv6Metric');
|
|
86
|
+
|
|
87
|
+
const payload2 = metrics.initMediaPayload('myIPv6Metric', {}, {clientType: 'TEAMS_CLIENT'});
|
|
88
|
+
|
|
89
|
+
assert(payload2.origin.clientInfo.localNetworkPrefix === '2001:d00::');
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
52
93
|
describe('#sendOperationalMetric', () => {
|
|
53
94
|
it('sends client metric via Metrics plugin', () => {
|
|
54
95
|
metrics.sendOperationalMetric('myMetric');
|
package/test/utils/testUtils.js
CHANGED
|
@@ -236,6 +236,22 @@ const waitUntil = (waitTime) => new Promise((resolve) => {
|
|
|
236
236
|
|
|
237
237
|
const flushPromises = () => new Promise(setImmediate);
|
|
238
238
|
|
|
239
|
+
const getCircularReplacer = () => {
|
|
240
|
+
const seen = new WeakSet();
|
|
241
|
+
|
|
242
|
+
return (_, value) => {
|
|
243
|
+
if (typeof value === 'object' && value !== null) {
|
|
244
|
+
if (seen.has(value)) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
seen.add(value);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// eslint-disable-next-line consistent-return
|
|
251
|
+
return value;
|
|
252
|
+
};
|
|
253
|
+
};
|
|
254
|
+
|
|
239
255
|
export default {
|
|
240
256
|
waitForSpy,
|
|
241
257
|
waitForStateChange,
|
|
@@ -246,6 +262,7 @@ export default {
|
|
|
246
262
|
addMedia,
|
|
247
263
|
waitUntil,
|
|
248
264
|
delayedTest,
|
|
249
|
-
flushPromises
|
|
265
|
+
flushPromises,
|
|
266
|
+
getCircularReplacer
|
|
250
267
|
};
|
|
251
268
|
|
|
@@ -12,6 +12,8 @@ require('@webex/internal-plugin-user');
|
|
|
12
12
|
require('@webex/internal-plugin-device');
|
|
13
13
|
require('@webex/internal-plugin-conversation');
|
|
14
14
|
require('@webex/internal-plugin-support');
|
|
15
|
+
require('@webex/plugin-people');
|
|
16
|
+
require('@webex/plugin-rooms');
|
|
15
17
|
require('@webex/plugin-meetings');
|
|
16
18
|
|
|
17
19
|
const generateTestUsers = (options) => testUser.create({count: options.count})
|