@webex/webex-core 3.12.0-webex-services-ready.1 → 3.12.0-webex-services-ready.2

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.
@@ -34,53 +34,6 @@ describe('webex-core', () => {
34
34
  });
35
35
 
36
36
  describe('#initialize', () => {
37
- it('listens for "loaded" event instead of "ready" to avoid deadlock', () => {
38
- services.listenToOnce = sinon.stub();
39
- services.initialize();
40
-
41
- // Second listenToOnce call should be for 'loaded' event
42
- assert.equal(services.listenToOnce.getCall(1).args[1], 'loaded');
43
- });
44
-
45
- it('services.ready starts as false', () => {
46
- assert.isFalse(services.ready);
47
- });
48
-
49
- it('sets ready to true and triggers services:initialized when initialization succeeds with credentials', async () => {
50
- services.listenToOnce = sinon.stub();
51
- services.initServiceCatalogs = sinon.stub().returns(Promise.resolve());
52
- services.trigger = sinon.stub();
53
- services.webex.credentials = {
54
- supertoken: {
55
- access_token: 'token',
56
- },
57
- };
58
-
59
- services.initialize();
60
-
61
- // call the onLoaded callback
62
- services.listenToOnce.getCall(1).args[2]();
63
- await waitForAsync();
64
-
65
- assert.isTrue(services.ready);
66
- sinon.assert.calledWith(services.trigger, 'services:initialized');
67
- });
68
-
69
- it('sets ready to true and triggers services:initialized when initialization succeeds without credentials', async () => {
70
- services.listenToOnce = sinon.stub();
71
- services.collectPreauthCatalog = sinon.stub().returns(Promise.resolve());
72
- services.trigger = sinon.stub();
73
-
74
- services.initialize();
75
-
76
- // call the onLoaded callback
77
- services.listenToOnce.getCall(1).args[2]();
78
- await waitForAsync();
79
-
80
- assert.isTrue(services.ready);
81
- sinon.assert.calledWith(services.trigger, 'services:initialized');
82
- });
83
-
84
37
  it('initFailed is false when initialization succeeds and credentials are available', async () => {
85
38
  services.listenToOnce = sinon.stub();
86
39
  services.initServiceCatalogs = sinon.stub().returns(Promise.resolve());
@@ -92,7 +45,8 @@ describe('webex-core', () => {
92
45
 
93
46
  services.initialize();
94
47
 
95
- // call the onLoaded callback
48
+ // call the onReady callback
49
+ services.listenToOnce.getCall(0).args[2]();
96
50
  services.listenToOnce.getCall(1).args[2]();
97
51
  await waitForAsync();
98
52
 
@@ -105,7 +59,8 @@ describe('webex-core', () => {
105
59
 
106
60
  services.initialize();
107
61
 
108
- // call the onLoaded callback
62
+ // call the onReady callback
63
+ services.listenToOnce.getCall(0).args[2]();
109
64
  services.listenToOnce.getCall(1).args[2]();
110
65
  await waitForAsync();
111
66
 
@@ -116,7 +71,7 @@ describe('webex-core', () => {
116
71
  {error: new Error('failed'), expectedMessage: 'failed'},
117
72
  {error: undefined, expectedMessage: undefined},
118
73
  ])(
119
- 'sets initFailed to true when collectPreauthCatalog errors but still sets ready to true',
74
+ 'sets initFailed to true when collectPreauthCatalog errors',
120
75
  async ({error, expectedMessage}) => {
121
76
  services.collectPreauthCatalog = sinon.stub().callsFake(() => {
122
77
  return Promise.reject(error);
@@ -124,18 +79,16 @@ describe('webex-core', () => {
124
79
 
125
80
  services.listenToOnce = sinon.stub();
126
81
  services.logger.error = sinon.stub();
127
- services.trigger = sinon.stub();
128
82
 
129
83
  services.initialize();
130
84
 
131
- // call the onLoaded callback
85
+ // call the onReady callback
86
+ services.listenToOnce.getCall(0).args[2]();
132
87
  services.listenToOnce.getCall(1).args[2]();
133
88
 
134
89
  await waitForAsync();
135
90
 
136
91
  assert.isTrue(services.initFailed);
137
- assert.isTrue(services.ready);
138
- sinon.assert.calledWith(services.trigger, 'services:initialized');
139
92
  sinon.assert.calledWith(
140
93
  services.logger.error,
141
94
  `services: failed to init initial services when no credentials available, ${expectedMessage}`
@@ -147,7 +100,7 @@ describe('webex-core', () => {
147
100
  {error: new Error('failed'), expectedMessage: 'failed'},
148
101
  {error: undefined, expectedMessage: undefined},
149
102
  ])(
150
- 'sets initFailed to true when initServiceCatalogs errors but still sets ready to true',
103
+ 'sets initFailed to true when initServiceCatalogs errors',
151
104
  async ({error, expectedMessage}) => {
152
105
  services.initServiceCatalogs = sinon.stub().callsFake(() => {
153
106
  return Promise.reject(error);
@@ -160,18 +113,16 @@ describe('webex-core', () => {
160
113
 
161
114
  services.listenToOnce = sinon.stub();
162
115
  services.logger.error = sinon.stub();
163
- services.trigger = sinon.stub();
164
116
 
165
117
  services.initialize();
166
118
 
167
- // call the onLoaded callback
119
+ // call the onReady callback
120
+ services.listenToOnce.getCall(0).args[2]();
168
121
  services.listenToOnce.getCall(1).args[2]();
169
122
 
170
123
  await waitForAsync();
171
124
 
172
125
  assert.isTrue(services.initFailed);
173
- assert.isTrue(services.ready);
174
- sinon.assert.calledWith(services.trigger, 'services:initialized');
175
126
  sinon.assert.calledWith(
176
127
  services.logger.error,
177
128
  `services: failed to init initial services when credentials available, ${expectedMessage}`
@@ -179,98 +130,290 @@ describe('webex-core', () => {
179
130
  }
180
131
  );
181
132
 
182
- describe('when change:canAuthorize fires', () => {
183
- it('calls initServiceCatalogs when canAuthorize becomes true and postauth catalog is not ready', async () => {
184
- services.listenToOnce = sinon.stub();
185
- services._loadCatalogFromCache = sinon.stub().returns(Promise.resolve(false));
186
- services.collectPreauthCatalog = sinon.stub().returns(Promise.resolve());
187
- services.initServiceCatalogs = sinon.stub().returns(Promise.resolve());
188
- services.trigger = sinon.stub();
189
- // Ensure no credentials so we go to the preauth path
190
- services.webex.credentials = {};
133
+ it('sets services.ready to true when waitForCatalogInit is disabled (default)', () => {
134
+ services.listenToOnce = sinon.stub();
135
+ services.initialize();
191
136
 
192
- services.initialize();
137
+ // Fire the change:config handler which decides gated-vs-ungated and, in
138
+ // ungated mode, flips services.ready to true.
139
+ services.listenToOnce.getCall(0).args[2]();
193
140
 
194
- // Get the catalog after initialize creates it
195
- const testCatalog = services._getCatalog();
196
- testCatalog.status.postauth.ready = false;
141
+ assert.isTrue(services.ready, 'services.ready should be true so it does not block webex.ready');
142
+ });
197
143
 
198
- // call the onLoaded callback (preauth path)
199
- services.listenToOnce.getCall(1).args[2]();
200
- await waitForAsync();
144
+ it('listens on the "ready" event when waitForCatalogInit is disabled (default)', () => {
145
+ services.listenToOnce = sinon.stub();
146
+ services.initialize();
201
147
 
202
- // Now set canAuthorize to true to simulate auth completing
203
- services.webex.canAuthorize = true;
148
+ // Fire change:config to trigger the mode-specific listener registration.
149
+ services.listenToOnce.getCall(0).args[2]();
204
150
 
205
- // call the change:canAuthorize callback (should be call 2)
206
- services.listenToOnce.getCall(2).args[2]();
207
- await waitForAsync();
151
+ const [, event] = services.listenToOnce.getCall(1).args;
152
+ assert.equal(event, 'ready', 'default path listens on webex ready');
153
+ });
154
+ });
208
155
 
209
- sinon.assert.calledOnce(services.initServiceCatalogs);
210
- assert.isTrue(testCatalog.isReady);
211
- });
156
+ describe('#initialize (waitForCatalogInit=true)', () => {
157
+ beforeEach(() => {
158
+ services.webex.config = {
159
+ ...(services.webex.config || {}),
160
+ services: {waitForCatalogInit: true},
161
+ };
162
+ // Reset ready flag: the outer beforeEach constructs services which
163
+ // runs initialize() once with no config (ungated path, flips ready to
164
+ // true). We reset here so tests that call initialize() a second time
165
+ // with the flag enabled observe the gated behavior from a clean state.
166
+ services.ready = false;
167
+ });
212
168
 
213
- it('does not call initServiceCatalogs when postauth catalog is already ready', async () => {
214
- services.listenToOnce = sinon.stub();
215
- services._loadCatalogFromCache = sinon.stub().returns(Promise.resolve(false));
216
- services.collectPreauthCatalog = sinon.stub().returns(Promise.resolve());
217
- services.initServiceCatalogs = sinon.stub().returns(Promise.resolve());
218
- services.trigger = sinon.stub();
219
- // Ensure no credentials so we go to the preauth path
220
- services.webex.credentials = {};
169
+ it('leaves services.ready=false after initialize (does not flip until finalize)', () => {
170
+ services.listenToOnce = sinon.stub();
171
+ services.initialize();
221
172
 
222
- services.initialize();
173
+ assert.isFalse(services.ready, 'services.ready should block webex.ready until finalize');
174
+ });
223
175
 
224
- // Get the catalog after initialize creates it
225
- const testCatalog = services._getCatalog();
176
+ it('listens on the "loaded" event (not "ready") to avoid deadlock', () => {
177
+ services.listenToOnce = sinon.stub();
178
+ services.initialize();
226
179
 
227
- // call the onLoaded callback (preauth path)
228
- services.listenToOnce.getCall(1).args[2]();
229
- await waitForAsync();
180
+ // Fire change:config to trigger the mode-specific listener registration.
181
+ services.listenToOnce.getCall(0).args[2]();
230
182
 
231
- // Set canAuthorize to true and postauth as ready BEFORE calling the callback
232
- services.webex.canAuthorize = true;
233
- testCatalog.status.postauth.ready = true;
183
+ const [, event] = services.listenToOnce.getCall(1).args;
184
+ assert.equal(event, 'loaded', 'gated path must listen on loaded to avoid deadlock');
185
+ });
234
186
 
235
- // call the change:canAuthorize callback (should be call 2)
236
- services.listenToOnce.getCall(2).args[2]();
237
- await waitForAsync();
187
+ it('flips services.ready=true after init succeeds with credentials', async () => {
188
+ services.listenToOnce = sinon.stub();
189
+ services.initServiceCatalogs = sinon.stub().returns(Promise.resolve());
190
+ services.webex.credentials = {
191
+ supertoken: {access_token: 'token'},
192
+ };
238
193
 
239
- sinon.assert.notCalled(services.initServiceCatalogs);
240
- });
194
+ services.initialize();
195
+ services.listenToOnce.getCall(0).args[2]();
196
+ services.listenToOnce.getCall(1).args[2]();
197
+ await waitForAsync();
241
198
 
242
- it('logs an error when initServiceCatalogs fails after auth', async () => {
243
- services.listenToOnce = sinon.stub();
244
- services._loadCatalogFromCache = sinon.stub().returns(Promise.resolve(false));
245
- services.collectPreauthCatalog = sinon.stub().returns(Promise.resolve());
246
- services.initServiceCatalogs = sinon.stub().rejects(new Error('auth failed'));
247
- services.logger.error = sinon.stub();
248
- services.trigger = sinon.stub();
249
- // Ensure no credentials so we go to the preauth path
250
- services.webex.credentials = {};
199
+ assert.isTrue(services.ready);
200
+ });
251
201
 
252
- services.initialize();
202
+ it('flips services.ready=true after init succeeds without credentials (preauth path)', async () => {
203
+ services.listenToOnce = sinon.stub();
204
+ services.collectPreauthCatalog = sinon.stub().returns(Promise.resolve());
253
205
 
254
- // Get the catalog after initialize creates it
255
- const testCatalog = services._getCatalog();
256
- testCatalog.status.postauth.ready = false;
206
+ services.initialize();
207
+ services.listenToOnce.getCall(0).args[2]();
208
+ services.listenToOnce.getCall(1).args[2]();
209
+ await waitForAsync();
257
210
 
258
- // call the onLoaded callback (preauth path)
259
- services.listenToOnce.getCall(1).args[2]();
260
- await waitForAsync();
211
+ assert.isTrue(services.ready);
212
+ });
261
213
 
262
- // Now set canAuthorize to true to simulate auth completing
263
- services.webex.canAuthorize = true;
214
+ it('flips services.ready=true even when initServiceCatalogs errors, so webex.ready can fire', async () => {
215
+ services.listenToOnce = sinon.stub();
216
+ services.initServiceCatalogs = sinon.stub().returns(Promise.reject(new Error('boom')));
217
+ services.webex.credentials = {
218
+ supertoken: {access_token: 'token'},
219
+ };
220
+ services.logger.error = sinon.stub();
264
221
 
265
- // call the change:canAuthorize callback (should be call 2)
266
- services.listenToOnce.getCall(2).args[2]();
267
- await waitForAsync();
222
+ services.initialize();
223
+ services.listenToOnce.getCall(0).args[2]();
224
+ services.listenToOnce.getCall(1).args[2]();
225
+ await waitForAsync();
268
226
 
269
- sinon.assert.calledWith(
270
- services.logger.error,
271
- 'services: failed to init service catalogs after auth, auth failed'
272
- );
273
- });
227
+ assert.isTrue(services.initFailed);
228
+ assert.isTrue(services.ready);
229
+ });
230
+
231
+ it('flips services.ready=true even when collectPreauthCatalog errors', async () => {
232
+ services.listenToOnce = sinon.stub();
233
+ services.collectPreauthCatalog = sinon.stub().returns(Promise.reject(new Error('boom')));
234
+ services.logger.error = sinon.stub();
235
+
236
+ services.initialize();
237
+ services.listenToOnce.getCall(0).args[2]();
238
+ services.listenToOnce.getCall(1).args[2]();
239
+ await waitForAsync();
240
+
241
+ assert.isTrue(services.initFailed);
242
+ assert.isTrue(services.ready);
243
+ });
244
+
245
+ it('flips services.ready=true when init times out', async () => {
246
+ const clock = sinon.useFakeTimers();
247
+ services.listenToOnce = sinon.stub();
248
+ services.initServiceCatalogs = sinon.stub().returns(new Promise(() => {}));
249
+ services.webex.credentials = {
250
+ supertoken: {access_token: 'token'},
251
+ };
252
+ services.logger.error = sinon.stub();
253
+
254
+ services.initialize();
255
+ services.listenToOnce.getCall(0).args[2]();
256
+ services.listenToOnce.getCall(1).args[2]();
257
+
258
+ await clock.tickAsync(15_001);
259
+ clock.restore();
260
+
261
+ assert.isTrue(services.initFailed);
262
+ assert.isTrue(services.ready);
263
+ sinon.assert.calledWithMatch(
264
+ services.logger.error,
265
+ /services: init timed out after 15000ms/
266
+ );
267
+ });
268
+
269
+ it('awaits an in-flight credentials refresh before flipping services.ready=true', async () => {
270
+ services.listenToOnce = sinon.stub();
271
+ services.initServiceCatalogs = sinon.stub().returns(Promise.resolve());
272
+
273
+ let onChangeIsRefreshing: (() => void) | undefined;
274
+ services.webex.credentials = {
275
+ supertoken: {access_token: 'token'},
276
+ isRefreshing: true,
277
+ once: sinon.stub().callsFake((event: string, cb: () => void) => {
278
+ if (event === 'change:isRefreshing') onChangeIsRefreshing = cb;
279
+ }),
280
+ };
281
+
282
+ services.initialize();
283
+ services.listenToOnce.getCall(0).args[2]();
284
+ services.listenToOnce.getCall(1).args[2]();
285
+ await waitForAsync();
286
+
287
+ assert.isFalse(services.ready, 'must not flip ready while refresh is in flight');
288
+ assert.isFunction(onChangeIsRefreshing, 'must subscribe to change:isRefreshing');
289
+ sinon.assert.calledWith(services.webex.credentials.once, 'change:isRefreshing');
290
+
291
+ onChangeIsRefreshing!();
292
+ await waitForAsync();
293
+
294
+ assert.isTrue(services.ready);
295
+ });
296
+
297
+ it('registers a change:canAuthorize listener when there is no supertoken (fresh-login path)', async () => {
298
+ services.listenToOnce = sinon.stub();
299
+ services.collectPreauthCatalog = sinon.stub().returns(Promise.resolve());
300
+ services.initServiceCatalogs = sinon.stub().returns(Promise.resolve());
301
+
302
+ services.initialize();
303
+ // initialize() creates a new catalog and replaces the WeakMap entry.
304
+ const currentCatalog = services._getCatalog();
305
+ services.listenToOnce.getCall(0).args[2]();
306
+ services.listenToOnce.getCall(1).args[2]();
307
+ await waitForAsync();
308
+
309
+ const freshLoginCall = services.listenToOnce
310
+ .getCalls()
311
+ .find((call: any) => call.args[1] === 'change:canAuthorize');
312
+ assert.isDefined(freshLoginCall, 'expected change:canAuthorize listener to be registered');
313
+
314
+ services.webex.canAuthorize = true;
315
+ currentCatalog.status.postauth.ready = false;
316
+ freshLoginCall!.args[2]();
317
+
318
+ assert.isTrue(
319
+ services.initServiceCatalogs.called,
320
+ 'expected postauth catalog init after canAuthorize flips'
321
+ );
322
+ });
323
+
324
+ it('does not re-init postauth catalog when canAuthorize fires but catalog is already ready', async () => {
325
+ services.listenToOnce = sinon.stub();
326
+ services.collectPreauthCatalog = sinon.stub().returns(Promise.resolve());
327
+ services.initServiceCatalogs = sinon.stub().returns(Promise.resolve());
328
+
329
+ services.initialize();
330
+ // initialize() creates a new catalog; grab the current one.
331
+ const currentCatalog = services._getCatalog();
332
+ services.listenToOnce.getCall(0).args[2]();
333
+ services.listenToOnce.getCall(1).args[2]();
334
+ await waitForAsync();
335
+
336
+ const freshLoginCall = services.listenToOnce
337
+ .getCalls()
338
+ .find((call: any) => call.args[1] === 'change:canAuthorize');
339
+
340
+ services.webex.canAuthorize = true;
341
+ currentCatalog.status.postauth.ready = true;
342
+ freshLoginCall!.args[2]();
343
+
344
+ assert.isFalse(
345
+ services.initServiceCatalogs.called,
346
+ 'must not re-fetch postauth catalog if it is already ready'
347
+ );
348
+ });
349
+
350
+ it('finalizes ready when cache is warm (skips network fetch)', async () => {
351
+ services.listenToOnce = sinon.stub();
352
+ services._loadCatalogFromCache = sinon.stub().returns(Promise.resolve(true));
353
+ services.initServiceCatalogs = sinon.stub().returns(Promise.resolve());
354
+ services.collectPreauthCatalog = sinon.stub().returns(Promise.resolve());
355
+
356
+ services.initialize();
357
+ services.listenToOnce.getCall(0).args[2]();
358
+ services.listenToOnce.getCall(1).args[2]();
359
+ await waitForAsync();
360
+ await waitForAsync();
361
+
362
+ assert.isTrue(services.ready);
363
+ assert.isFalse(
364
+ services.initServiceCatalogs.called,
365
+ 'must skip network fetch when cache is warm'
366
+ );
367
+ assert.isFalse(
368
+ services.collectPreauthCatalog.called,
369
+ 'must skip preauth fetch when cache is warm'
370
+ );
371
+ });
372
+ });
373
+
374
+ describe('#_finalizeReady', () => {
375
+ beforeEach(() => {
376
+ // Outer beforeEach construction already ran initialize() (ungated,
377
+ // sets ready=true). Reset so _finalizeReady's flip is observable.
378
+ services.ready = false;
379
+ });
380
+
381
+ it('sets ready=true immediately when credentials are not refreshing', async () => {
382
+ services.webex.credentials = {isRefreshing: false};
383
+ assert.isFalse(services.ready);
384
+
385
+ await services._finalizeReady();
386
+
387
+ assert.isTrue(services.ready);
388
+ });
389
+
390
+ it('sets ready=true when credentials are missing', async () => {
391
+ services.webex.credentials = undefined;
392
+
393
+ await services._finalizeReady();
394
+
395
+ assert.isTrue(services.ready);
396
+ });
397
+
398
+ it('awaits change:isRefreshing before setting ready=true', async () => {
399
+ let onChangeIsRefreshing: (() => void) | undefined;
400
+ services.webex.credentials = {
401
+ isRefreshing: true,
402
+ once: sinon.stub().callsFake((event: string, cb: () => void) => {
403
+ if (event === 'change:isRefreshing') onChangeIsRefreshing = cb;
404
+ }),
405
+ };
406
+
407
+ const settled = services._finalizeReady();
408
+ await waitForAsync();
409
+
410
+ assert.isFalse(services.ready, 'ready must not flip while refresh is in flight');
411
+ assert.isFunction(onChangeIsRefreshing);
412
+
413
+ onChangeIsRefreshing!();
414
+ await settled;
415
+
416
+ assert.isTrue(services.ready);
274
417
  });
275
418
  });
276
419
 
@@ -425,7 +568,7 @@ describe('webex-core', () => {
425
568
 
426
569
  services.initServiceCatalogs = sinon.stub().returns(Promise.resolve());
427
570
  services.webex.credentials = {
428
- getOrgId: sinon.stub().returns(''),
571
+ getOrgId: sinon.stub().returns('')
429
572
  };
430
573
  catalog.status = {};
431
574
  });
@@ -466,7 +609,7 @@ describe('webex-core', () => {
466
609
  const serviceGroup = 'postauth';
467
610
  const hostmap = {services: [{hostmap: 'hostmap'}]};
468
611
 
469
- services._formatReceivedHostmap = sinon.stub().returns({services: [{some: 'hostmap'}]});
612
+ services._formatReceivedHostmap = sinon.stub().returns({services : [{some: 'hostmap'}]});
470
613
 
471
614
  catalog.updateServiceGroups = sinon.stub().returns(Promise.resolve([{some: 'value'}]));
472
615
 
@@ -482,7 +625,7 @@ describe('webex-core', () => {
482
625
  const serviceGroup = 'postauth';
483
626
  const hostmap = {};
484
627
 
485
- services._formatReceivedHostmap = sinon.stub().returns({services: undefined});
628
+ services._formatReceivedHostmap = sinon.stub().returns({services : undefined});
486
629
 
487
630
  catalog.updateServiceGroups = sinon.stub().returns(Promise.resolve([{some: 'value'}]));
488
631
 
@@ -721,13 +864,13 @@ describe('webex-core', () => {
721
864
  });
722
865
 
723
866
  describe('#invalidateCache', () => {
724
- beforeEach(() => {
867
+ beforeEach( () => {
725
868
  services.initServiceCatalogs = sinon.stub().returns(Promise.resolve());
726
869
  services.webex.credentials = {
727
- getOrgId: sinon.stub().returns(''),
870
+ getOrgId: sinon.stub().returns('')
728
871
  };
729
872
  catalog.status = {};
730
- });
873
+ })
731
874
  it('should log the timestamp parameter', async () => {
732
875
  const timestamp = '1234567890';
733
876
  services.logger.info = sinon.stub();
@@ -735,11 +878,7 @@ describe('webex-core', () => {
735
878
 
736
879
  await services.invalidateCache(timestamp);
737
880
 
738
- assert.calledWith(
739
- services.logger.info,
740
- 'services: invalidate cache, timestamp:',
741
- timestamp
742
- );
881
+ assert.calledWith(services.logger.info, 'services: invalidate cache, timestamp:', timestamp);
743
882
  });
744
883
 
745
884
  it('should call initServiceCatalogs when invalidate timestamp is newer than catalog timestamp', async () => {
@@ -866,30 +1005,30 @@ describe('webex-core', () => {
866
1005
  // Arrange: seed internal _services with mobius (including duplicate baseUrl)
867
1006
  services._services = [
868
1007
  {
869
- id: 'urn:TEAM:us-east-2_a:mobius',
870
- serviceName: 'mobius',
871
- serviceUrls: [
872
- {baseUrl: 'https://mobius-us-east-2.prod.infra.webex.com/api/v1', priority: 5},
873
- {baseUrl: 'https://mobius-eu-central-1.prod.infra.webex.com/api/v1', priority: 10},
874
- {baseUrl: 'https://mobius-ap-southeast-2.prod.infra.webex.com/api/v1', priority: 15}, // duplicate
1008
+ "id": "urn:TEAM:us-east-2_a:mobius",
1009
+ "serviceName": 'mobius',
1010
+ "serviceUrls": [
1011
+ {"baseUrl": 'https://mobius-us-east-2.prod.infra.webex.com/api/v1', "priority": 5},
1012
+ {"baseUrl": 'https://mobius-eu-central-1.prod.infra.webex.com/api/v1', "priority": 10},
1013
+ {"baseUrl": 'https://mobius-ap-southeast-2.prod.infra.webex.com/api/v1', "priority": 15}, // duplicate
875
1014
  ],
876
1015
  },
877
1016
  {
878
- id: 'urn:TEAM:ap-southeast-2_m:mobius',
879
- serviceName: 'mobius',
880
- serviceUrls: [
881
- {
882
- baseUrl: 'https://mobius-me-central-1.prod.infra.webex.com/api/v1',
883
- priority: 5,
884
- },
885
- {
886
- baseUrl: 'https://mobius-eu-central-1.prod.infra.webex.com/api/v1',
887
- priority: 10,
888
- },
889
- {
890
- baseUrl: 'https://mobius-ap-southeast-2.prod.infra.webex.com/api/v1',
891
- priority: 15,
892
- },
1017
+ "id": "urn:TEAM:ap-southeast-2_m:mobius",
1018
+ "serviceName": "mobius",
1019
+ "serviceUrls": [
1020
+ {
1021
+ "baseUrl": "https://mobius-me-central-1.prod.infra.webex.com/api/v1",
1022
+ "priority": 5
1023
+ },
1024
+ {
1025
+ "baseUrl": "https://mobius-eu-central-1.prod.infra.webex.com/api/v1",
1026
+ "priority": 10
1027
+ },
1028
+ {
1029
+ "baseUrl": "https://mobius-ap-southeast-2.prod.infra.webex.com/api/v1",
1030
+ "priority": 15
1031
+ },
893
1032
  ],
894
1033
  },
895
1034
  // Non-mobius service should be ignored by getMobiusClusters
@@ -907,64 +1046,42 @@ describe('webex-core', () => {
907
1046
  assert.deepEqual(
908
1047
  clusters.map(({host, id, ttl, priority}) => ({host, id, ttl, priority})),
909
1048
  [
910
- {
911
- host: 'mobius-us-east-2.prod.infra.webex.com',
912
- id: 'urn:TEAM:us-east-2_a:mobius',
913
- ttl: 0,
914
- priority: 5,
915
- },
916
- {
917
- host: 'mobius-eu-central-1.prod.infra.webex.com',
918
- id: 'urn:TEAM:us-east-2_a:mobius',
919
- ttl: 0,
920
- priority: 10,
921
- },
922
- {
923
- host: 'mobius-ap-southeast-2.prod.infra.webex.com',
924
- id: 'urn:TEAM:us-east-2_a:mobius',
925
- ttl: 0,
926
- priority: 15,
927
- },
928
- {
929
- host: 'mobius-me-central-1.prod.infra.webex.com',
930
- id: 'urn:TEAM:ap-southeast-2_m:mobius',
931
- ttl: 0,
932
- priority: 5,
933
- },
1049
+ {host: 'mobius-us-east-2.prod.infra.webex.com', id: 'urn:TEAM:us-east-2_a:mobius', ttl: 0, priority: 5},
1050
+ {host: 'mobius-eu-central-1.prod.infra.webex.com', id: 'urn:TEAM:us-east-2_a:mobius', ttl: 0, priority: 10},
1051
+ {host: 'mobius-ap-southeast-2.prod.infra.webex.com', id: 'urn:TEAM:us-east-2_a:mobius', ttl: 0, priority: 15},
1052
+ {host: 'mobius-me-central-1.prod.infra.webex.com', id: 'urn:TEAM:ap-southeast-2_m:mobius', ttl: 0, priority: 5},
934
1053
  ]
935
1054
  );
936
1055
  });
937
1056
  });
938
-
1057
+
939
1058
  describe('#isValidHost', () => {
940
1059
  beforeEach(() => {
941
1060
  // Setting up a mock services list
942
- services._services = [
943
- {
944
- id: 'urn:IDENTITY:PC75:adminAudit',
945
- serviceName: 'adminAudit',
946
- serviceUrls: [
947
- {
948
- baseUrl: 'https://audit-ci-r.wbx2.com/audit-ci/api/v2',
949
- priority: 5,
950
- },
951
- {
952
- baseUrl: 'https://audit-ci-t.wbx2.com/audit-ci/api/v2',
953
- priority: 10,
954
- },
955
- ],
956
- },
957
- {
958
- id: 'urn:IDENTITY:PC75:cdf',
959
- serviceName: 'cdf',
960
- serviceUrls: [
961
- {
962
- baseUrl: 'https://wapdavis.webex.com/davis/api/v1',
963
- priority: 5,
964
- },
965
- ],
966
- },
967
- ];
1061
+ services._services = [{
1062
+ "id": "urn:IDENTITY:PC75:adminAudit",
1063
+ "serviceName": "adminAudit",
1064
+ "serviceUrls": [
1065
+ {
1066
+ "baseUrl": "https://audit-ci-r.wbx2.com/audit-ci/api/v2",
1067
+ "priority": 5
1068
+ },
1069
+ {
1070
+ "baseUrl": "https://audit-ci-t.wbx2.com/audit-ci/api/v2",
1071
+ "priority": 10
1072
+ }
1073
+ ]
1074
+ },
1075
+ {
1076
+ "id": "urn:IDENTITY:PC75:cdf",
1077
+ "serviceName": "cdf",
1078
+ "serviceUrls": [
1079
+ {
1080
+ "baseUrl": "https://wapdavis.webex.com/davis/api/v1",
1081
+ "priority": 5
1082
+ }
1083
+ ]
1084
+ }];
968
1085
  });
969
1086
  afterAll(() => {
970
1087
  // Clean up the mock services list