@webex/plugin-meetings 3.11.0-next.4 → 3.11.0-next.41
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/aiEnableRequest/index.js +184 -0
- package/dist/aiEnableRequest/index.js.map +1 -0
- package/dist/aiEnableRequest/utils.js +36 -0
- package/dist/aiEnableRequest/utils.js.map +1 -0
- package/dist/annotation/index.js +3 -3
- 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 +5 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +26 -6
- package/dist/constants.js.map +1 -1
- package/dist/hashTree/constants.js +3 -1
- package/dist/hashTree/constants.js.map +1 -1
- package/dist/hashTree/hashTree.js +18 -0
- package/dist/hashTree/hashTree.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +709 -380
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/types.js +4 -2
- package/dist/hashTree/types.js.map +1 -1
- package/dist/hashTree/utils.js +10 -0
- package/dist/hashTree/utils.js.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/constant.js +12 -0
- package/dist/interceptors/constant.js.map +1 -0
- package/dist/interceptors/dataChannelAuthToken.js +233 -0
- package/dist/interceptors/dataChannelAuthToken.js.map +1 -0
- package/dist/interceptors/index.js +7 -0
- package/dist/interceptors/index.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 +5 -3
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +125 -68
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +1 -0
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +57 -1
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/properties.js +4 -2
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +7 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +209 -90
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +50 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +128 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +78 -36
- package/dist/meetings/index.js.map +1 -1
- package/dist/member/index.js +10 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +10 -0
- package/dist/member/util.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +11 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/types/aiEnableRequest/index.d.ts +5 -0
- package/dist/types/aiEnableRequest/utils.d.ts +2 -0
- package/dist/types/config.d.ts +3 -0
- package/dist/types/constants.d.ts +21 -1
- package/dist/types/hashTree/constants.d.ts +1 -0
- package/dist/types/hashTree/hashTree.d.ts +7 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +99 -14
- package/dist/types/hashTree/types.d.ts +3 -0
- package/dist/types/hashTree/utils.d.ts +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/interceptors/constant.d.ts +5 -0
- package/dist/types/interceptors/dataChannelAuthToken.d.ts +35 -0
- package/dist/types/interceptors/index.d.ts +2 -1
- package/dist/types/locus-info/index.d.ts +9 -2
- package/dist/types/locus-info/types.d.ts +1 -0
- package/dist/types/media/MediaConnectionAwaiter.d.ts +10 -1
- package/dist/types/media/properties.d.ts +2 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
- package/dist/types/meeting/index.d.ts +24 -2
- package/dist/types/meeting/request.d.ts +16 -1
- package/dist/types/meeting/request.type.d.ts +5 -0
- package/dist/types/meeting/util.d.ts +31 -0
- package/dist/types/meetings/index.d.ts +4 -2
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/util.d.ts +5 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/reactions/reactions.type.d.ts +1 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/aiEnableRequest/README.md +84 -0
- package/src/aiEnableRequest/index.ts +170 -0
- package/src/aiEnableRequest/utils.ts +25 -0
- package/src/annotation/index.ts +7 -4
- package/src/config.ts +3 -0
- package/src/constants.ts +26 -1
- package/src/hashTree/constants.ts +1 -0
- package/src/hashTree/hashTree.ts +17 -0
- package/src/hashTree/hashTreeParser.ts +627 -249
- package/src/hashTree/types.ts +4 -0
- package/src/hashTree/utils.ts +9 -0
- package/src/index.ts +8 -1
- package/src/interceptors/constant.ts +6 -0
- package/src/interceptors/dataChannelAuthToken.ts +142 -0
- package/src/interceptors/index.ts +2 -1
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/controlsUtils.ts +11 -0
- package/src/locus-info/index.ts +146 -58
- package/src/locus-info/selfUtils.ts +1 -0
- package/src/locus-info/types.ts +1 -0
- package/src/media/MediaConnectionAwaiter.ts +41 -1
- package/src/media/properties.ts +3 -1
- package/src/meeting/in-meeting-actions.ts +12 -0
- package/src/meeting/index.ts +127 -17
- package/src/meeting/request.ts +42 -0
- package/src/meeting/request.type.ts +6 -0
- package/src/meeting/util.ts +156 -1
- package/src/meetings/index.ts +94 -9
- package/src/member/index.ts +10 -0
- package/src/member/util.ts +12 -0
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +1 -1
- package/src/multistream/remoteMediaManager.ts +13 -0
- package/src/reactions/reactions.type.ts +1 -0
- package/test/unit/spec/aiEnableRequest/index.ts +981 -0
- package/test/unit/spec/aiEnableRequest/utils.ts +130 -0
- package/test/unit/spec/hashTree/hashTree.ts +66 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +1869 -189
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +141 -0
- package/test/unit/spec/locus-info/controlsUtils.js +29 -0
- package/test/unit/spec/locus-info/index.js +201 -45
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +41 -1
- package/test/unit/spec/media/properties.ts +12 -3
- package/test/unit/spec/meeting/in-meeting-actions.ts +8 -2
- package/test/unit/spec/meeting/index.js +441 -75
- package/test/unit/spec/meeting/request.js +64 -0
- package/test/unit/spec/meeting/utils.js +433 -22
- package/test/unit/spec/meetings/index.js +550 -10
- package/test/unit/spec/member/index.js +28 -4
- package/test/unit/spec/member/util.js +65 -27
- package/test/unit/spec/multistream/remoteMediaManager.ts +30 -0
|
@@ -0,0 +1,981 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2026 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
5
|
+
import {assert} from '@webex/test-helper-chai';
|
|
6
|
+
import sinon from 'sinon';
|
|
7
|
+
import {EventEmitter} from 'stream';
|
|
8
|
+
|
|
9
|
+
import AIEnableRequest from '../../../../src/aiEnableRequest/index';
|
|
10
|
+
import {AI_ENABLE_REQUEST, HTTP_VERBS, LOCUSEVENT, MEETINGS} from '../../../../src/constants';
|
|
11
|
+
|
|
12
|
+
describe('plugin-meetings', () => {
|
|
13
|
+
describe('AIEnableRequest', () => {
|
|
14
|
+
let webex: any;
|
|
15
|
+
let aiEnableRequest: any;
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
// @ts-ignore - MockWebex is not typed correctly
|
|
19
|
+
webex = new MockWebex({
|
|
20
|
+
children: {
|
|
21
|
+
aiEnableRequest: AIEnableRequest,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
aiEnableRequest = webex.internal.aiEnableRequest;
|
|
26
|
+
|
|
27
|
+
// Set up mercury as an EventEmitter
|
|
28
|
+
webex.internal.mercury = new EventEmitter();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('#namespace', () => {
|
|
32
|
+
it('should have the correct namespace', () => {
|
|
33
|
+
assert.equal(aiEnableRequest.namespace, MEETINGS);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('#approvalUrlUpdate', () => {
|
|
38
|
+
it('should update the approvalUrl property', () => {
|
|
39
|
+
const testApprovalUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id/approval';
|
|
40
|
+
|
|
41
|
+
aiEnableRequest.approvalUrlUpdate(testApprovalUrl);
|
|
42
|
+
|
|
43
|
+
assert.equal(aiEnableRequest.approvalUrl, testApprovalUrl);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should handle updating approvalUrl multiple times', () => {
|
|
47
|
+
const firstUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id-1/approval';
|
|
48
|
+
const secondUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id-2/approval';
|
|
49
|
+
|
|
50
|
+
aiEnableRequest.approvalUrlUpdate(firstUrl);
|
|
51
|
+
assert.equal(aiEnableRequest.approvalUrl, firstUrl);
|
|
52
|
+
|
|
53
|
+
aiEnableRequest.approvalUrlUpdate(secondUrl);
|
|
54
|
+
assert.equal(aiEnableRequest.approvalUrl, secondUrl);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe('#selfParticipantIdUpdate', () => {
|
|
59
|
+
it('should update the selfParticipantId property', () => {
|
|
60
|
+
const testSelfParticipantId = 'participant-123';
|
|
61
|
+
|
|
62
|
+
aiEnableRequest.selfParticipantIdUpdate(testSelfParticipantId);
|
|
63
|
+
|
|
64
|
+
assert.equal(aiEnableRequest.selfParticipantId, testSelfParticipantId);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should handle updating selfParticipantId multiple times', () => {
|
|
68
|
+
const firstId = 'participant-111';
|
|
69
|
+
const secondId = 'participant-222';
|
|
70
|
+
|
|
71
|
+
aiEnableRequest.selfParticipantIdUpdate(firstId);
|
|
72
|
+
assert.equal(aiEnableRequest.selfParticipantId, firstId);
|
|
73
|
+
|
|
74
|
+
aiEnableRequest.selfParticipantIdUpdate(secondId);
|
|
75
|
+
assert.equal(aiEnableRequest.selfParticipantId, secondId);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should call listenToApprovalRequests on first update', () => {
|
|
79
|
+
const listenToApprovalRequestsSpy = sinon.spy(aiEnableRequest, 'listenToApprovalRequests');
|
|
80
|
+
const testSelfParticipantId = 'participant-123';
|
|
81
|
+
|
|
82
|
+
aiEnableRequest.selfParticipantIdUpdate(testSelfParticipantId);
|
|
83
|
+
|
|
84
|
+
sinon.assert.calledOnce(listenToApprovalRequestsSpy);
|
|
85
|
+
assert.isTrue(aiEnableRequest.hasSubscribedToEvents);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should not call listenToApprovalRequests on subsequent updates', () => {
|
|
89
|
+
const testSelfParticipantId = 'participant-123';
|
|
90
|
+
|
|
91
|
+
// First update
|
|
92
|
+
aiEnableRequest.selfParticipantIdUpdate(testSelfParticipantId);
|
|
93
|
+
|
|
94
|
+
const listenToApprovalRequestsSpy = sinon.spy(aiEnableRequest, 'listenToApprovalRequests');
|
|
95
|
+
|
|
96
|
+
// Second update
|
|
97
|
+
aiEnableRequest.selfParticipantIdUpdate('participant-456');
|
|
98
|
+
|
|
99
|
+
sinon.assert.notCalled(listenToApprovalRequestsSpy);
|
|
100
|
+
assert.isTrue(aiEnableRequest.hasSubscribedToEvents);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe('#listenToApprovalRequests', () => {
|
|
105
|
+
let listenToSpy;
|
|
106
|
+
let triggerSpy;
|
|
107
|
+
const testSelfParticipantId = 'self-participant-123';
|
|
108
|
+
const testInitiatorId = 'initiator-participant-456';
|
|
109
|
+
const testApproverId = 'approver-participant-789';
|
|
110
|
+
const testUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id/approval';
|
|
111
|
+
|
|
112
|
+
beforeEach(() => {
|
|
113
|
+
aiEnableRequest.selfParticipantId = testSelfParticipantId;
|
|
114
|
+
listenToSpy = sinon.spy(aiEnableRequest, 'listenTo');
|
|
115
|
+
triggerSpy = sinon.spy(aiEnableRequest, 'trigger');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
afterEach(() => {
|
|
119
|
+
sinon.restore();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should listen to mercury approval request events', () => {
|
|
123
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
124
|
+
|
|
125
|
+
sinon.assert.calledOnce(listenToSpy);
|
|
126
|
+
sinon.assert.calledWith(
|
|
127
|
+
listenToSpy,
|
|
128
|
+
webex.internal.mercury,
|
|
129
|
+
`event:${LOCUSEVENT.APPROVAL_REQUEST}`
|
|
130
|
+
);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should trigger event when user is the approver', () => {
|
|
134
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
135
|
+
|
|
136
|
+
const event = {
|
|
137
|
+
data: {
|
|
138
|
+
approval: {
|
|
139
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
140
|
+
receivers: [{participantId: testSelfParticipantId}],
|
|
141
|
+
initiator: {participantId: testInitiatorId},
|
|
142
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
143
|
+
url: testUrl,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
149
|
+
|
|
150
|
+
sinon.assert.calledOnce(triggerSpy);
|
|
151
|
+
sinon.assert.calledWith(triggerSpy, AI_ENABLE_REQUEST.EVENTS.APPROVAL_REQUEST_ARRIVED, {
|
|
152
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
153
|
+
isApprover: true,
|
|
154
|
+
isInitiator: false,
|
|
155
|
+
initiatorId: testInitiatorId,
|
|
156
|
+
approverId: testSelfParticipantId,
|
|
157
|
+
url: testUrl,
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('should trigger event when user is the initiator', () => {
|
|
162
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
163
|
+
|
|
164
|
+
const event = {
|
|
165
|
+
data: {
|
|
166
|
+
approval: {
|
|
167
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
168
|
+
receivers: [{participantId: testApproverId}],
|
|
169
|
+
initiator: {participantId: testSelfParticipantId},
|
|
170
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
171
|
+
url: testUrl,
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
177
|
+
|
|
178
|
+
sinon.assert.calledOnce(triggerSpy);
|
|
179
|
+
sinon.assert.calledWith(triggerSpy, AI_ENABLE_REQUEST.EVENTS.APPROVAL_REQUEST_ARRIVED, {
|
|
180
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
181
|
+
isApprover: false,
|
|
182
|
+
isInitiator: true,
|
|
183
|
+
initiatorId: testSelfParticipantId,
|
|
184
|
+
approverId: testApproverId,
|
|
185
|
+
url: testUrl,
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should not trigger event when user is neither approver nor initiator', () => {
|
|
190
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
191
|
+
|
|
192
|
+
const event = {
|
|
193
|
+
data: {
|
|
194
|
+
approval: {
|
|
195
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
196
|
+
receivers: [{participantId: testApproverId}],
|
|
197
|
+
initiator: {participantId: testInitiatorId},
|
|
198
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
199
|
+
url: testUrl,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
205
|
+
|
|
206
|
+
sinon.assert.notCalled(triggerSpy);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('should trigger DECLINED_ALL event even when user is neither approver nor initiator', () => {
|
|
210
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
211
|
+
|
|
212
|
+
const event = {
|
|
213
|
+
data: {
|
|
214
|
+
approval: {
|
|
215
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
216
|
+
receivers: [{participantId: testApproverId}],
|
|
217
|
+
initiator: {participantId: testInitiatorId},
|
|
218
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.DECLINED_ALL,
|
|
219
|
+
url: testUrl,
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
225
|
+
|
|
226
|
+
sinon.assert.calledOnce(triggerSpy);
|
|
227
|
+
sinon.assert.calledWith(triggerSpy, AI_ENABLE_REQUEST.EVENTS.APPROVAL_REQUEST_ARRIVED, {
|
|
228
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.DECLINED_ALL,
|
|
229
|
+
isApprover: false,
|
|
230
|
+
isInitiator: false,
|
|
231
|
+
initiatorId: testInitiatorId,
|
|
232
|
+
approverId: testApproverId,
|
|
233
|
+
url: testUrl,
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('should not trigger event when resourceType does not match', () => {
|
|
238
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
239
|
+
|
|
240
|
+
const event = {
|
|
241
|
+
data: {
|
|
242
|
+
approval: {
|
|
243
|
+
resourceType: 'SomeOtherResourceType',
|
|
244
|
+
receivers: [{participantId: testSelfParticipantId}],
|
|
245
|
+
initiator: {participantId: testInitiatorId},
|
|
246
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
247
|
+
url: testUrl,
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
253
|
+
|
|
254
|
+
sinon.assert.notCalled(triggerSpy);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it('should handle events with different action types', () => {
|
|
258
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
259
|
+
|
|
260
|
+
const actionTypes = [
|
|
261
|
+
AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
262
|
+
AI_ENABLE_REQUEST.ACTION_TYPE.ACCEPTED,
|
|
263
|
+
AI_ENABLE_REQUEST.ACTION_TYPE.DECLINED,
|
|
264
|
+
AI_ENABLE_REQUEST.ACTION_TYPE.DECLINED_ALL,
|
|
265
|
+
];
|
|
266
|
+
|
|
267
|
+
actionTypes.forEach((actionType) => {
|
|
268
|
+
const event = {
|
|
269
|
+
data: {
|
|
270
|
+
approval: {
|
|
271
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
272
|
+
receivers: [{participantId: testSelfParticipantId}],
|
|
273
|
+
initiator: {participantId: testInitiatorId},
|
|
274
|
+
actionType,
|
|
275
|
+
url: testUrl,
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
sinon.assert.callCount(triggerSpy, actionTypes.length);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it('should handle missing approver participantId', () => {
|
|
287
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
288
|
+
|
|
289
|
+
const event = {
|
|
290
|
+
data: {
|
|
291
|
+
approval: {
|
|
292
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
293
|
+
receivers: [{}],
|
|
294
|
+
initiator: {participantId: testSelfParticipantId},
|
|
295
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
296
|
+
url: testUrl,
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
302
|
+
|
|
303
|
+
sinon.assert.calledOnce(triggerSpy);
|
|
304
|
+
const callArgs = triggerSpy.getCall(0).args[1];
|
|
305
|
+
assert.isFalse(callArgs.isApprover);
|
|
306
|
+
assert.isTrue(callArgs.isInitiator);
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it('should handle missing initiator participantId', () => {
|
|
310
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
311
|
+
|
|
312
|
+
const event = {
|
|
313
|
+
data: {
|
|
314
|
+
approval: {
|
|
315
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
316
|
+
receivers: [{participantId: testSelfParticipantId}],
|
|
317
|
+
initiator: {},
|
|
318
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
319
|
+
url: testUrl,
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
325
|
+
|
|
326
|
+
sinon.assert.calledOnce(triggerSpy);
|
|
327
|
+
const callArgs = triggerSpy.getCall(0).args[1];
|
|
328
|
+
assert.isTrue(callArgs.isApprover);
|
|
329
|
+
assert.isFalse(callArgs.isInitiator);
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it('should handle empty receivers array', () => {
|
|
333
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
334
|
+
|
|
335
|
+
const event = {
|
|
336
|
+
data: {
|
|
337
|
+
approval: {
|
|
338
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
339
|
+
receivers: [],
|
|
340
|
+
initiator: {participantId: testSelfParticipantId},
|
|
341
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
342
|
+
url: testUrl,
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
348
|
+
|
|
349
|
+
sinon.assert.calledOnce(triggerSpy);
|
|
350
|
+
const callArgs = triggerSpy.getCall(0).args[1];
|
|
351
|
+
assert.isFalse(callArgs.isApprover);
|
|
352
|
+
assert.isTrue(callArgs.isInitiator);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it('should include all relevant data in triggered event', () => {
|
|
356
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
357
|
+
|
|
358
|
+
const customUrl = 'https://custom.url/approval';
|
|
359
|
+
const event = {
|
|
360
|
+
data: {
|
|
361
|
+
approval: {
|
|
362
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
363
|
+
receivers: [{participantId: testSelfParticipantId}],
|
|
364
|
+
initiator: {participantId: testInitiatorId},
|
|
365
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.ACCEPTED,
|
|
366
|
+
url: customUrl,
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
372
|
+
|
|
373
|
+
sinon.assert.calledOnce(triggerSpy);
|
|
374
|
+
const triggeredEvent = triggerSpy.getCall(0).args[1];
|
|
375
|
+
assert.equal(triggeredEvent.actionType, AI_ENABLE_REQUEST.ACTION_TYPE.ACCEPTED);
|
|
376
|
+
assert.equal(triggeredEvent.url, customUrl);
|
|
377
|
+
assert.equal(triggeredEvent.initiatorId, testInitiatorId);
|
|
378
|
+
assert.equal(triggeredEvent.approverId, testSelfParticipantId);
|
|
379
|
+
assert.isTrue(triggeredEvent.isApprover);
|
|
380
|
+
assert.isFalse(triggeredEvent.isInitiator);
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
describe('#requestEnableAIAssistant', () => {
|
|
385
|
+
let requestStub;
|
|
386
|
+
const testApprovalUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id/approval';
|
|
387
|
+
const testSelfParticipantId = 'self-participant-123';
|
|
388
|
+
const testApproverId = 'approver-participant-456';
|
|
389
|
+
|
|
390
|
+
beforeEach(() => {
|
|
391
|
+
aiEnableRequest.approvalUrl = testApprovalUrl;
|
|
392
|
+
aiEnableRequest.selfParticipantId = testSelfParticipantId;
|
|
393
|
+
requestStub = sinon.stub(aiEnableRequest, 'request').resolves({
|
|
394
|
+
statusCode: 200,
|
|
395
|
+
body: {},
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
afterEach(() => {
|
|
400
|
+
sinon.restore();
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
it('should make a POST request to the approval URL', async () => {
|
|
404
|
+
await aiEnableRequest.requestEnableAIAssistant({approverId: testApproverId});
|
|
405
|
+
|
|
406
|
+
sinon.assert.calledOnce(requestStub);
|
|
407
|
+
sinon.assert.calledWith(requestStub, {
|
|
408
|
+
method: HTTP_VERBS.POST,
|
|
409
|
+
uri: testApprovalUrl,
|
|
410
|
+
body: {
|
|
411
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
412
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
413
|
+
initiator: {
|
|
414
|
+
participantId: testSelfParticipantId,
|
|
415
|
+
},
|
|
416
|
+
approver: {
|
|
417
|
+
participantId: testApproverId,
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
it('should use the correct action type REQUESTED', async () => {
|
|
424
|
+
await aiEnableRequest.requestEnableAIAssistant({approverId: testApproverId});
|
|
425
|
+
|
|
426
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
427
|
+
assert.equal(callArgs.body.actionType, AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED);
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it('should use the correct resource type AiAssistant', async () => {
|
|
431
|
+
await aiEnableRequest.requestEnableAIAssistant({approverId: testApproverId});
|
|
432
|
+
|
|
433
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
434
|
+
assert.equal(callArgs.body.resourceType, AI_ENABLE_REQUEST.RESOURCE_TYPE);
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
it('should include the initiator participant ID', async () => {
|
|
438
|
+
await aiEnableRequest.requestEnableAIAssistant({approverId: testApproverId});
|
|
439
|
+
|
|
440
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
441
|
+
assert.deepEqual(callArgs.body.initiator, {
|
|
442
|
+
participantId: testSelfParticipantId,
|
|
443
|
+
});
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
it('should include the approver participant ID', async () => {
|
|
447
|
+
await aiEnableRequest.requestEnableAIAssistant({approverId: testApproverId});
|
|
448
|
+
|
|
449
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
450
|
+
assert.deepEqual(callArgs.body.approver, {
|
|
451
|
+
participantId: testApproverId,
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
it('should return a Promise', () => {
|
|
456
|
+
const result = aiEnableRequest.requestEnableAIAssistant({approverId: testApproverId});
|
|
457
|
+
|
|
458
|
+
assert.instanceOf(result, Promise);
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
it('should resolve with the request response', async () => {
|
|
462
|
+
const mockResponse = {
|
|
463
|
+
statusCode: 200,
|
|
464
|
+
body: {
|
|
465
|
+
approvalId: 'approval-789',
|
|
466
|
+
},
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
requestStub.resolves(mockResponse);
|
|
470
|
+
|
|
471
|
+
const result = await aiEnableRequest.requestEnableAIAssistant({approverId: testApproverId});
|
|
472
|
+
|
|
473
|
+
assert.deepEqual(result, mockResponse);
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
it('should handle request failures', async () => {
|
|
477
|
+
const mockError = new Error('Request failed');
|
|
478
|
+
requestStub.rejects(mockError);
|
|
479
|
+
|
|
480
|
+
try {
|
|
481
|
+
await aiEnableRequest.requestEnableAIAssistant({approverId: testApproverId});
|
|
482
|
+
assert.fail('Should have thrown an error');
|
|
483
|
+
} catch (error) {
|
|
484
|
+
assert.equal(error.message, 'Request failed');
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
it('should work with different participant IDs', async () => {
|
|
489
|
+
const differentSelfId = 'different-self-999';
|
|
490
|
+
const differentApproverId = 'different-approver-888';
|
|
491
|
+
|
|
492
|
+
aiEnableRequest.selfParticipantId = differentSelfId;
|
|
493
|
+
await aiEnableRequest.requestEnableAIAssistant({approverId: differentApproverId});
|
|
494
|
+
|
|
495
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
496
|
+
assert.equal(callArgs.body.initiator.participantId, differentSelfId);
|
|
497
|
+
assert.equal(callArgs.body.approver.participantId, differentApproverId);
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
describe('#sendApprovalRequest', () => {
|
|
502
|
+
let requestStub;
|
|
503
|
+
const testUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id/approval';
|
|
504
|
+
const testInitiatorId = 'initiator-participant-123';
|
|
505
|
+
const testApproverId = 'approver-participant-456';
|
|
506
|
+
|
|
507
|
+
beforeEach(() => {
|
|
508
|
+
requestStub = sinon.stub(aiEnableRequest, 'request').resolves({
|
|
509
|
+
statusCode: 200,
|
|
510
|
+
body: {},
|
|
511
|
+
});
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
afterEach(() => {
|
|
515
|
+
sinon.restore();
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
it('should make a request with the specified method', async () => {
|
|
519
|
+
await aiEnableRequest.sendApprovalRequest({
|
|
520
|
+
url: testUrl,
|
|
521
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
522
|
+
initiatorId: testInitiatorId,
|
|
523
|
+
approverId: testApproverId,
|
|
524
|
+
method: HTTP_VERBS.POST,
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
sinon.assert.calledOnce(requestStub);
|
|
528
|
+
sinon.assert.calledWith(requestStub, {
|
|
529
|
+
method: HTTP_VERBS.POST,
|
|
530
|
+
uri: testUrl,
|
|
531
|
+
body: {
|
|
532
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
533
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
534
|
+
initiator: {
|
|
535
|
+
participantId: testInitiatorId,
|
|
536
|
+
},
|
|
537
|
+
approver: {
|
|
538
|
+
participantId: testApproverId,
|
|
539
|
+
},
|
|
540
|
+
},
|
|
541
|
+
});
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
it('should accept any action type', async () => {
|
|
545
|
+
await aiEnableRequest.sendApprovalRequest({
|
|
546
|
+
url: testUrl,
|
|
547
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.ACCEPTED,
|
|
548
|
+
initiatorId: testInitiatorId,
|
|
549
|
+
approverId: testApproverId,
|
|
550
|
+
method: HTTP_VERBS.PUT,
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
554
|
+
assert.equal(callArgs.body.actionType, AI_ENABLE_REQUEST.ACTION_TYPE.ACCEPTED);
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
it('should include the correct resource type', async () => {
|
|
558
|
+
await aiEnableRequest.sendApprovalRequest({
|
|
559
|
+
url: testUrl,
|
|
560
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
561
|
+
initiatorId: testInitiatorId,
|
|
562
|
+
approverId: testApproverId,
|
|
563
|
+
method: HTTP_VERBS.POST,
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
567
|
+
assert.equal(callArgs.body.resourceType, AI_ENABLE_REQUEST.RESOURCE_TYPE);
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
it('should return a Promise', () => {
|
|
571
|
+
const result = aiEnableRequest.sendApprovalRequest({
|
|
572
|
+
url: testUrl,
|
|
573
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
574
|
+
initiatorId: testInitiatorId,
|
|
575
|
+
approverId: testApproverId,
|
|
576
|
+
method: HTTP_VERBS.POST,
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
assert.instanceOf(result, Promise);
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
it('should resolve with the request response', async () => {
|
|
583
|
+
const mockResponse = {
|
|
584
|
+
statusCode: 200,
|
|
585
|
+
body: {approvalId: 'approval-789'},
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
requestStub.resolves(mockResponse);
|
|
589
|
+
|
|
590
|
+
const result = await aiEnableRequest.sendApprovalRequest({
|
|
591
|
+
url: testUrl,
|
|
592
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
593
|
+
initiatorId: testInitiatorId,
|
|
594
|
+
approverId: testApproverId,
|
|
595
|
+
method: HTTP_VERBS.POST,
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
assert.deepEqual(result, mockResponse);
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
it('should handle request failures', async () => {
|
|
602
|
+
const mockError = new Error('Request failed');
|
|
603
|
+
requestStub.rejects(mockError);
|
|
604
|
+
|
|
605
|
+
try {
|
|
606
|
+
await aiEnableRequest.sendApprovalRequest({
|
|
607
|
+
url: testUrl,
|
|
608
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
609
|
+
initiatorId: testInitiatorId,
|
|
610
|
+
approverId: testApproverId,
|
|
611
|
+
method: HTTP_VERBS.POST,
|
|
612
|
+
});
|
|
613
|
+
assert.fail('Should have thrown an error');
|
|
614
|
+
} catch (error) {
|
|
615
|
+
assert.equal(error.message, 'Request failed');
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
it('should use the specified HTTP method', async () => {
|
|
620
|
+
await aiEnableRequest.sendApprovalRequest({
|
|
621
|
+
url: testUrl,
|
|
622
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.ACCEPTED,
|
|
623
|
+
initiatorId: testInitiatorId,
|
|
624
|
+
approverId: testApproverId,
|
|
625
|
+
method: HTTP_VERBS.PUT,
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
629
|
+
assert.equal(callArgs.method, HTTP_VERBS.PUT);
|
|
630
|
+
});
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
describe('#acceptEnableAIAssistantRequest', () => {
|
|
634
|
+
let requestStub;
|
|
635
|
+
const testUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id/approval';
|
|
636
|
+
const testInitiatorId = 'initiator-participant-123';
|
|
637
|
+
const testSelfParticipantId = 'self-participant-456';
|
|
638
|
+
|
|
639
|
+
beforeEach(() => {
|
|
640
|
+
aiEnableRequest.selfParticipantId = testSelfParticipantId;
|
|
641
|
+
requestStub = sinon.stub(aiEnableRequest, 'request').resolves({
|
|
642
|
+
statusCode: 200,
|
|
643
|
+
body: {},
|
|
644
|
+
});
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
afterEach(() => {
|
|
648
|
+
sinon.restore();
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
it('should make a PUT request to the provided URL', async () => {
|
|
652
|
+
await aiEnableRequest.acceptEnableAIAssistantRequest({
|
|
653
|
+
url: testUrl,
|
|
654
|
+
initiatorId: testInitiatorId,
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
sinon.assert.calledOnce(requestStub);
|
|
658
|
+
sinon.assert.calledWith(requestStub, {
|
|
659
|
+
method: HTTP_VERBS.PUT,
|
|
660
|
+
uri: testUrl,
|
|
661
|
+
body: {
|
|
662
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.ACCEPTED,
|
|
663
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
664
|
+
initiator: {
|
|
665
|
+
participantId: testInitiatorId,
|
|
666
|
+
},
|
|
667
|
+
approver: {
|
|
668
|
+
participantId: testSelfParticipantId,
|
|
669
|
+
},
|
|
670
|
+
},
|
|
671
|
+
});
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
it('should use the correct action type ACCEPTED', async () => {
|
|
675
|
+
await aiEnableRequest.acceptEnableAIAssistantRequest({
|
|
676
|
+
url: testUrl,
|
|
677
|
+
initiatorId: testInitiatorId,
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
681
|
+
assert.equal(callArgs.body.actionType, AI_ENABLE_REQUEST.ACTION_TYPE.ACCEPTED);
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
it('should include the initiator participant ID', async () => {
|
|
685
|
+
await aiEnableRequest.acceptEnableAIAssistantRequest({
|
|
686
|
+
url: testUrl,
|
|
687
|
+
initiatorId: testInitiatorId,
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
691
|
+
assert.deepEqual(callArgs.body.initiator, {
|
|
692
|
+
participantId: testInitiatorId,
|
|
693
|
+
});
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
it('should include the approver participant ID as selfParticipantId', async () => {
|
|
697
|
+
await aiEnableRequest.acceptEnableAIAssistantRequest({
|
|
698
|
+
url: testUrl,
|
|
699
|
+
initiatorId: testInitiatorId,
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
703
|
+
assert.deepEqual(callArgs.body.approver, {
|
|
704
|
+
participantId: testSelfParticipantId,
|
|
705
|
+
});
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
it('should return a Promise', () => {
|
|
709
|
+
const result = aiEnableRequest.acceptEnableAIAssistantRequest({
|
|
710
|
+
url: testUrl,
|
|
711
|
+
initiatorId: testInitiatorId,
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
assert.instanceOf(result, Promise);
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
it('should resolve with the request response', async () => {
|
|
718
|
+
const mockResponse = {
|
|
719
|
+
statusCode: 200,
|
|
720
|
+
body: {success: true},
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
requestStub.resolves(mockResponse);
|
|
724
|
+
|
|
725
|
+
const result = await aiEnableRequest.acceptEnableAIAssistantRequest({
|
|
726
|
+
url: testUrl,
|
|
727
|
+
initiatorId: testInitiatorId,
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
assert.deepEqual(result, mockResponse);
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
it('should handle request failures', async () => {
|
|
734
|
+
const mockError = new Error('Request failed');
|
|
735
|
+
requestStub.rejects(mockError);
|
|
736
|
+
|
|
737
|
+
try {
|
|
738
|
+
await aiEnableRequest.acceptEnableAIAssistantRequest({
|
|
739
|
+
url: testUrl,
|
|
740
|
+
initiatorId: testInitiatorId,
|
|
741
|
+
});
|
|
742
|
+
assert.fail('Should have thrown an error');
|
|
743
|
+
} catch (error) {
|
|
744
|
+
assert.equal(error.message, 'Request failed');
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
describe('#declineEnableAIAssistantRequest', () => {
|
|
750
|
+
let requestStub;
|
|
751
|
+
const testUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id/approval';
|
|
752
|
+
const testInitiatorId = 'initiator-participant-123';
|
|
753
|
+
const testSelfParticipantId = 'self-participant-456';
|
|
754
|
+
|
|
755
|
+
beforeEach(() => {
|
|
756
|
+
aiEnableRequest.selfParticipantId = testSelfParticipantId;
|
|
757
|
+
requestStub = sinon.stub(aiEnableRequest, 'request').resolves({
|
|
758
|
+
statusCode: 200,
|
|
759
|
+
body: {},
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
afterEach(() => {
|
|
764
|
+
sinon.restore();
|
|
765
|
+
});
|
|
766
|
+
|
|
767
|
+
it('should make a PUT request to the provided URL', async () => {
|
|
768
|
+
await aiEnableRequest.declineEnableAIAssistantRequest({
|
|
769
|
+
url: testUrl,
|
|
770
|
+
initiatorId: testInitiatorId,
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
sinon.assert.calledOnce(requestStub);
|
|
774
|
+
sinon.assert.calledWith(requestStub, {
|
|
775
|
+
method: HTTP_VERBS.PUT,
|
|
776
|
+
uri: testUrl,
|
|
777
|
+
body: {
|
|
778
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.DECLINED,
|
|
779
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
780
|
+
initiator: {
|
|
781
|
+
participantId: testInitiatorId,
|
|
782
|
+
},
|
|
783
|
+
approver: {
|
|
784
|
+
participantId: testSelfParticipantId,
|
|
785
|
+
},
|
|
786
|
+
},
|
|
787
|
+
});
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
it('should use the correct action type DECLINED', async () => {
|
|
791
|
+
await aiEnableRequest.declineEnableAIAssistantRequest({
|
|
792
|
+
url: testUrl,
|
|
793
|
+
initiatorId: testInitiatorId,
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
797
|
+
assert.equal(callArgs.body.actionType, AI_ENABLE_REQUEST.ACTION_TYPE.DECLINED);
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
it('should include the initiator participant ID', async () => {
|
|
801
|
+
await aiEnableRequest.declineEnableAIAssistantRequest({
|
|
802
|
+
url: testUrl,
|
|
803
|
+
initiatorId: testInitiatorId,
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
807
|
+
assert.deepEqual(callArgs.body.initiator, {
|
|
808
|
+
participantId: testInitiatorId,
|
|
809
|
+
});
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
it('should include the approver participant ID as selfParticipantId', async () => {
|
|
813
|
+
await aiEnableRequest.declineEnableAIAssistantRequest({
|
|
814
|
+
url: testUrl,
|
|
815
|
+
initiatorId: testInitiatorId,
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
819
|
+
assert.deepEqual(callArgs.body.approver, {
|
|
820
|
+
participantId: testSelfParticipantId,
|
|
821
|
+
});
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
it('should return a Promise', () => {
|
|
825
|
+
const result = aiEnableRequest.declineEnableAIAssistantRequest({
|
|
826
|
+
url: testUrl,
|
|
827
|
+
initiatorId: testInitiatorId,
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
assert.instanceOf(result, Promise);
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
it('should resolve with the request response', async () => {
|
|
834
|
+
const mockResponse = {
|
|
835
|
+
statusCode: 200,
|
|
836
|
+
body: {success: true},
|
|
837
|
+
};
|
|
838
|
+
|
|
839
|
+
requestStub.resolves(mockResponse);
|
|
840
|
+
|
|
841
|
+
const result = await aiEnableRequest.declineEnableAIAssistantRequest({
|
|
842
|
+
url: testUrl,
|
|
843
|
+
initiatorId: testInitiatorId,
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
assert.deepEqual(result, mockResponse);
|
|
847
|
+
});
|
|
848
|
+
|
|
849
|
+
it('should handle request failures', async () => {
|
|
850
|
+
const mockError = new Error('Request failed');
|
|
851
|
+
requestStub.rejects(mockError);
|
|
852
|
+
|
|
853
|
+
try {
|
|
854
|
+
await aiEnableRequest.declineEnableAIAssistantRequest({
|
|
855
|
+
url: testUrl,
|
|
856
|
+
initiatorId: testInitiatorId,
|
|
857
|
+
});
|
|
858
|
+
assert.fail('Should have thrown an error');
|
|
859
|
+
} catch (error) {
|
|
860
|
+
assert.equal(error.message, 'Request failed');
|
|
861
|
+
}
|
|
862
|
+
});
|
|
863
|
+
});
|
|
864
|
+
|
|
865
|
+
describe('#declineAllEnableAIAssistantRequests', () => {
|
|
866
|
+
let requestStub;
|
|
867
|
+
const testUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id/approval';
|
|
868
|
+
const testInitiatorId = 'initiator-participant-123';
|
|
869
|
+
const testSelfParticipantId = 'self-participant-456';
|
|
870
|
+
|
|
871
|
+
beforeEach(() => {
|
|
872
|
+
aiEnableRequest.selfParticipantId = testSelfParticipantId;
|
|
873
|
+
requestStub = sinon.stub(aiEnableRequest, 'request').resolves({
|
|
874
|
+
statusCode: 200,
|
|
875
|
+
body: {},
|
|
876
|
+
});
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
afterEach(() => {
|
|
880
|
+
sinon.restore();
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
it('should make a PUT request to the provided URL', async () => {
|
|
884
|
+
await aiEnableRequest.declineAllEnableAIAssistantRequests({
|
|
885
|
+
url: testUrl,
|
|
886
|
+
initiatorId: testInitiatorId,
|
|
887
|
+
});
|
|
888
|
+
|
|
889
|
+
sinon.assert.calledOnce(requestStub);
|
|
890
|
+
sinon.assert.calledWith(requestStub, {
|
|
891
|
+
method: HTTP_VERBS.PUT,
|
|
892
|
+
uri: testUrl,
|
|
893
|
+
body: {
|
|
894
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.DECLINED_ALL,
|
|
895
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
896
|
+
initiator: {
|
|
897
|
+
participantId: testInitiatorId,
|
|
898
|
+
},
|
|
899
|
+
approver: {
|
|
900
|
+
participantId: testSelfParticipantId,
|
|
901
|
+
},
|
|
902
|
+
},
|
|
903
|
+
});
|
|
904
|
+
});
|
|
905
|
+
|
|
906
|
+
it('should use the correct action type DECLINED_ALL', async () => {
|
|
907
|
+
await aiEnableRequest.declineAllEnableAIAssistantRequests({
|
|
908
|
+
url: testUrl,
|
|
909
|
+
initiatorId: testInitiatorId,
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
913
|
+
assert.equal(callArgs.body.actionType, AI_ENABLE_REQUEST.ACTION_TYPE.DECLINED_ALL);
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
it('should include the initiator participant ID', async () => {
|
|
917
|
+
await aiEnableRequest.declineAllEnableAIAssistantRequests({
|
|
918
|
+
url: testUrl,
|
|
919
|
+
initiatorId: testInitiatorId,
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
923
|
+
assert.deepEqual(callArgs.body.initiator, {
|
|
924
|
+
participantId: testInitiatorId,
|
|
925
|
+
});
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
it('should include the approver participant ID as selfParticipantId', async () => {
|
|
929
|
+
await aiEnableRequest.declineAllEnableAIAssistantRequests({
|
|
930
|
+
url: testUrl,
|
|
931
|
+
initiatorId: testInitiatorId,
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
const callArgs = requestStub.getCall(0).args[0];
|
|
935
|
+
assert.deepEqual(callArgs.body.approver, {
|
|
936
|
+
participantId: testSelfParticipantId,
|
|
937
|
+
});
|
|
938
|
+
});
|
|
939
|
+
|
|
940
|
+
it('should return a Promise', () => {
|
|
941
|
+
const result = aiEnableRequest.declineAllEnableAIAssistantRequests({
|
|
942
|
+
url: testUrl,
|
|
943
|
+
initiatorId: testInitiatorId,
|
|
944
|
+
});
|
|
945
|
+
|
|
946
|
+
assert.instanceOf(result, Promise);
|
|
947
|
+
});
|
|
948
|
+
|
|
949
|
+
it('should resolve with the request response', async () => {
|
|
950
|
+
const mockResponse = {
|
|
951
|
+
statusCode: 200,
|
|
952
|
+
body: {declinedCount: 3},
|
|
953
|
+
};
|
|
954
|
+
|
|
955
|
+
requestStub.resolves(mockResponse);
|
|
956
|
+
|
|
957
|
+
const result = await aiEnableRequest.declineAllEnableAIAssistantRequests({
|
|
958
|
+
url: testUrl,
|
|
959
|
+
initiatorId: testInitiatorId,
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
assert.deepEqual(result, mockResponse);
|
|
963
|
+
});
|
|
964
|
+
|
|
965
|
+
it('should handle request failures', async () => {
|
|
966
|
+
const mockError = new Error('Request failed');
|
|
967
|
+
requestStub.rejects(mockError);
|
|
968
|
+
|
|
969
|
+
try {
|
|
970
|
+
await aiEnableRequest.declineAllEnableAIAssistantRequests({
|
|
971
|
+
url: testUrl,
|
|
972
|
+
initiatorId: testInitiatorId,
|
|
973
|
+
});
|
|
974
|
+
assert.fail('Should have thrown an error');
|
|
975
|
+
} catch (error) {
|
|
976
|
+
assert.equal(error.message, 'Request failed');
|
|
977
|
+
}
|
|
978
|
+
});
|
|
979
|
+
});
|
|
980
|
+
});
|
|
981
|
+
});
|