@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.
- package/dist/config.js +36 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.js +11 -3
- package/dist/constants.js.map +1 -1
- package/dist/dss-batcher.js +139 -0
- package/dist/dss-batcher.js.map +1 -0
- package/dist/dss-errors.js +50 -0
- package/dist/dss-errors.js.map +1 -0
- package/dist/dss.js +194 -93
- package/dist/dss.js.map +1 -1
- package/dist/index.js +4 -7
- package/dist/index.js.map +1 -1
- package/dist/types.js +1 -5
- package/dist/types.js.map +1 -1
- package/package.json +9 -6
- package/src/config.ts +31 -0
- package/src/constants.ts +5 -0
- package/src/dss-batcher.ts +129 -0
- package/src/dss-errors.ts +36 -0
- package/src/dss.ts +211 -52
- package/src/index.ts +2 -1
- package/src/types.ts +36 -9
- package/test/unit/spec/dss-batcher.ts +139 -0
- package/test/unit/spec/dss.ts +1082 -172
package/test/unit/spec/dss.ts
CHANGED
|
@@ -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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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 =
|
|
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,
|
|
34
|
+
uuidStub = sinon.stub(uuid, 'v4').returns('randomid');
|
|
28
35
|
|
|
29
36
|
webex.canAuthorize = true;
|
|
30
|
-
webex.internal.device.orgId =
|
|
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(
|
|
49
|
-
it(
|
|
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
|
-
|
|
56
|
-
expect(firstCallArgs[
|
|
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
|
-
|
|
60
|
-
expect(secondCallArgs[
|
|
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(
|
|
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
|
-
|
|
83
|
+
'SDK cannot authorize'
|
|
70
84
|
);
|
|
71
85
|
assert.equal(webex.internal.dss.registered, false);
|
|
72
86
|
});
|
|
73
87
|
});
|
|
74
88
|
|
|
75
|
-
describe(
|
|
76
|
-
it(
|
|
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
|
-
|
|
97
|
+
|
|
98
|
+
expect(firstCallArgs[0]).to.equal('event:directory.lookup');
|
|
84
99
|
|
|
85
100
|
const secondCallArgs = webex.internal.mercury.off.getCall(1).args;
|
|
86
|
-
|
|
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(
|
|
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,
|
|
107
|
-
|
|
124
|
+
set(data, dataPath, results);
|
|
125
|
+
|
|
126
|
+
return {data};
|
|
108
127
|
};
|
|
109
128
|
|
|
110
|
-
const
|
|
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 =
|
|
136
|
+
const requestId = 'randomid';
|
|
125
137
|
|
|
126
138
|
expect(webex.request.getCall(0).args).to.deep.equal([
|
|
127
139
|
{
|
|
128
|
-
service:
|
|
140
|
+
service: 'directorySearch',
|
|
129
141
|
body: {
|
|
130
142
|
requestId,
|
|
131
143
|
...bodyParams,
|
|
132
144
|
},
|
|
133
|
-
contentType:
|
|
134
|
-
method:
|
|
145
|
+
contentType: 'application/json',
|
|
146
|
+
method: 'POST',
|
|
135
147
|
resource,
|
|
136
148
|
},
|
|
137
149
|
]);
|
|
138
150
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
-
|
|
144
|
-
|
|
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(
|
|
148
|
-
it(
|
|
149
|
-
webex.internal.device.orgId =
|
|
150
|
-
webex.internal.dss._request = sinon
|
|
151
|
-
.
|
|
152
|
-
|
|
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:
|
|
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(
|
|
206
|
+
expect(result).to.equal('some return value');
|
|
162
207
|
});
|
|
163
208
|
|
|
164
|
-
it(
|
|
165
|
-
await
|
|
166
|
-
method:
|
|
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
|
-
|
|
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(
|
|
179
|
-
it(
|
|
180
|
-
webex.internal.device.orgId =
|
|
181
|
-
webex.internal.dss._request = sinon
|
|
182
|
-
.
|
|
183
|
-
|
|
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:
|
|
295
|
+
dataPath: 'lookupResult.entities',
|
|
296
|
+
foundPath: 'lookupResult.entitiesFound',
|
|
189
297
|
resource: '/lookup/orgid/userOrgId/identities',
|
|
190
298
|
params: {
|
|
191
|
-
lookupValues: [
|
|
299
|
+
lookupValues: ['id1'],
|
|
192
300
|
},
|
|
193
301
|
},
|
|
194
302
|
]);
|
|
195
|
-
expect(result).to.equal(
|
|
303
|
+
expect(result).to.equal('some return value');
|
|
196
304
|
});
|
|
197
305
|
|
|
198
|
-
it(
|
|
199
|
-
webex.internal.device.orgId =
|
|
200
|
-
webex.internal.dss._request = sinon
|
|
201
|
-
.
|
|
202
|
-
|
|
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:
|
|
323
|
+
dataPath: 'lookupResult.entities',
|
|
324
|
+
foundPath: 'lookupResult.entitiesFound',
|
|
208
325
|
resource: '/lookup/orgid/userOrgId/entityprovidertype/CI_USER',
|
|
209
326
|
params: {
|
|
210
|
-
lookupValues: [
|
|
327
|
+
lookupValues: ['id1'],
|
|
211
328
|
},
|
|
212
329
|
},
|
|
213
330
|
]);
|
|
214
|
-
expect(result).to.equal(
|
|
331
|
+
expect(result).to.equal('some return value');
|
|
215
332
|
});
|
|
216
333
|
|
|
217
|
-
it(
|
|
218
|
-
await
|
|
219
|
-
method:
|
|
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
|
-
|
|
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
|
-
|
|
227
|
-
|
|
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(
|
|
234
|
-
it(
|
|
235
|
-
webex.internal.device.orgId =
|
|
236
|
-
webex.internal.dss._request = sinon
|
|
237
|
-
.
|
|
238
|
-
|
|
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
|
-
|
|
669
|
+
email: 'email1',
|
|
242
670
|
});
|
|
671
|
+
|
|
243
672
|
expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
|
|
244
673
|
{
|
|
245
|
-
dataPath:
|
|
674
|
+
dataPath: 'lookupResult.entities',
|
|
675
|
+
foundPath: 'lookupResult.entitiesFound',
|
|
246
676
|
resource: '/lookup/orgid/userOrgId/emails',
|
|
247
677
|
params: {
|
|
248
|
-
lookupValues: [
|
|
678
|
+
lookupValues: ['email1'],
|
|
249
679
|
},
|
|
250
680
|
},
|
|
251
681
|
]);
|
|
252
|
-
expect(result).to.equal(
|
|
682
|
+
expect(result).to.equal('some return value');
|
|
253
683
|
});
|
|
254
684
|
|
|
255
|
-
it(
|
|
256
|
-
await
|
|
257
|
-
method:
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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(
|
|
272
|
-
it(
|
|
273
|
-
webex.internal.device.orgId =
|
|
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(
|
|
762
|
+
.returns(Promise.resolve({resultArray: 'some return value'}));
|
|
277
763
|
|
|
278
764
|
const result = await webex.internal.dss.search({
|
|
279
|
-
requestedTypes: [
|
|
765
|
+
requestedTypes: ['PERSON', 'ROBOT'],
|
|
280
766
|
resultSize: 100,
|
|
281
|
-
queryString:
|
|
767
|
+
queryString: 'query',
|
|
282
768
|
});
|
|
769
|
+
|
|
283
770
|
expect(webex.internal.dss._request.getCall(0).args).to.deep.equal([
|
|
284
771
|
{
|
|
285
|
-
dataPath:
|
|
772
|
+
dataPath: 'directoryEntities',
|
|
286
773
|
resource: '/search/orgid/userOrgId/entities',
|
|
287
774
|
params: {
|
|
288
|
-
queryString:
|
|
775
|
+
queryString: 'query',
|
|
289
776
|
resultSize: 100,
|
|
290
|
-
requestedTypes: [
|
|
777
|
+
requestedTypes: ['PERSON', 'ROBOT'],
|
|
291
778
|
},
|
|
292
779
|
},
|
|
293
780
|
]);
|
|
294
|
-
expect(result).to.equal(
|
|
781
|
+
expect(result).to.equal('some return value');
|
|
295
782
|
});
|
|
296
783
|
|
|
297
|
-
it(
|
|
298
|
-
await
|
|
299
|
-
method:
|
|
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: [
|
|
789
|
+
requestedTypes: ['PERSON', 'ROBOT'],
|
|
305
790
|
resultSize: 100,
|
|
306
|
-
queryString:
|
|
791
|
+
queryString: 'query',
|
|
307
792
|
},
|
|
308
793
|
bodyParams: {
|
|
309
|
-
requestedTypes: [
|
|
794
|
+
requestedTypes: ['PERSON', 'ROBOT'],
|
|
310
795
|
resultSize: 100,
|
|
311
|
-
queryString:
|
|
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(
|
|
318
|
-
it(
|
|
907
|
+
describe('#_request', () => {
|
|
908
|
+
it('handles a request correctly', async () => {
|
|
319
909
|
webex.request = sinon.stub();
|
|
320
|
-
uuid.v4.returns(
|
|
910
|
+
uuid.v4.returns('randomid');
|
|
321
911
|
const promise = webex.internal.dss._request({
|
|
322
|
-
resource:
|
|
323
|
-
params: {
|
|
324
|
-
dataPath:
|
|
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:
|
|
919
|
+
service: 'directorySearch',
|
|
330
920
|
body: {
|
|
331
|
-
requestId:
|
|
332
|
-
some:
|
|
921
|
+
requestId: 'randomid',
|
|
922
|
+
some: 'param',
|
|
333
923
|
},
|
|
334
|
-
contentType:
|
|
335
|
-
method:
|
|
336
|
-
resource:
|
|
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
|
-
|
|
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
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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
|
-
|
|
353
|
-
|
|
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
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
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
|
-
|
|
366
|
-
|
|
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
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
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
|
-
|
|
378
|
-
|
|
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
|
});
|