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

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 +19 -20
  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,747 +1,747 @@
1
- import {assert} from '@webex/test-helper-chai';
2
- import sinon from 'sinon';
3
- import {ServiceRegistry, serviceConstants} from '@webex/webex-core';
4
-
5
- const {SERVICE_CATALOGS, SERVICE_CATALOGS_ENUM_TYPES: SCET} = serviceConstants;
6
-
7
- describe('webex-core', () => {
8
- describe('ServiceRegistry', () => {
9
- let fixture;
10
- let fixtureHosts;
11
- let serviceRegistry;
12
-
13
- beforeAll(() => {
14
- fixture = {
15
- serviceLinks: {
16
- 'example-service-a-name': 'http://example-service-a.com/',
17
- 'example-service-b-name': 'http://example-service-b.com/',
18
- },
19
- hostCatalog: {
20
- 'example-service-a': [
21
- {
22
- host: 'example-service-a-h1.com',
23
- id: 'head:group:cluster-a-h1:example-service-a-name',
24
- priority: 5,
25
- },
26
- {
27
- host: 'example-service-a-h2.com',
28
- id: 'head:group:cluster-a-h2:example-service-a-name',
29
- priority: 3,
30
- },
31
- ],
32
- 'example-service-b': [
33
- {
34
- host: 'example-service-b-h1.com',
35
- id: 'head:group:cluster-b-h1:example-service-b-name',
36
- priority: 5,
37
- },
38
- {
39
- host: 'example-service-b-h2.com',
40
- id: 'head:group:cluster-b-h2:example-service-b-name',
41
- priority: 3,
42
- },
43
- ],
44
- 'example-service-c': [
45
- {
46
- host: 'example-service-c-h1.com',
47
- id: 'head:group:cluster-c-h1:example-service-a-name',
48
- priority: 5,
49
- },
50
- {
51
- host: 'example-service-c-h2.com',
52
- id: 'head:group:cluster-c-h2:example-service-a-name',
53
- priority: 3,
54
- },
55
- ],
56
- },
57
- };
58
-
59
- fixtureHosts = Object.keys(fixture.hostCatalog).reduce((output, key) => {
60
- output.push(...fixture.hostCatalog[key]);
61
-
62
- return output;
63
- }, []);
64
- });
65
-
66
- beforeEach(() => {
67
- serviceRegistry = new ServiceRegistry();
68
- });
69
-
70
- describe('class members', () => {
71
- describe('#hosts', () => {
72
- it('should be an array', () => {
73
- assert.isArray(serviceRegistry.hosts);
74
- });
75
- });
76
-
77
- describe('#map', () => {
78
- let priorityLocalHosts;
79
-
80
- beforeEach(() => {
81
- serviceRegistry.load(
82
- ServiceRegistry.mapRemoteCatalog({
83
- catalog: SERVICE_CATALOGS[0],
84
- ...fixture,
85
- })
86
- );
87
-
88
- const {hostCatalog} = fixture;
89
-
90
- priorityLocalHosts = {
91
- 'example-service-a-name': hostCatalog['example-service-a'][0].host,
92
- 'example-service-b-name': hostCatalog['example-service-b'][0].host,
93
- };
94
- });
95
-
96
- it('should only return hosts that are active/local/priority', () => {
97
- const {map} = serviceRegistry;
98
- const priorityLocalHostsKeys = Object.keys(priorityLocalHosts);
99
-
100
- assert.isTrue(
101
- priorityLocalHostsKeys.every((key) => map[key].includes(priorityLocalHosts[key]))
102
- );
103
- });
104
- });
105
- });
106
-
107
- describe('#clear()', () => {
108
- let filter;
109
- let host;
110
-
111
- beforeEach(() => {
112
- serviceRegistry.load(ServiceRegistry.mapRemoteCatalog({
113
- catalog: SERVICE_CATALOGS[0],
114
- ...fixture
115
- }));
116
-
117
- host = serviceRegistry.hosts[0];
118
-
119
- filter = {
120
- active: true,
121
- catalog: host.catalog,
122
- cluster: host.id,
123
- local: true,
124
- priority: true,
125
- service: host.service,
126
- url: host.url,
127
- };
128
- });
129
-
130
- it('should remove all hosts when called without a filter', () => {
131
- serviceRegistry.clear();
132
-
133
- assert.equal(serviceRegistry.hosts.length, 0);
134
- });
135
-
136
- it('should remove only filtered hosts when called with a filter', () => {
137
- serviceRegistry.clear(filter);
138
-
139
- assert.notInclude(serviceRegistry.hosts, host);
140
- });
141
-
142
- it('should remove multiple hosts based on the provided filter', () => {
143
- host.setStatus({failed: true});
144
- serviceRegistry.clear({active: true});
145
- assert.deepEqual(serviceRegistry.hosts, [host]);
146
- });
147
-
148
- it('should return the removed hosts', () => {
149
- const [removedHost] = serviceRegistry.clear(filter);
150
-
151
- assert.equal(removedHost, host);
152
- });
153
- });
154
-
155
- describe('#failed()', () => {
156
- let filter;
157
- let filteredHost;
158
-
159
- beforeEach(() => {
160
- serviceRegistry.load(ServiceRegistry.mapRemoteCatalog({
161
- catalog: SERVICE_CATALOGS[0],
162
- ...fixture
163
- }));
164
-
165
- filteredHost = serviceRegistry.hosts[0];
166
-
167
- filter = {
168
- active: true,
169
- catalog: filteredHost.catalog,
170
- cluster: filteredHost.id,
171
- local: true,
172
- priority: true,
173
- service: filteredHost.service,
174
- url: filteredHost.url,
175
- };
176
- });
177
-
178
- it('should mark all hosts as failed when called without a filter', () => {
179
- serviceRegistry.failed();
180
- assert.isTrue(serviceRegistry.hosts.every((failedHost) => failedHost.failed));
181
- });
182
-
183
- it('should mark the target hosts as failed', () => {
184
- serviceRegistry.failed(filter);
185
- assert.isTrue(filteredHost.failed);
186
- });
187
-
188
- it('should return the marked host', () => {
189
- const [failedHost] = serviceRegistry.failed(filter);
190
-
191
- assert.equal(failedHost, filteredHost);
192
- });
193
- });
194
-
195
- describe('#filterActive()', () => {
196
- let hostList;
197
- let failedHost;
198
- let filteredHosts;
199
-
200
- beforeEach(() => {
201
- hostList = ServiceRegistry.mapRemoteCatalog({
202
- catalog: SERVICE_CATALOGS[0],
203
- ...fixture,
204
- });
205
-
206
- serviceRegistry.load(hostList);
207
- failedHost = serviceRegistry.hosts[0];
208
- failedHost.setStatus({failed: true, replaced: true});
209
- });
210
-
211
- it('should return all hosts when called without params', () => {
212
- filteredHosts = serviceRegistry.filterActive();
213
-
214
- assert.equal(filteredHosts.length, hostList.length);
215
- });
216
-
217
- it('should return only active hosts when called with true', () => {
218
- filteredHosts = serviceRegistry.filterActive(true);
219
-
220
- assert.isBelow(filteredHosts.length, hostList.length);
221
- assert.notInclude(filteredHosts, failedHost);
222
- });
223
-
224
- it('should return only inactive hosts when active is false', () => {
225
- filteredHosts = serviceRegistry.filterActive(false);
226
-
227
- assert.equal(filteredHosts.length, 1);
228
- assert.include(filteredHosts[0], failedHost);
229
- });
230
- });
231
-
232
- describe('#filterCatalog()', () => {
233
- let filteredHosts;
234
- let hostsCustomA;
235
- let hostsCustomB;
236
-
237
- beforeEach(() => {
238
- hostsCustomA = ServiceRegistry.mapRemoteCatalog({
239
- catalog: SERVICE_CATALOGS[0],
240
- ...fixture,
241
- });
242
-
243
- hostsCustomB = ServiceRegistry.mapRemoteCatalog({
244
- catalog: SERVICE_CATALOGS[1],
245
- ...fixture,
246
- });
247
-
248
- serviceRegistry.load(hostsCustomA);
249
- serviceRegistry.load(hostsCustomB);
250
- });
251
-
252
- it('should return all hosts when called without params', () => {
253
- filteredHosts = serviceRegistry.filterCatalog();
254
-
255
- assert.deepEqual(filteredHosts, serviceRegistry.hosts);
256
- });
257
-
258
- it('should return only service hosts in the specific catalog', () => {
259
- filteredHosts = serviceRegistry.filterCatalog(SERVICE_CATALOGS[0]);
260
-
261
- assert.equal(filteredHosts.length, hostsCustomA.length);
262
- assert.isTrue(filteredHosts.every((host) => host.catalog === SERVICE_CATALOGS[0]));
263
- });
264
-
265
- it('should return service hosts for an array of catalogs', () => {
266
- filteredHosts = serviceRegistry.filterCatalog([SERVICE_CATALOGS[0], SERVICE_CATALOGS[1]]);
267
-
268
- assert.equal(filteredHosts.length, hostsCustomA.length + hostsCustomB.length);
269
-
270
- assert.isTrue(
271
- filteredHosts.every((host) =>
272
- [SERVICE_CATALOGS[0], SERVICE_CATALOGS[1]].includes(host.catalog)
273
- )
274
- );
275
- });
276
-
277
- it('should return only service hosts from valid catalogs', () => {
278
- filteredHosts = serviceRegistry.filterCatalog([SERVICE_CATALOGS[0], 'invalid', -1]);
279
-
280
- assert.equal(filteredHosts.length, hostsCustomA.length);
281
- assert.isTrue(filteredHosts.every((host) => host.catalog === SERVICE_CATALOGS[0]));
282
- });
283
- });
284
-
285
- describe('#filterLocal()', () => {
286
- let filteredHosts;
287
- let remoteHosts;
288
- let localHosts;
289
-
290
- beforeEach(() => {
291
- serviceRegistry.load(
292
- ServiceRegistry.mapRemoteCatalog({
293
- catalog: SERVICE_CATALOGS[0],
294
- ...fixture,
295
- })
296
- );
297
-
298
- remoteHosts = fixture.hostCatalog['example-service-c'];
299
- localHosts = [
300
- ...fixture.hostCatalog['example-service-a'],
301
- ...fixture.hostCatalog['example-service-b'],
302
- ];
303
- });
304
-
305
- it('should return all hosts when called without params', () => {
306
- filteredHosts = serviceRegistry.filterLocal();
307
-
308
- assert.deepEqual(filteredHosts, serviceRegistry.hosts);
309
- });
310
-
311
- it('should return only local hosts when called with true', () => {
312
- filteredHosts = serviceRegistry.filterLocal(true);
313
-
314
- assert.equal(filteredHosts.length, localHosts.length);
315
- assert.isTrue(filteredHosts.every((host) => host.local === true));
316
- });
317
-
318
- it('should return only hosts remote hosts when called with false', () => {
319
- filteredHosts = serviceRegistry.filterLocal(false);
320
-
321
- assert.equal(filteredHosts.length, remoteHosts.length);
322
- assert.isTrue(filteredHosts.every((host) => host.local === false));
323
- });
324
- });
325
-
326
- describe('#filterPriority()', () => {
327
- let filteredHosts;
328
- let priorityHosts;
329
-
330
- beforeEach(() => {
331
- serviceRegistry.load(
332
- ServiceRegistry.mapRemoteCatalog({
333
- catalog: SERVICE_CATALOGS[0],
334
- ...fixture,
335
- })
336
- );
337
-
338
- priorityHosts = [
339
- fixture.hostCatalog['example-service-a'][0],
340
- fixture.hostCatalog['example-service-b'][0],
341
- fixture.hostCatalog['example-service-c'][0],
342
- ];
343
- });
344
-
345
- it('should return all hosts when called without params', () => {
346
- filteredHosts = serviceRegistry.filterPriority();
347
-
348
- assert.deepEqual(filteredHosts, serviceRegistry.hosts);
349
- });
350
-
351
- it('should return only priority hosts when called with true', () => {
352
- filteredHosts = serviceRegistry.filterPriority(true);
353
-
354
- assert.equal(filteredHosts.length, priorityHosts.length);
355
- });
356
-
357
- it('should not return inactive hosts when called with true', () => {
358
- filteredHosts = serviceRegistry.filterPriority(true);
359
- filteredHosts[0].setStatus({failed: true});
360
-
361
- const failedHost = filteredHosts[0];
362
-
363
- filteredHosts = serviceRegistry.filterPriority(true);
364
-
365
- assert.notInclude(filteredHosts, failedHost);
366
- });
367
-
368
- it('should return all hosts when called with false', () => {
369
- filteredHosts = serviceRegistry.filterPriority(false);
370
-
371
- assert.deepEqual(filteredHosts, serviceRegistry.hosts);
372
- });
373
- });
374
-
375
- describe('#filterService()', () => {
376
- let filteredHosts;
377
- let otherHosts;
378
- let otherServiceName;
379
- let serviceHosts;
380
- let serviceName;
381
-
382
- beforeEach(() => {
383
- serviceRegistry.load(
384
- ServiceRegistry.mapRemoteCatalog({
385
- catalog: SERVICE_CATALOGS[0],
386
- ...fixture,
387
- })
388
- );
389
-
390
- otherHosts = [...fixture.hostCatalog['example-service-b']];
391
-
392
- serviceHosts = [
393
- ...fixture.hostCatalog['example-service-a'],
394
- ...fixture.hostCatalog['example-service-c'],
395
- ];
396
-
397
- otherServiceName = 'example-service-b-name';
398
- serviceName = 'example-service-a-name';
399
- });
400
-
401
- it('should return all hosts when called without params', () => {
402
- filteredHosts = serviceRegistry.filterService();
403
-
404
- assert.equal(filteredHosts.length, serviceRegistry.hosts.length);
405
- });
406
-
407
- it('should return hosts that belong to a service', () => {
408
- filteredHosts = serviceRegistry.filterService(serviceName);
409
-
410
- assert.equal(filteredHosts.length, serviceHosts.length);
411
- assert.isTrue(filteredHosts.every((host) => host.service === serviceName));
412
- });
413
-
414
- it('should return all hosts that belong to an array of services', () => {
415
- filteredHosts = serviceRegistry.filterService([otherServiceName, serviceName]);
416
-
417
- assert.equal(filteredHosts.length, [...otherHosts, ...serviceHosts].length);
418
-
419
- assert.isTrue(
420
- filteredHosts.every((host) => [otherServiceName, serviceName].includes(host.service))
421
- );
422
- });
423
-
424
- it('should return an empty array when given an invalid service', () => {
425
- filteredHosts = serviceRegistry.filterService('invalid');
426
-
427
- assert.equal(filteredHosts.length, 0);
428
- });
429
- });
430
-
431
- describe('#filterUrl()', () => {
432
- let filteredHosts;
433
- let filteredHostA;
434
- let filteredHostB;
435
-
436
- beforeEach(() => {
437
- serviceRegistry.load(
438
- ServiceRegistry.mapRemoteCatalog({
439
- catalog: SERVICE_CATALOGS[0],
440
- ...fixture,
441
- })
442
- );
443
-
444
- filteredHostA = serviceRegistry.hosts[0];
445
- filteredHostB = serviceRegistry.hosts[1];
446
- });
447
-
448
- it('should return all hosts when called without params', () => {
449
- filteredHosts = serviceRegistry.filterUrl();
450
-
451
- assert.deepEqual(filteredHosts, serviceRegistry.hosts);
452
- });
453
-
454
- it('should return only service hosts with a specific url', () => {
455
- [filteredHosts] = serviceRegistry.filterUrl(filteredHostA.url);
456
-
457
- assert.equal(filteredHosts, filteredHostA);
458
- });
459
-
460
- it('should return service hosts for an array of urls', () => {
461
- filteredHosts = serviceRegistry.filterUrl([filteredHostA.url, filteredHostB.url]);
462
-
463
- assert.equal(filteredHosts.length, 2);
464
- assert.isTrue(
465
- filteredHosts.every((foundHost) => [filteredHostA, filteredHostB].includes(foundHost))
466
- );
467
- });
468
-
469
- it('should return an empty array when given an invalid url', () => {
470
- filteredHosts = serviceRegistry.filterUrl('invalid');
471
- assert.equal(filteredHosts.length, 0);
472
- });
473
- });
474
-
475
- describe('#find()', () => {
476
- let filter;
477
- let host;
478
-
479
- beforeEach(() => {
480
- serviceRegistry.load(ServiceRegistry.mapRemoteCatalog({
481
- catalog: SERVICE_CATALOGS[0],
482
- ...fixture
483
- }));
484
-
485
- host = serviceRegistry.hosts[0];
486
-
487
- filter = {
488
- active: true,
489
- catalog: host.catalog,
490
- cluster: host.id,
491
- local: true,
492
- priority: true,
493
- service: host.service,
494
- url: host.url,
495
- };
496
- });
497
-
498
- it("should call the 'filterActive()' method with params", () => {
499
- sinon.spy(serviceRegistry, 'filterActive');
500
- serviceRegistry.find(filter);
501
- assert.calledWith(serviceRegistry.filterActive, filter.active);
502
- });
503
-
504
- it("should call the 'filterCatalog()' method with params", () => {
505
- sinon.spy(serviceRegistry, 'filterCatalog');
506
- serviceRegistry.find(filter);
507
- assert.calledWith(serviceRegistry.filterCatalog, filter.catalog);
508
- });
509
-
510
- it("should call the 'filterCluster()' method with params", () => {
511
- sinon.spy(serviceRegistry, 'filterCluster');
512
- serviceRegistry.find(filter);
513
- assert.calledWith(serviceRegistry.filterCluster, filter.cluster);
514
- });
515
-
516
- it("should call the 'filterLocal()' method with params", () => {
517
- sinon.spy(serviceRegistry, 'filterLocal');
518
- serviceRegistry.find(filter);
519
- assert.calledWith(serviceRegistry.filterLocal, filter.local);
520
- });
521
-
522
- it("should call the 'filterPriority()' method with params", () => {
523
- sinon.spy(serviceRegistry, 'filterPriority');
524
- serviceRegistry.find(filter);
525
- assert.calledWith(serviceRegistry.filterPriority, filter.priority);
526
- });
527
-
528
- it("should call the 'filterService()' method with params", () => {
529
- sinon.spy(serviceRegistry, 'filterService');
530
- serviceRegistry.find(filter);
531
- assert.calledWith(serviceRegistry.filterService, filter.service);
532
- });
533
-
534
- it("should call the 'filterUrl()' method with params", () => {
535
- sinon.spy(serviceRegistry, 'filterUrl');
536
- serviceRegistry.find(filter);
537
- assert.calledWith(serviceRegistry.filterUrl, filter.url);
538
- });
539
-
540
- it('should return an array of filtered hosts', () => {
541
- const foundHosts = serviceRegistry.find(filter);
542
-
543
- assert.equal(foundHosts[0], host);
544
- assert.equal(foundHosts.length, 1);
545
- });
546
-
547
- it('should return all of the hosts when called without params', () => {
548
- const foundHosts = serviceRegistry.find();
549
-
550
- assert.deepEqual(foundHosts, serviceRegistry.hosts);
551
- });
552
- });
553
-
554
- describe('#load()', () => {
555
- it('should amend all provided hosts to the hosts array', () => {
556
- serviceRegistry.load(
557
- ServiceRegistry.mapRemoteCatalog({
558
- catalog: SERVICE_CATALOGS[0],
559
- ...fixture,
560
- })
561
- );
562
-
563
- assert.equal(serviceRegistry.hosts.length, fixtureHosts.length);
564
- });
565
-
566
- it('should ignore unloadable hosts', () => {
567
- const unloadables = ServiceRegistry.mapRemoteCatalog({
568
- catalog: SERVICE_CATALOGS[0],
569
- ...fixture,
570
- }).map((unloadable) => ({...unloadable, catalog: 'invalid'}));
571
-
572
- serviceRegistry.load(unloadables);
573
-
574
- assert.equal(serviceRegistry.hosts.length, 0);
575
- });
576
-
577
- it('should return itself', () => {
578
- assert.equal(serviceRegistry.load([]), serviceRegistry);
579
- });
580
- });
581
-
582
- describe('#replaced()', () => {
583
- let filter;
584
- let filteredHost;
585
-
586
- beforeEach(() => {
587
- serviceRegistry.load(ServiceRegistry.mapRemoteCatalog({
588
- catalog: SERVICE_CATALOGS[0],
589
- ...fixture
590
- }));
591
-
592
- filteredHost = serviceRegistry.hosts[0];
593
-
594
- filter = {
595
- active: true,
596
- catalog: filteredHost.catalog,
597
- cluster: filteredHost.id,
598
- local: true,
599
- priority: true,
600
- service: filteredHost.service,
601
- url: filteredHost.url,
602
- };
603
- });
604
-
605
- it('should mark all hosts as replaced when called without params', () => {
606
- serviceRegistry.replaced();
607
- assert.isTrue(serviceRegistry.hosts.every((replacedHost) => replacedHost.replaced));
608
- });
609
-
610
- it('should mark the target hosts as replaced', () => {
611
- serviceRegistry.replaced(filter);
612
- assert.isTrue(filteredHost.replaced);
613
- });
614
-
615
- it('should return the marked host', () => {
616
- const [replacedHost] = serviceRegistry.replaced(filter);
617
-
618
- assert.equal(replacedHost, filteredHost);
619
- });
620
- });
621
-
622
- describe('#reset()', () => {
623
- let filter;
624
- let filteredHost;
625
-
626
- beforeEach(() => {
627
- serviceRegistry.load(ServiceRegistry.mapRemoteCatalog({
628
- catalog: SERVICE_CATALOGS[0],
629
- ...fixture
630
- }));
631
-
632
- filteredHost = serviceRegistry.hosts[0];
633
-
634
- filter = {
635
- url: filteredHost.url,
636
- };
637
-
638
- serviceRegistry.failed();
639
- });
640
-
641
- it('should reset all hosts when called withour a filter', () => {
642
- serviceRegistry.reset();
643
- assert.isTrue(serviceRegistry.hosts.every((resetHost) => resetHost.failed === false));
644
- });
645
-
646
- it('should reset the failed status of the target host', () => {
647
- serviceRegistry.reset(filter);
648
- assert.isFalse(filteredHost.failed);
649
- });
650
-
651
- it('should not reset the failed status of non-targetted hosts', () => {
652
- serviceRegistry.reset(filter);
653
- assert.isTrue(
654
- serviceRegistry.hosts.every((foundHost) => foundHost.failed || foundHost === filteredHost)
655
- );
656
- });
657
-
658
- it('should not reset the replaced status of hosts', () => {
659
- serviceRegistry.replaced();
660
- serviceRegistry.reset();
661
- assert.isTrue(serviceRegistry.hosts.every((foundHost) => foundHost.replaced));
662
- });
663
-
664
- it('should return the reset host', () => {
665
- const [resetHost] = serviceRegistry.reset(filter);
666
-
667
- assert.equal(resetHost, filteredHost);
668
- });
669
- });
670
-
671
- describe('static methods', () => {
672
- describe('#mapCatalogName()', () => {
673
- let index;
674
- let name;
675
-
676
- beforeEach(() => {
677
- index = 0;
678
- name = SERVICE_CATALOGS[index];
679
- });
680
-
681
- it('should map an index to the matching name', () => {
682
- assert.equal(ServiceRegistry.mapCatalogName({id: index, type: SCET.STRING}), name);
683
- });
684
-
685
- it('should map an index to the matching index', () => {
686
- assert.equal(ServiceRegistry.mapCatalogName({id: index, type: SCET.NUMBER}), index);
687
- });
688
-
689
- it('should map a name to the matching index', () => {
690
- assert.equal(ServiceRegistry.mapCatalogName({id: name, type: SCET.NUMBER}), index);
691
- });
692
-
693
- it('should map a name to the matching name', () => {
694
- assert.equal(ServiceRegistry.mapCatalogName({id: name, type: SCET.STRING}), name);
695
- });
696
-
697
- it("should return undefined if an index doesn't exist", () => {
698
- assert.isUndefined(ServiceRegistry.mapCatalogName({id: -1, type: SCET.NUMBER}));
699
- });
700
-
701
- it("should return undefined if a name doesn't exist", () => {
702
- assert.isUndefined(ServiceRegistry.mapCatalogName({id: 'invalid', type: SCET.NUMBER}));
703
- });
704
- });
705
-
706
- describe('#mapRemoteCatalog()', () => {
707
- it('should return an array', () => {
708
- const mappedHosts = ServiceRegistry.mapRemoteCatalog({
709
- catalog: SERVICE_CATALOGS[0],
710
- ...fixture,
711
- });
712
-
713
- assert.isArray(mappedHosts);
714
- });
715
-
716
- it('should include all provided hosts', () => {
717
- const mappedHosts = ServiceRegistry.mapRemoteCatalog({
718
- catalog: SERVICE_CATALOGS[0],
719
- ...fixture,
720
- });
721
-
722
- assert.equal(mappedHosts.length, fixtureHosts.length);
723
- });
724
-
725
- it('should not map using an invalid catalog name', () => {
726
- assert.throws(() =>
727
- ServiceRegistry.mapRemoteCatalog({
728
- catalog: 'invalid',
729
- ...fixture,
730
- })
731
- );
732
- });
733
-
734
- it('should map catalog indexes to catalog names', () => {
735
- const catalogIndex = 4;
736
-
737
- const mappedHosts = ServiceRegistry.mapRemoteCatalog({
738
- catalog: catalogIndex,
739
- ...fixture,
740
- });
741
-
742
- assert.equal(mappedHosts[0].catalog, SERVICE_CATALOGS[catalogIndex]);
743
- });
744
- });
745
- });
746
- });
747
- });
1
+ import {assert} from '@webex/test-helper-chai';
2
+ import sinon from 'sinon';
3
+ import {ServiceRegistry, serviceConstants} from '@webex/webex-core';
4
+
5
+ const {SERVICE_CATALOGS, SERVICE_CATALOGS_ENUM_TYPES: SCET} = serviceConstants;
6
+
7
+ describe('webex-core', () => {
8
+ describe('ServiceRegistry', () => {
9
+ let fixture;
10
+ let fixtureHosts;
11
+ let serviceRegistry;
12
+
13
+ beforeAll(() => {
14
+ fixture = {
15
+ serviceLinks: {
16
+ 'example-service-a-name': 'http://example-service-a.com/',
17
+ 'example-service-b-name': 'http://example-service-b.com/',
18
+ },
19
+ hostCatalog: {
20
+ 'example-service-a': [
21
+ {
22
+ host: 'example-service-a-h1.com',
23
+ id: 'head:group:cluster-a-h1:example-service-a-name',
24
+ priority: 5,
25
+ },
26
+ {
27
+ host: 'example-service-a-h2.com',
28
+ id: 'head:group:cluster-a-h2:example-service-a-name',
29
+ priority: 3,
30
+ },
31
+ ],
32
+ 'example-service-b': [
33
+ {
34
+ host: 'example-service-b-h1.com',
35
+ id: 'head:group:cluster-b-h1:example-service-b-name',
36
+ priority: 5,
37
+ },
38
+ {
39
+ host: 'example-service-b-h2.com',
40
+ id: 'head:group:cluster-b-h2:example-service-b-name',
41
+ priority: 3,
42
+ },
43
+ ],
44
+ 'example-service-c': [
45
+ {
46
+ host: 'example-service-c-h1.com',
47
+ id: 'head:group:cluster-c-h1:example-service-a-name',
48
+ priority: 5,
49
+ },
50
+ {
51
+ host: 'example-service-c-h2.com',
52
+ id: 'head:group:cluster-c-h2:example-service-a-name',
53
+ priority: 3,
54
+ },
55
+ ],
56
+ },
57
+ };
58
+
59
+ fixtureHosts = Object.keys(fixture.hostCatalog).reduce((output, key) => {
60
+ output.push(...fixture.hostCatalog[key]);
61
+
62
+ return output;
63
+ }, []);
64
+ });
65
+
66
+ beforeEach(() => {
67
+ serviceRegistry = new ServiceRegistry();
68
+ });
69
+
70
+ describe('class members', () => {
71
+ describe('#hosts', () => {
72
+ it('should be an array', () => {
73
+ assert.isArray(serviceRegistry.hosts);
74
+ });
75
+ });
76
+
77
+ describe('#map', () => {
78
+ let priorityLocalHosts;
79
+
80
+ beforeEach(() => {
81
+ serviceRegistry.load(
82
+ ServiceRegistry.mapRemoteCatalog({
83
+ catalog: SERVICE_CATALOGS[0],
84
+ ...fixture,
85
+ })
86
+ );
87
+
88
+ const {hostCatalog} = fixture;
89
+
90
+ priorityLocalHosts = {
91
+ 'example-service-a-name': hostCatalog['example-service-a'][0].host,
92
+ 'example-service-b-name': hostCatalog['example-service-b'][0].host,
93
+ };
94
+ });
95
+
96
+ it('should only return hosts that are active/local/priority', () => {
97
+ const {map} = serviceRegistry;
98
+ const priorityLocalHostsKeys = Object.keys(priorityLocalHosts);
99
+
100
+ assert.isTrue(
101
+ priorityLocalHostsKeys.every((key) => map[key].includes(priorityLocalHosts[key]))
102
+ );
103
+ });
104
+ });
105
+ });
106
+
107
+ describe('#clear()', () => {
108
+ let filter;
109
+ let host;
110
+
111
+ beforeEach(() => {
112
+ serviceRegistry.load(ServiceRegistry.mapRemoteCatalog({
113
+ catalog: SERVICE_CATALOGS[0],
114
+ ...fixture
115
+ }));
116
+
117
+ host = serviceRegistry.hosts[0];
118
+
119
+ filter = {
120
+ active: true,
121
+ catalog: host.catalog,
122
+ cluster: host.id,
123
+ local: true,
124
+ priority: true,
125
+ service: host.service,
126
+ url: host.url,
127
+ };
128
+ });
129
+
130
+ it('should remove all hosts when called without a filter', () => {
131
+ serviceRegistry.clear();
132
+
133
+ assert.equal(serviceRegistry.hosts.length, 0);
134
+ });
135
+
136
+ it('should remove only filtered hosts when called with a filter', () => {
137
+ serviceRegistry.clear(filter);
138
+
139
+ assert.notInclude(serviceRegistry.hosts, host);
140
+ });
141
+
142
+ it('should remove multiple hosts based on the provided filter', () => {
143
+ host.setStatus({failed: true});
144
+ serviceRegistry.clear({active: true});
145
+ assert.deepEqual(serviceRegistry.hosts, [host]);
146
+ });
147
+
148
+ it('should return the removed hosts', () => {
149
+ const [removedHost] = serviceRegistry.clear(filter);
150
+
151
+ assert.equal(removedHost, host);
152
+ });
153
+ });
154
+
155
+ describe('#failed()', () => {
156
+ let filter;
157
+ let filteredHost;
158
+
159
+ beforeEach(() => {
160
+ serviceRegistry.load(ServiceRegistry.mapRemoteCatalog({
161
+ catalog: SERVICE_CATALOGS[0],
162
+ ...fixture
163
+ }));
164
+
165
+ filteredHost = serviceRegistry.hosts[0];
166
+
167
+ filter = {
168
+ active: true,
169
+ catalog: filteredHost.catalog,
170
+ cluster: filteredHost.id,
171
+ local: true,
172
+ priority: true,
173
+ service: filteredHost.service,
174
+ url: filteredHost.url,
175
+ };
176
+ });
177
+
178
+ it('should mark all hosts as failed when called without a filter', () => {
179
+ serviceRegistry.failed();
180
+ assert.isTrue(serviceRegistry.hosts.every((failedHost) => failedHost.failed));
181
+ });
182
+
183
+ it('should mark the target hosts as failed', () => {
184
+ serviceRegistry.failed(filter);
185
+ assert.isTrue(filteredHost.failed);
186
+ });
187
+
188
+ it('should return the marked host', () => {
189
+ const [failedHost] = serviceRegistry.failed(filter);
190
+
191
+ assert.equal(failedHost, filteredHost);
192
+ });
193
+ });
194
+
195
+ describe('#filterActive()', () => {
196
+ let hostList;
197
+ let failedHost;
198
+ let filteredHosts;
199
+
200
+ beforeEach(() => {
201
+ hostList = ServiceRegistry.mapRemoteCatalog({
202
+ catalog: SERVICE_CATALOGS[0],
203
+ ...fixture,
204
+ });
205
+
206
+ serviceRegistry.load(hostList);
207
+ failedHost = serviceRegistry.hosts[0];
208
+ failedHost.setStatus({failed: true, replaced: true});
209
+ });
210
+
211
+ it('should return all hosts when called without params', () => {
212
+ filteredHosts = serviceRegistry.filterActive();
213
+
214
+ assert.equal(filteredHosts.length, hostList.length);
215
+ });
216
+
217
+ it('should return only active hosts when called with true', () => {
218
+ filteredHosts = serviceRegistry.filterActive(true);
219
+
220
+ assert.isBelow(filteredHosts.length, hostList.length);
221
+ assert.notInclude(filteredHosts, failedHost);
222
+ });
223
+
224
+ it('should return only inactive hosts when active is false', () => {
225
+ filteredHosts = serviceRegistry.filterActive(false);
226
+
227
+ assert.equal(filteredHosts.length, 1);
228
+ assert.include(filteredHosts[0], failedHost);
229
+ });
230
+ });
231
+
232
+ describe('#filterCatalog()', () => {
233
+ let filteredHosts;
234
+ let hostsCustomA;
235
+ let hostsCustomB;
236
+
237
+ beforeEach(() => {
238
+ hostsCustomA = ServiceRegistry.mapRemoteCatalog({
239
+ catalog: SERVICE_CATALOGS[0],
240
+ ...fixture,
241
+ });
242
+
243
+ hostsCustomB = ServiceRegistry.mapRemoteCatalog({
244
+ catalog: SERVICE_CATALOGS[1],
245
+ ...fixture,
246
+ });
247
+
248
+ serviceRegistry.load(hostsCustomA);
249
+ serviceRegistry.load(hostsCustomB);
250
+ });
251
+
252
+ it('should return all hosts when called without params', () => {
253
+ filteredHosts = serviceRegistry.filterCatalog();
254
+
255
+ assert.deepEqual(filteredHosts, serviceRegistry.hosts);
256
+ });
257
+
258
+ it('should return only service hosts in the specific catalog', () => {
259
+ filteredHosts = serviceRegistry.filterCatalog(SERVICE_CATALOGS[0]);
260
+
261
+ assert.equal(filteredHosts.length, hostsCustomA.length);
262
+ assert.isTrue(filteredHosts.every((host) => host.catalog === SERVICE_CATALOGS[0]));
263
+ });
264
+
265
+ it('should return service hosts for an array of catalogs', () => {
266
+ filteredHosts = serviceRegistry.filterCatalog([SERVICE_CATALOGS[0], SERVICE_CATALOGS[1]]);
267
+
268
+ assert.equal(filteredHosts.length, hostsCustomA.length + hostsCustomB.length);
269
+
270
+ assert.isTrue(
271
+ filteredHosts.every((host) =>
272
+ [SERVICE_CATALOGS[0], SERVICE_CATALOGS[1]].includes(host.catalog)
273
+ )
274
+ );
275
+ });
276
+
277
+ it('should return only service hosts from valid catalogs', () => {
278
+ filteredHosts = serviceRegistry.filterCatalog([SERVICE_CATALOGS[0], 'invalid', -1]);
279
+
280
+ assert.equal(filteredHosts.length, hostsCustomA.length);
281
+ assert.isTrue(filteredHosts.every((host) => host.catalog === SERVICE_CATALOGS[0]));
282
+ });
283
+ });
284
+
285
+ describe('#filterLocal()', () => {
286
+ let filteredHosts;
287
+ let remoteHosts;
288
+ let localHosts;
289
+
290
+ beforeEach(() => {
291
+ serviceRegistry.load(
292
+ ServiceRegistry.mapRemoteCatalog({
293
+ catalog: SERVICE_CATALOGS[0],
294
+ ...fixture,
295
+ })
296
+ );
297
+
298
+ remoteHosts = fixture.hostCatalog['example-service-c'];
299
+ localHosts = [
300
+ ...fixture.hostCatalog['example-service-a'],
301
+ ...fixture.hostCatalog['example-service-b'],
302
+ ];
303
+ });
304
+
305
+ it('should return all hosts when called without params', () => {
306
+ filteredHosts = serviceRegistry.filterLocal();
307
+
308
+ assert.deepEqual(filteredHosts, serviceRegistry.hosts);
309
+ });
310
+
311
+ it('should return only local hosts when called with true', () => {
312
+ filteredHosts = serviceRegistry.filterLocal(true);
313
+
314
+ assert.equal(filteredHosts.length, localHosts.length);
315
+ assert.isTrue(filteredHosts.every((host) => host.local === true));
316
+ });
317
+
318
+ it('should return only hosts remote hosts when called with false', () => {
319
+ filteredHosts = serviceRegistry.filterLocal(false);
320
+
321
+ assert.equal(filteredHosts.length, remoteHosts.length);
322
+ assert.isTrue(filteredHosts.every((host) => host.local === false));
323
+ });
324
+ });
325
+
326
+ describe('#filterPriority()', () => {
327
+ let filteredHosts;
328
+ let priorityHosts;
329
+
330
+ beforeEach(() => {
331
+ serviceRegistry.load(
332
+ ServiceRegistry.mapRemoteCatalog({
333
+ catalog: SERVICE_CATALOGS[0],
334
+ ...fixture,
335
+ })
336
+ );
337
+
338
+ priorityHosts = [
339
+ fixture.hostCatalog['example-service-a'][0],
340
+ fixture.hostCatalog['example-service-b'][0],
341
+ fixture.hostCatalog['example-service-c'][0],
342
+ ];
343
+ });
344
+
345
+ it('should return all hosts when called without params', () => {
346
+ filteredHosts = serviceRegistry.filterPriority();
347
+
348
+ assert.deepEqual(filteredHosts, serviceRegistry.hosts);
349
+ });
350
+
351
+ it('should return only priority hosts when called with true', () => {
352
+ filteredHosts = serviceRegistry.filterPriority(true);
353
+
354
+ assert.equal(filteredHosts.length, priorityHosts.length);
355
+ });
356
+
357
+ it('should not return inactive hosts when called with true', () => {
358
+ filteredHosts = serviceRegistry.filterPriority(true);
359
+ filteredHosts[0].setStatus({failed: true});
360
+
361
+ const failedHost = filteredHosts[0];
362
+
363
+ filteredHosts = serviceRegistry.filterPriority(true);
364
+
365
+ assert.notInclude(filteredHosts, failedHost);
366
+ });
367
+
368
+ it('should return all hosts when called with false', () => {
369
+ filteredHosts = serviceRegistry.filterPriority(false);
370
+
371
+ assert.deepEqual(filteredHosts, serviceRegistry.hosts);
372
+ });
373
+ });
374
+
375
+ describe('#filterService()', () => {
376
+ let filteredHosts;
377
+ let otherHosts;
378
+ let otherServiceName;
379
+ let serviceHosts;
380
+ let serviceName;
381
+
382
+ beforeEach(() => {
383
+ serviceRegistry.load(
384
+ ServiceRegistry.mapRemoteCatalog({
385
+ catalog: SERVICE_CATALOGS[0],
386
+ ...fixture,
387
+ })
388
+ );
389
+
390
+ otherHosts = [...fixture.hostCatalog['example-service-b']];
391
+
392
+ serviceHosts = [
393
+ ...fixture.hostCatalog['example-service-a'],
394
+ ...fixture.hostCatalog['example-service-c'],
395
+ ];
396
+
397
+ otherServiceName = 'example-service-b-name';
398
+ serviceName = 'example-service-a-name';
399
+ });
400
+
401
+ it('should return all hosts when called without params', () => {
402
+ filteredHosts = serviceRegistry.filterService();
403
+
404
+ assert.equal(filteredHosts.length, serviceRegistry.hosts.length);
405
+ });
406
+
407
+ it('should return hosts that belong to a service', () => {
408
+ filteredHosts = serviceRegistry.filterService(serviceName);
409
+
410
+ assert.equal(filteredHosts.length, serviceHosts.length);
411
+ assert.isTrue(filteredHosts.every((host) => host.service === serviceName));
412
+ });
413
+
414
+ it('should return all hosts that belong to an array of services', () => {
415
+ filteredHosts = serviceRegistry.filterService([otherServiceName, serviceName]);
416
+
417
+ assert.equal(filteredHosts.length, [...otherHosts, ...serviceHosts].length);
418
+
419
+ assert.isTrue(
420
+ filteredHosts.every((host) => [otherServiceName, serviceName].includes(host.service))
421
+ );
422
+ });
423
+
424
+ it('should return an empty array when given an invalid service', () => {
425
+ filteredHosts = serviceRegistry.filterService('invalid');
426
+
427
+ assert.equal(filteredHosts.length, 0);
428
+ });
429
+ });
430
+
431
+ describe('#filterUrl()', () => {
432
+ let filteredHosts;
433
+ let filteredHostA;
434
+ let filteredHostB;
435
+
436
+ beforeEach(() => {
437
+ serviceRegistry.load(
438
+ ServiceRegistry.mapRemoteCatalog({
439
+ catalog: SERVICE_CATALOGS[0],
440
+ ...fixture,
441
+ })
442
+ );
443
+
444
+ filteredHostA = serviceRegistry.hosts[0];
445
+ filteredHostB = serviceRegistry.hosts[1];
446
+ });
447
+
448
+ it('should return all hosts when called without params', () => {
449
+ filteredHosts = serviceRegistry.filterUrl();
450
+
451
+ assert.deepEqual(filteredHosts, serviceRegistry.hosts);
452
+ });
453
+
454
+ it('should return only service hosts with a specific url', () => {
455
+ [filteredHosts] = serviceRegistry.filterUrl(filteredHostA.url);
456
+
457
+ assert.equal(filteredHosts, filteredHostA);
458
+ });
459
+
460
+ it('should return service hosts for an array of urls', () => {
461
+ filteredHosts = serviceRegistry.filterUrl([filteredHostA.url, filteredHostB.url]);
462
+
463
+ assert.equal(filteredHosts.length, 2);
464
+ assert.isTrue(
465
+ filteredHosts.every((foundHost) => [filteredHostA, filteredHostB].includes(foundHost))
466
+ );
467
+ });
468
+
469
+ it('should return an empty array when given an invalid url', () => {
470
+ filteredHosts = serviceRegistry.filterUrl('invalid');
471
+ assert.equal(filteredHosts.length, 0);
472
+ });
473
+ });
474
+
475
+ describe('#find()', () => {
476
+ let filter;
477
+ let host;
478
+
479
+ beforeEach(() => {
480
+ serviceRegistry.load(ServiceRegistry.mapRemoteCatalog({
481
+ catalog: SERVICE_CATALOGS[0],
482
+ ...fixture
483
+ }));
484
+
485
+ host = serviceRegistry.hosts[0];
486
+
487
+ filter = {
488
+ active: true,
489
+ catalog: host.catalog,
490
+ cluster: host.id,
491
+ local: true,
492
+ priority: true,
493
+ service: host.service,
494
+ url: host.url,
495
+ };
496
+ });
497
+
498
+ it("should call the 'filterActive()' method with params", () => {
499
+ sinon.spy(serviceRegistry, 'filterActive');
500
+ serviceRegistry.find(filter);
501
+ assert.calledWith(serviceRegistry.filterActive, filter.active);
502
+ });
503
+
504
+ it("should call the 'filterCatalog()' method with params", () => {
505
+ sinon.spy(serviceRegistry, 'filterCatalog');
506
+ serviceRegistry.find(filter);
507
+ assert.calledWith(serviceRegistry.filterCatalog, filter.catalog);
508
+ });
509
+
510
+ it("should call the 'filterCluster()' method with params", () => {
511
+ sinon.spy(serviceRegistry, 'filterCluster');
512
+ serviceRegistry.find(filter);
513
+ assert.calledWith(serviceRegistry.filterCluster, filter.cluster);
514
+ });
515
+
516
+ it("should call the 'filterLocal()' method with params", () => {
517
+ sinon.spy(serviceRegistry, 'filterLocal');
518
+ serviceRegistry.find(filter);
519
+ assert.calledWith(serviceRegistry.filterLocal, filter.local);
520
+ });
521
+
522
+ it("should call the 'filterPriority()' method with params", () => {
523
+ sinon.spy(serviceRegistry, 'filterPriority');
524
+ serviceRegistry.find(filter);
525
+ assert.calledWith(serviceRegistry.filterPriority, filter.priority);
526
+ });
527
+
528
+ it("should call the 'filterService()' method with params", () => {
529
+ sinon.spy(serviceRegistry, 'filterService');
530
+ serviceRegistry.find(filter);
531
+ assert.calledWith(serviceRegistry.filterService, filter.service);
532
+ });
533
+
534
+ it("should call the 'filterUrl()' method with params", () => {
535
+ sinon.spy(serviceRegistry, 'filterUrl');
536
+ serviceRegistry.find(filter);
537
+ assert.calledWith(serviceRegistry.filterUrl, filter.url);
538
+ });
539
+
540
+ it('should return an array of filtered hosts', () => {
541
+ const foundHosts = serviceRegistry.find(filter);
542
+
543
+ assert.equal(foundHosts[0], host);
544
+ assert.equal(foundHosts.length, 1);
545
+ });
546
+
547
+ it('should return all of the hosts when called without params', () => {
548
+ const foundHosts = serviceRegistry.find();
549
+
550
+ assert.deepEqual(foundHosts, serviceRegistry.hosts);
551
+ });
552
+ });
553
+
554
+ describe('#load()', () => {
555
+ it('should amend all provided hosts to the hosts array', () => {
556
+ serviceRegistry.load(
557
+ ServiceRegistry.mapRemoteCatalog({
558
+ catalog: SERVICE_CATALOGS[0],
559
+ ...fixture,
560
+ })
561
+ );
562
+
563
+ assert.equal(serviceRegistry.hosts.length, fixtureHosts.length);
564
+ });
565
+
566
+ it('should ignore unloadable hosts', () => {
567
+ const unloadables = ServiceRegistry.mapRemoteCatalog({
568
+ catalog: SERVICE_CATALOGS[0],
569
+ ...fixture,
570
+ }).map((unloadable) => ({...unloadable, catalog: 'invalid'}));
571
+
572
+ serviceRegistry.load(unloadables);
573
+
574
+ assert.equal(serviceRegistry.hosts.length, 0);
575
+ });
576
+
577
+ it('should return itself', () => {
578
+ assert.equal(serviceRegistry.load([]), serviceRegistry);
579
+ });
580
+ });
581
+
582
+ describe('#replaced()', () => {
583
+ let filter;
584
+ let filteredHost;
585
+
586
+ beforeEach(() => {
587
+ serviceRegistry.load(ServiceRegistry.mapRemoteCatalog({
588
+ catalog: SERVICE_CATALOGS[0],
589
+ ...fixture
590
+ }));
591
+
592
+ filteredHost = serviceRegistry.hosts[0];
593
+
594
+ filter = {
595
+ active: true,
596
+ catalog: filteredHost.catalog,
597
+ cluster: filteredHost.id,
598
+ local: true,
599
+ priority: true,
600
+ service: filteredHost.service,
601
+ url: filteredHost.url,
602
+ };
603
+ });
604
+
605
+ it('should mark all hosts as replaced when called without params', () => {
606
+ serviceRegistry.replaced();
607
+ assert.isTrue(serviceRegistry.hosts.every((replacedHost) => replacedHost.replaced));
608
+ });
609
+
610
+ it('should mark the target hosts as replaced', () => {
611
+ serviceRegistry.replaced(filter);
612
+ assert.isTrue(filteredHost.replaced);
613
+ });
614
+
615
+ it('should return the marked host', () => {
616
+ const [replacedHost] = serviceRegistry.replaced(filter);
617
+
618
+ assert.equal(replacedHost, filteredHost);
619
+ });
620
+ });
621
+
622
+ describe('#reset()', () => {
623
+ let filter;
624
+ let filteredHost;
625
+
626
+ beforeEach(() => {
627
+ serviceRegistry.load(ServiceRegistry.mapRemoteCatalog({
628
+ catalog: SERVICE_CATALOGS[0],
629
+ ...fixture
630
+ }));
631
+
632
+ filteredHost = serviceRegistry.hosts[0];
633
+
634
+ filter = {
635
+ url: filteredHost.url,
636
+ };
637
+
638
+ serviceRegistry.failed();
639
+ });
640
+
641
+ it('should reset all hosts when called withour a filter', () => {
642
+ serviceRegistry.reset();
643
+ assert.isTrue(serviceRegistry.hosts.every((resetHost) => resetHost.failed === false));
644
+ });
645
+
646
+ it('should reset the failed status of the target host', () => {
647
+ serviceRegistry.reset(filter);
648
+ assert.isFalse(filteredHost.failed);
649
+ });
650
+
651
+ it('should not reset the failed status of non-targetted hosts', () => {
652
+ serviceRegistry.reset(filter);
653
+ assert.isTrue(
654
+ serviceRegistry.hosts.every((foundHost) => foundHost.failed || foundHost === filteredHost)
655
+ );
656
+ });
657
+
658
+ it('should not reset the replaced status of hosts', () => {
659
+ serviceRegistry.replaced();
660
+ serviceRegistry.reset();
661
+ assert.isTrue(serviceRegistry.hosts.every((foundHost) => foundHost.replaced));
662
+ });
663
+
664
+ it('should return the reset host', () => {
665
+ const [resetHost] = serviceRegistry.reset(filter);
666
+
667
+ assert.equal(resetHost, filteredHost);
668
+ });
669
+ });
670
+
671
+ describe('static methods', () => {
672
+ describe('#mapCatalogName()', () => {
673
+ let index;
674
+ let name;
675
+
676
+ beforeEach(() => {
677
+ index = 0;
678
+ name = SERVICE_CATALOGS[index];
679
+ });
680
+
681
+ it('should map an index to the matching name', () => {
682
+ assert.equal(ServiceRegistry.mapCatalogName({id: index, type: SCET.STRING}), name);
683
+ });
684
+
685
+ it('should map an index to the matching index', () => {
686
+ assert.equal(ServiceRegistry.mapCatalogName({id: index, type: SCET.NUMBER}), index);
687
+ });
688
+
689
+ it('should map a name to the matching index', () => {
690
+ assert.equal(ServiceRegistry.mapCatalogName({id: name, type: SCET.NUMBER}), index);
691
+ });
692
+
693
+ it('should map a name to the matching name', () => {
694
+ assert.equal(ServiceRegistry.mapCatalogName({id: name, type: SCET.STRING}), name);
695
+ });
696
+
697
+ it("should return undefined if an index doesn't exist", () => {
698
+ assert.isUndefined(ServiceRegistry.mapCatalogName({id: -1, type: SCET.NUMBER}));
699
+ });
700
+
701
+ it("should return undefined if a name doesn't exist", () => {
702
+ assert.isUndefined(ServiceRegistry.mapCatalogName({id: 'invalid', type: SCET.NUMBER}));
703
+ });
704
+ });
705
+
706
+ describe('#mapRemoteCatalog()', () => {
707
+ it('should return an array', () => {
708
+ const mappedHosts = ServiceRegistry.mapRemoteCatalog({
709
+ catalog: SERVICE_CATALOGS[0],
710
+ ...fixture,
711
+ });
712
+
713
+ assert.isArray(mappedHosts);
714
+ });
715
+
716
+ it('should include all provided hosts', () => {
717
+ const mappedHosts = ServiceRegistry.mapRemoteCatalog({
718
+ catalog: SERVICE_CATALOGS[0],
719
+ ...fixture,
720
+ });
721
+
722
+ assert.equal(mappedHosts.length, fixtureHosts.length);
723
+ });
724
+
725
+ it('should not map using an invalid catalog name', () => {
726
+ assert.throws(() =>
727
+ ServiceRegistry.mapRemoteCatalog({
728
+ catalog: 'invalid',
729
+ ...fixture,
730
+ })
731
+ );
732
+ });
733
+
734
+ it('should map catalog indexes to catalog names', () => {
735
+ const catalogIndex = 4;
736
+
737
+ const mappedHosts = ServiceRegistry.mapRemoteCatalog({
738
+ catalog: catalogIndex,
739
+ ...fixture,
740
+ });
741
+
742
+ assert.equal(mappedHosts[0].catalog, SERVICE_CATALOGS[catalogIndex]);
743
+ });
744
+ });
745
+ });
746
+ });
747
+ });