@rancher/shell 3.0.1-rc.4 → 3.0.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 (64) hide show
  1. package/assets/data/aws-regions.json +1 -0
  2. package/assets/styles/base/_basic.scss +5 -0
  3. package/assets/styles/base/_mixins.scss +8 -0
  4. package/assets/styles/global/_button.scss +5 -0
  5. package/assets/styles/themes/_dark.scss +2 -0
  6. package/assets/styles/themes/_light.scss +2 -0
  7. package/assets/translations/en-us.yaml +27 -11
  8. package/assets/translations/zh-hans.yaml +1 -1
  9. package/chart/monitoring/StorageClassSelector.vue +1 -1
  10. package/components/AssignTo.vue +1 -0
  11. package/components/AsyncButton.vue +1 -0
  12. package/components/BackLink.vue +8 -2
  13. package/components/PaginatedResourceTable.vue +135 -0
  14. package/components/ResourceList/index.vue +0 -1
  15. package/components/ResourceTable.vue +6 -1
  16. package/components/SortableTable/index.vue +8 -6
  17. package/components/Tabbed/index.vue +35 -2
  18. package/components/form/ResourceLabeledSelect.vue +2 -2
  19. package/components/form/ResourceTabs/index.vue +0 -23
  20. package/components/form/Taints.vue +1 -1
  21. package/components/nav/TopLevelMenu.helper.ts +546 -0
  22. package/components/nav/TopLevelMenu.vue +124 -159
  23. package/components/nav/__tests__/TopLevelMenu.test.ts +338 -326
  24. package/config/pagination-table-headers.js +4 -4
  25. package/config/product/explorer.js +2 -0
  26. package/config/router/routes.js +1 -1
  27. package/config/settings.ts +13 -1
  28. package/core/plugin.ts +8 -1
  29. package/core/types-provisioning.ts +5 -0
  30. package/core/types.ts +26 -1
  31. package/dialog/DrainNode.vue +6 -6
  32. package/edit/catalog.cattle.io.clusterrepo.vue +95 -52
  33. package/edit/provisioning.cattle.io.cluster/index.vue +8 -3
  34. package/list/node.vue +8 -5
  35. package/mixins/resource-fetch-api-pagination.js +40 -5
  36. package/mixins/resource-fetch.js +48 -5
  37. package/models/management.cattle.io.nodepool.js +5 -4
  38. package/models/provisioning.cattle.io.cluster.js +2 -10
  39. package/package.json +6 -6
  40. package/pages/about.vue +22 -0
  41. package/pages/c/_cluster/explorer/__tests__/index.test.ts +36 -24
  42. package/pages/c/_cluster/explorer/index.vue +100 -59
  43. package/pages/home.vue +308 -123
  44. package/plugins/dashboard-store/__tests__/mutations.test.ts +2 -0
  45. package/plugins/dashboard-store/actions.js +29 -19
  46. package/plugins/dashboard-store/getters.js +5 -2
  47. package/plugins/dashboard-store/mutations.js +4 -2
  48. package/plugins/steve/__tests__/mutations.test.ts +2 -1
  49. package/plugins/steve/steve-pagination-utils.ts +25 -2
  50. package/plugins/steve/subscribe.js +22 -8
  51. package/scripts/extension/parse-tag-name +2 -0
  52. package/scripts/test-plugins-build.sh +1 -0
  53. package/store/index.js +31 -9
  54. package/tsconfig.json +7 -1
  55. package/types/resources/settings.d.ts +1 -1
  56. package/types/shell/index.d.ts +1107 -1276
  57. package/types/store/dashboard-store.types.ts +4 -0
  58. package/types/store/pagination.types.ts +13 -0
  59. package/types/store/vuex.d.ts +8 -0
  60. package/types/vue-shim.d.ts +6 -31
  61. package/utils/cluster.js +92 -1
  62. package/utils/pagination-utils.ts +17 -8
  63. package/utils/pagination-wrapper.ts +70 -0
  64. package/utils/uiplugins.ts +18 -4
@@ -1,40 +1,85 @@
1
- import TopLevelMenu from '@shell/components/nav/TopLevelMenu';
1
+ import TopLevelMenu from '@shell/components/nav/TopLevelMenu.vue';
2
2
  import { SETTING } from '@shell/config/settings';
3
3
  import { mount, Wrapper } from '@vue/test-utils';
4
+ import { CAPI, COUNT, MANAGEMENT } from '@shell/config/types';
5
+ import { PINNED_CLUSTERS } from '@shell/store/prefs';
6
+ import { nextTick } from 'vue';
7
+
8
+ /**
9
+ * `clusters` doubles up as both mgmt and prov clusters (don't shoot the messenger)
10
+ */
11
+ const generateStore = (clusters: any[], settings = [{}]) => {
12
+ return {
13
+ getters: {
14
+ 'management/byId': jest.fn(),
15
+ 'management/schemaFor': () => ({}),
16
+ 'management/paginationEnabled': () => false,
17
+ 'i18n/t': jest.fn(),
18
+ 'features/get': jest.fn(),
19
+ 'prefs/theme': jest.fn(),
20
+ defaultClusterId: jest.fn(),
21
+ clusterId: jest.fn(),
22
+ 'type-map/activeProducts': [],
23
+ 'management/all': (type: string) => {
24
+ switch (type) {
25
+ case CAPI.RANCHER_CLUSTER:
26
+ return clusters;
27
+ case MANAGEMENT.CLUSTER:
28
+ return clusters;
29
+ case COUNT:
30
+ return [{ counts: { [MANAGEMENT.CLUSTER]: { summary: { count: clusters.length } } } }];
31
+ case MANAGEMENT.SETTING:
32
+ return settings;
33
+ }
34
+ },
35
+ 'prefs/get': (pref: string) => {
36
+ if (pref === PINNED_CLUSTERS) {
37
+ return [];
38
+ }
39
+ },
40
+ },
41
+ dispatch: (action: string, args: any) => {
42
+ if (action === 'management/findAll' && args.type === CAPI.RANCHER_CLUSTER) {
43
+ return clusters;
44
+ }
45
+ }
46
+ };
47
+ };
4
48
 
5
- // DISCLAIMER: This should not be added here, although we have several store requests which are irrelevant
6
- const defaultStore = {
7
- 'management/byId': jest.fn(),
8
- 'management/schemaFor': () => ({}),
9
- 'i18n/t': jest.fn(),
10
- 'features/get': jest.fn(),
11
- 'prefs/theme': jest.fn(),
12
- defaultClusterId: jest.fn(),
13
- clusterId: jest.fn(),
14
- 'type-map/activeProducts': [],
49
+ const waitForIt = async() => {
50
+ jest.advanceTimersByTime(1000); // Wait for debounced call to fetch updated cluster list
51
+ await nextTick(); // Wait for changes to cluster list to trigger changes
15
52
  };
16
53
 
17
54
  describe('topLevelMenu', () => {
18
- it('should display clusters', () => {
55
+ beforeEach(() => {
56
+ jest.useFakeTimers();
57
+ });
58
+
59
+ afterEach(() => {
60
+ jest.runOnlyPendingTimers();
61
+ jest.useRealTimers();
62
+ });
63
+
64
+ it('should display clusters', async() => {
65
+ const clusters = [{
66
+ name: 'whatever',
67
+ id: 'an-id1',
68
+ mgmt: { id: 'an-id1' },
69
+ }];
19
70
  const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
20
71
  global: {
21
72
  mocks: {
22
- $store: {
23
- getters: {
24
- 'management/all': () => [{
25
- name: 'whatever',
26
- id: 'an-id1',
27
- mgmt: { id: 'an-id1' },
28
- }],
29
- ...defaultStore
30
- },
31
- },
73
+ $route: {},
74
+ $store: { ...generateStore(clusters) },
32
75
  },
33
76
 
34
77
  stubs: ['BrandImage', 'router-link'],
35
78
  },
36
79
  });
37
80
 
81
+ await waitForIt();
82
+
38
83
  const cluster = wrapper.find('[data-testid="top-level-menu-cluster-0"]');
39
84
 
40
85
  expect(cluster.exists()).toBe(true);
@@ -42,57 +87,49 @@ describe('topLevelMenu', () => {
42
87
 
43
88
  it('should show local cluster always on top of the list of clusters (unpinned and ready clusters)', async() => {
44
89
  const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
45
- data: () => {
46
- return { hasProvCluster: true, showPinClusters: true };
47
- },
48
-
49
90
  global: {
50
91
  mocks: {
92
+ $route: {},
51
93
  $store: {
52
- getters: {
53
- // these objs are doubling as a prov clusters
54
- // from which the "description" field comes from
55
- // This is triggered by the "hasProvCluster" above
56
- // (check all "management/all" getters on the component code)
57
- 'management/all': () => [
58
- {
59
- name: 'x32-cwf5-name',
60
- id: 'an-id1',
61
- mgmt: { id: 'an-id1' },
62
- nameDisplay: 'c-cluster',
63
- isReady: true
64
- },
65
- {
66
- name: 'x33-cwf5-name',
67
- id: 'an-id2',
68
- mgmt: { id: 'an-id2' },
69
- nameDisplay: 'a-cluster',
70
- isReady: true
71
- },
72
- {
73
- name: 'x34-cwf5-name',
74
- id: 'an-id3',
75
- mgmt: { id: 'an-id3' },
76
- nameDisplay: 'b-cluster',
77
- isReady: true
78
- },
79
- {
80
- name: 'local-name',
81
- id: 'local',
82
- mgmt: { id: 'local' },
83
- nameDisplay: 'local',
84
- isReady: true
85
- },
86
- ],
87
- ...defaultStore
88
- },
89
- },
94
+ ...generateStore([
95
+ {
96
+ name: 'x32-cwf5-name',
97
+ id: 'an-id1',
98
+ mgmt: { id: 'an-id1' },
99
+ nameDisplay: 'c-cluster',
100
+ isReady: true
101
+ },
102
+ {
103
+ name: 'x33-cwf5-name',
104
+ id: 'an-id2',
105
+ mgmt: { id: 'an-id2' },
106
+ nameDisplay: 'a-cluster',
107
+ isReady: true
108
+ },
109
+ {
110
+ name: 'x34-cwf5-name',
111
+ id: 'an-id3',
112
+ mgmt: { id: 'an-id3' },
113
+ nameDisplay: 'b-cluster',
114
+ isReady: true
115
+ },
116
+ {
117
+ name: 'local-name',
118
+ id: 'local',
119
+ mgmt: { id: 'local' },
120
+ nameDisplay: 'local',
121
+ isReady: true
122
+ },
123
+ ])
124
+ }
90
125
  },
91
126
 
92
127
  stubs: ['BrandImage', 'router-link'],
93
128
  },
94
129
  });
95
130
 
131
+ await waitForIt();
132
+
96
133
  expect(wrapper.find('[data-testid="top-level-menu-cluster-0"] .cluster-name p').text()).toStrictEqual('local');
97
134
  expect(wrapper.find('[data-testid="top-level-menu-cluster-1"] .cluster-name p').text()).toStrictEqual('a-cluster');
98
135
  expect(wrapper.find('[data-testid="top-level-menu-cluster-2"] .cluster-name p').text()).toStrictEqual('b-cluster');
@@ -100,58 +137,50 @@ describe('topLevelMenu', () => {
100
137
  });
101
138
 
102
139
  it('should show local cluster always on top of the list of clusters (unpinned and mix ready/unready clusters)', async() => {
103
- const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
104
- data: () => {
105
- return { hasProvCluster: true, showPinClusters: true };
140
+ const clusters = [
141
+ {
142
+ name: 'x32-cwf5-name',
143
+ id: 'an-id1',
144
+ mgmt: { id: 'an-id1' },
145
+ nameDisplay: 'c-cluster',
146
+ isReady: true
147
+ },
148
+ {
149
+ name: 'x33-cwf5-name',
150
+ id: 'an-id2',
151
+ mgmt: { id: 'an-id2' },
152
+ nameDisplay: 'a-cluster',
153
+ isReady: false
106
154
  },
155
+ {
156
+ name: 'x34-cwf5-name',
157
+ id: 'an-id3',
158
+ mgmt: { id: 'an-id3' },
159
+ nameDisplay: 'b-cluster',
160
+ isReady: true
161
+ },
162
+ {
163
+ name: 'local-name',
164
+ id: 'local',
165
+ mgmt: { id: 'local' },
166
+ nameDisplay: 'local',
167
+ isReady: true,
168
+ isLocal: true,
169
+ },
170
+ ];
107
171
 
172
+ const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
108
173
  global: {
109
174
  mocks: {
110
- $store: {
111
- getters: {
112
- // these objs are doubling as a prov clusters
113
- // from which the "description" field comes from
114
- // This is triggered by the "hasProvCluster" above
115
- // (check all "management/all" getters on the component code)
116
- 'management/all': () => [
117
- {
118
- name: 'x32-cwf5-name',
119
- id: 'an-id1',
120
- mgmt: { id: 'an-id1' },
121
- nameDisplay: 'c-cluster',
122
- isReady: true
123
- },
124
- {
125
- name: 'x33-cwf5-name',
126
- id: 'an-id2',
127
- mgmt: { id: 'an-id2' },
128
- nameDisplay: 'a-cluster',
129
- isReady: false
130
- },
131
- {
132
- name: 'x34-cwf5-name',
133
- id: 'an-id3',
134
- mgmt: { id: 'an-id3' },
135
- nameDisplay: 'b-cluster',
136
- isReady: true
137
- },
138
- {
139
- name: 'local-name',
140
- id: 'local',
141
- mgmt: { id: 'local' },
142
- nameDisplay: 'local',
143
- isReady: true
144
- },
145
- ],
146
- ...defaultStore
147
- },
148
- },
175
+ $route: {},
176
+ $store: { ...generateStore(clusters) }
149
177
  },
150
-
151
178
  stubs: ['BrandImage', 'router-link'],
152
179
  },
153
180
  });
154
181
 
182
+ await waitForIt();
183
+
155
184
  expect(wrapper.find('[data-testid="top-level-menu-cluster-0"] .cluster-name p').text()).toStrictEqual('local');
156
185
  expect(wrapper.find('[data-testid="top-level-menu-cluster-1"] .cluster-name p').text()).toStrictEqual('b-cluster');
157
186
  expect(wrapper.find('[data-testid="top-level-menu-cluster-2"] .cluster-name p').text()).toStrictEqual('c-cluster');
@@ -160,61 +189,53 @@ describe('topLevelMenu', () => {
160
189
 
161
190
  it('should show local cluster always on top of the list of clusters (pinned and ready clusters)', async() => {
162
191
  const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
163
- data: () => {
164
- return { hasProvCluster: true, showPinClusters: true };
165
- },
166
-
167
192
  global: {
168
193
  mocks: {
194
+ $route: {},
169
195
  $store: {
170
- getters: {
171
- // these objs are doubling as a prov clusters
172
- // from which the "description" field comes from
173
- // This is triggered by the "hasProvCluster" above
174
- // (check all "management/all" getters on the component code)
175
- 'management/all': () => [
176
- {
177
- name: 'x32-cwf5-name',
178
- id: 'an-id1',
179
- mgmt: { id: 'an-id1' },
180
- nameDisplay: 'c-cluster',
181
- isReady: true,
182
- pinned: true
183
- },
184
- {
185
- name: 'x33-cwf5-name',
186
- id: 'an-id2',
187
- mgmt: { id: 'an-id2' },
188
- nameDisplay: 'a-cluster',
189
- isReady: true,
190
- pinned: true
191
- },
192
- {
193
- name: 'x34-cwf5-name',
194
- id: 'an-id3',
195
- mgmt: { id: 'an-id3' },
196
- nameDisplay: 'b-cluster',
197
- isReady: true,
198
- pinned: true
199
- },
200
- {
201
- name: 'local-name',
202
- id: 'local',
203
- mgmt: { id: 'local' },
204
- nameDisplay: 'local',
205
- isReady: true,
206
- pinned: true
207
- },
208
- ],
209
- ...defaultStore
210
- },
211
- },
196
+ ...generateStore([
197
+ {
198
+ name: 'x32-cwf5-name',
199
+ id: 'an-id1',
200
+ mgmt: { id: 'an-id1' },
201
+ nameDisplay: 'c-cluster',
202
+ isReady: true,
203
+ pinned: true
204
+ },
205
+ {
206
+ name: 'x33-cwf5-name',
207
+ id: 'an-id2',
208
+ mgmt: { id: 'an-id2' },
209
+ nameDisplay: 'a-cluster',
210
+ isReady: true,
211
+ pinned: true
212
+ },
213
+ {
214
+ name: 'x34-cwf5-name',
215
+ id: 'an-id3',
216
+ mgmt: { id: 'an-id3' },
217
+ nameDisplay: 'b-cluster',
218
+ isReady: true,
219
+ pinned: true
220
+ },
221
+ {
222
+ name: 'local-name',
223
+ id: 'local',
224
+ mgmt: { id: 'local' },
225
+ nameDisplay: 'local',
226
+ isReady: true,
227
+ pinned: true
228
+ },
229
+ ])
230
+ }
212
231
  },
213
232
 
214
233
  stubs: ['BrandImage', 'router-link'],
215
234
  },
216
235
  });
217
236
 
237
+ await waitForIt();
238
+
218
239
  expect(wrapper.find('[data-testid="pinned-ready-cluster-0"] .cluster-name p').text()).toStrictEqual('local');
219
240
  expect(wrapper.find('[data-testid="pinned-ready-cluster-1"] .cluster-name p').text()).toStrictEqual('a-cluster');
220
241
  expect(wrapper.find('[data-testid="pinned-ready-cluster-2"] .cluster-name p').text()).toStrictEqual('b-cluster');
@@ -229,55 +250,51 @@ describe('topLevelMenu', () => {
229
250
 
230
251
  global: {
231
252
  mocks: {
253
+ $route: {},
232
254
  $store: {
233
- getters: {
234
- // these objs are doubling as a prov clusters
235
- // from which the "description" field comes from
236
- // This is triggered by the "hasProvCluster" above
237
- // (check all "management/all" getters on the component code)
238
- 'management/all': () => [
239
- {
240
- name: 'x32-cwf5-name',
241
- id: 'an-id1',
242
- mgmt: { id: 'an-id1' },
243
- nameDisplay: 'c-cluster',
244
- isReady: true,
245
- pinned: true
246
- },
247
- {
248
- name: 'x33-cwf5-name',
249
- id: 'an-id2',
250
- mgmt: { id: 'an-id2' },
251
- nameDisplay: 'a-cluster',
252
- isReady: true,
253
- pinned: true
254
- },
255
- {
256
- name: 'x34-cwf5-name',
257
- id: 'an-id3',
258
- mgmt: { id: 'an-id3' },
259
- nameDisplay: 'b-cluster',
260
- isReady: false,
261
- pinned: true
262
- },
263
- {
264
- name: 'local-name',
265
- id: 'local',
266
- mgmt: { id: 'local' },
267
- nameDisplay: 'local',
268
- isReady: true,
269
- pinned: true
270
- },
271
- ],
272
- ...defaultStore
273
- },
274
- },
255
+ ...generateStore([
256
+ {
257
+ name: 'x32-cwf5-name',
258
+ id: 'an-id1',
259
+ mgmt: { id: 'an-id1' },
260
+ nameDisplay: 'c-cluster',
261
+ isReady: true,
262
+ pinned: true
263
+ },
264
+ {
265
+ name: 'x33-cwf5-name',
266
+ id: 'an-id2',
267
+ mgmt: { id: 'an-id2' },
268
+ nameDisplay: 'a-cluster',
269
+ isReady: true,
270
+ pinned: true
271
+ },
272
+ {
273
+ name: 'x34-cwf5-name',
274
+ id: 'an-id3',
275
+ mgmt: { id: 'an-id3' },
276
+ nameDisplay: 'b-cluster',
277
+ isReady: false,
278
+ pinned: true
279
+ },
280
+ {
281
+ name: 'local-name',
282
+ id: 'local',
283
+ mgmt: { id: 'local' },
284
+ nameDisplay: 'local',
285
+ isReady: true,
286
+ pinned: true
287
+ },
288
+ ])
289
+ }
275
290
  },
276
291
 
277
292
  stubs: ['BrandImage', 'router-link'],
278
293
  },
279
294
  });
280
295
 
296
+ await waitForIt();
297
+
281
298
  expect(wrapper.find('[data-testid="pinned-ready-cluster-0"] .cluster-name p').text()).toStrictEqual('local');
282
299
  expect(wrapper.find('[data-testid="pinned-ready-cluster-1"] .cluster-name p').text()).toStrictEqual('a-cluster');
283
300
  expect(wrapper.find('[data-testid="pinned-ready-cluster-2"] .cluster-name p').text()).toStrictEqual('c-cluster');
@@ -286,59 +303,48 @@ describe('topLevelMenu', () => {
286
303
 
287
304
  it('should show description if it is available on the prov cluster', async() => {
288
305
  const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
289
- data: () => {
290
- return { hasProvCluster: true, showPinClusters: true };
291
- },
292
-
293
306
  global: {
294
307
  mocks: {
308
+ $route: {},
295
309
  $store: {
296
- getters: {
297
- // these objs are doubling as a prov clusters
298
- // from which the "description" field comes from
299
- // This is triggered by the "hasProvCluster" above
300
- // (check all "management/all" getters on the component code)
301
- // https://github.com/rancher/dashboard/issues/10441
302
- 'management/all': () => [
303
- // pinned ready cluster
304
- {
305
- name: 'whatever',
306
- id: 'an-id1',
307
- mgmt: { id: 'an-id1' },
308
- description: 'some-description1',
309
- nameDisplay: 'some-label',
310
- isReady: true,
311
- pinned: true
312
- },
313
- // pinned NOT ready cluster
314
- {
315
- name: 'whatever',
316
- id: 'an-id2',
317
- mgmt: { id: 'an-id2' },
318
- description: 'some-description2',
319
- nameDisplay: 'some-label',
320
- pinned: true
321
- },
322
- // unpinned ready cluster
323
- {
324
- name: 'whatever',
325
- id: 'an-id3',
326
- mgmt: { id: 'an-id3' },
327
- description: 'some-description3',
328
- nameDisplay: 'some-label',
329
- isReady: true
330
- },
331
- // unpinned NOT ready cluster
332
- {
333
- name: 'whatever',
334
- id: 'an-id4',
335
- mgmt: { id: 'an-id4' },
336
- description: 'some-description4',
337
- nameDisplay: 'some-label'
338
- },
339
- ],
340
- ...defaultStore
341
- },
310
+ ...generateStore([
311
+ // pinned ready cluster
312
+ {
313
+ name: 'whatever',
314
+ id: 'an-id1',
315
+ mgmt: { id: 'an-id1' },
316
+ description: 'some-description1',
317
+ nameDisplay: 'some-label',
318
+ isReady: true,
319
+ pinned: true
320
+ },
321
+ // pinned NOT ready cluster
322
+ {
323
+ name: 'whatever',
324
+ id: 'an-id2',
325
+ mgmt: { id: 'an-id2' },
326
+ description: 'some-description2',
327
+ nameDisplay: 'some-label',
328
+ pinned: true
329
+ },
330
+ // unpinned ready cluster
331
+ {
332
+ name: 'whatever',
333
+ id: 'an-id3',
334
+ mgmt: { id: 'an-id3' },
335
+ description: 'some-description3',
336
+ nameDisplay: 'some-label',
337
+ isReady: true
338
+ },
339
+ // unpinned NOT ready cluster
340
+ {
341
+ name: 'whatever',
342
+ id: 'an-id4',
343
+ mgmt: { id: 'an-id4' },
344
+ description: 'some-description4',
345
+ nameDisplay: 'some-label'
346
+ },
347
+ ])
342
348
  },
343
349
  },
344
350
 
@@ -346,6 +352,8 @@ describe('topLevelMenu', () => {
346
352
  },
347
353
  });
348
354
 
355
+ await waitForIt();
356
+
349
357
  const description1 = wrapper.find('[data-testid="pinned-menu-cluster-an-id1"] .description');
350
358
  const description2 = wrapper.find('[data-testid="pinned-menu-cluster-disabled-an-id2"] .description');
351
359
  const description3 = wrapper.find('[data-testid="menu-cluster-an-id3"] .description');
@@ -359,65 +367,57 @@ describe('topLevelMenu', () => {
359
367
 
360
368
  it('should show description if it is available on the mgmt cluster (relevant for RKE1/ember world)', async() => {
361
369
  const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
362
- data: () => {
363
- return { hasProvCluster: true, showPinClusters: true };
364
- },
365
-
366
370
  global: {
367
371
  mocks: {
372
+ $route: {},
368
373
  $store: {
369
- getters: {
370
- // "hasProvCluster" as false will make this getter
371
- // a mgmt cluster only return, therefore covering the
372
- // scenario where descriptions come from RKE1/ember world clusters
373
- // https://github.com/rancher/dashboard/issues/10441
374
- 'management/all': () => [
375
- // pinned ready cluster
376
- {
377
- name: 'whatever',
378
- id: 'an-id1',
379
- mgmt: { id: 'an-id1' },
380
- description: 'some-description1',
381
- nameDisplay: 'some-label',
382
- isReady: true,
383
- pinned: true
384
- },
385
- // pinned NOT ready cluster
386
- {
387
- name: 'whatever',
388
- id: 'an-id2',
389
- mgmt: { id: 'an-id2' },
390
- description: 'some-description2',
391
- nameDisplay: 'some-label',
392
- pinned: true
393
- },
394
- // unpinned ready cluster
395
- {
396
- name: 'whatever',
397
- id: 'an-id3',
398
- mgmt: { id: 'an-id3' },
399
- description: 'some-description3',
400
- nameDisplay: 'some-label',
401
- isReady: true
402
- },
403
- // unpinned NOT ready cluster
404
- {
405
- name: 'whatever',
406
- id: 'an-id4',
407
- mgmt: { id: 'an-id4' },
408
- description: 'some-description4',
409
- nameDisplay: 'some-label'
410
- },
411
- ],
412
- ...defaultStore
413
- },
414
- },
374
+ ...generateStore([
375
+ // pinned ready cluster
376
+ {
377
+ name: 'whatever',
378
+ id: 'an-id1',
379
+ mgmt: { id: 'an-id1' },
380
+ description: 'some-description1',
381
+ nameDisplay: 'some-label',
382
+ isReady: true,
383
+ pinned: true
384
+ },
385
+ // pinned NOT ready cluster
386
+ {
387
+ name: 'whatever',
388
+ id: 'an-id2',
389
+ mgmt: { id: 'an-id2' },
390
+ description: 'some-description2',
391
+ nameDisplay: 'some-label',
392
+ pinned: true
393
+ },
394
+ // unpinned ready cluster
395
+ {
396
+ name: 'whatever',
397
+ id: 'an-id3',
398
+ mgmt: { id: 'an-id3' },
399
+ description: 'some-description3',
400
+ nameDisplay: 'some-label',
401
+ isReady: true
402
+ },
403
+ // unpinned NOT ready cluster
404
+ {
405
+ name: 'whatever',
406
+ id: 'an-id4',
407
+ mgmt: { id: 'an-id4' },
408
+ description: 'some-description4',
409
+ nameDisplay: 'some-label'
410
+ },
411
+ ]),
412
+ }
415
413
  },
416
414
 
417
415
  stubs: ['BrandImage', 'router-link'],
418
416
  },
419
417
  });
420
418
 
419
+ await waitForIt();
420
+
421
421
  const description1 = wrapper.find('[data-testid="pinned-menu-cluster-an-id1"] .description');
422
422
  const description2 = wrapper.find('[data-testid="pinned-menu-cluster-disabled-an-id2"] .description');
423
423
  const description3 = wrapper.find('[data-testid="menu-cluster-an-id3"] .description');
@@ -429,13 +429,15 @@ describe('topLevelMenu', () => {
429
429
  expect(description4.text()).toStrictEqual('some-description4');
430
430
  });
431
431
 
432
- it('should not "crash" the component if the structure of banner settings is in an old format', () => {
432
+ it('should not "crash" the component if the structure of banner settings is in an old format', async() => {
433
433
  const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
434
434
  global: {
435
435
  mocks: {
436
+ $route: {},
436
437
  $store: {
437
- getters: {
438
- 'management/all': () => [{ name: 'whatever' },
438
+ ...generateStore(
439
+ [{ name: 'whatever' }],
440
+ [
439
441
  // object based on https://github.com/rancher/dashboard/issues/10140#issuecomment-1883252402
440
442
  {
441
443
  id: SETTING.BANNERS,
@@ -448,16 +450,18 @@ describe('topLevelMenu', () => {
448
450
  showHeader: 'true',
449
451
  showFooter: 'true'
450
452
  })
451
- }],
452
- ...defaultStore
453
- },
454
- },
453
+ }
454
+ ]
455
+ ),
456
+ }
455
457
  },
456
458
 
457
459
  stubs: ['BrandImage', 'router-link'],
458
460
  },
459
461
  });
460
462
 
463
+ await waitForIt();
464
+
461
465
  expect(wrapper.vm.sideMenuStyle).toStrictEqual({
462
466
  marginBottom: '2em',
463
467
  marginTop: '2em'
@@ -466,21 +470,21 @@ describe('topLevelMenu', () => {
466
470
 
467
471
  describe('searching a term', () => {
468
472
  describe('should displays a no results message if have clusters but', () => {
469
- it('given no matching clusters', () => {
473
+ it('given no matching clusters', async() => {
470
474
  const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
471
475
  data: () => ({ clusterFilter: 'whatever' }),
472
476
 
473
477
  global: {
474
478
  mocks: {
479
+ $route: {},
475
480
  $store: {
476
- getters: {
477
- 'management/all': () => [{
481
+ ...generateStore([
482
+ {
478
483
  id: 'an-id1',
479
484
  mgmt: { id: 'an-id1' },
480
485
  nameDisplay: 'something else'
481
- }],
482
- ...defaultStore
483
- },
486
+ }
487
+ ])
484
488
  },
485
489
  },
486
490
 
@@ -488,27 +492,29 @@ describe('topLevelMenu', () => {
488
492
  },
489
493
  });
490
494
 
495
+ await waitForIt();
496
+
491
497
  const noResults = wrapper.find('[data-testid="top-level-menu-no-results"]');
492
498
 
493
499
  expect(noResults.exists()).toBe(true);
494
500
  });
495
501
 
496
- it('given no matched pinned clusters', () => {
502
+ it('given no matched pinned clusters', async() => {
497
503
  const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
498
504
  data: () => ({ clusterFilter: 'whatever' }),
499
505
 
500
506
  global: {
501
507
  mocks: {
508
+ $route: {},
502
509
  $store: {
503
- getters: {
504
- 'management/all': () => [{
510
+ ...generateStore([
511
+ {
505
512
  id: 'an-id1',
506
513
  mgmt: { id: 'an-id1' },
507
514
  nameDisplay: 'something else',
508
515
  pinned: true
509
- }],
510
- ...defaultStore
511
- },
516
+ }
517
+ ])
512
518
  },
513
519
  },
514
520
 
@@ -516,6 +522,8 @@ describe('topLevelMenu', () => {
516
522
  },
517
523
  });
518
524
 
525
+ await waitForIt();
526
+
519
527
  const noResults = wrapper.find('[data-testid="top-level-menu-no-results"]');
520
528
 
521
529
  expect(noResults.exists()).toBe(true);
@@ -523,22 +531,22 @@ describe('topLevelMenu', () => {
523
531
  });
524
532
 
525
533
  describe('should not displays a no results message', () => {
526
- it('given matching clusters', () => {
534
+ it('given matching clusters', async() => {
527
535
  const search = 'you found me';
528
536
  const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
529
537
  data: () => ({ clusterFilter: search }),
530
538
 
531
539
  global: {
532
540
  mocks: {
541
+ $route: {},
533
542
  $store: {
534
- getters: {
535
- 'management/all': () => [{
543
+ ...generateStore([
544
+ {
536
545
  id: 'an-id1',
537
546
  mgmt: { id: 'an-id1' },
538
547
  nameDisplay: search
539
- }],
540
- ...defaultStore
541
- },
548
+ }
549
+ ])
542
550
  },
543
551
  },
544
552
 
@@ -546,29 +554,31 @@ describe('topLevelMenu', () => {
546
554
  },
547
555
  });
548
556
 
557
+ await waitForIt();
558
+
549
559
  const noResults = wrapper.find('[data-testid="top-level-menu-no-results"]');
550
560
 
551
561
  expect(wrapper.vm.clustersFiltered).toHaveLength(1);
552
562
  expect(noResults.exists()).toBe(false);
553
563
  });
554
564
 
555
- it('given clusters with status pinned', () => {
565
+ it('given clusters with status pinned', async() => {
556
566
  const search = 'you found me';
557
567
  const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
558
568
  data: () => ({ clusterFilter: search }),
559
569
 
560
570
  global: {
561
571
  mocks: {
572
+ $route: {},
562
573
  $store: {
563
- getters: {
564
- 'management/all': () => [{
574
+ ...generateStore([
575
+ {
565
576
  nameDisplay: search,
566
577
  pinned: true,
567
578
  id: 'an-id1',
568
579
  mgmt: { id: 'an-id1' },
569
- }],
570
- ...defaultStore
571
- },
580
+ }
581
+ ])
572
582
  },
573
583
  },
574
584
 
@@ -576,6 +586,8 @@ describe('topLevelMenu', () => {
576
586
  },
577
587
  });
578
588
 
589
+ await waitForIt();
590
+
579
591
  const noResults = wrapper.find('[data-testid="top-level-menu-no-results"]');
580
592
 
581
593
  expect(wrapper.vm.pinFiltered).toHaveLength(1);