@webex/webex-core 2.59.2 → 2.59.3-next.1

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.
Files changed (189) hide show
  1. package/.eslintrc.js +6 -6
  2. package/README.md +79 -79
  3. package/babel.config.js +3 -3
  4. package/dist/config.js +24 -24
  5. package/dist/config.js.map +1 -1
  6. package/dist/credentials-config.js +56 -56
  7. package/dist/credentials-config.js.map +1 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/interceptors/auth.js +28 -28
  10. package/dist/interceptors/auth.js.map +1 -1
  11. package/dist/interceptors/default-options.js +24 -24
  12. package/dist/interceptors/default-options.js.map +1 -1
  13. package/dist/interceptors/embargo.js +9 -9
  14. package/dist/interceptors/embargo.js.map +1 -1
  15. package/dist/interceptors/network-timing.js +19 -19
  16. package/dist/interceptors/network-timing.js.map +1 -1
  17. package/dist/interceptors/payload-transformer.js +19 -19
  18. package/dist/interceptors/payload-transformer.js.map +1 -1
  19. package/dist/interceptors/rate-limit.js +40 -40
  20. package/dist/interceptors/rate-limit.js.map +1 -1
  21. package/dist/interceptors/redirect.js +13 -13
  22. package/dist/interceptors/redirect.js.map +1 -1
  23. package/dist/interceptors/request-event.js +23 -23
  24. package/dist/interceptors/request-event.js.map +1 -1
  25. package/dist/interceptors/request-logger.js +13 -13
  26. package/dist/interceptors/request-logger.js.map +1 -1
  27. package/dist/interceptors/request-timing.js +23 -23
  28. package/dist/interceptors/request-timing.js.map +1 -1
  29. package/dist/interceptors/response-logger.js +19 -19
  30. package/dist/interceptors/response-logger.js.map +1 -1
  31. package/dist/interceptors/user-agent.js +29 -29
  32. package/dist/interceptors/user-agent.js.map +1 -1
  33. package/dist/interceptors/webex-tracking-id.js +15 -15
  34. package/dist/interceptors/webex-tracking-id.js.map +1 -1
  35. package/dist/interceptors/webex-user-agent.js +13 -13
  36. package/dist/interceptors/webex-user-agent.js.map +1 -1
  37. package/dist/lib/batcher.js +83 -83
  38. package/dist/lib/batcher.js.map +1 -1
  39. package/dist/lib/credentials/credentials.js +103 -103
  40. package/dist/lib/credentials/credentials.js.map +1 -1
  41. package/dist/lib/credentials/grant-errors.js +17 -17
  42. package/dist/lib/credentials/grant-errors.js.map +1 -1
  43. package/dist/lib/credentials/index.js +2 -2
  44. package/dist/lib/credentials/index.js.map +1 -1
  45. package/dist/lib/credentials/scope.js +11 -11
  46. package/dist/lib/credentials/scope.js.map +1 -1
  47. package/dist/lib/credentials/token-collection.js +2 -2
  48. package/dist/lib/credentials/token-collection.js.map +1 -1
  49. package/dist/lib/credentials/token.js +145 -145
  50. package/dist/lib/credentials/token.js.map +1 -1
  51. package/dist/lib/page.js +49 -49
  52. package/dist/lib/page.js.map +1 -1
  53. package/dist/lib/services/constants.js.map +1 -1
  54. package/dist/lib/services/index.js +2 -2
  55. package/dist/lib/services/index.js.map +1 -1
  56. package/dist/lib/services/interceptors/server-error.js +9 -9
  57. package/dist/lib/services/interceptors/server-error.js.map +1 -1
  58. package/dist/lib/services/interceptors/service.js +24 -24
  59. package/dist/lib/services/interceptors/service.js.map +1 -1
  60. package/dist/lib/services/metrics.js.map +1 -1
  61. package/dist/lib/services/service-catalog.js +104 -104
  62. package/dist/lib/services/service-catalog.js.map +1 -1
  63. package/dist/lib/services/service-fed-ramp.js.map +1 -1
  64. package/dist/lib/services/service-host.js +134 -134
  65. package/dist/lib/services/service-host.js.map +1 -1
  66. package/dist/lib/services/service-registry.js +175 -175
  67. package/dist/lib/services/service-registry.js.map +1 -1
  68. package/dist/lib/services/service-state.js +38 -38
  69. package/dist/lib/services/service-state.js.map +1 -1
  70. package/dist/lib/services/service-url.js +31 -31
  71. package/dist/lib/services/service-url.js.map +1 -1
  72. package/dist/lib/services/services.js +245 -245
  73. package/dist/lib/services/services.js.map +1 -1
  74. package/dist/lib/stateless-webex-plugin.js +28 -28
  75. package/dist/lib/stateless-webex-plugin.js.map +1 -1
  76. package/dist/lib/storage/decorators.js +27 -27
  77. package/dist/lib/storage/decorators.js.map +1 -1
  78. package/dist/lib/storage/errors.js +4 -4
  79. package/dist/lib/storage/errors.js.map +1 -1
  80. package/dist/lib/storage/index.js.map +1 -1
  81. package/dist/lib/storage/make-webex-plugin-store.js +44 -44
  82. package/dist/lib/storage/make-webex-plugin-store.js.map +1 -1
  83. package/dist/lib/storage/make-webex-store.js +40 -40
  84. package/dist/lib/storage/make-webex-store.js.map +1 -1
  85. package/dist/lib/storage/memory-store-adapter.js +9 -9
  86. package/dist/lib/storage/memory-store-adapter.js.map +1 -1
  87. package/dist/lib/webex-core-plugin-mixin.js +13 -13
  88. package/dist/lib/webex-core-plugin-mixin.js.map +1 -1
  89. package/dist/lib/webex-http-error.js +9 -9
  90. package/dist/lib/webex-http-error.js.map +1 -1
  91. package/dist/lib/webex-internal-core-plugin-mixin.js +13 -13
  92. package/dist/lib/webex-internal-core-plugin-mixin.js.map +1 -1
  93. package/dist/lib/webex-plugin.js +36 -36
  94. package/dist/lib/webex-plugin.js.map +1 -1
  95. package/dist/plugins/logger.js +9 -9
  96. package/dist/plugins/logger.js.map +1 -1
  97. package/dist/webex-core.js +104 -104
  98. package/dist/webex-core.js.map +1 -1
  99. package/dist/webex-internal-core.js +12 -12
  100. package/dist/webex-internal-core.js.map +1 -1
  101. package/jest.config.js +3 -3
  102. package/package.json +20 -19
  103. package/process +1 -1
  104. package/src/config.js +90 -90
  105. package/src/credentials-config.js +212 -212
  106. package/src/index.js +62 -62
  107. package/src/interceptors/auth.js +186 -186
  108. package/src/interceptors/default-options.js +55 -55
  109. package/src/interceptors/embargo.js +43 -43
  110. package/src/interceptors/network-timing.js +54 -54
  111. package/src/interceptors/payload-transformer.js +55 -55
  112. package/src/interceptors/rate-limit.js +169 -169
  113. package/src/interceptors/redirect.js +106 -106
  114. package/src/interceptors/request-event.js +93 -93
  115. package/src/interceptors/request-logger.js +78 -78
  116. package/src/interceptors/request-timing.js +65 -65
  117. package/src/interceptors/response-logger.js +98 -98
  118. package/src/interceptors/user-agent.js +77 -77
  119. package/src/interceptors/webex-tracking-id.js +73 -73
  120. package/src/interceptors/webex-user-agent.js +79 -79
  121. package/src/lib/batcher.js +307 -307
  122. package/src/lib/credentials/credentials.js +552 -552
  123. package/src/lib/credentials/grant-errors.js +92 -92
  124. package/src/lib/credentials/index.js +16 -16
  125. package/src/lib/credentials/scope.js +34 -34
  126. package/src/lib/credentials/token-collection.js +17 -17
  127. package/src/lib/credentials/token.js +559 -559
  128. package/src/lib/page.js +159 -159
  129. package/src/lib/services/constants.js +9 -9
  130. package/src/lib/services/index.js +26 -26
  131. package/src/lib/services/interceptors/server-error.js +48 -48
  132. package/src/lib/services/interceptors/service.js +101 -101
  133. package/src/lib/services/metrics.js +4 -4
  134. package/src/lib/services/service-catalog.js +435 -435
  135. package/src/lib/services/service-fed-ramp.js +4 -4
  136. package/src/lib/services/service-host.js +267 -267
  137. package/src/lib/services/service-registry.js +465 -465
  138. package/src/lib/services/service-state.js +78 -78
  139. package/src/lib/services/service-url.js +124 -124
  140. package/src/lib/services/services.js +1018 -1018
  141. package/src/lib/stateless-webex-plugin.js +98 -98
  142. package/src/lib/storage/decorators.js +220 -220
  143. package/src/lib/storage/errors.js +15 -15
  144. package/src/lib/storage/index.js +10 -10
  145. package/src/lib/storage/make-webex-plugin-store.js +211 -211
  146. package/src/lib/storage/make-webex-store.js +140 -140
  147. package/src/lib/storage/memory-store-adapter.js +79 -79
  148. package/src/lib/webex-core-plugin-mixin.js +114 -114
  149. package/src/lib/webex-http-error.js +61 -61
  150. package/src/lib/webex-internal-core-plugin-mixin.js +107 -107
  151. package/src/lib/webex-plugin.js +222 -222
  152. package/src/plugins/logger.js +60 -60
  153. package/src/webex-core.js +745 -745
  154. package/src/webex-internal-core.js +46 -46
  155. package/test/integration/spec/credentials/credentials.js +139 -139
  156. package/test/integration/spec/credentials/token.js +102 -102
  157. package/test/integration/spec/services/service-catalog.js +838 -838
  158. package/test/integration/spec/services/services.js +1221 -1221
  159. package/test/integration/spec/webex-core.js +178 -178
  160. package/test/unit/spec/_setup.js +44 -44
  161. package/test/unit/spec/credentials/credentials.js +1017 -1017
  162. package/test/unit/spec/credentials/token.js +441 -441
  163. package/test/unit/spec/interceptors/auth.js +521 -521
  164. package/test/unit/spec/interceptors/default-options.js +84 -84
  165. package/test/unit/spec/interceptors/embargo.js +144 -144
  166. package/test/unit/spec/interceptors/network-timing.js +49 -49
  167. package/test/unit/spec/interceptors/payload-transformer.js +155 -155
  168. package/test/unit/spec/interceptors/rate-limit.js +302 -302
  169. package/test/unit/spec/interceptors/redirect.js +102 -102
  170. package/test/unit/spec/interceptors/request-timing.js +92 -92
  171. package/test/unit/spec/interceptors/user-agent.js +76 -76
  172. package/test/unit/spec/interceptors/webex-tracking-id.js +76 -76
  173. package/test/unit/spec/interceptors/webex-user-agent.js +159 -159
  174. package/test/unit/spec/lib/batcher.js +330 -330
  175. package/test/unit/spec/lib/page.js +148 -148
  176. package/test/unit/spec/lib/webex-plugin.js +48 -48
  177. package/test/unit/spec/services/interceptors/server-error.js +204 -204
  178. package/test/unit/spec/services/interceptors/service.js +188 -188
  179. package/test/unit/spec/services/service-catalog.js +194 -194
  180. package/test/unit/spec/services/service-host.js +260 -260
  181. package/test/unit/spec/services/service-registry.js +747 -747
  182. package/test/unit/spec/services/service-state.js +60 -60
  183. package/test/unit/spec/services/service-url.js +258 -258
  184. package/test/unit/spec/services/services.js +348 -348
  185. package/test/unit/spec/storage/persist.js +50 -50
  186. package/test/unit/spec/storage/storage-adapter.js +12 -12
  187. package/test/unit/spec/storage/wait-for-value.js +81 -81
  188. package/test/unit/spec/webex-core.js +253 -253
  189. package/test/unit/spec/webex-internal-core.js +91 -91
@@ -1,838 +1,838 @@
1
- /*!
2
- * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
- */
4
-
5
- import '@webex/internal-plugin-device';
6
-
7
- import {assert} from '@webex/test-helper-chai';
8
- import sinon from 'sinon';
9
- import WebexCore, {ServiceUrl} from '@webex/webex-core';
10
- import testUsers from '@webex/test-helper-test-users';
11
-
12
- /* eslint-disable no-underscore-dangle */
13
- describe('webex-core', () => {
14
- describe('ServiceCatalog', () => {
15
- let webexUser;
16
- let webex;
17
- let services;
18
- let catalog;
19
-
20
- before('create users', () =>
21
- testUsers
22
- .create({count: 1})
23
- .then(
24
- ([user]) =>
25
- new Promise((resolve) => {
26
- setTimeout(() => {
27
- webexUser = user;
28
- webex = new WebexCore({credentials: user.token});
29
- services = webex.internal.services;
30
- catalog = services._getCatalog();
31
- resolve();
32
- }, 1000);
33
- })
34
- )
35
- .then(() => webex.internal.device.register())
36
- .then(() => services.waitForCatalog('postauth', 10))
37
- .then(() =>
38
- services.updateServices({
39
- from: 'limited',
40
- query: {userId: webexUser.id},
41
- })
42
- )
43
- );
44
-
45
- describe('#status()', () => {
46
- it('updates ready when services ready', () => {
47
- assert.equal(catalog.status.postauth.ready, true);
48
- });
49
- });
50
-
51
- describe('#_getUrl()', () => {
52
- let testUrlTemplate;
53
- let testUrl;
54
-
55
- beforeEach('load test url', () => {
56
- testUrlTemplate = {
57
- defaultUrl: 'https://www.example.com/api/v1',
58
- hosts: [],
59
- name: 'exampleValid',
60
- };
61
- testUrl = new ServiceUrl({...testUrlTemplate});
62
- catalog._loadServiceUrls('preauth', [testUrl]);
63
- });
64
-
65
- afterEach('unload test url', () => {
66
- catalog._unloadServiceUrls('preauth', [testUrl]);
67
- });
68
-
69
- it('returns a ServiceUrl from a specific serviceGroup', () => {
70
- const serviceUrl = catalog._getUrl(testUrlTemplate.name, 'preauth');
71
-
72
- assert.equal(serviceUrl.defaultUrl, testUrlTemplate.defaultUrl);
73
- assert.equal(serviceUrl.hosts, testUrlTemplate.hosts);
74
- assert.equal(serviceUrl.name, testUrlTemplate.name);
75
- });
76
-
77
- it("returns undefined if url doesn't exist", () => {
78
- const serviceUrl = catalog._getUrl('invalidUrl');
79
-
80
- assert.typeOf(serviceUrl, 'undefined');
81
- });
82
-
83
- it("returns undefined if url doesn't exist in serviceGroup", () => {
84
- const serviceUrl = catalog._getUrl(testUrlTemplate.name, 'Discovery');
85
-
86
- assert.typeOf(serviceUrl, 'undefined');
87
- });
88
- });
89
-
90
- describe('#findClusterId()', () => {
91
- let testUrlTemplate;
92
- let testUrl;
93
-
94
- beforeEach('load test url', () => {
95
- testUrlTemplate = {
96
- defaultUrl: 'https://www.example.com/api/v1',
97
- hosts: [
98
- {
99
- host: 'www.example-p5.com',
100
- ttl: -1,
101
- priority: 5,
102
- homeCluster: false,
103
- id: '0:0:0:exampleClusterIdFind',
104
- },
105
- {
106
- host: 'www.example-p3.com',
107
- ttl: -1,
108
- priority: 3,
109
- homeCluster: true,
110
- id: '0:0:0:exampleClusterIdFind',
111
- },
112
- {
113
- host: 'www.example-p6.com',
114
- ttl: -1,
115
- priority: 6,
116
- homeCluster: true,
117
- id: '0:0:2:exampleClusterIdFind',
118
- },
119
- ],
120
- name: 'exampleClusterIdFind',
121
- };
122
- testUrl = new ServiceUrl({...testUrlTemplate});
123
- catalog._loadServiceUrls('preauth', [testUrl]);
124
- });
125
-
126
- afterEach('unload test url', () => {
127
- catalog._unloadServiceUrls('preauth', [testUrl]);
128
- });
129
-
130
- it('returns a home cluster clusterId when found with default url', () => {
131
- assert.equal(
132
- catalog.findClusterId(testUrlTemplate.defaultUrl),
133
- testUrlTemplate.hosts[1].id
134
- );
135
- });
136
-
137
- it('returns a clusterId when found with priority host url', () => {
138
- assert.equal(catalog.findClusterId(testUrl.get(true)), testUrlTemplate.hosts[0].id);
139
- });
140
-
141
- it('returns a clusterId when found with resource-appended url', () => {
142
- assert.equal(
143
- catalog.findClusterId(`${testUrl.get()}example/resource/value`),
144
- testUrlTemplate.hosts[0].id
145
- );
146
- });
147
-
148
- it("returns undefined when the url doesn't exist in catalog", () => {
149
- assert.isUndefined(catalog.findClusterId('http://not-a-known-url.com/'));
150
- });
151
-
152
- it("returns undefined when the string isn't a url", () => {
153
- assert.isUndefined(catalog.findClusterId('not a url'));
154
- });
155
- });
156
-
157
- describe('#findServiceFromClusterId()', () => {
158
- let testUrlTemplate;
159
- let testUrl;
160
-
161
- beforeEach('load test url', () => {
162
- testUrlTemplate = {
163
- defaultUrl: 'https://www.example.com/api/v1',
164
- hosts: [
165
- {
166
- homeCluster: true,
167
- host: 'www.example-p5.com',
168
- ttl: -1,
169
- priority: 5,
170
- id: '0:0:clusterA:example-test',
171
- },
172
- {
173
- host: 'www.example-p3.com',
174
- ttl: -1,
175
- priority: 3,
176
- id: '0:0:clusterB:example-test',
177
- },
178
- ],
179
- name: 'example-test',
180
- };
181
- testUrl = new ServiceUrl({...testUrlTemplate});
182
- catalog._loadServiceUrls('preauth', [testUrl]);
183
- });
184
-
185
- afterEach('unload test url', () => {
186
- catalog._unloadServiceUrls('preauth', [testUrl]);
187
- });
188
-
189
- it('finds a valid service url from only a clusterId', () => {
190
- const serviceFound = catalog.findServiceFromClusterId({
191
- clusterId: testUrlTemplate.hosts[0].id,
192
- priorityHost: false,
193
- });
194
-
195
- assert.equal(serviceFound.name, testUrl.name);
196
- assert.equal(serviceFound.url, testUrl.defaultUrl);
197
- });
198
-
199
- it('finds a valid priority service url', () => {
200
- const serviceFound = catalog.findServiceFromClusterId({
201
- clusterId: testUrlTemplate.hosts[0].id,
202
- priorityHost: true,
203
- });
204
-
205
- assert.equal(serviceFound.name, testUrl.name);
206
- assert.equal(serviceFound.url, catalog.get(testUrl.name, true));
207
- });
208
-
209
- it('finds a valid service when a service group is defined', () => {
210
- const serviceFound = catalog.findServiceFromClusterId({
211
- clusterId: testUrlTemplate.hosts[0].id,
212
- priorityHost: false,
213
- serviceGroup: 'preauth',
214
- });
215
-
216
- assert.equal(serviceFound.name, testUrl.name);
217
- assert.equal(serviceFound.url, testUrl.defaultUrl);
218
- });
219
-
220
- it("fails to find a valid service when it's not in a group", () => {
221
- assert.isUndefined(
222
- catalog.findServiceFromClusterId({
223
- clusterId: testUrlTemplate.hosts[0].id,
224
- serviceGroup: 'signin',
225
- })
226
- );
227
- });
228
-
229
- it("returns undefined when service doesn't exist", () => {
230
- assert.isUndefined(catalog.findServiceFromClusterId({clusterId: 'not a clusterId'}));
231
- });
232
-
233
- it('should return a remote cluster url with a remote clusterId', () => {
234
- const serviceFound = catalog.findServiceFromClusterId({
235
- clusterId: testUrlTemplate.hosts[1].id,
236
- });
237
-
238
- assert.equal(serviceFound.name, testUrl.name);
239
- assert.isTrue(serviceFound.url.includes(testUrlTemplate.hosts[1].host));
240
- });
241
- });
242
-
243
- describe('#findServiceUrlFromUrl()', () => {
244
- let testUrlTemplate;
245
- let testUrl;
246
-
247
- beforeEach('load test url', () => {
248
- testUrlTemplate = {
249
- defaultUrl: 'https://www.example.com/api/v1',
250
- hosts: [
251
- {
252
- homeCluster: true,
253
- host: 'www.example-p5.com',
254
- ttl: -1,
255
- priority: 5,
256
- id: 'exampleClusterId',
257
- },
258
- {
259
- host: 'www.example-p3.com',
260
- ttl: -1,
261
- priority: 3,
262
- id: 'exampleClusterId',
263
- },
264
- ],
265
- name: 'exampleValid',
266
- };
267
- testUrl = new ServiceUrl({...testUrlTemplate});
268
- catalog._loadServiceUrls('preauth', [testUrl]);
269
- });
270
-
271
- afterEach('unload test url', () => {
272
- catalog._unloadServiceUrls('preauth', [testUrl]);
273
- });
274
-
275
- it('finds a service if it exists', () => {
276
- assert.equal(catalog.findServiceUrlFromUrl(testUrlTemplate.defaultUrl), testUrl);
277
- });
278
-
279
- it('finds a service if its a priority host url', () => {
280
- assert.equal(catalog.findServiceUrlFromUrl(testUrl.get(true)).name, testUrl.name);
281
- });
282
-
283
- it("returns undefined if the url doesn't exist", () => {
284
- assert.isUndefined(catalog.findServiceUrlFromUrl('https://na.com/'));
285
- });
286
-
287
- it('returns undefined if the param is not a url', () => {
288
- assert.isUndefined(catalog.findServiceUrlFromUrl('not a url'));
289
- });
290
- });
291
-
292
- describe('#list()', () => {
293
- it('retreives priority host urls base on priorityHost parameter', () => {
294
- const serviceList = catalog.list(true);
295
-
296
- const foundPriorityValues = catalog.serviceGroups.postauth.some((serviceUrl) =>
297
- serviceUrl.hosts.some(({host}) =>
298
- Object.keys(serviceList).some((key) => serviceList[key].includes(host))
299
- )
300
- );
301
-
302
- assert.isTrue(foundPriorityValues);
303
- });
304
-
305
- it('returns an object of based on serviceGroup parameter', () => {
306
- let serviceList = catalog.list(true, 'discovery');
307
-
308
- assert.equal(Object.keys(serviceList).length, catalog.serviceGroups.discovery.length);
309
-
310
- serviceList = catalog.list(true, 'preauth');
311
-
312
- assert.equal(Object.keys(serviceList).length, catalog.serviceGroups.preauth.length);
313
-
314
- serviceList = catalog.list(true, 'postauth');
315
-
316
- assert.isAtLeast(Object.keys(serviceList).length, catalog.serviceGroups.postauth.length);
317
- });
318
-
319
- it('matches the values in serviceUrl', () => {
320
- let serviceList = catalog.list();
321
-
322
- Object.keys(serviceList).forEach((key) => {
323
- assert.equal(serviceList[key], catalog._getUrl(key).get());
324
- });
325
-
326
- serviceList = catalog.list(true, 'postauth');
327
-
328
- Object.keys(serviceList).forEach((key) => {
329
- assert.equal(serviceList[key], catalog._getUrl(key, 'postauth').get(true));
330
- });
331
- });
332
- });
333
-
334
- describe('#get()', () => {
335
- let testUrlTemplate;
336
- let testUrl;
337
-
338
- beforeEach('load test url', () => {
339
- testUrlTemplate = {
340
- defaultUrl: 'https://www.example.com/api/v1',
341
- hosts: [],
342
- name: 'exampleValid',
343
- };
344
- testUrl = new ServiceUrl({...testUrlTemplate});
345
- catalog._loadServiceUrls('preauth', [testUrl]);
346
- });
347
-
348
- afterEach('unload test url', () => {
349
- catalog._unloadServiceUrls('preauth', [testUrl]);
350
- });
351
-
352
- it('returns a valid string when name is specified', () => {
353
- const url = catalog.get(testUrlTemplate.name);
354
-
355
- assert.typeOf(url, 'string');
356
- assert.equal(url, testUrlTemplate.defaultUrl);
357
- });
358
-
359
- it("returns undefined if url doesn't exist", () => {
360
- const s = catalog.get('invalidUrl');
361
-
362
- assert.typeOf(s, 'undefined');
363
- });
364
-
365
- it('calls _getUrl', () => {
366
- sinon.spy(catalog, '_getUrl');
367
-
368
- catalog.get();
369
-
370
- assert.called(catalog._getUrl);
371
- });
372
-
373
- it('gets a service from a specific serviceGroup', () => {
374
- assert.isDefined(catalog.get(testUrlTemplate.name, false, 'preauth'));
375
- });
376
-
377
- it("fails to get a service if serviceGroup isn't accurate", () => {
378
- assert.isUndefined(catalog.get(testUrlTemplate.name, false, 'discovery'));
379
- });
380
- });
381
-
382
- describe('#markFailedUrl()', () => {
383
- let testUrlTemplate;
384
- let testUrl;
385
-
386
- beforeEach('load test url', () => {
387
- testUrlTemplate = {
388
- defaultUrl: 'https://www.example.com/api/v1',
389
- hosts: [
390
- {
391
- host: 'www.example-p5.com',
392
- ttl: -1,
393
- priority: 5,
394
- id: '0:0:0:exampleValid',
395
- homeCluster: true,
396
- },
397
- {
398
- host: 'www.example-p3.com',
399
- ttl: -1,
400
- priority: 3,
401
- id: '0:0:0:exampleValid',
402
- homeCluster: true,
403
- },
404
- ],
405
- name: 'exampleValid',
406
- };
407
- testUrl = new ServiceUrl({...testUrlTemplate});
408
- catalog._loadServiceUrls('preauth', [testUrl]);
409
- });
410
-
411
- afterEach('unload test url', () => {
412
- catalog._unloadServiceUrls('preauth', [testUrl]);
413
- });
414
-
415
- it('marks a host as failed', () => {
416
- const priorityUrl = catalog.get(testUrlTemplate.name, true);
417
-
418
- catalog.markFailedUrl(priorityUrl);
419
-
420
- const failedHost = testUrl.hosts.find((host) => host.failed);
421
-
422
- assert.isDefined(failedHost);
423
- });
424
-
425
- it('returns the next priority url', () => {
426
- const priorityUrl = catalog.get(testUrlTemplate.name, true);
427
- const nextPriorityUrl = catalog.markFailedUrl(priorityUrl);
428
-
429
- assert.notEqual(priorityUrl, nextPriorityUrl);
430
- });
431
- });
432
-
433
- describe('#_loadServiceUrls()', () => {
434
- let testUrlTemplate;
435
- let testUrl;
436
-
437
- beforeEach('init test url', () => {
438
- testUrlTemplate = {
439
- defaultUrl: 'https://www.example.com/api/v1',
440
- hosts: [],
441
- name: 'exampleValid',
442
- };
443
- testUrl = new ServiceUrl({...testUrlTemplate});
444
- });
445
-
446
- it('appends services to different service groups', () => {
447
- catalog._loadServiceUrls('postauth', [testUrl]);
448
- catalog._loadServiceUrls('preauth', [testUrl]);
449
- catalog._loadServiceUrls('discovery', [testUrl]);
450
-
451
- catalog.serviceGroups.postauth.includes(testUrl);
452
- catalog.serviceGroups.preauth.includes(testUrl);
453
- catalog.serviceGroups.discovery.includes(testUrl);
454
-
455
- catalog._unloadServiceUrls('postauth', [testUrl]);
456
- catalog._unloadServiceUrls('preauth', [testUrl]);
457
- catalog._unloadServiceUrls('discovery', [testUrl]);
458
- });
459
- });
460
-
461
- describe('#_unloadServiceUrls()', () => {
462
- let testUrlTemplate;
463
- let testUrl;
464
-
465
- beforeEach('init test url', () => {
466
- testUrlTemplate = {
467
- defaultUrl: 'https://www.example.com/api/v1',
468
- hosts: [],
469
- name: 'exampleValid',
470
- };
471
- testUrl = new ServiceUrl({...testUrlTemplate});
472
- });
473
-
474
- it('appends services to different service groups', () => {
475
- catalog._loadServiceUrls('postauth', [testUrl]);
476
- catalog._loadServiceUrls('preauth', [testUrl]);
477
- catalog._loadServiceUrls('discovery', [testUrl]);
478
-
479
- const oBaseLength = catalog.serviceGroups.postauth.length;
480
- const oLimitedLength = catalog.serviceGroups.preauth.length;
481
- const oDiscoveryLength = catalog.serviceGroups.discovery.length;
482
-
483
- catalog._unloadServiceUrls('postauth', [testUrl]);
484
- catalog._unloadServiceUrls('preauth', [testUrl]);
485
- catalog._unloadServiceUrls('discovery', [testUrl]);
486
-
487
- assert.isAbove(oBaseLength, catalog.serviceGroups.postauth.length);
488
- assert.isAbove(oLimitedLength, catalog.serviceGroups.preauth.length);
489
- assert.isAbove(oDiscoveryLength, catalog.serviceGroups.discovery.length);
490
- });
491
- });
492
-
493
- describe('#_fetchNewServiceHostmap()', () => {
494
- let fullRemoteHM;
495
- let limitedRemoteHM;
496
-
497
- beforeEach(() =>
498
- Promise.all([
499
- services._fetchNewServiceHostmap(),
500
- services._fetchNewServiceHostmap({
501
- from: 'limited',
502
- query: {userId: webexUser.id},
503
- }),
504
- ]).then(([fRHM, lRHM]) => {
505
- fullRemoteHM = fRHM;
506
- limitedRemoteHM = lRHM;
507
-
508
- return Promise.resolve();
509
- })
510
- );
511
-
512
- it('resolves to an authed u2c hostmap when no params specified', () => {
513
- assert.typeOf(fullRemoteHM, 'array');
514
- assert.isAbove(fullRemoteHM.length, 0);
515
- });
516
-
517
- it('resolves to a limited u2c hostmap when params specified', () => {
518
- assert.typeOf(limitedRemoteHM, 'array');
519
- assert.isAbove(limitedRemoteHM.length, 0);
520
- });
521
-
522
- it('rejects if the params provided are invalid', () =>
523
- services
524
- ._fetchNewServiceHostmap({
525
- from: 'limited',
526
- query: {userId: 'notValid'},
527
- })
528
- .then(() => {
529
- assert.isTrue(false, 'should have rejected');
530
-
531
- return Promise.reject();
532
- })
533
- .catch((e) => {
534
- assert.typeOf(e, 'Error');
535
-
536
- return Promise.resolve();
537
- }));
538
- });
539
-
540
- describe('#waitForCatalog()', () => {
541
- let promise;
542
- let serviceHostmap;
543
- let formattedHM;
544
-
545
- beforeEach(() => {
546
- serviceHostmap = {
547
- serviceLinks: {
548
- 'example-a': 'https://example-a.com/api/v1',
549
- 'example-b': 'https://example-b.com/api/v1',
550
- 'example-c': 'https://example-c.com/api/v1',
551
- },
552
- hostCatalog: {
553
- 'example-a.com': [
554
- {
555
- host: 'example-a-1.com',
556
- ttl: -1,
557
- priority: 5,
558
- id: '0:0:0:example-a',
559
- },
560
- {
561
- host: 'example-a-2.com',
562
- ttl: -1,
563
- priority: 3,
564
- id: '0:0:0:example-a',
565
- },
566
- {
567
- host: 'example-a-3.com',
568
- ttl: -1,
569
- priority: 1,
570
- id: '0:0:0:example-a',
571
- },
572
- ],
573
- 'example-b.com': [
574
- {
575
- host: 'example-b-1.com',
576
- ttl: -1,
577
- priority: 5,
578
- id: '0:0:0:example-b',
579
- },
580
- {
581
- host: 'example-b-2.com',
582
- ttl: -1,
583
- priority: 3,
584
- id: '0:0:0:example-b',
585
- },
586
- {
587
- host: 'example-b-3.com',
588
- ttl: -1,
589
- priority: 1,
590
- id: '0:0:0:example-b',
591
- },
592
- ],
593
- 'example-c.com': [
594
- {
595
- host: 'example-c-1.com',
596
- ttl: -1,
597
- priority: 5,
598
- id: '0:0:0:example-c',
599
- },
600
- {
601
- host: 'example-c-2.com',
602
- ttl: -1,
603
- priority: 3,
604
- id: '0:0:0:example-c',
605
- },
606
- {
607
- host: 'example-c-3.com',
608
- ttl: -1,
609
- priority: 1,
610
- id: '0:0:0:example-c',
611
- },
612
- ],
613
- },
614
- format: 'hostmap',
615
- };
616
- formattedHM = services._formatReceivedHostmap(serviceHostmap);
617
-
618
- promise = catalog.waitForCatalog('preauth', 1);
619
- });
620
-
621
- it('returns a promise', () => {
622
- assert.typeOf(promise, 'promise');
623
- });
624
-
625
- it('returns a rejected promise if timeout is reached', () =>
626
- promise.catch(() => {
627
- assert(true, 'promise rejected');
628
-
629
- return Promise.resolve();
630
- }));
631
-
632
- it('returns a resolved promise once ready', () => {
633
- catalog.waitForCatalog('postauth', 1).then(() => {
634
- assert(true, 'promise resolved');
635
- });
636
-
637
- catalog.updateServiceUrls('postauth', formattedHM);
638
- });
639
- });
640
-
641
- describe('#updateServiceUrls()', () => {
642
- let serviceHostmap;
643
- let formattedHM;
644
-
645
- beforeEach(() => {
646
- serviceHostmap = {
647
- serviceLinks: {
648
- 'example-a': 'https://example-a.com/api/v1',
649
- 'example-b': 'https://example-b.com/api/v1',
650
- 'example-c': 'https://example-c.com/api/v1',
651
- },
652
- hostCatalog: {
653
- 'example-a.com': [
654
- {
655
- host: 'example-a-1.com',
656
- ttl: -1,
657
- priority: 5,
658
- id: '0:0:0:example-a',
659
- },
660
- {
661
- host: 'example-a-2.com',
662
- ttl: -1,
663
- priority: 3,
664
- id: '0:0:0:example-a',
665
- },
666
- {
667
- host: 'example-a-3.com',
668
- ttl: -1,
669
- priority: 1,
670
- id: '0:0:0:example-a',
671
- },
672
- ],
673
- 'example-b.com': [
674
- {
675
- host: 'example-b-1.com',
676
- ttl: -1,
677
- priority: 5,
678
- id: '0:0:0:example-b',
679
- },
680
- {
681
- host: 'example-b-2.com',
682
- ttl: -1,
683
- priority: 3,
684
- id: '0:0:0:example-b',
685
- },
686
- {
687
- host: 'example-b-3.com',
688
- ttl: -1,
689
- priority: 1,
690
- id: '0:0:0:example-b',
691
- },
692
- ],
693
- 'example-c.com': [
694
- {
695
- host: 'example-c-1.com',
696
- ttl: -1,
697
- priority: 5,
698
- id: '0:0:0:example-c',
699
- },
700
- {
701
- host: 'example-c-2.com',
702
- ttl: -1,
703
- priority: 3,
704
- id: '0:0:0:example-c',
705
- },
706
- {
707
- host: 'example-c-3.com',
708
- ttl: -1,
709
- priority: 1,
710
- id: '0:0:0:example-c',
711
- },
712
- ],
713
- },
714
- format: 'hostmap',
715
- };
716
- formattedHM = services._formatReceivedHostmap(serviceHostmap);
717
- });
718
-
719
- it('removes any unused urls from current services', () => {
720
- catalog.updateServiceUrls('preauth', formattedHM);
721
-
722
- const originalLength = catalog.serviceGroups.preauth.length;
723
-
724
- catalog.updateServiceUrls('preauth', []);
725
-
726
- assert.isBelow(catalog.serviceGroups.preauth.length, originalLength);
727
- });
728
-
729
- it('updates the target catalog to contain the provided hosts', () => {
730
- catalog.updateServiceUrls('preauth', formattedHM);
731
-
732
- assert.equal(catalog.serviceGroups.preauth.length, formattedHM.length);
733
- });
734
-
735
- it('updates any existing ServiceUrls', () => {
736
- const newServiceHM = {
737
- serviceLinks: {
738
- 'example-a': 'https://e-a.com/api/v1',
739
- 'example-b': 'https://e-b.com/api/v1',
740
- 'example-c': 'https://e-c.com/api/v1',
741
- },
742
- hostCatalog: {
743
- 'e-a.com': [],
744
- 'e-b.com': [],
745
- 'e-c.com': [],
746
- },
747
- };
748
-
749
- const newFormattedHM = services._formatReceivedHostmap(newServiceHM);
750
-
751
- catalog.updateServiceUrls('preauth', formattedHM);
752
-
753
- const oServicesB = catalog.list(false, 'preauth');
754
- const oServicesH = catalog.list(true, 'preauth');
755
-
756
- catalog.updateServiceUrls('preauth', newFormattedHM);
757
-
758
- const nServicesB = catalog.list(false, 'preauth');
759
- const nServicesH = catalog.list(true, 'preauth');
760
-
761
- Object.keys(nServicesB).forEach((key) => {
762
- assert.notEqual(nServicesB[key], oServicesB[key]);
763
- });
764
-
765
- Object.keys(nServicesH).forEach((key) => {
766
- assert.notEqual(nServicesH[key], oServicesH[key]);
767
- });
768
- });
769
-
770
- it('creates an array of equal length of serviceLinks', () => {
771
- assert.equal(Object.keys(serviceHostmap.serviceLinks).length, formattedHM.length);
772
- });
773
-
774
- it('creates an array of equal length of hostMap', () => {
775
- assert.equal(Object.keys(serviceHostmap.hostCatalog).length, formattedHM.length);
776
- });
777
-
778
- it('creates an array with matching url data', () => {
779
- formattedHM.forEach((entry) => {
780
- assert.equal(serviceHostmap.serviceLinks[entry.name], entry.defaultUrl);
781
- });
782
- });
783
-
784
- it('creates an array with matching host data', () => {
785
- Object.keys(serviceHostmap.hostCatalog).forEach((key) => {
786
- const hostGroup = serviceHostmap.hostCatalog[key];
787
-
788
- const foundMatch = hostGroup.every((inboundHost) =>
789
- formattedHM.find((formattedService) =>
790
- formattedService.hosts.find(
791
- (formattedHost) => formattedHost.host === inboundHost.host
792
- )
793
- )
794
- );
795
-
796
- assert.isTrue(
797
- foundMatch,
798
- `did not find matching host data for the \`${key}\` host group.`
799
- );
800
- });
801
- });
802
-
803
- it('creates an array with matching names', () => {
804
- assert.hasAllKeys(
805
- serviceHostmap.serviceLinks,
806
- formattedHM.map((item) => item.name)
807
- );
808
- });
809
-
810
- it('returns self', () => {
811
- const returnValue = catalog.updateServiceUrls('preauth', formattedHM);
812
-
813
- assert.equal(returnValue, catalog);
814
- });
815
-
816
- it('triggers authorization events', (done) => {
817
- catalog.once('preauth', () => {
818
- assert(true, 'triggered once');
819
- done();
820
- });
821
-
822
- catalog.updateServiceUrls('preauth', formattedHM);
823
- });
824
-
825
- it('updates the services list', (done) => {
826
- catalog.serviceGroups.preauth = [];
827
-
828
- catalog.once('preauth', () => {
829
- assert.isAbove(catalog.serviceGroups.preauth.length, 0);
830
- done();
831
- });
832
-
833
- catalog.updateServiceUrls('preauth', formattedHM);
834
- });
835
- });
836
- });
837
- });
838
- /* eslint-enable no-underscore-dangle */
1
+ /*!
2
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
+ */
4
+
5
+ import '@webex/internal-plugin-device';
6
+
7
+ import {assert} from '@webex/test-helper-chai';
8
+ import sinon from 'sinon';
9
+ import WebexCore, {ServiceUrl} from '@webex/webex-core';
10
+ import testUsers from '@webex/test-helper-test-users';
11
+
12
+ /* eslint-disable no-underscore-dangle */
13
+ describe('webex-core', () => {
14
+ describe('ServiceCatalog', () => {
15
+ let webexUser;
16
+ let webex;
17
+ let services;
18
+ let catalog;
19
+
20
+ before('create users', () =>
21
+ testUsers
22
+ .create({count: 1})
23
+ .then(
24
+ ([user]) =>
25
+ new Promise((resolve) => {
26
+ setTimeout(() => {
27
+ webexUser = user;
28
+ webex = new WebexCore({credentials: user.token});
29
+ services = webex.internal.services;
30
+ catalog = services._getCatalog();
31
+ resolve();
32
+ }, 1000);
33
+ })
34
+ )
35
+ .then(() => webex.internal.device.register())
36
+ .then(() => services.waitForCatalog('postauth', 10))
37
+ .then(() =>
38
+ services.updateServices({
39
+ from: 'limited',
40
+ query: {userId: webexUser.id},
41
+ })
42
+ )
43
+ );
44
+
45
+ describe('#status()', () => {
46
+ it('updates ready when services ready', () => {
47
+ assert.equal(catalog.status.postauth.ready, true);
48
+ });
49
+ });
50
+
51
+ describe('#_getUrl()', () => {
52
+ let testUrlTemplate;
53
+ let testUrl;
54
+
55
+ beforeEach('load test url', () => {
56
+ testUrlTemplate = {
57
+ defaultUrl: 'https://www.example.com/api/v1',
58
+ hosts: [],
59
+ name: 'exampleValid',
60
+ };
61
+ testUrl = new ServiceUrl({...testUrlTemplate});
62
+ catalog._loadServiceUrls('preauth', [testUrl]);
63
+ });
64
+
65
+ afterEach('unload test url', () => {
66
+ catalog._unloadServiceUrls('preauth', [testUrl]);
67
+ });
68
+
69
+ it('returns a ServiceUrl from a specific serviceGroup', () => {
70
+ const serviceUrl = catalog._getUrl(testUrlTemplate.name, 'preauth');
71
+
72
+ assert.equal(serviceUrl.defaultUrl, testUrlTemplate.defaultUrl);
73
+ assert.equal(serviceUrl.hosts, testUrlTemplate.hosts);
74
+ assert.equal(serviceUrl.name, testUrlTemplate.name);
75
+ });
76
+
77
+ it("returns undefined if url doesn't exist", () => {
78
+ const serviceUrl = catalog._getUrl('invalidUrl');
79
+
80
+ assert.typeOf(serviceUrl, 'undefined');
81
+ });
82
+
83
+ it("returns undefined if url doesn't exist in serviceGroup", () => {
84
+ const serviceUrl = catalog._getUrl(testUrlTemplate.name, 'Discovery');
85
+
86
+ assert.typeOf(serviceUrl, 'undefined');
87
+ });
88
+ });
89
+
90
+ describe('#findClusterId()', () => {
91
+ let testUrlTemplate;
92
+ let testUrl;
93
+
94
+ beforeEach('load test url', () => {
95
+ testUrlTemplate = {
96
+ defaultUrl: 'https://www.example.com/api/v1',
97
+ hosts: [
98
+ {
99
+ host: 'www.example-p5.com',
100
+ ttl: -1,
101
+ priority: 5,
102
+ homeCluster: false,
103
+ id: '0:0:0:exampleClusterIdFind',
104
+ },
105
+ {
106
+ host: 'www.example-p3.com',
107
+ ttl: -1,
108
+ priority: 3,
109
+ homeCluster: true,
110
+ id: '0:0:0:exampleClusterIdFind',
111
+ },
112
+ {
113
+ host: 'www.example-p6.com',
114
+ ttl: -1,
115
+ priority: 6,
116
+ homeCluster: true,
117
+ id: '0:0:2:exampleClusterIdFind',
118
+ },
119
+ ],
120
+ name: 'exampleClusterIdFind',
121
+ };
122
+ testUrl = new ServiceUrl({...testUrlTemplate});
123
+ catalog._loadServiceUrls('preauth', [testUrl]);
124
+ });
125
+
126
+ afterEach('unload test url', () => {
127
+ catalog._unloadServiceUrls('preauth', [testUrl]);
128
+ });
129
+
130
+ it('returns a home cluster clusterId when found with default url', () => {
131
+ assert.equal(
132
+ catalog.findClusterId(testUrlTemplate.defaultUrl),
133
+ testUrlTemplate.hosts[1].id
134
+ );
135
+ });
136
+
137
+ it('returns a clusterId when found with priority host url', () => {
138
+ assert.equal(catalog.findClusterId(testUrl.get(true)), testUrlTemplate.hosts[0].id);
139
+ });
140
+
141
+ it('returns a clusterId when found with resource-appended url', () => {
142
+ assert.equal(
143
+ catalog.findClusterId(`${testUrl.get()}example/resource/value`),
144
+ testUrlTemplate.hosts[0].id
145
+ );
146
+ });
147
+
148
+ it("returns undefined when the url doesn't exist in catalog", () => {
149
+ assert.isUndefined(catalog.findClusterId('http://not-a-known-url.com/'));
150
+ });
151
+
152
+ it("returns undefined when the string isn't a url", () => {
153
+ assert.isUndefined(catalog.findClusterId('not a url'));
154
+ });
155
+ });
156
+
157
+ describe('#findServiceFromClusterId()', () => {
158
+ let testUrlTemplate;
159
+ let testUrl;
160
+
161
+ beforeEach('load test url', () => {
162
+ testUrlTemplate = {
163
+ defaultUrl: 'https://www.example.com/api/v1',
164
+ hosts: [
165
+ {
166
+ homeCluster: true,
167
+ host: 'www.example-p5.com',
168
+ ttl: -1,
169
+ priority: 5,
170
+ id: '0:0:clusterA:example-test',
171
+ },
172
+ {
173
+ host: 'www.example-p3.com',
174
+ ttl: -1,
175
+ priority: 3,
176
+ id: '0:0:clusterB:example-test',
177
+ },
178
+ ],
179
+ name: 'example-test',
180
+ };
181
+ testUrl = new ServiceUrl({...testUrlTemplate});
182
+ catalog._loadServiceUrls('preauth', [testUrl]);
183
+ });
184
+
185
+ afterEach('unload test url', () => {
186
+ catalog._unloadServiceUrls('preauth', [testUrl]);
187
+ });
188
+
189
+ it('finds a valid service url from only a clusterId', () => {
190
+ const serviceFound = catalog.findServiceFromClusterId({
191
+ clusterId: testUrlTemplate.hosts[0].id,
192
+ priorityHost: false,
193
+ });
194
+
195
+ assert.equal(serviceFound.name, testUrl.name);
196
+ assert.equal(serviceFound.url, testUrl.defaultUrl);
197
+ });
198
+
199
+ it('finds a valid priority service url', () => {
200
+ const serviceFound = catalog.findServiceFromClusterId({
201
+ clusterId: testUrlTemplate.hosts[0].id,
202
+ priorityHost: true,
203
+ });
204
+
205
+ assert.equal(serviceFound.name, testUrl.name);
206
+ assert.equal(serviceFound.url, catalog.get(testUrl.name, true));
207
+ });
208
+
209
+ it('finds a valid service when a service group is defined', () => {
210
+ const serviceFound = catalog.findServiceFromClusterId({
211
+ clusterId: testUrlTemplate.hosts[0].id,
212
+ priorityHost: false,
213
+ serviceGroup: 'preauth',
214
+ });
215
+
216
+ assert.equal(serviceFound.name, testUrl.name);
217
+ assert.equal(serviceFound.url, testUrl.defaultUrl);
218
+ });
219
+
220
+ it("fails to find a valid service when it's not in a group", () => {
221
+ assert.isUndefined(
222
+ catalog.findServiceFromClusterId({
223
+ clusterId: testUrlTemplate.hosts[0].id,
224
+ serviceGroup: 'signin',
225
+ })
226
+ );
227
+ });
228
+
229
+ it("returns undefined when service doesn't exist", () => {
230
+ assert.isUndefined(catalog.findServiceFromClusterId({clusterId: 'not a clusterId'}));
231
+ });
232
+
233
+ it('should return a remote cluster url with a remote clusterId', () => {
234
+ const serviceFound = catalog.findServiceFromClusterId({
235
+ clusterId: testUrlTemplate.hosts[1].id,
236
+ });
237
+
238
+ assert.equal(serviceFound.name, testUrl.name);
239
+ assert.isTrue(serviceFound.url.includes(testUrlTemplate.hosts[1].host));
240
+ });
241
+ });
242
+
243
+ describe('#findServiceUrlFromUrl()', () => {
244
+ let testUrlTemplate;
245
+ let testUrl;
246
+
247
+ beforeEach('load test url', () => {
248
+ testUrlTemplate = {
249
+ defaultUrl: 'https://www.example.com/api/v1',
250
+ hosts: [
251
+ {
252
+ homeCluster: true,
253
+ host: 'www.example-p5.com',
254
+ ttl: -1,
255
+ priority: 5,
256
+ id: 'exampleClusterId',
257
+ },
258
+ {
259
+ host: 'www.example-p3.com',
260
+ ttl: -1,
261
+ priority: 3,
262
+ id: 'exampleClusterId',
263
+ },
264
+ ],
265
+ name: 'exampleValid',
266
+ };
267
+ testUrl = new ServiceUrl({...testUrlTemplate});
268
+ catalog._loadServiceUrls('preauth', [testUrl]);
269
+ });
270
+
271
+ afterEach('unload test url', () => {
272
+ catalog._unloadServiceUrls('preauth', [testUrl]);
273
+ });
274
+
275
+ it('finds a service if it exists', () => {
276
+ assert.equal(catalog.findServiceUrlFromUrl(testUrlTemplate.defaultUrl), testUrl);
277
+ });
278
+
279
+ it('finds a service if its a priority host url', () => {
280
+ assert.equal(catalog.findServiceUrlFromUrl(testUrl.get(true)).name, testUrl.name);
281
+ });
282
+
283
+ it("returns undefined if the url doesn't exist", () => {
284
+ assert.isUndefined(catalog.findServiceUrlFromUrl('https://na.com/'));
285
+ });
286
+
287
+ it('returns undefined if the param is not a url', () => {
288
+ assert.isUndefined(catalog.findServiceUrlFromUrl('not a url'));
289
+ });
290
+ });
291
+
292
+ describe('#list()', () => {
293
+ it('retreives priority host urls base on priorityHost parameter', () => {
294
+ const serviceList = catalog.list(true);
295
+
296
+ const foundPriorityValues = catalog.serviceGroups.postauth.some((serviceUrl) =>
297
+ serviceUrl.hosts.some(({host}) =>
298
+ Object.keys(serviceList).some((key) => serviceList[key].includes(host))
299
+ )
300
+ );
301
+
302
+ assert.isTrue(foundPriorityValues);
303
+ });
304
+
305
+ it('returns an object of based on serviceGroup parameter', () => {
306
+ let serviceList = catalog.list(true, 'discovery');
307
+
308
+ assert.equal(Object.keys(serviceList).length, catalog.serviceGroups.discovery.length);
309
+
310
+ serviceList = catalog.list(true, 'preauth');
311
+
312
+ assert.equal(Object.keys(serviceList).length, catalog.serviceGroups.preauth.length);
313
+
314
+ serviceList = catalog.list(true, 'postauth');
315
+
316
+ assert.isAtLeast(Object.keys(serviceList).length, catalog.serviceGroups.postauth.length);
317
+ });
318
+
319
+ it('matches the values in serviceUrl', () => {
320
+ let serviceList = catalog.list();
321
+
322
+ Object.keys(serviceList).forEach((key) => {
323
+ assert.equal(serviceList[key], catalog._getUrl(key).get());
324
+ });
325
+
326
+ serviceList = catalog.list(true, 'postauth');
327
+
328
+ Object.keys(serviceList).forEach((key) => {
329
+ assert.equal(serviceList[key], catalog._getUrl(key, 'postauth').get(true));
330
+ });
331
+ });
332
+ });
333
+
334
+ describe('#get()', () => {
335
+ let testUrlTemplate;
336
+ let testUrl;
337
+
338
+ beforeEach('load test url', () => {
339
+ testUrlTemplate = {
340
+ defaultUrl: 'https://www.example.com/api/v1',
341
+ hosts: [],
342
+ name: 'exampleValid',
343
+ };
344
+ testUrl = new ServiceUrl({...testUrlTemplate});
345
+ catalog._loadServiceUrls('preauth', [testUrl]);
346
+ });
347
+
348
+ afterEach('unload test url', () => {
349
+ catalog._unloadServiceUrls('preauth', [testUrl]);
350
+ });
351
+
352
+ it('returns a valid string when name is specified', () => {
353
+ const url = catalog.get(testUrlTemplate.name);
354
+
355
+ assert.typeOf(url, 'string');
356
+ assert.equal(url, testUrlTemplate.defaultUrl);
357
+ });
358
+
359
+ it("returns undefined if url doesn't exist", () => {
360
+ const s = catalog.get('invalidUrl');
361
+
362
+ assert.typeOf(s, 'undefined');
363
+ });
364
+
365
+ it('calls _getUrl', () => {
366
+ sinon.spy(catalog, '_getUrl');
367
+
368
+ catalog.get();
369
+
370
+ assert.called(catalog._getUrl);
371
+ });
372
+
373
+ it('gets a service from a specific serviceGroup', () => {
374
+ assert.isDefined(catalog.get(testUrlTemplate.name, false, 'preauth'));
375
+ });
376
+
377
+ it("fails to get a service if serviceGroup isn't accurate", () => {
378
+ assert.isUndefined(catalog.get(testUrlTemplate.name, false, 'discovery'));
379
+ });
380
+ });
381
+
382
+ describe('#markFailedUrl()', () => {
383
+ let testUrlTemplate;
384
+ let testUrl;
385
+
386
+ beforeEach('load test url', () => {
387
+ testUrlTemplate = {
388
+ defaultUrl: 'https://www.example.com/api/v1',
389
+ hosts: [
390
+ {
391
+ host: 'www.example-p5.com',
392
+ ttl: -1,
393
+ priority: 5,
394
+ id: '0:0:0:exampleValid',
395
+ homeCluster: true,
396
+ },
397
+ {
398
+ host: 'www.example-p3.com',
399
+ ttl: -1,
400
+ priority: 3,
401
+ id: '0:0:0:exampleValid',
402
+ homeCluster: true,
403
+ },
404
+ ],
405
+ name: 'exampleValid',
406
+ };
407
+ testUrl = new ServiceUrl({...testUrlTemplate});
408
+ catalog._loadServiceUrls('preauth', [testUrl]);
409
+ });
410
+
411
+ afterEach('unload test url', () => {
412
+ catalog._unloadServiceUrls('preauth', [testUrl]);
413
+ });
414
+
415
+ it('marks a host as failed', () => {
416
+ const priorityUrl = catalog.get(testUrlTemplate.name, true);
417
+
418
+ catalog.markFailedUrl(priorityUrl);
419
+
420
+ const failedHost = testUrl.hosts.find((host) => host.failed);
421
+
422
+ assert.isDefined(failedHost);
423
+ });
424
+
425
+ it('returns the next priority url', () => {
426
+ const priorityUrl = catalog.get(testUrlTemplate.name, true);
427
+ const nextPriorityUrl = catalog.markFailedUrl(priorityUrl);
428
+
429
+ assert.notEqual(priorityUrl, nextPriorityUrl);
430
+ });
431
+ });
432
+
433
+ describe('#_loadServiceUrls()', () => {
434
+ let testUrlTemplate;
435
+ let testUrl;
436
+
437
+ beforeEach('init test url', () => {
438
+ testUrlTemplate = {
439
+ defaultUrl: 'https://www.example.com/api/v1',
440
+ hosts: [],
441
+ name: 'exampleValid',
442
+ };
443
+ testUrl = new ServiceUrl({...testUrlTemplate});
444
+ });
445
+
446
+ it('appends services to different service groups', () => {
447
+ catalog._loadServiceUrls('postauth', [testUrl]);
448
+ catalog._loadServiceUrls('preauth', [testUrl]);
449
+ catalog._loadServiceUrls('discovery', [testUrl]);
450
+
451
+ catalog.serviceGroups.postauth.includes(testUrl);
452
+ catalog.serviceGroups.preauth.includes(testUrl);
453
+ catalog.serviceGroups.discovery.includes(testUrl);
454
+
455
+ catalog._unloadServiceUrls('postauth', [testUrl]);
456
+ catalog._unloadServiceUrls('preauth', [testUrl]);
457
+ catalog._unloadServiceUrls('discovery', [testUrl]);
458
+ });
459
+ });
460
+
461
+ describe('#_unloadServiceUrls()', () => {
462
+ let testUrlTemplate;
463
+ let testUrl;
464
+
465
+ beforeEach('init test url', () => {
466
+ testUrlTemplate = {
467
+ defaultUrl: 'https://www.example.com/api/v1',
468
+ hosts: [],
469
+ name: 'exampleValid',
470
+ };
471
+ testUrl = new ServiceUrl({...testUrlTemplate});
472
+ });
473
+
474
+ it('appends services to different service groups', () => {
475
+ catalog._loadServiceUrls('postauth', [testUrl]);
476
+ catalog._loadServiceUrls('preauth', [testUrl]);
477
+ catalog._loadServiceUrls('discovery', [testUrl]);
478
+
479
+ const oBaseLength = catalog.serviceGroups.postauth.length;
480
+ const oLimitedLength = catalog.serviceGroups.preauth.length;
481
+ const oDiscoveryLength = catalog.serviceGroups.discovery.length;
482
+
483
+ catalog._unloadServiceUrls('postauth', [testUrl]);
484
+ catalog._unloadServiceUrls('preauth', [testUrl]);
485
+ catalog._unloadServiceUrls('discovery', [testUrl]);
486
+
487
+ assert.isAbove(oBaseLength, catalog.serviceGroups.postauth.length);
488
+ assert.isAbove(oLimitedLength, catalog.serviceGroups.preauth.length);
489
+ assert.isAbove(oDiscoveryLength, catalog.serviceGroups.discovery.length);
490
+ });
491
+ });
492
+
493
+ describe('#_fetchNewServiceHostmap()', () => {
494
+ let fullRemoteHM;
495
+ let limitedRemoteHM;
496
+
497
+ beforeEach(() =>
498
+ Promise.all([
499
+ services._fetchNewServiceHostmap(),
500
+ services._fetchNewServiceHostmap({
501
+ from: 'limited',
502
+ query: {userId: webexUser.id},
503
+ }),
504
+ ]).then(([fRHM, lRHM]) => {
505
+ fullRemoteHM = fRHM;
506
+ limitedRemoteHM = lRHM;
507
+
508
+ return Promise.resolve();
509
+ })
510
+ );
511
+
512
+ it('resolves to an authed u2c hostmap when no params specified', () => {
513
+ assert.typeOf(fullRemoteHM, 'array');
514
+ assert.isAbove(fullRemoteHM.length, 0);
515
+ });
516
+
517
+ it('resolves to a limited u2c hostmap when params specified', () => {
518
+ assert.typeOf(limitedRemoteHM, 'array');
519
+ assert.isAbove(limitedRemoteHM.length, 0);
520
+ });
521
+
522
+ it('rejects if the params provided are invalid', () =>
523
+ services
524
+ ._fetchNewServiceHostmap({
525
+ from: 'limited',
526
+ query: {userId: 'notValid'},
527
+ })
528
+ .then(() => {
529
+ assert.isTrue(false, 'should have rejected');
530
+
531
+ return Promise.reject();
532
+ })
533
+ .catch((e) => {
534
+ assert.typeOf(e, 'Error');
535
+
536
+ return Promise.resolve();
537
+ }));
538
+ });
539
+
540
+ describe('#waitForCatalog()', () => {
541
+ let promise;
542
+ let serviceHostmap;
543
+ let formattedHM;
544
+
545
+ beforeEach(() => {
546
+ serviceHostmap = {
547
+ serviceLinks: {
548
+ 'example-a': 'https://example-a.com/api/v1',
549
+ 'example-b': 'https://example-b.com/api/v1',
550
+ 'example-c': 'https://example-c.com/api/v1',
551
+ },
552
+ hostCatalog: {
553
+ 'example-a.com': [
554
+ {
555
+ host: 'example-a-1.com',
556
+ ttl: -1,
557
+ priority: 5,
558
+ id: '0:0:0:example-a',
559
+ },
560
+ {
561
+ host: 'example-a-2.com',
562
+ ttl: -1,
563
+ priority: 3,
564
+ id: '0:0:0:example-a',
565
+ },
566
+ {
567
+ host: 'example-a-3.com',
568
+ ttl: -1,
569
+ priority: 1,
570
+ id: '0:0:0:example-a',
571
+ },
572
+ ],
573
+ 'example-b.com': [
574
+ {
575
+ host: 'example-b-1.com',
576
+ ttl: -1,
577
+ priority: 5,
578
+ id: '0:0:0:example-b',
579
+ },
580
+ {
581
+ host: 'example-b-2.com',
582
+ ttl: -1,
583
+ priority: 3,
584
+ id: '0:0:0:example-b',
585
+ },
586
+ {
587
+ host: 'example-b-3.com',
588
+ ttl: -1,
589
+ priority: 1,
590
+ id: '0:0:0:example-b',
591
+ },
592
+ ],
593
+ 'example-c.com': [
594
+ {
595
+ host: 'example-c-1.com',
596
+ ttl: -1,
597
+ priority: 5,
598
+ id: '0:0:0:example-c',
599
+ },
600
+ {
601
+ host: 'example-c-2.com',
602
+ ttl: -1,
603
+ priority: 3,
604
+ id: '0:0:0:example-c',
605
+ },
606
+ {
607
+ host: 'example-c-3.com',
608
+ ttl: -1,
609
+ priority: 1,
610
+ id: '0:0:0:example-c',
611
+ },
612
+ ],
613
+ },
614
+ format: 'hostmap',
615
+ };
616
+ formattedHM = services._formatReceivedHostmap(serviceHostmap);
617
+
618
+ promise = catalog.waitForCatalog('preauth', 1);
619
+ });
620
+
621
+ it('returns a promise', () => {
622
+ assert.typeOf(promise, 'promise');
623
+ });
624
+
625
+ it('returns a rejected promise if timeout is reached', () =>
626
+ promise.catch(() => {
627
+ assert(true, 'promise rejected');
628
+
629
+ return Promise.resolve();
630
+ }));
631
+
632
+ it('returns a resolved promise once ready', () => {
633
+ catalog.waitForCatalog('postauth', 1).then(() => {
634
+ assert(true, 'promise resolved');
635
+ });
636
+
637
+ catalog.updateServiceUrls('postauth', formattedHM);
638
+ });
639
+ });
640
+
641
+ describe('#updateServiceUrls()', () => {
642
+ let serviceHostmap;
643
+ let formattedHM;
644
+
645
+ beforeEach(() => {
646
+ serviceHostmap = {
647
+ serviceLinks: {
648
+ 'example-a': 'https://example-a.com/api/v1',
649
+ 'example-b': 'https://example-b.com/api/v1',
650
+ 'example-c': 'https://example-c.com/api/v1',
651
+ },
652
+ hostCatalog: {
653
+ 'example-a.com': [
654
+ {
655
+ host: 'example-a-1.com',
656
+ ttl: -1,
657
+ priority: 5,
658
+ id: '0:0:0:example-a',
659
+ },
660
+ {
661
+ host: 'example-a-2.com',
662
+ ttl: -1,
663
+ priority: 3,
664
+ id: '0:0:0:example-a',
665
+ },
666
+ {
667
+ host: 'example-a-3.com',
668
+ ttl: -1,
669
+ priority: 1,
670
+ id: '0:0:0:example-a',
671
+ },
672
+ ],
673
+ 'example-b.com': [
674
+ {
675
+ host: 'example-b-1.com',
676
+ ttl: -1,
677
+ priority: 5,
678
+ id: '0:0:0:example-b',
679
+ },
680
+ {
681
+ host: 'example-b-2.com',
682
+ ttl: -1,
683
+ priority: 3,
684
+ id: '0:0:0:example-b',
685
+ },
686
+ {
687
+ host: 'example-b-3.com',
688
+ ttl: -1,
689
+ priority: 1,
690
+ id: '0:0:0:example-b',
691
+ },
692
+ ],
693
+ 'example-c.com': [
694
+ {
695
+ host: 'example-c-1.com',
696
+ ttl: -1,
697
+ priority: 5,
698
+ id: '0:0:0:example-c',
699
+ },
700
+ {
701
+ host: 'example-c-2.com',
702
+ ttl: -1,
703
+ priority: 3,
704
+ id: '0:0:0:example-c',
705
+ },
706
+ {
707
+ host: 'example-c-3.com',
708
+ ttl: -1,
709
+ priority: 1,
710
+ id: '0:0:0:example-c',
711
+ },
712
+ ],
713
+ },
714
+ format: 'hostmap',
715
+ };
716
+ formattedHM = services._formatReceivedHostmap(serviceHostmap);
717
+ });
718
+
719
+ it('removes any unused urls from current services', () => {
720
+ catalog.updateServiceUrls('preauth', formattedHM);
721
+
722
+ const originalLength = catalog.serviceGroups.preauth.length;
723
+
724
+ catalog.updateServiceUrls('preauth', []);
725
+
726
+ assert.isBelow(catalog.serviceGroups.preauth.length, originalLength);
727
+ });
728
+
729
+ it('updates the target catalog to contain the provided hosts', () => {
730
+ catalog.updateServiceUrls('preauth', formattedHM);
731
+
732
+ assert.equal(catalog.serviceGroups.preauth.length, formattedHM.length);
733
+ });
734
+
735
+ it('updates any existing ServiceUrls', () => {
736
+ const newServiceHM = {
737
+ serviceLinks: {
738
+ 'example-a': 'https://e-a.com/api/v1',
739
+ 'example-b': 'https://e-b.com/api/v1',
740
+ 'example-c': 'https://e-c.com/api/v1',
741
+ },
742
+ hostCatalog: {
743
+ 'e-a.com': [],
744
+ 'e-b.com': [],
745
+ 'e-c.com': [],
746
+ },
747
+ };
748
+
749
+ const newFormattedHM = services._formatReceivedHostmap(newServiceHM);
750
+
751
+ catalog.updateServiceUrls('preauth', formattedHM);
752
+
753
+ const oServicesB = catalog.list(false, 'preauth');
754
+ const oServicesH = catalog.list(true, 'preauth');
755
+
756
+ catalog.updateServiceUrls('preauth', newFormattedHM);
757
+
758
+ const nServicesB = catalog.list(false, 'preauth');
759
+ const nServicesH = catalog.list(true, 'preauth');
760
+
761
+ Object.keys(nServicesB).forEach((key) => {
762
+ assert.notEqual(nServicesB[key], oServicesB[key]);
763
+ });
764
+
765
+ Object.keys(nServicesH).forEach((key) => {
766
+ assert.notEqual(nServicesH[key], oServicesH[key]);
767
+ });
768
+ });
769
+
770
+ it('creates an array of equal length of serviceLinks', () => {
771
+ assert.equal(Object.keys(serviceHostmap.serviceLinks).length, formattedHM.length);
772
+ });
773
+
774
+ it('creates an array of equal length of hostMap', () => {
775
+ assert.equal(Object.keys(serviceHostmap.hostCatalog).length, formattedHM.length);
776
+ });
777
+
778
+ it('creates an array with matching url data', () => {
779
+ formattedHM.forEach((entry) => {
780
+ assert.equal(serviceHostmap.serviceLinks[entry.name], entry.defaultUrl);
781
+ });
782
+ });
783
+
784
+ it('creates an array with matching host data', () => {
785
+ Object.keys(serviceHostmap.hostCatalog).forEach((key) => {
786
+ const hostGroup = serviceHostmap.hostCatalog[key];
787
+
788
+ const foundMatch = hostGroup.every((inboundHost) =>
789
+ formattedHM.find((formattedService) =>
790
+ formattedService.hosts.find(
791
+ (formattedHost) => formattedHost.host === inboundHost.host
792
+ )
793
+ )
794
+ );
795
+
796
+ assert.isTrue(
797
+ foundMatch,
798
+ `did not find matching host data for the \`${key}\` host group.`
799
+ );
800
+ });
801
+ });
802
+
803
+ it('creates an array with matching names', () => {
804
+ assert.hasAllKeys(
805
+ serviceHostmap.serviceLinks,
806
+ formattedHM.map((item) => item.name)
807
+ );
808
+ });
809
+
810
+ it('returns self', () => {
811
+ const returnValue = catalog.updateServiceUrls('preauth', formattedHM);
812
+
813
+ assert.equal(returnValue, catalog);
814
+ });
815
+
816
+ it('triggers authorization events', (done) => {
817
+ catalog.once('preauth', () => {
818
+ assert(true, 'triggered once');
819
+ done();
820
+ });
821
+
822
+ catalog.updateServiceUrls('preauth', formattedHM);
823
+ });
824
+
825
+ it('updates the services list', (done) => {
826
+ catalog.serviceGroups.preauth = [];
827
+
828
+ catalog.once('preauth', () => {
829
+ assert.isAbove(catalog.serviceGroups.preauth.length, 0);
830
+ done();
831
+ });
832
+
833
+ catalog.updateServiceUrls('preauth', formattedHM);
834
+ });
835
+ });
836
+ });
837
+ });
838
+ /* eslint-enable no-underscore-dangle */