@webex/internal-plugin-dss 3.0.0-beta.40 → 3.0.0-beta.400
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/config.js +36 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.js +11 -1
- package/dist/constants.js.map +1 -1
- package/dist/dss-batcher.js +139 -0
- package/dist/dss-batcher.js.map +1 -0
- package/dist/dss-errors.js +50 -0
- package/dist/dss-errors.js.map +1 -0
- package/dist/dss.js +187 -31
- package/dist/dss.js.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/types.js +0 -1
- package/dist/types.js.map +1 -1
- package/package.json +9 -6
- package/src/config.ts +31 -0
- package/src/constants.ts +5 -0
- package/src/dss-batcher.ts +129 -0
- package/src/dss-errors.ts +36 -0
- package/src/dss.ts +187 -32
- package/src/index.ts +2 -1
- package/src/types.ts +28 -3
- package/test/unit/spec/dss-batcher.ts +139 -0
- package/test/unit/spec/dss.ts +994 -62
package/test/unit/spec/dss.ts
CHANGED
|
@@ -1,28 +1,35 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2015-2022 Cisco Systems, Inc. See LICENSE file.
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
import
|
|
4
|
+
/* eslint-disable no-underscore-dangle */
|
|
5
|
+
import chai from 'chai';
|
|
6
|
+
import chaiAsPromised from 'chai-as-promised';
|
|
7
|
+
import {assert, expect} from '@webex/test-helper-chai';
|
|
6
8
|
import DSS from '@webex/internal-plugin-dss';
|
|
9
|
+
import {Batcher} from '@webex/webex-core';
|
|
7
10
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
8
11
|
import sinon from 'sinon';
|
|
9
|
-
import {expect} from 'chai';
|
|
10
12
|
import {set} from 'lodash';
|
|
11
13
|
import uuid from 'uuid';
|
|
14
|
+
import config from '@webex/internal-plugin-dss/src/config';
|
|
12
15
|
|
|
16
|
+
chai.use(chaiAsPromised);
|
|
13
17
|
describe('plugin-dss', () => {
|
|
14
18
|
describe('DSS', () => {
|
|
19
|
+
const originalBatcherRequest = Batcher.prototype.request;
|
|
15
20
|
let webex;
|
|
16
21
|
let uuidStub;
|
|
17
22
|
let mercuryCallbacks;
|
|
23
|
+
let clock;
|
|
18
24
|
|
|
19
25
|
beforeEach(() => {
|
|
20
|
-
webex =
|
|
26
|
+
webex = MockWebex({
|
|
21
27
|
canAuthorize: false,
|
|
22
28
|
children: {
|
|
23
29
|
dss: DSS,
|
|
24
30
|
},
|
|
25
31
|
});
|
|
32
|
+
webex.config.dss = config.dss;
|
|
26
33
|
|
|
27
34
|
uuidStub = sinon.stub(uuid, 'v4').returns('randomid');
|
|
28
35
|
|
|
@@ -39,10 +46,14 @@ describe('plugin-dss', () => {
|
|
|
39
46
|
}),
|
|
40
47
|
off: sinon.spy(),
|
|
41
48
|
};
|
|
49
|
+
|
|
50
|
+
clock = sinon.useFakeTimers();
|
|
42
51
|
});
|
|
43
52
|
|
|
44
53
|
afterEach(() => {
|
|
45
54
|
uuidStub.restore();
|
|
55
|
+
clock.restore();
|
|
56
|
+
Batcher.prototype.request = originalBatcherRequest;
|
|
46
57
|
});
|
|
47
58
|
|
|
48
59
|
describe('#register()', () => {
|
|
@@ -52,10 +63,12 @@ describe('plugin-dss', () => {
|
|
|
52
63
|
assert.callCount(webex.internal.mercury.on, 2);
|
|
53
64
|
|
|
54
65
|
const firstCallArgs = webex.internal.mercury.on.getCall(0).args;
|
|
66
|
+
|
|
55
67
|
expect(firstCallArgs[0]).to.equal('event:directory.lookup');
|
|
56
68
|
expect(firstCallArgs[1]).to.be.a('function');
|
|
57
69
|
|
|
58
70
|
const secondCallArgs = webex.internal.mercury.on.getCall(1).args;
|
|
71
|
+
|
|
59
72
|
expect(secondCallArgs[0]).to.equal('event:directory.search');
|
|
60
73
|
expect(secondCallArgs[1]).to.be.a('function');
|
|
61
74
|
|
|
@@ -81,9 +94,11 @@ describe('plugin-dss', () => {
|
|
|
81
94
|
assert.callCount(webex.internal.mercury.off, 2);
|
|
82
95
|
|
|
83
96
|
const firstCallArgs = webex.internal.mercury.off.getCall(0).args;
|
|
97
|
+
|
|
84
98
|
expect(firstCallArgs[0]).to.equal('event:directory.lookup');
|
|
85
99
|
|
|
86
100
|
const secondCallArgs = webex.internal.mercury.off.getCall(1).args;
|
|
101
|
+
|
|
87
102
|
expect(secondCallArgs[0]).to.equal('event:directory.search');
|
|
88
103
|
|
|
89
104
|
assert.equal(webex.internal.dss.registered, false);
|
|
@@ -91,24 +106,27 @@ describe('plugin-dss', () => {
|
|
|
91
106
|
|
|
92
107
|
it('handles unregister when it is not registered', async () => {
|
|
93
108
|
const result = await webex.internal.dss.unregister();
|
|
109
|
+
|
|
94
110
|
await expect(result).equal(undefined);
|
|
95
111
|
assert.equal(webex.internal.dss.registered, false);
|
|
96
112
|
});
|
|
97
113
|
});
|
|
98
114
|
|
|
99
|
-
const createData = (requestId, sequence, finished, dataPath) => {
|
|
115
|
+
const createData = (requestId, sequence, finished, dataPath, results) => {
|
|
100
116
|
const data = {
|
|
101
117
|
requestId,
|
|
102
118
|
sequence,
|
|
103
119
|
};
|
|
120
|
+
|
|
104
121
|
if (finished) {
|
|
105
122
|
(data as any).finished = finished;
|
|
106
123
|
}
|
|
107
|
-
set(data, dataPath,
|
|
124
|
+
set(data, dataPath, results);
|
|
125
|
+
|
|
108
126
|
return {data};
|
|
109
127
|
};
|
|
110
128
|
|
|
111
|
-
const
|
|
129
|
+
const testMakeRequest = async ({method, resource, params, bodyParams}) => {
|
|
112
130
|
webex.request = sinon.stub();
|
|
113
131
|
|
|
114
132
|
await webex.internal.dss.register();
|
|
@@ -130,23 +148,58 @@ describe('plugin-dss', () => {
|
|
|
130
148
|
},
|
|
131
149
|
]);
|
|
132
150
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
151
|
+
return {requestId, promise};
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const testMakeBatchedRequests = async ({requests, calls}) => {
|
|
155
|
+
requests.forEach((request, index) => {
|
|
156
|
+
uuidStub.onCall(index).returns(request.id);
|
|
157
|
+
});
|
|
158
|
+
webex.request = sinon.stub();
|
|
159
|
+
|
|
160
|
+
await webex.internal.dss.register();
|
|
136
161
|
|
|
137
|
-
const
|
|
138
|
-
|
|
162
|
+
const promises = calls.map((call) => webex.internal.dss[call.method](call.params));
|
|
163
|
+
|
|
164
|
+
await clock.tickAsync(49);
|
|
165
|
+
expect(webex.request.notCalled).to.be.true;
|
|
166
|
+
await clock.tickAsync(1);
|
|
167
|
+
expect(webex.request.called).to.be.true;
|
|
168
|
+
|
|
169
|
+
requests.forEach((request, index) => {
|
|
170
|
+
expect(webex.request.getCall(index).args).to.deep.equal([
|
|
171
|
+
{
|
|
172
|
+
service: 'directorySearch',
|
|
173
|
+
body: {
|
|
174
|
+
requestId: request.id,
|
|
175
|
+
...request.bodyParams,
|
|
176
|
+
},
|
|
177
|
+
contentType: 'application/json',
|
|
178
|
+
method: 'POST',
|
|
179
|
+
resource: request.resource,
|
|
180
|
+
},
|
|
181
|
+
]);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
return {promises};
|
|
139
185
|
};
|
|
140
186
|
|
|
141
187
|
describe('#lookupDetail', () => {
|
|
142
188
|
it('calls _request correctly', async () => {
|
|
143
189
|
webex.internal.device.orgId = 'userOrgId';
|
|
144
|
-
webex.internal.dss._request = sinon.stub().returns(
|
|
190
|
+
webex.internal.dss._request = sinon.stub().returns(
|
|
191
|
+
Promise.resolve({
|
|
192
|
+
resultArray: ['some return value'],
|
|
193
|
+
foundArray: ['test id'],
|
|
194
|
+
})
|
|
195
|
+
);
|
|
145
196
|
|
|
146
197
|
const result = await webex.internal.dss.lookupDetail({id: 'test id'});
|
|
198
|
+
|
|
147
199
|
expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
|
|
148
200
|
{
|
|
149
201
|
dataPath: 'lookupResult.entities',
|
|
202
|
+
foundPath: 'lookupResult.entitiesFound',
|
|
150
203
|
resource: '/lookup/orgid/userOrgId/identity/test id/detail',
|
|
151
204
|
},
|
|
152
205
|
]);
|
|
@@ -154,31 +207,96 @@ describe('plugin-dss', () => {
|
|
|
154
207
|
});
|
|
155
208
|
|
|
156
209
|
it('works correctly', async () => {
|
|
157
|
-
await
|
|
210
|
+
const {requestId, promise} = await testMakeRequest({
|
|
158
211
|
method: 'lookupDetail',
|
|
159
|
-
dataPath: 'lookupResult.entities',
|
|
160
|
-
event: 'event:directory.lookup',
|
|
161
212
|
resource: '/lookup/orgid/userOrgId/identity/test id/detail',
|
|
162
|
-
params: {
|
|
163
|
-
|
|
164
|
-
|
|
213
|
+
params: {id: 'test id'},
|
|
214
|
+
bodyParams: {},
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
218
|
+
createData(requestId, 0, true, 'lookupResult', {
|
|
219
|
+
entities: ['data0'],
|
|
220
|
+
entitiesFound: ['test id'],
|
|
221
|
+
})
|
|
222
|
+
);
|
|
223
|
+
const result = await promise;
|
|
224
|
+
|
|
225
|
+
expect(result).to.deep.equal('data0');
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('fails correctly if lookup fails', async () => {
|
|
229
|
+
const {requestId, promise} = await testMakeRequest({
|
|
230
|
+
method: 'lookupDetail',
|
|
231
|
+
resource: '/lookup/orgid/userOrgId/identity/test id/detail',
|
|
232
|
+
params: {id: 'test id'},
|
|
233
|
+
bodyParams: {},
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
237
|
+
createData(requestId, 0, true, 'lookupResult', {entitiesNotFound: ['test id']})
|
|
238
|
+
);
|
|
239
|
+
const result = await promise;
|
|
240
|
+
|
|
241
|
+
expect(result).to.be.null;
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('fails with default timeout when mercury does not respond', async () => {
|
|
245
|
+
const {promise} = await testMakeRequest({
|
|
246
|
+
method: 'lookupDetail',
|
|
247
|
+
resource: '/lookup/orgid/userOrgId/identity/test id/detail',
|
|
248
|
+
params: {id: 'test id'},
|
|
249
|
+
bodyParams: {},
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
await clock.tickAsync(6000);
|
|
253
|
+
|
|
254
|
+
return assert.isRejected(
|
|
255
|
+
promise,
|
|
256
|
+
'The DSS did not respond within 6000 ms.' +
|
|
257
|
+
'\n Request Id: randomid' +
|
|
258
|
+
'\n Resource: /lookup/orgid/userOrgId/identity/test id/detail' +
|
|
259
|
+
'\n Params: undefined'
|
|
260
|
+
);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('does not fail with timeout when mercury response in time', async () => {
|
|
264
|
+
const {requestId, promise} = await testMakeRequest({
|
|
265
|
+
method: 'lookupDetail',
|
|
266
|
+
resource: '/lookup/orgid/userOrgId/identity/test id/detail',
|
|
267
|
+
params: {id: 'test id'},
|
|
165
268
|
bodyParams: {},
|
|
166
269
|
});
|
|
270
|
+
|
|
271
|
+
await clock.tickAsync(499);
|
|
272
|
+
|
|
273
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
274
|
+
createData(requestId, 0, true, 'lookupResult', {entitiesNotFound: ['test id']})
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
return assert.isFulfilled(promise);
|
|
167
278
|
});
|
|
168
279
|
});
|
|
169
280
|
|
|
170
281
|
describe('#lookup', () => {
|
|
171
282
|
it('calls _request correctly', async () => {
|
|
172
283
|
webex.internal.device.orgId = 'userOrgId';
|
|
173
|
-
webex.internal.dss._request = sinon.stub().returns(
|
|
284
|
+
webex.internal.dss._request = sinon.stub().returns(
|
|
285
|
+
Promise.resolve({
|
|
286
|
+
resultArray: ['some return value'],
|
|
287
|
+
foundArray: ['id1'],
|
|
288
|
+
})
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
const result = await webex.internal.dss.lookup({id: 'id1', shouldBatch: false});
|
|
174
292
|
|
|
175
|
-
const result = await webex.internal.dss.lookup({ids: ['id1', 'id2']});
|
|
176
293
|
expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
|
|
177
294
|
{
|
|
178
295
|
dataPath: 'lookupResult.entities',
|
|
296
|
+
foundPath: 'lookupResult.entitiesFound',
|
|
179
297
|
resource: '/lookup/orgid/userOrgId/identities',
|
|
180
298
|
params: {
|
|
181
|
-
lookupValues: ['id1'
|
|
299
|
+
lookupValues: ['id1'],
|
|
182
300
|
},
|
|
183
301
|
},
|
|
184
302
|
]);
|
|
@@ -187,18 +305,26 @@ describe('plugin-dss', () => {
|
|
|
187
305
|
|
|
188
306
|
it('calls _request correctly with entityProviderType', async () => {
|
|
189
307
|
webex.internal.device.orgId = 'userOrgId';
|
|
190
|
-
webex.internal.dss._request = sinon.stub().returns(
|
|
308
|
+
webex.internal.dss._request = sinon.stub().returns(
|
|
309
|
+
Promise.resolve({
|
|
310
|
+
resultArray: ['some return value'],
|
|
311
|
+
foundArray: ['id1'],
|
|
312
|
+
})
|
|
313
|
+
);
|
|
191
314
|
|
|
192
315
|
const result = await webex.internal.dss.lookup({
|
|
193
|
-
|
|
316
|
+
id: 'id1',
|
|
194
317
|
entityProviderType: 'CI_USER',
|
|
318
|
+
shouldBatch: false,
|
|
195
319
|
});
|
|
320
|
+
|
|
196
321
|
expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
|
|
197
322
|
{
|
|
198
323
|
dataPath: 'lookupResult.entities',
|
|
324
|
+
foundPath: 'lookupResult.entitiesFound',
|
|
199
325
|
resource: '/lookup/orgid/userOrgId/entityprovidertype/CI_USER',
|
|
200
326
|
params: {
|
|
201
|
-
lookupValues: ['id1'
|
|
327
|
+
lookupValues: ['id1'],
|
|
202
328
|
},
|
|
203
329
|
},
|
|
204
330
|
]);
|
|
@@ -206,35 +332,350 @@ describe('plugin-dss', () => {
|
|
|
206
332
|
});
|
|
207
333
|
|
|
208
334
|
it('works correctly', async () => {
|
|
209
|
-
await
|
|
335
|
+
const {requestId, promise} = await testMakeRequest({
|
|
210
336
|
method: 'lookup',
|
|
211
|
-
dataPath: 'lookupResult.entities',
|
|
212
|
-
event: 'event:directory.lookup',
|
|
213
337
|
resource: '/lookup/orgid/userOrgId/identities',
|
|
214
|
-
params: {
|
|
215
|
-
|
|
338
|
+
params: {id: 'id1', shouldBatch: false},
|
|
339
|
+
bodyParams: {lookupValues: ['id1']},
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
343
|
+
createData(requestId, 0, true, 'lookupResult', {
|
|
344
|
+
entities: ['data0'],
|
|
345
|
+
entitiesFound: ['id1'],
|
|
346
|
+
})
|
|
347
|
+
);
|
|
348
|
+
const result = await promise;
|
|
349
|
+
|
|
350
|
+
expect(result).to.deep.equal('data0');
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it('fails correctly if lookup fails', async () => {
|
|
354
|
+
const {requestId, promise} = await testMakeRequest({
|
|
355
|
+
method: 'lookup',
|
|
356
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
357
|
+
params: {id: 'id1', shouldBatch: false},
|
|
358
|
+
bodyParams: {lookupValues: ['id1']},
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
362
|
+
createData(requestId, 0, true, 'lookupResult', {entitiesNotFound: ['id1']})
|
|
363
|
+
);
|
|
364
|
+
const result = await promise;
|
|
365
|
+
|
|
366
|
+
expect(result).to.be.null;
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
it('calls _batchedLookup correctly', async () => {
|
|
370
|
+
webex.internal.device.orgId = 'userOrgId';
|
|
371
|
+
webex.internal.dss._batchedLookup = sinon
|
|
372
|
+
.stub()
|
|
373
|
+
.returns(Promise.resolve('some return value'));
|
|
374
|
+
|
|
375
|
+
const result = await webex.internal.dss.lookup({id: 'id1'});
|
|
376
|
+
|
|
377
|
+
expect(webex.internal.dss._batchedLookup.getCall(0).args).to.deep.equal([
|
|
378
|
+
{
|
|
379
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
380
|
+
lookupValue: 'id1',
|
|
216
381
|
},
|
|
217
|
-
|
|
218
|
-
|
|
382
|
+
]);
|
|
383
|
+
expect(result).to.equal('some return value');
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
it('calls _batchedLookup correctly with entityProviderType', async () => {
|
|
387
|
+
webex.internal.device.orgId = 'userOrgId';
|
|
388
|
+
webex.internal.dss._batchedLookup = sinon
|
|
389
|
+
.stub()
|
|
390
|
+
.returns(Promise.resolve('some return value'));
|
|
391
|
+
|
|
392
|
+
const result = await webex.internal.dss.lookup({
|
|
393
|
+
id: 'id1',
|
|
394
|
+
entityProviderType: 'CI_USER',
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
expect(webex.internal.dss._batchedLookup.getCall(0).args).to.deep.equal([
|
|
398
|
+
{
|
|
399
|
+
resource: '/lookup/orgid/userOrgId/entityprovidertype/CI_USER',
|
|
400
|
+
lookupValue: 'id1',
|
|
219
401
|
},
|
|
402
|
+
]);
|
|
403
|
+
expect(result).to.equal('some return value');
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
it('Single batched lookup is made after 50 ms and works', async () => {
|
|
407
|
+
const {promises} = await testMakeBatchedRequests({
|
|
408
|
+
requests: [
|
|
409
|
+
{
|
|
410
|
+
id: 'randomid1',
|
|
411
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
412
|
+
bodyParams: {lookupValues: ['id1']},
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
calls: [
|
|
416
|
+
{
|
|
417
|
+
method: 'lookup',
|
|
418
|
+
params: {id: 'id1', shouldBatch: true},
|
|
419
|
+
},
|
|
420
|
+
],
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
424
|
+
createData('randomid1', 0, true, 'lookupResult', {
|
|
425
|
+
entities: ['data0'],
|
|
426
|
+
entitiesFound: ['id1'],
|
|
427
|
+
})
|
|
428
|
+
);
|
|
429
|
+
const result = await promises[0];
|
|
430
|
+
|
|
431
|
+
expect(result).to.deep.equal('data0');
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
it('Single batched lookup fails correctly if lookup fails', async () => {
|
|
435
|
+
const {promises} = await testMakeBatchedRequests({
|
|
436
|
+
requests: [
|
|
437
|
+
{
|
|
438
|
+
id: 'randomid1',
|
|
439
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
440
|
+
bodyParams: {lookupValues: ['id1']},
|
|
441
|
+
},
|
|
442
|
+
],
|
|
443
|
+
calls: [
|
|
444
|
+
{
|
|
445
|
+
method: 'lookup',
|
|
446
|
+
params: {id: 'id1', shouldBatch: true},
|
|
447
|
+
},
|
|
448
|
+
],
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
452
|
+
createData('randomid1', 0, true, 'lookupResult', {entitiesNotFound: ['id1']})
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
const result = await promises[0];
|
|
456
|
+
|
|
457
|
+
expect(result).to.be.null;
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
it('Batch of 2 lookups is made after 50 ms and works', async () => {
|
|
461
|
+
const {promises} = await testMakeBatchedRequests({
|
|
462
|
+
requests: [
|
|
463
|
+
{
|
|
464
|
+
id: 'randomid1',
|
|
465
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
466
|
+
bodyParams: {lookupValues: ['id1', 'id2']},
|
|
467
|
+
},
|
|
468
|
+
],
|
|
469
|
+
calls: [
|
|
470
|
+
{
|
|
471
|
+
method: 'lookup',
|
|
472
|
+
params: {id: 'id1', shouldBatch: true},
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
method: 'lookup',
|
|
476
|
+
params: {id: 'id2', shouldBatch: true},
|
|
477
|
+
},
|
|
478
|
+
],
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
482
|
+
createData('randomid1', 0, true, 'lookupResult', {
|
|
483
|
+
entities: ['data1', 'data2'],
|
|
484
|
+
entitiesFound: ['id1', 'id2'],
|
|
485
|
+
})
|
|
486
|
+
);
|
|
487
|
+
const result1 = await promises[0];
|
|
488
|
+
|
|
489
|
+
expect(result1).to.equal('data1');
|
|
490
|
+
const result2 = await promises[1];
|
|
491
|
+
|
|
492
|
+
expect(result2).to.equal('data2');
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
it('Batch of 2 lookups is made after 50 ms and one fails correctly', async () => {
|
|
496
|
+
const {promises} = await testMakeBatchedRequests({
|
|
497
|
+
requests: [
|
|
498
|
+
{
|
|
499
|
+
id: 'randomid1',
|
|
500
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
501
|
+
bodyParams: {lookupValues: ['id1', 'id2']},
|
|
502
|
+
},
|
|
503
|
+
],
|
|
504
|
+
calls: [
|
|
505
|
+
{
|
|
506
|
+
method: 'lookup',
|
|
507
|
+
params: {id: 'id1', shouldBatch: true},
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
method: 'lookup',
|
|
511
|
+
params: {id: 'id2', shouldBatch: true},
|
|
512
|
+
},
|
|
513
|
+
],
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
517
|
+
createData('randomid1', 0, true, 'lookupResult', {
|
|
518
|
+
entities: ['data2'],
|
|
519
|
+
entitiesFound: ['id2'],
|
|
520
|
+
entitiesNotFound: ['id1'],
|
|
521
|
+
})
|
|
522
|
+
);
|
|
523
|
+
const result1 = await promises[0];
|
|
524
|
+
|
|
525
|
+
expect(result1).to.be.null;
|
|
526
|
+
|
|
527
|
+
const result2 = await promises[1];
|
|
528
|
+
|
|
529
|
+
expect(result2).to.equal('data2');
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
it('Two unrelated lookups are made after 50 ms and work', async () => {
|
|
533
|
+
const {promises} = await testMakeBatchedRequests({
|
|
534
|
+
requests: [
|
|
535
|
+
{
|
|
536
|
+
id: 'randomid1',
|
|
537
|
+
resource: '/lookup/orgid/userOrgId/entityprovidertype/CI_USER',
|
|
538
|
+
bodyParams: {lookupValues: ['id1']},
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
id: 'randomid2',
|
|
542
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
543
|
+
bodyParams: {lookupValues: ['id2']},
|
|
544
|
+
},
|
|
545
|
+
],
|
|
546
|
+
calls: [
|
|
547
|
+
{
|
|
548
|
+
method: 'lookup',
|
|
549
|
+
params: {id: 'id1', entityProviderType: 'CI_USER', shouldBatch: true},
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
method: 'lookup',
|
|
553
|
+
params: {id: 'id2', shouldBatch: true},
|
|
554
|
+
},
|
|
555
|
+
],
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
559
|
+
createData('randomid1', 0, true, 'lookupResult', {
|
|
560
|
+
entities: ['data1'],
|
|
561
|
+
entitiesFound: ['id1'],
|
|
562
|
+
})
|
|
563
|
+
);
|
|
564
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
565
|
+
createData('randomid2', 0, true, 'lookupResult', {
|
|
566
|
+
entities: ['data2'],
|
|
567
|
+
entitiesFound: ['id2'],
|
|
568
|
+
})
|
|
569
|
+
);
|
|
570
|
+
const result1 = await promises[0];
|
|
571
|
+
|
|
572
|
+
expect(result1).to.equal('data1');
|
|
573
|
+
const result2 = await promises[1];
|
|
574
|
+
|
|
575
|
+
expect(result2).to.equal('data2');
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
it('Two unrelated lookups are made after 50 ms and one fails correctly', async () => {
|
|
579
|
+
const {promises} = await testMakeBatchedRequests({
|
|
580
|
+
requests: [
|
|
581
|
+
{
|
|
582
|
+
id: 'randomid1',
|
|
583
|
+
resource: '/lookup/orgid/userOrgId/entityprovidertype/CI_USER',
|
|
584
|
+
bodyParams: {lookupValues: ['id1']},
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
id: 'randomid2',
|
|
588
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
589
|
+
bodyParams: {lookupValues: ['id2']},
|
|
590
|
+
},
|
|
591
|
+
],
|
|
592
|
+
calls: [
|
|
593
|
+
{
|
|
594
|
+
method: 'lookup',
|
|
595
|
+
params: {id: 'id1', entityProviderType: 'CI_USER', shouldBatch: true},
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
method: 'lookup',
|
|
599
|
+
params: {id: 'id2', shouldBatch: true},
|
|
600
|
+
},
|
|
601
|
+
],
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
605
|
+
createData('randomid1', 0, true, 'lookupResult', {entitiesNotFound: ['id1']})
|
|
606
|
+
);
|
|
607
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
608
|
+
createData('randomid2', 0, true, 'lookupResult', {
|
|
609
|
+
entities: ['data2'],
|
|
610
|
+
entitiesFound: ['id2'],
|
|
611
|
+
})
|
|
612
|
+
);
|
|
613
|
+
const result1 = await promises[0];
|
|
614
|
+
|
|
615
|
+
expect(result1).to.be.null;
|
|
616
|
+
const result2 = await promises[1];
|
|
617
|
+
|
|
618
|
+
expect(result2).to.equal('data2');
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
it('fails with default timeout when mercury does not respond', async () => {
|
|
622
|
+
const {promise} = await testMakeRequest({
|
|
623
|
+
method: 'lookup',
|
|
624
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
625
|
+
params: {id: 'id1', shouldBatch: false},
|
|
626
|
+
bodyParams: {lookupValues: ['id1']},
|
|
220
627
|
});
|
|
628
|
+
|
|
629
|
+
await clock.tickAsync(6000);
|
|
630
|
+
|
|
631
|
+
return assert.isRejected(
|
|
632
|
+
promise,
|
|
633
|
+
'The DSS did not respond within 6000 ms.' +
|
|
634
|
+
'\n Request Id: randomid' +
|
|
635
|
+
'\n Resource: /lookup/orgid/userOrgId/identities' +
|
|
636
|
+
'\n Params: {"lookupValues":["id1"]}'
|
|
637
|
+
);
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
it('does not fail with timeout when mercury response in time', async () => {
|
|
641
|
+
const {promise, requestId} = await testMakeRequest({
|
|
642
|
+
method: 'lookup',
|
|
643
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
644
|
+
params: {id: 'id1', shouldBatch: false},
|
|
645
|
+
bodyParams: {lookupValues: ['id1']},
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
await clock.tickAsync(499);
|
|
649
|
+
|
|
650
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
651
|
+
createData(requestId, 0, true, 'lookupResult', {entitiesNotFound: ['test id']})
|
|
652
|
+
);
|
|
653
|
+
|
|
654
|
+
return assert.isFulfilled(promise);
|
|
221
655
|
});
|
|
222
656
|
});
|
|
223
657
|
|
|
224
658
|
describe('#lookupByEmail', () => {
|
|
225
659
|
it('calls _request correctly', async () => {
|
|
226
660
|
webex.internal.device.orgId = 'userOrgId';
|
|
227
|
-
webex.internal.dss._request = sinon.stub().returns(
|
|
661
|
+
webex.internal.dss._request = sinon.stub().returns(
|
|
662
|
+
Promise.resolve({
|
|
663
|
+
resultArray: ['some return value'],
|
|
664
|
+
foundArray: ['email1'],
|
|
665
|
+
})
|
|
666
|
+
);
|
|
228
667
|
|
|
229
668
|
const result = await webex.internal.dss.lookupByEmail({
|
|
230
|
-
|
|
669
|
+
email: 'email1',
|
|
231
670
|
});
|
|
671
|
+
|
|
232
672
|
expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
|
|
233
673
|
{
|
|
234
674
|
dataPath: 'lookupResult.entities',
|
|
675
|
+
foundPath: 'lookupResult.entitiesFound',
|
|
235
676
|
resource: '/lookup/orgid/userOrgId/emails',
|
|
236
677
|
params: {
|
|
237
|
-
lookupValues: ['email1'
|
|
678
|
+
lookupValues: ['email1'],
|
|
238
679
|
},
|
|
239
680
|
},
|
|
240
681
|
]);
|
|
@@ -242,31 +683,90 @@ describe('plugin-dss', () => {
|
|
|
242
683
|
});
|
|
243
684
|
|
|
244
685
|
it('works correctly', async () => {
|
|
245
|
-
await
|
|
686
|
+
const {requestId, promise} = await testMakeRequest({
|
|
246
687
|
method: 'lookupByEmail',
|
|
247
|
-
dataPath: 'lookupResult.entities',
|
|
248
|
-
event: 'event:directory.lookup',
|
|
249
688
|
resource: '/lookup/orgid/userOrgId/emails',
|
|
250
|
-
params: {
|
|
251
|
-
|
|
252
|
-
},
|
|
253
|
-
bodyParams: {
|
|
254
|
-
lookupValues: ['email1', 'email2'],
|
|
255
|
-
},
|
|
689
|
+
params: {email: 'email1'},
|
|
690
|
+
bodyParams: {lookupValues: ['email1']},
|
|
256
691
|
});
|
|
692
|
+
|
|
693
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
694
|
+
createData(requestId, 0, true, 'lookupResult', {
|
|
695
|
+
entities: ['data0'],
|
|
696
|
+
entitiesFound: ['email1'],
|
|
697
|
+
})
|
|
698
|
+
);
|
|
699
|
+
const result = await promise;
|
|
700
|
+
|
|
701
|
+
expect(result).to.deep.equal('data0');
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
it('fails correctly if lookup fails', async () => {
|
|
705
|
+
const {requestId, promise} = await testMakeRequest({
|
|
706
|
+
method: 'lookupByEmail',
|
|
707
|
+
resource: '/lookup/orgid/userOrgId/emails',
|
|
708
|
+
params: {email: 'email1'},
|
|
709
|
+
bodyParams: {lookupValues: ['email1']},
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
713
|
+
createData(requestId, 0, true, 'lookupResult', {}) // entitiesNotFound isn't returned for email
|
|
714
|
+
);
|
|
715
|
+
const result = await promise;
|
|
716
|
+
|
|
717
|
+
expect(result).to.be.null;
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
it('fails with default timeout when mercury does not respond', async () => {
|
|
721
|
+
const {promise} = await testMakeRequest({
|
|
722
|
+
method: 'lookupByEmail',
|
|
723
|
+
resource: '/lookup/orgid/userOrgId/emails',
|
|
724
|
+
params: {email: 'email1'},
|
|
725
|
+
bodyParams: {lookupValues: ['email1']},
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
await clock.tickAsync(6000);
|
|
729
|
+
|
|
730
|
+
return assert.isRejected(
|
|
731
|
+
promise,
|
|
732
|
+
'The DSS did not respond within 6000 ms.' +
|
|
733
|
+
'\n Request Id: randomid' +
|
|
734
|
+
'\n Resource: /lookup/orgid/userOrgId/emails' +
|
|
735
|
+
'\n Params: {"lookupValues":["email1"]}'
|
|
736
|
+
);
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
it('does not fail with timeout when mercury response in time', async () => {
|
|
740
|
+
const {requestId, promise} = await testMakeRequest({
|
|
741
|
+
method: 'lookupByEmail',
|
|
742
|
+
resource: '/lookup/orgid/userOrgId/emails',
|
|
743
|
+
params: {email: 'email1'},
|
|
744
|
+
bodyParams: {lookupValues: ['email1']},
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
await clock.tickAsync(5999);
|
|
748
|
+
|
|
749
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
750
|
+
createData(requestId, 0, true, 'lookupResult', {}) // entitiesNotFound isn't returned for email
|
|
751
|
+
);
|
|
752
|
+
|
|
753
|
+
return assert.isFulfilled(promise);
|
|
257
754
|
});
|
|
258
755
|
});
|
|
259
756
|
|
|
260
757
|
describe('#search', () => {
|
|
261
758
|
it('calls _request correctly', async () => {
|
|
262
759
|
webex.internal.device.orgId = 'userOrgId';
|
|
263
|
-
webex.internal.dss._request = sinon
|
|
760
|
+
webex.internal.dss._request = sinon
|
|
761
|
+
.stub()
|
|
762
|
+
.returns(Promise.resolve({resultArray: 'some return value'}));
|
|
264
763
|
|
|
265
764
|
const result = await webex.internal.dss.search({
|
|
266
765
|
requestedTypes: ['PERSON', 'ROBOT'],
|
|
267
766
|
resultSize: 100,
|
|
268
767
|
queryString: 'query',
|
|
269
768
|
});
|
|
769
|
+
|
|
270
770
|
expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
|
|
271
771
|
{
|
|
272
772
|
dataPath: 'directoryEntities',
|
|
@@ -282,10 +782,8 @@ describe('plugin-dss', () => {
|
|
|
282
782
|
});
|
|
283
783
|
|
|
284
784
|
it('works correctly', async () => {
|
|
285
|
-
await
|
|
785
|
+
const {requestId, promise} = await testMakeRequest({
|
|
286
786
|
method: 'search',
|
|
287
|
-
event: 'event:directory.search',
|
|
288
|
-
dataPath: 'directoryEntities',
|
|
289
787
|
resource: '/search/orgid/userOrgId/entities',
|
|
290
788
|
params: {
|
|
291
789
|
requestedTypes: ['PERSON', 'ROBOT'],
|
|
@@ -298,6 +796,111 @@ describe('plugin-dss', () => {
|
|
|
298
796
|
queryString: 'query',
|
|
299
797
|
},
|
|
300
798
|
});
|
|
799
|
+
|
|
800
|
+
mercuryCallbacks['event:directory.search'](
|
|
801
|
+
createData(requestId, 1, false, 'directoryEntities', ['data1'])
|
|
802
|
+
);
|
|
803
|
+
mercuryCallbacks['event:directory.search'](
|
|
804
|
+
createData(requestId, 2, true, 'directoryEntities', ['data2'])
|
|
805
|
+
);
|
|
806
|
+
mercuryCallbacks['event:directory.search'](
|
|
807
|
+
createData(requestId, 0, false, 'directoryEntities', ['data0'])
|
|
808
|
+
);
|
|
809
|
+
const result = await promise;
|
|
810
|
+
|
|
811
|
+
expect(result).to.deep.equal(['data0', 'data1', 'data2']);
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
it('fails with default timeout when mercury does not respond', async () => {
|
|
815
|
+
const {promise} = await testMakeRequest({
|
|
816
|
+
method: 'search',
|
|
817
|
+
resource: '/search/orgid/userOrgId/entities',
|
|
818
|
+
params: {
|
|
819
|
+
requestedTypes: ['PERSON', 'ROBOT'],
|
|
820
|
+
resultSize: 100,
|
|
821
|
+
queryString: 'query',
|
|
822
|
+
},
|
|
823
|
+
bodyParams: {
|
|
824
|
+
requestedTypes: ['PERSON', 'ROBOT'],
|
|
825
|
+
resultSize: 100,
|
|
826
|
+
queryString: 'query',
|
|
827
|
+
},
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
await clock.tickAsync(6000);
|
|
831
|
+
|
|
832
|
+
return assert.isRejected(
|
|
833
|
+
promise,
|
|
834
|
+
'The DSS did not respond within 6000 ms.' +
|
|
835
|
+
'\n Request Id: randomid' +
|
|
836
|
+
'\n Resource: /search/orgid/userOrgId/entities' +
|
|
837
|
+
'\n Params: {"queryString":"query","resultSize":100,"requestedTypes":["PERSON","ROBOT"]}'
|
|
838
|
+
);
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
it('does not fail with timeout when mercury response in time', async () => {
|
|
842
|
+
const {requestId, promise} = await testMakeRequest({
|
|
843
|
+
method: 'search',
|
|
844
|
+
resource: '/search/orgid/userOrgId/entities',
|
|
845
|
+
params: {
|
|
846
|
+
requestedTypes: ['PERSON', 'ROBOT'],
|
|
847
|
+
resultSize: 100,
|
|
848
|
+
queryString: 'query',
|
|
849
|
+
},
|
|
850
|
+
bodyParams: {
|
|
851
|
+
requestedTypes: ['PERSON', 'ROBOT'],
|
|
852
|
+
resultSize: 100,
|
|
853
|
+
queryString: 'query',
|
|
854
|
+
},
|
|
855
|
+
});
|
|
856
|
+
|
|
857
|
+
await clock.tickAsync(5999);
|
|
858
|
+
|
|
859
|
+
mercuryCallbacks['event:directory.search'](
|
|
860
|
+
createData(requestId, 1, false, 'directoryEntities', ['data1'])
|
|
861
|
+
);
|
|
862
|
+
mercuryCallbacks['event:directory.search'](
|
|
863
|
+
createData(requestId, 2, true, 'directoryEntities', ['data2'])
|
|
864
|
+
);
|
|
865
|
+
mercuryCallbacks['event:directory.search'](
|
|
866
|
+
createData(requestId, 0, false, 'directoryEntities', ['data0'])
|
|
867
|
+
);
|
|
868
|
+
|
|
869
|
+
return assert.isFulfilled(promise);
|
|
870
|
+
});
|
|
871
|
+
|
|
872
|
+
it('fails with timeout when request only partially resolved', async () => {
|
|
873
|
+
const {requestId, promise} = await testMakeRequest({
|
|
874
|
+
method: 'search',
|
|
875
|
+
resource: '/search/orgid/userOrgId/entities',
|
|
876
|
+
params: {
|
|
877
|
+
requestedTypes: ['PERSON', 'ROBOT'],
|
|
878
|
+
resultSize: 100,
|
|
879
|
+
queryString: 'query',
|
|
880
|
+
},
|
|
881
|
+
bodyParams: {
|
|
882
|
+
requestedTypes: ['PERSON', 'ROBOT'],
|
|
883
|
+
resultSize: 100,
|
|
884
|
+
queryString: 'query',
|
|
885
|
+
},
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
mercuryCallbacks['event:directory.search'](
|
|
889
|
+
createData(requestId, 2, true, 'directoryEntities', ['data2'])
|
|
890
|
+
);
|
|
891
|
+
mercuryCallbacks['event:directory.search'](
|
|
892
|
+
createData(requestId, 0, false, 'directoryEntities', ['data0'])
|
|
893
|
+
);
|
|
894
|
+
|
|
895
|
+
await clock.tickAsync(6000);
|
|
896
|
+
|
|
897
|
+
return assert.isRejected(
|
|
898
|
+
promise,
|
|
899
|
+
'The DSS did not respond within 6000 ms.' +
|
|
900
|
+
'\n Request Id: randomid' +
|
|
901
|
+
'\n Resource: /search/orgid/userOrgId/entities' +
|
|
902
|
+
'\n Params: {"queryString":"query","resultSize":100,"requestedTypes":["PERSON","ROBOT"]}'
|
|
903
|
+
);
|
|
301
904
|
});
|
|
302
905
|
});
|
|
303
906
|
|
|
@@ -326,34 +929,363 @@ describe('plugin-dss', () => {
|
|
|
326
929
|
|
|
327
930
|
webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
|
|
328
931
|
sequence: 1,
|
|
329
|
-
a: {
|
|
330
|
-
b: {
|
|
331
|
-
c: ['data1'],
|
|
332
|
-
},
|
|
333
|
-
},
|
|
932
|
+
a: {b: {c: ['data1']}},
|
|
334
933
|
});
|
|
335
|
-
|
|
336
934
|
webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
|
|
337
935
|
sequence: 2,
|
|
338
936
|
finished: true,
|
|
339
|
-
a: {
|
|
340
|
-
|
|
341
|
-
|
|
937
|
+
a: {b: {c: ['data2']}},
|
|
938
|
+
});
|
|
939
|
+
webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
|
|
940
|
+
sequence: 0,
|
|
941
|
+
a: {b: {c: ['data0']}},
|
|
942
|
+
});
|
|
943
|
+
|
|
944
|
+
const result = await promise;
|
|
945
|
+
|
|
946
|
+
expect(result).to.deep.equal({
|
|
947
|
+
resultArray: ['data0', 'data1', 'data2'],
|
|
948
|
+
});
|
|
949
|
+
});
|
|
950
|
+
|
|
951
|
+
it('handles a request with foundPath correctly', async () => {
|
|
952
|
+
webex.request = sinon.stub();
|
|
953
|
+
uuid.v4.returns('randomid');
|
|
954
|
+
const promise = webex.internal.dss._request({
|
|
955
|
+
resource: '/search/orgid/userOrgId/entities',
|
|
956
|
+
params: {some: 'param'},
|
|
957
|
+
dataPath: 'a.b.c',
|
|
958
|
+
foundPath: 'someFoundPath',
|
|
959
|
+
});
|
|
960
|
+
|
|
961
|
+
expect(webex.request.getCall(0).args).to.deep.equal([
|
|
962
|
+
{
|
|
963
|
+
service: 'directorySearch',
|
|
964
|
+
body: {
|
|
965
|
+
requestId: 'randomid',
|
|
966
|
+
some: 'param',
|
|
342
967
|
},
|
|
968
|
+
contentType: 'application/json',
|
|
969
|
+
method: 'POST',
|
|
970
|
+
resource: '/search/orgid/userOrgId/entities',
|
|
343
971
|
},
|
|
344
|
-
|
|
972
|
+
]);
|
|
345
973
|
|
|
974
|
+
webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
|
|
975
|
+
sequence: 1,
|
|
976
|
+
a: {b: {c: ['data1']}},
|
|
977
|
+
someFoundPath: ['id1'],
|
|
978
|
+
});
|
|
979
|
+
webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
|
|
980
|
+
sequence: 2,
|
|
981
|
+
finished: true,
|
|
982
|
+
a: {b: {c: ['data2']}},
|
|
983
|
+
someFoundPath: ['id2'],
|
|
984
|
+
});
|
|
346
985
|
webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
|
|
347
986
|
sequence: 0,
|
|
348
|
-
a: {
|
|
349
|
-
|
|
350
|
-
|
|
987
|
+
a: {b: {c: ['data0']}},
|
|
988
|
+
someFoundPath: ['id0'],
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
const result = await promise;
|
|
992
|
+
|
|
993
|
+
expect(result).to.deep.equal({
|
|
994
|
+
resultArray: ['data0', 'data1', 'data2'],
|
|
995
|
+
foundArray: ['id0', 'id1', 'id2'],
|
|
996
|
+
});
|
|
997
|
+
});
|
|
998
|
+
|
|
999
|
+
it('handles a request with foundPath and notFoundPath correctly', async () => {
|
|
1000
|
+
webex.request = sinon.stub();
|
|
1001
|
+
uuid.v4.returns('randomid');
|
|
1002
|
+
const promise = webex.internal.dss._request({
|
|
1003
|
+
resource: '/search/orgid/userOrgId/entities',
|
|
1004
|
+
params: {some: 'param'},
|
|
1005
|
+
dataPath: 'a.b.c',
|
|
1006
|
+
foundPath: 'someFoundPath',
|
|
1007
|
+
notFoundPath: 'someNotFoundPath',
|
|
1008
|
+
});
|
|
1009
|
+
|
|
1010
|
+
expect(webex.request.getCall(0).args).to.deep.equal([
|
|
1011
|
+
{
|
|
1012
|
+
service: 'directorySearch',
|
|
1013
|
+
body: {
|
|
1014
|
+
requestId: 'randomid',
|
|
1015
|
+
some: 'param',
|
|
351
1016
|
},
|
|
1017
|
+
contentType: 'application/json',
|
|
1018
|
+
method: 'POST',
|
|
1019
|
+
resource: '/search/orgid/userOrgId/entities',
|
|
352
1020
|
},
|
|
1021
|
+
]);
|
|
1022
|
+
|
|
1023
|
+
webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
|
|
1024
|
+
sequence: 1,
|
|
1025
|
+
a: {b: {c: ['data1']}},
|
|
1026
|
+
someFoundPath: ['id1'],
|
|
1027
|
+
});
|
|
1028
|
+
webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
|
|
1029
|
+
sequence: 2,
|
|
1030
|
+
finished: true,
|
|
1031
|
+
a: {b: {c: ['data2']}},
|
|
1032
|
+
someFoundPath: ['id2'],
|
|
1033
|
+
someNotFoundPath: ['id3'],
|
|
1034
|
+
});
|
|
1035
|
+
webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
|
|
1036
|
+
sequence: 0,
|
|
1037
|
+
a: {b: {c: ['data0']}},
|
|
1038
|
+
someFoundPath: ['id0'],
|
|
353
1039
|
});
|
|
354
1040
|
|
|
355
1041
|
const result = await promise;
|
|
356
|
-
|
|
1042
|
+
|
|
1043
|
+
expect(result).to.deep.equal({
|
|
1044
|
+
resultArray: ['data0', 'data1', 'data2'],
|
|
1045
|
+
foundArray: ['id0', 'id1', 'id2'],
|
|
1046
|
+
notFoundArray: ['id3'],
|
|
1047
|
+
});
|
|
1048
|
+
});
|
|
1049
|
+
});
|
|
1050
|
+
|
|
1051
|
+
describe('#_batchedLookup', () => {
|
|
1052
|
+
const checkStandardProperties = (batcher) => {
|
|
1053
|
+
expect(batcher.dataPath).to.equal('lookupResult.entities');
|
|
1054
|
+
expect(batcher.entitiesFoundPath).to.equal('lookupResult.entitiesFound');
|
|
1055
|
+
expect(batcher.entitiesNotFoundPath).to.equal('lookupResult.entitiesNotFound');
|
|
1056
|
+
expect(batcher.requestKey).to.equal('lookupValues');
|
|
1057
|
+
expect(batcher.config).to.deep.equal({
|
|
1058
|
+
batcherWait: 50,
|
|
1059
|
+
batcherMaxCalls: 50,
|
|
1060
|
+
batcherMaxWait: 150,
|
|
1061
|
+
requestTimeout: 6000,
|
|
1062
|
+
});
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
it('calls batcher.request on new batcher for first lookup', async () => {
|
|
1066
|
+
const resource = '/lookup/orgid/userOrgId/identities';
|
|
1067
|
+
const response = 'response1';
|
|
1068
|
+
|
|
1069
|
+
Batcher.prototype.request = sinon.stub().returns(Promise.resolve(response));
|
|
1070
|
+
|
|
1071
|
+
expect(webex.internal.dss.batchers).to.deep.equal({});
|
|
1072
|
+
|
|
1073
|
+
const result = await webex.internal.dss._batchedLookup({
|
|
1074
|
+
resource,
|
|
1075
|
+
lookupValue: 'id1',
|
|
1076
|
+
});
|
|
1077
|
+
|
|
1078
|
+
const batcher = webex.internal.dss.batchers[resource];
|
|
1079
|
+
|
|
1080
|
+
expect(batcher).to.exist;
|
|
1081
|
+
expect(batcher.resource).to.equal(resource);
|
|
1082
|
+
checkStandardProperties(batcher);
|
|
1083
|
+
|
|
1084
|
+
expect(Batcher.prototype.request.getCall(0).args).to.deep.equal(['id1']);
|
|
1085
|
+
expect(result).to.equal(response);
|
|
1086
|
+
});
|
|
1087
|
+
|
|
1088
|
+
it('calls batcher.request on new batcher for lookup with new resource', async () => {
|
|
1089
|
+
const resource1 = '/lookup/orgid/userOrgId/identities';
|
|
1090
|
+
const resource2 = '/lookup/orgid/userOrgId/entityprovidertype/CI_USER';
|
|
1091
|
+
const response1 = 'response1';
|
|
1092
|
+
const response2 = 'response2';
|
|
1093
|
+
|
|
1094
|
+
Batcher.prototype.request = sinon
|
|
1095
|
+
.stub()
|
|
1096
|
+
.onFirstCall()
|
|
1097
|
+
.returns(Promise.resolve(response1))
|
|
1098
|
+
.onSecondCall()
|
|
1099
|
+
.returns(Promise.resolve(response2));
|
|
1100
|
+
|
|
1101
|
+
expect(webex.internal.dss.batchers).to.deep.equal({});
|
|
1102
|
+
|
|
1103
|
+
await webex.internal.dss._batchedLookup({
|
|
1104
|
+
resource: resource1,
|
|
1105
|
+
lookupValue: 'id1',
|
|
1106
|
+
});
|
|
1107
|
+
|
|
1108
|
+
const result = await webex.internal.dss._batchedLookup({
|
|
1109
|
+
resource: resource2,
|
|
1110
|
+
lookupValue: 'id2',
|
|
1111
|
+
});
|
|
1112
|
+
|
|
1113
|
+
expect(webex.internal.dss.batchers[resource1]).to.exist;
|
|
1114
|
+
const batcher = webex.internal.dss.batchers[resource2];
|
|
1115
|
+
|
|
1116
|
+
expect(batcher).to.exist;
|
|
1117
|
+
expect(batcher.resource).to.equal(resource2);
|
|
1118
|
+
checkStandardProperties(batcher);
|
|
1119
|
+
|
|
1120
|
+
expect(Batcher.prototype.request.getCall(1).args).to.deep.equal(['id2']);
|
|
1121
|
+
expect(result).to.equal(response2);
|
|
1122
|
+
});
|
|
1123
|
+
|
|
1124
|
+
it('calls batcher.request on existing batcher for lookup with existing reource', async () => {
|
|
1125
|
+
const resource1 = '/lookup/orgid/userOrgId/identities';
|
|
1126
|
+
const response1 = 'response1';
|
|
1127
|
+
const response2 = 'response2';
|
|
1128
|
+
|
|
1129
|
+
Batcher.prototype.request = sinon
|
|
1130
|
+
.stub()
|
|
1131
|
+
.onFirstCall()
|
|
1132
|
+
.returns(Promise.resolve(response1))
|
|
1133
|
+
.onSecondCall()
|
|
1134
|
+
.returns(Promise.resolve(response2));
|
|
1135
|
+
|
|
1136
|
+
expect(webex.internal.dss.batchers).to.deep.equal({});
|
|
1137
|
+
|
|
1138
|
+
await webex.internal.dss._batchedLookup({
|
|
1139
|
+
resource: resource1,
|
|
1140
|
+
lookupValue: 'id1',
|
|
1141
|
+
});
|
|
1142
|
+
expect(webex.internal.dss.batchers[resource1]).to.exist;
|
|
1143
|
+
const initialBatcher = webex.internal.dss.batchers[resource1];
|
|
1144
|
+
|
|
1145
|
+
const result = await webex.internal.dss._batchedLookup({
|
|
1146
|
+
resource: resource1,
|
|
1147
|
+
lookupValue: 'id2',
|
|
1148
|
+
});
|
|
1149
|
+
|
|
1150
|
+
const batcher = webex.internal.dss.batchers[resource1];
|
|
1151
|
+
|
|
1152
|
+
expect(batcher).to.equal(initialBatcher);
|
|
1153
|
+
expect(batcher.resource).to.equal(resource1);
|
|
1154
|
+
checkStandardProperties(batcher);
|
|
1155
|
+
|
|
1156
|
+
expect(Batcher.prototype.request.getCall(1).args).to.deep.equal(['id2']);
|
|
1157
|
+
expect(result).to.equal(response2);
|
|
1158
|
+
});
|
|
1159
|
+
|
|
1160
|
+
it('fails fails when mercury does not respond, later batches can still pass ok', async () => {
|
|
1161
|
+
// Batch 1
|
|
1162
|
+
const {
|
|
1163
|
+
promises: [p1, p2, p3],
|
|
1164
|
+
} = await testMakeBatchedRequests({
|
|
1165
|
+
requests: [
|
|
1166
|
+
{
|
|
1167
|
+
id: 'req-id-1',
|
|
1168
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
1169
|
+
bodyParams: {lookupValues: ['id1', 'id2', 'id3']},
|
|
1170
|
+
},
|
|
1171
|
+
],
|
|
1172
|
+
calls: [
|
|
1173
|
+
{
|
|
1174
|
+
method: 'lookup',
|
|
1175
|
+
params: {id: 'id1', shouldBatch: true},
|
|
1176
|
+
},
|
|
1177
|
+
{
|
|
1178
|
+
method: 'lookup',
|
|
1179
|
+
params: {id: 'id2', shouldBatch: true},
|
|
1180
|
+
},
|
|
1181
|
+
{
|
|
1182
|
+
method: 'lookup',
|
|
1183
|
+
params: {id: 'id3', shouldBatch: true},
|
|
1184
|
+
},
|
|
1185
|
+
],
|
|
1186
|
+
});
|
|
1187
|
+
|
|
1188
|
+
// Batch 2
|
|
1189
|
+
const {
|
|
1190
|
+
promises: [p4],
|
|
1191
|
+
} = await testMakeBatchedRequests({
|
|
1192
|
+
requests: [
|
|
1193
|
+
{
|
|
1194
|
+
id: 'randomid',
|
|
1195
|
+
resource: '/lookup/orgid/userOrgId/identities',
|
|
1196
|
+
bodyParams: {lookupValues: ['id4']},
|
|
1197
|
+
},
|
|
1198
|
+
],
|
|
1199
|
+
calls: [
|
|
1200
|
+
{
|
|
1201
|
+
method: 'lookup',
|
|
1202
|
+
params: {id: 'id4', shouldBatch: true},
|
|
1203
|
+
},
|
|
1204
|
+
],
|
|
1205
|
+
});
|
|
1206
|
+
|
|
1207
|
+
// Batch 1 - only 1 mercury response out of 2 received
|
|
1208
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
1209
|
+
createData('req-id-1', 0, false, 'lookupResult', {
|
|
1210
|
+
entitiesFound: ['id1', 'id3'],
|
|
1211
|
+
entities: ['data1', 'data3'],
|
|
1212
|
+
})
|
|
1213
|
+
);
|
|
1214
|
+
|
|
1215
|
+
// Batch 2 - response
|
|
1216
|
+
mercuryCallbacks['event:directory.lookup'](
|
|
1217
|
+
createData('randomid', 0, true, 'lookupResult', {entitiesNotFound: ['id4']})
|
|
1218
|
+
);
|
|
1219
|
+
|
|
1220
|
+
// Timeout
|
|
1221
|
+
await clock.tickAsync(6000);
|
|
1222
|
+
|
|
1223
|
+
return Promise.all([
|
|
1224
|
+
assert.isRejected(
|
|
1225
|
+
p1,
|
|
1226
|
+
'The DSS did not respond within 6000 ms.' +
|
|
1227
|
+
'\n Request Id: req-id-1' +
|
|
1228
|
+
'\n Resource: /lookup/orgid/userOrgId/identities' +
|
|
1229
|
+
'\n Params: {"lookupValues":["id1","id2","id3"]}'
|
|
1230
|
+
),
|
|
1231
|
+
assert.isRejected(
|
|
1232
|
+
p2,
|
|
1233
|
+
'The DSS did not respond within 6000 ms.' +
|
|
1234
|
+
'\n Request Id: req-id-1' +
|
|
1235
|
+
'\n Resource: /lookup/orgid/userOrgId/identities' +
|
|
1236
|
+
'\n Params: {"lookupValues":["id1","id2","id3"]}'
|
|
1237
|
+
),
|
|
1238
|
+
assert.isRejected(
|
|
1239
|
+
p3,
|
|
1240
|
+
'The DSS did not respond within 6000 ms.' +
|
|
1241
|
+
'\n Request Id: req-id-1' +
|
|
1242
|
+
'\n Resource: /lookup/orgid/userOrgId/identities' +
|
|
1243
|
+
'\n Params: {"lookupValues":["id1","id2","id3"]}'
|
|
1244
|
+
),
|
|
1245
|
+
assert.isFulfilled(p4),
|
|
1246
|
+
]);
|
|
1247
|
+
});
|
|
1248
|
+
});
|
|
1249
|
+
|
|
1250
|
+
describe('#searchPlaces', () => {
|
|
1251
|
+
it('calls _request correctly', async () => {
|
|
1252
|
+
webex.internal.device.orgId = 'userOrgId';
|
|
1253
|
+
webex.internal.dss._request = sinon.stub().returns(Promise.resolve('some return value'));
|
|
1254
|
+
|
|
1255
|
+
const result = await webex.internal.dss.searchPlaces({
|
|
1256
|
+
resultSize: 100,
|
|
1257
|
+
queryString: 'query',
|
|
1258
|
+
isOnlySchedulableRooms: true,
|
|
1259
|
+
});
|
|
1260
|
+
expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
|
|
1261
|
+
{
|
|
1262
|
+
dataPath: 'directoryEntities',
|
|
1263
|
+
resource: '/search/orgid/userOrgId/places',
|
|
1264
|
+
params: {
|
|
1265
|
+
queryString: 'query',
|
|
1266
|
+
resultSize: 100,
|
|
1267
|
+
isOnlySchedulableRooms: true,
|
|
1268
|
+
},
|
|
1269
|
+
},
|
|
1270
|
+
]);
|
|
1271
|
+
expect(result).to.equal('some return value');
|
|
1272
|
+
});
|
|
1273
|
+
|
|
1274
|
+
it('works correctly', async () => {
|
|
1275
|
+
await testMakeRequest({
|
|
1276
|
+
method: 'searchPlaces',
|
|
1277
|
+
resource: '/search/orgid/userOrgId/places',
|
|
1278
|
+
params: {
|
|
1279
|
+
isOnlySchedulableRooms: true,
|
|
1280
|
+
resultSize: 100,
|
|
1281
|
+
queryString: 'query',
|
|
1282
|
+
},
|
|
1283
|
+
bodyParams: {
|
|
1284
|
+
isOnlySchedulableRooms: true,
|
|
1285
|
+
resultSize: 100,
|
|
1286
|
+
queryString: 'query',
|
|
1287
|
+
},
|
|
1288
|
+
});
|
|
357
1289
|
});
|
|
358
1290
|
});
|
|
359
1291
|
});
|