@webex/internal-plugin-dss 3.0.0-beta.3 → 3.0.0-beta.300

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.
@@ -1,33 +1,40 @@
1
1
  /*!
2
2
  * Copyright (c) 2015-2022 Cisco Systems, Inc. See LICENSE file.
3
3
  */
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';
8
+ import DSS from '@webex/internal-plugin-dss';
9
+ import {Batcher} from '@webex/webex-core';
10
+ import MockWebex from '@webex/test-helper-mock-webex';
11
+ import sinon from 'sinon';
12
+ import {set} from 'lodash';
13
+ import uuid from 'uuid';
14
+ import config from '@webex/internal-plugin-dss/src/config';
4
15
 
5
- import { assert } from "@webex/test-helper-chai";
6
- import DSS from "@webex/internal-plugin-dss";
7
- import MockWebex from "@webex/test-helper-mock-webex";
8
- import sinon from "sinon";
9
- import { expect } from "chai";
10
- import { set } from "lodash";
11
- import uuid from "uuid";
12
-
13
- describe("plugin-dss", () => {
14
- describe("DSS", () => {
16
+ chai.use(chaiAsPromised);
17
+ describe('plugin-dss', () => {
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 = new MockWebex({
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
- uuidStub = sinon.stub(uuid, "v4").returns("randomid");
34
+ uuidStub = sinon.stub(uuid, 'v4').returns('randomid');
28
35
 
29
36
  webex.canAuthorize = true;
30
- webex.internal.device.orgId = "userOrgId";
37
+ webex.internal.device.orgId = 'userOrgId';
31
38
 
32
39
  mercuryCallbacks = {};
33
40
 
@@ -39,343 +46,1246 @@ 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
- describe("#register()", () => {
49
- it("registers correctly", async () => {
59
+ describe('#register()', () => {
60
+ it('registers correctly', async () => {
50
61
  await webex.internal.dss.register();
51
62
 
52
63
  assert.callCount(webex.internal.mercury.on, 2);
53
64
 
54
65
  const firstCallArgs = webex.internal.mercury.on.getCall(0).args;
55
- expect(firstCallArgs[0]).to.equal("event:directory.lookup");
56
- expect(firstCallArgs[1]).to.be.a("function");
66
+
67
+ expect(firstCallArgs[0]).to.equal('event:directory.lookup');
68
+ expect(firstCallArgs[1]).to.be.a('function');
57
69
 
58
70
  const secondCallArgs = webex.internal.mercury.on.getCall(1).args;
59
- expect(secondCallArgs[0]).to.equal("event:directory.search");
60
- expect(secondCallArgs[1]).to.be.a("function");
71
+
72
+ expect(secondCallArgs[0]).to.equal('event:directory.search');
73
+ expect(secondCallArgs[1]).to.be.a('function');
61
74
 
62
75
  assert.equal(webex.internal.dss.registered, true);
63
76
  });
64
77
 
65
- it("rejects when it cannot authorize", async () => {
78
+ it('rejects when it cannot authorize', async () => {
66
79
  webex.canAuthorize = false;
80
+ // @ts-ignore
67
81
  await expect(webex.internal.dss.register()).to.be.rejectedWith(
68
82
  Error,
69
- "SDK cannot authorize"
83
+ 'SDK cannot authorize'
70
84
  );
71
85
  assert.equal(webex.internal.dss.registered, false);
72
86
  });
73
87
  });
74
88
 
75
- describe("#unregister()", () => {
76
- it("unregisters correctly", async () => {
89
+ describe('#unregister()', () => {
90
+ it('unregisters correctly', async () => {
77
91
  webex.internal.dss.registered = true;
78
92
  await webex.internal.dss.unregister();
79
93
 
80
94
  assert.callCount(webex.internal.mercury.off, 2);
81
95
 
82
96
  const firstCallArgs = webex.internal.mercury.off.getCall(0).args;
83
- expect(firstCallArgs[0]).to.equal("event:directory.lookup");
97
+
98
+ expect(firstCallArgs[0]).to.equal('event:directory.lookup');
84
99
 
85
100
  const secondCallArgs = webex.internal.mercury.off.getCall(1).args;
86
- expect(secondCallArgs[0]).to.equal("event:directory.search");
101
+
102
+ expect(secondCallArgs[0]).to.equal('event:directory.search');
87
103
 
88
104
  assert.equal(webex.internal.dss.registered, false);
89
105
  });
90
106
 
91
- it("handles unregister when it is not registered", async () => {
107
+ it('handles unregister when it is not registered', async () => {
92
108
  const result = await webex.internal.dss.unregister();
109
+
93
110
  await expect(result).equal(undefined);
94
111
  assert.equal(webex.internal.dss.registered, false);
95
112
  });
96
113
  });
97
114
 
98
- const createData = (requestId, sequence, finished, dataPath) => {
115
+ const createData = (requestId, sequence, finished, dataPath, results) => {
99
116
  const data = {
100
117
  requestId,
101
118
  sequence,
102
119
  };
120
+
103
121
  if (finished) {
104
122
  (data as any).finished = finished;
105
123
  }
106
- set(data, dataPath, [`data${sequence}`]);
107
- return { data };
124
+ set(data, dataPath, results);
125
+
126
+ return {data};
108
127
  };
109
128
 
110
- const testRequest = async ({
111
- method,
112
- resource,
113
- params,
114
- bodyParams,
115
- dataPath,
116
- event,
117
- }) => {
129
+ const testMakeRequest = async ({method, resource, params, bodyParams}) => {
118
130
  webex.request = sinon.stub();
119
131
 
120
132
  await webex.internal.dss.register();
121
133
 
122
134
  const promise = webex.internal.dss[method](params);
123
135
 
124
- const requestId = "randomid";
136
+ const requestId = 'randomid';
125
137
 
126
138
  expect(webex.request.getCall(0).args).to.deep.equal([
127
139
  {
128
- service: "directorySearch",
140
+ service: 'directorySearch',
129
141
  body: {
130
142
  requestId,
131
143
  ...bodyParams,
132
144
  },
133
- contentType: "application/json",
134
- method: "POST",
145
+ contentType: 'application/json',
146
+ method: 'POST',
135
147
  resource,
136
148
  },
137
149
  ]);
138
150
 
139
- mercuryCallbacks[event](createData(requestId, 1, false, dataPath));
140
- mercuryCallbacks[event](createData(requestId, 2, true, dataPath));
141
- mercuryCallbacks[event](createData(requestId, 0, false, dataPath));
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();
142
159
 
143
- const result = await promise;
144
- expect(result).to.deep.equal(["data0", "data1", "data2"]);
160
+ await webex.internal.dss.register();
161
+
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};
145
185
  };
146
186
 
147
- describe("#lookupDetail", () => {
148
- it("calls _request correctly", async () => {
149
- webex.internal.device.orgId = "userOrgId";
150
- webex.internal.dss._request = sinon
151
- .stub()
152
- .returns(Promise.resolve("some return value"));
187
+ describe('#lookupDetail', () => {
188
+ it('calls _request correctly', async () => {
189
+ webex.internal.device.orgId = 'userOrgId';
190
+ webex.internal.dss._request = sinon.stub().returns(
191
+ Promise.resolve({
192
+ resultArray: ['some return value'],
193
+ foundArray: ['test id'],
194
+ })
195
+ );
196
+
197
+ const result = await webex.internal.dss.lookupDetail({id: 'test id'});
153
198
 
154
- const result = await webex.internal.dss.lookupDetail({ id: "test id" });
155
199
  expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
156
200
  {
157
- dataPath: "lookupResult.entities",
201
+ dataPath: 'lookupResult.entities',
202
+ foundPath: 'lookupResult.entitiesFound',
158
203
  resource: '/lookup/orgid/userOrgId/identity/test id/detail',
159
204
  },
160
205
  ]);
161
- expect(result).to.equal("some return value");
206
+ expect(result).to.equal('some return value');
162
207
  });
163
208
 
164
- it("works correctly", async () => {
165
- await testRequest({
166
- method: "lookupDetail",
167
- dataPath: "lookupResult.entities",
168
- event: "event:directory.lookup",
209
+ it('works correctly', async () => {
210
+ const {requestId, promise} = await testMakeRequest({
211
+ method: 'lookupDetail',
169
212
  resource: '/lookup/orgid/userOrgId/identity/test id/detail',
170
- params: {
171
- id: "test id",
172
- },
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'},
173
233
  bodyParams: {},
174
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'},
268
+ bodyParams: {},
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);
175
278
  });
176
279
  });
177
280
 
178
- describe("#lookup", () => {
179
- it("calls _request correctly", async () => {
180
- webex.internal.device.orgId = "userOrgId";
181
- webex.internal.dss._request = sinon
182
- .stub()
183
- .returns(Promise.resolve("some return value"));
281
+ describe('#lookup', () => {
282
+ it('calls _request correctly', async () => {
283
+ webex.internal.device.orgId = 'userOrgId';
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});
184
292
 
185
- const result = await webex.internal.dss.lookup({ ids: ["id1", "id2"] });
186
293
  expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
187
294
  {
188
- dataPath: "lookupResult.entities",
295
+ dataPath: 'lookupResult.entities',
296
+ foundPath: 'lookupResult.entitiesFound',
189
297
  resource: '/lookup/orgid/userOrgId/identities',
190
298
  params: {
191
- lookupValues: ["id1", "id2"],
299
+ lookupValues: ['id1'],
192
300
  },
193
301
  },
194
302
  ]);
195
- expect(result).to.equal("some return value");
303
+ expect(result).to.equal('some return value');
196
304
  });
197
305
 
198
- it("calls _request correctly with entityProviderType", async () => {
199
- webex.internal.device.orgId = "userOrgId";
200
- webex.internal.dss._request = sinon
201
- .stub()
202
- .returns(Promise.resolve("some return value"));
306
+ it('calls _request correctly with entityProviderType', async () => {
307
+ webex.internal.device.orgId = 'userOrgId';
308
+ webex.internal.dss._request = sinon.stub().returns(
309
+ Promise.resolve({
310
+ resultArray: ['some return value'],
311
+ foundArray: ['id1'],
312
+ })
313
+ );
314
+
315
+ const result = await webex.internal.dss.lookup({
316
+ id: 'id1',
317
+ entityProviderType: 'CI_USER',
318
+ shouldBatch: false,
319
+ });
203
320
 
204
- const result = await webex.internal.dss.lookup({ ids: ["id1", "id2"], entityProviderType: 'CI_USER' });
205
321
  expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
206
322
  {
207
- dataPath: "lookupResult.entities",
323
+ dataPath: 'lookupResult.entities',
324
+ foundPath: 'lookupResult.entitiesFound',
208
325
  resource: '/lookup/orgid/userOrgId/entityprovidertype/CI_USER',
209
326
  params: {
210
- lookupValues: ["id1", "id2"],
327
+ lookupValues: ['id1'],
211
328
  },
212
329
  },
213
330
  ]);
214
- expect(result).to.equal("some return value");
331
+ expect(result).to.equal('some return value');
215
332
  });
216
333
 
217
- it("works correctly", async () => {
218
- await testRequest({
219
- method: "lookup",
220
- dataPath: "lookupResult.entities",
221
- event: "event:directory.lookup",
334
+ it('works correctly', async () => {
335
+ const {requestId, promise} = await testMakeRequest({
336
+ method: 'lookup',
222
337
  resource: '/lookup/orgid/userOrgId/identities',
223
- params: {
224
- ids: ["id1", "id2"],
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',
225
381
  },
226
- bodyParams: {
227
- lookupValues: ["id1", "id2"],
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',
228
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
+ ],
229
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']},
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);
230
655
  });
231
656
  });
232
657
 
233
- describe("#lookupByEmail", () => {
234
- it("calls _request correctly", async () => {
235
- webex.internal.device.orgId = "userOrgId";
236
- webex.internal.dss._request = sinon
237
- .stub()
238
- .returns(Promise.resolve("some return value"));
658
+ describe('#lookupByEmail', () => {
659
+ it('calls _request correctly', async () => {
660
+ webex.internal.device.orgId = 'userOrgId';
661
+ webex.internal.dss._request = sinon.stub().returns(
662
+ Promise.resolve({
663
+ resultArray: ['some return value'],
664
+ foundArray: ['email1'],
665
+ })
666
+ );
239
667
 
240
668
  const result = await webex.internal.dss.lookupByEmail({
241
- emails: ["email1", "email2"],
669
+ email: 'email1',
242
670
  });
671
+
243
672
  expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
244
673
  {
245
- dataPath: "lookupResult.entities",
674
+ dataPath: 'lookupResult.entities',
675
+ foundPath: 'lookupResult.entitiesFound',
246
676
  resource: '/lookup/orgid/userOrgId/emails',
247
677
  params: {
248
- lookupValues: ["email1", "email2"],
678
+ lookupValues: ['email1'],
249
679
  },
250
680
  },
251
681
  ]);
252
- expect(result).to.equal("some return value");
682
+ expect(result).to.equal('some return value');
253
683
  });
254
684
 
255
- it("works correctly", async () => {
256
- await testRequest({
257
- method: "lookupByEmail",
258
- dataPath: "lookupResult.entities",
259
- event: "event:directory.lookup",
685
+ it('works correctly', async () => {
686
+ const {requestId, promise} = await testMakeRequest({
687
+ method: 'lookupByEmail',
260
688
  resource: '/lookup/orgid/userOrgId/emails',
261
- params: {
262
- emails: ["email1", "email2"],
263
- },
264
- bodyParams: {
265
- lookupValues: ["email1", "email2"],
266
- },
689
+ params: {email: 'email1'},
690
+ bodyParams: {lookupValues: ['email1']},
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']},
267
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);
268
754
  });
269
755
  });
270
756
 
271
- describe("#search", () => {
272
- it("calls _request correctly", async () => {
273
- webex.internal.device.orgId = "userOrgId";
757
+ describe('#search', () => {
758
+ it('calls _request correctly', async () => {
759
+ webex.internal.device.orgId = 'userOrgId';
274
760
  webex.internal.dss._request = sinon
275
761
  .stub()
276
- .returns(Promise.resolve("some return value"));
762
+ .returns(Promise.resolve({resultArray: 'some return value'}));
277
763
 
278
764
  const result = await webex.internal.dss.search({
279
- requestedTypes: ["PERSON", "ROBOT"],
765
+ requestedTypes: ['PERSON', 'ROBOT'],
280
766
  resultSize: 100,
281
- queryString: "query",
767
+ queryString: 'query',
282
768
  });
769
+
283
770
  expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
284
771
  {
285
- dataPath: "directoryEntities",
772
+ dataPath: 'directoryEntities',
286
773
  resource: '/search/orgid/userOrgId/entities',
287
774
  params: {
288
- queryString: "query",
775
+ queryString: 'query',
289
776
  resultSize: 100,
290
- requestedTypes: ["PERSON", "ROBOT"],
777
+ requestedTypes: ['PERSON', 'ROBOT'],
291
778
  },
292
779
  },
293
780
  ]);
294
- expect(result).to.equal("some return value");
781
+ expect(result).to.equal('some return value');
295
782
  });
296
783
 
297
- it("works correctly", async () => {
298
- await testRequest({
299
- method: "search",
300
- event: "event:directory.search",
301
- dataPath: "directoryEntities",
784
+ it('works correctly', async () => {
785
+ const {requestId, promise} = await testMakeRequest({
786
+ method: 'search',
302
787
  resource: '/search/orgid/userOrgId/entities',
303
788
  params: {
304
- requestedTypes: ["PERSON", "ROBOT"],
789
+ requestedTypes: ['PERSON', 'ROBOT'],
305
790
  resultSize: 100,
306
- queryString: "query",
791
+ queryString: 'query',
307
792
  },
308
793
  bodyParams: {
309
- requestedTypes: ["PERSON", "ROBOT"],
794
+ requestedTypes: ['PERSON', 'ROBOT'],
310
795
  resultSize: 100,
311
- queryString: "query",
796
+ queryString: 'query',
312
797
  },
313
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
+ );
314
904
  });
315
905
  });
316
906
 
317
- describe("#_request", () => {
318
- it("handles a request correctly", async () => {
907
+ describe('#_request', () => {
908
+ it('handles a request correctly', async () => {
319
909
  webex.request = sinon.stub();
320
- uuid.v4.returns("randomid");
910
+ uuid.v4.returns('randomid');
321
911
  const promise = webex.internal.dss._request({
322
- resource: "/search/orgid/userOrgId/entities",
323
- params: { some: "param" },
324
- dataPath: "a.b.c",
912
+ resource: '/search/orgid/userOrgId/entities',
913
+ params: {some: 'param'},
914
+ dataPath: 'a.b.c',
325
915
  });
326
916
 
327
917
  expect(webex.request.getCall(0).args).to.deep.equal([
328
918
  {
329
- service: "directorySearch",
919
+ service: 'directorySearch',
330
920
  body: {
331
- requestId: "randomid",
332
- some: "param",
921
+ requestId: 'randomid',
922
+ some: 'param',
333
923
  },
334
- contentType: "application/json",
335
- method: "POST",
336
- resource: "/search/orgid/userOrgId/entities",
924
+ contentType: 'application/json',
925
+ method: 'POST',
926
+ resource: '/search/orgid/userOrgId/entities',
337
927
  },
338
928
  ]);
339
929
 
340
- webex.internal.dss.trigger(
341
- webex.internal.dss._getResultEventName("randomid"),
930
+ webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
931
+ sequence: 1,
932
+ a: {b: {c: ['data1']}},
933
+ });
934
+ webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
935
+ sequence: 2,
936
+ finished: true,
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([
342
962
  {
343
- sequence: 1,
344
- a: {
345
- b: {
346
- c: ["data1"],
347
- },
963
+ service: 'directorySearch',
964
+ body: {
965
+ requestId: 'randomid',
966
+ some: 'param',
348
967
  },
349
- }
350
- );
968
+ contentType: 'application/json',
969
+ method: 'POST',
970
+ resource: '/search/orgid/userOrgId/entities',
971
+ },
972
+ ]);
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
+ });
985
+ webex.internal.dss.trigger(webex.internal.dss._getResultEventName('randomid'), {
986
+ sequence: 0,
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
+ });
351
998
 
352
- webex.internal.dss.trigger(
353
- webex.internal.dss._getResultEventName("randomid"),
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([
354
1011
  {
355
- sequence: 2,
356
- finished: true,
357
- a: {
358
- b: {
359
- c: ["data2"],
360
- },
1012
+ service: 'directorySearch',
1013
+ body: {
1014
+ requestId: 'randomid',
1015
+ some: 'param',
361
1016
  },
362
- }
1017
+ contentType: 'application/json',
1018
+ method: 'POST',
1019
+ resource: '/search/orgid/userOrgId/entities',
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'],
1039
+ });
1040
+
1041
+ const result = await promise;
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']})
363
1218
  );
364
1219
 
365
- webex.internal.dss.trigger(
366
- webex.internal.dss._getResultEventName("randomid"),
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([
367
1261
  {
368
- sequence: 0,
369
- a: {
370
- b: {
371
- c: ["data0"],
372
- },
1262
+ dataPath: 'directoryEntities',
1263
+ resource: '/search/orgid/userOrgId/places',
1264
+ params: {
1265
+ queryString: 'query',
1266
+ resultSize: 100,
1267
+ isOnlySchedulableRooms: true,
373
1268
  },
374
- }
375
- );
1269
+ },
1270
+ ]);
1271
+ expect(result).to.equal('some return value');
1272
+ });
376
1273
 
377
- const result = await promise;
378
- expect(result).to.deep.equal(["data0", "data1", "data2"]);
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
+ });
379
1289
  });
380
1290
  });
381
1291
  });