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