@rancher/shell 0.3.27 → 0.3.28

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 (65) hide show
  1. package/assets/translations/en-us.yaml +4 -20
  2. package/assets/translations/zh-hans.yaml +0 -23
  3. package/chart/gatekeeper.vue +2 -11
  4. package/chart/istio.vue +1 -10
  5. package/chart/logging/index.vue +2 -11
  6. package/chart/monitoring/index.vue +1 -9
  7. package/chart/rancher-backup/index.vue +1 -9
  8. package/components/Carousel.vue +2 -1
  9. package/components/formatter/ClusterProvider.vue +1 -18
  10. package/components/nav/WindowManager/ContainerLogs.vue +22 -19
  11. package/config/product/manager.js +0 -13
  12. package/config/types.js +0 -4
  13. package/edit/management.cattle.io.project.vue +1 -52
  14. package/edit/management.cattle.io.setting.vue +31 -2
  15. package/edit/provisioning.cattle.io.cluster/Basics.vue +6 -107
  16. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +0 -3
  17. package/edit/provisioning.cattle.io.cluster/rke2.vue +3 -128
  18. package/middleware/authenticated.js +4 -2
  19. package/models/__tests__/management.cattle.io.cluster.test.ts +19 -0
  20. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +90 -0
  21. package/models/cluster.x-k8s.io.machine.js +1 -1
  22. package/models/management.cattle.io.cluster.js +4 -0
  23. package/models/management.cattle.io.project.js +0 -36
  24. package/models/management.cattle.io.setting.js +11 -7
  25. package/models/provisioning.cattle.io.cluster.js +16 -4
  26. package/package.json +1 -1
  27. package/pages/auth/setup.vue +38 -1
  28. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +2 -17
  29. package/pages/c/_cluster/apps/charts/index.vue +0 -15
  30. package/pages/c/_cluster/apps/charts/install.helpers.js +2 -13
  31. package/pages/c/_cluster/apps/charts/install.vue +1 -1
  32. package/pages/c/_cluster/explorer/index.vue +0 -47
  33. package/pages/c/_cluster/manager/pages/_page.vue +4 -5
  34. package/rancher-components/BadgeState/BadgeState.vue +1 -5
  35. package/rancher-components/Banner/Banner.test.ts +1 -51
  36. package/rancher-components/Banner/Banner.vue +53 -134
  37. package/rancher-components/Card/Card.vue +7 -24
  38. package/rancher-components/Form/Checkbox/Checkbox.test.ts +29 -20
  39. package/rancher-components/Form/Checkbox/Checkbox.vue +20 -45
  40. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +8 -2
  41. package/rancher-components/Form/LabeledInput/LabeledInput.vue +10 -22
  42. package/rancher-components/Form/Radio/RadioButton.vue +13 -30
  43. package/rancher-components/Form/Radio/RadioGroup.vue +7 -26
  44. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -7
  45. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +38 -25
  46. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +11 -23
  47. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +5 -19
  48. package/rancher-components/StringList/StringList.test.ts +49 -453
  49. package/rancher-components/StringList/StringList.vue +58 -92
  50. package/rancher-components/components/StringList/StringList.test.ts +270 -0
  51. package/rancher-components/components/StringList/StringList.vue +57 -18
  52. package/store/prefs.js +0 -3
  53. package/types/shell/index.d.ts +22 -16
  54. package/utils/custom-validators.js +0 -2
  55. package/utils/error.js +16 -1
  56. package/utils/validators/formRules/__tests__/index.test.ts +49 -4
  57. package/utils/validators/formRules/index.ts +12 -9
  58. package/utils/validators/setting.js +6 -10
  59. package/.DS_Store +0 -0
  60. package/components/ChartPsp.vue +0 -76
  61. package/components/__tests__/ChartPsp.test.ts +0 -75
  62. package/components/formatter/__tests__/ClusterProvider.test.ts +0 -28
  63. package/rancher-components/Card/Card.test.ts +0 -37
  64. package/rancher-components/Form/Radio/RadioButton.test.ts +0 -31
  65. package/yarn-error.log +0 -200
@@ -82,6 +82,13 @@ export default Vue.extend({
82
82
  return {} as ErrorMessages;
83
83
  },
84
84
  },
85
+ /**
86
+ * Enables bulk addition and defines the delimiter to split the input string.
87
+ */
88
+ bulkAdditionDelimiter: {
89
+ type: RegExp,
90
+ default: null,
91
+ }
85
92
  },
86
93
  data() {
87
94
  return {
@@ -125,13 +132,9 @@ export default Vue.extend({
125
132
  },
126
133
 
127
134
  methods: {
128
- onChange(value: string) {
135
+ onChange(value: string, index?: number) {
129
136
  this.value = value;
130
-
131
- const items = [
132
- ...this.items,
133
- this.value
134
- ];
137
+ const items = this.addValueToItems(this.items, value, index);
135
138
 
136
139
  this.toggleError(
137
140
  'duplicate',
@@ -321,10 +324,7 @@ export default Vue.extend({
321
324
  const value = this.value?.trim();
322
325
 
323
326
  if (value) {
324
- const items = [
325
- ...this.items,
326
- value,
327
- ];
327
+ const items = this.addValueToItems(this.items, value);
328
328
 
329
329
  if (!hasDuplicatedStrings(items, this.caseSensitive)) {
330
330
  this.updateItems(items);
@@ -343,12 +343,8 @@ export default Vue.extend({
343
343
  const value = this.value?.trim();
344
344
 
345
345
  if (value) {
346
- const items = [...this.items];
347
- const index = findStringIndex(items, item, false);
348
-
349
- if (index !== -1) {
350
- items[index] = value;
351
- }
346
+ const index = findStringIndex(this.items, item, false);
347
+ const items = index !== -1 ? this.addValueToItems(this.items, value, index) : this.items;
352
348
 
353
349
  if (!hasDuplicatedStrings(items, this.caseSensitive)) {
354
350
  this.updateItems(items);
@@ -360,6 +356,49 @@ export default Vue.extend({
360
356
  }
361
357
  },
362
358
 
359
+ /**
360
+ * Add a new or update an exiting item in the items list.
361
+ *
362
+ * @param items The current items list.
363
+ * @param value The new value to be added.
364
+ * @param index The list index of the item to be updated (optional).
365
+ * @returns Updated items list.
366
+ */
367
+ addValueToItems(items: string[], value: string, index?: number): string[] {
368
+ const updatedItems = [...items];
369
+
370
+ // Add new item
371
+ if (index === undefined) {
372
+ if (this.bulkAdditionDelimiter && value.search(this.bulkAdditionDelimiter) >= 0) {
373
+ updatedItems.push(...this.splitBulkValue(value));
374
+ } else {
375
+ updatedItems.push(value);
376
+ }
377
+ } else { // Update existing item
378
+ if (this.bulkAdditionDelimiter && value.search(this.bulkAdditionDelimiter) >= 0) {
379
+ updatedItems.splice(index, 1, ...this.splitBulkValue(value));
380
+ } else {
381
+ updatedItems[index] = value;
382
+ }
383
+ }
384
+
385
+ return updatedItems;
386
+ },
387
+
388
+ /**
389
+ * Split the value by the defined delimiter and remove empty strings.
390
+ *
391
+ * @param value The value to be split.
392
+ * @returns Array containing split values.
393
+ */
394
+ splitBulkValue(value: string): string[] {
395
+ return value
396
+ .split(this.bulkAdditionDelimiter)
397
+ .filter((item) => {
398
+ return item.trim().length > 0;
399
+ });
400
+ },
401
+
363
402
  /**
364
403
  * Remove an item from items list
365
404
  */
@@ -393,7 +432,7 @@ export default Vue.extend({
393
432
  @dblclick="onClickEmptyBody()"
394
433
  >
395
434
  <div
396
- v-for="item in items"
435
+ v-for="(item, index) in items"
397
436
  :key="item"
398
437
  :ref="item"
399
438
  :class="{
@@ -421,7 +460,7 @@ export default Vue.extend({
421
460
  :data-testid="`item-edit-${item}`"
422
461
  class="edit-input static"
423
462
  :value="value != null ? value : item"
424
- @input="onChange($event)"
463
+ @input="onChange($event, index)"
425
464
  @blur.prevent="updateItem(item)"
426
465
  @keydown.native.enter="updateItem(item, !errors.duplicate)"
427
466
  />
package/store/prefs.js CHANGED
@@ -112,9 +112,6 @@ export const _RKE1 = 'rke1';
112
112
  export const _RKE2 = 'rke2';
113
113
  export const PROVISIONER = create('provisioner', _RKE2, { options: [_RKE1, _RKE2] });
114
114
 
115
- // Promo for Pod Security Policies (PSPs) being deprecated on kube version 1.25 on Cluster Dashboard page
116
- export const PSP_DEPRECATION_BANNER = create('hide-psp-deprecation-banner', false, { parseJSON });
117
-
118
115
  // Maximum number of clusters to show in the slide-in menu
119
116
  export const MENU_MAX_CLUSTERS = 10;
120
117
  // Prompt for confirm when scaling down node pool in GUI and save the pref
@@ -1765,8 +1765,6 @@ export const NODE: "node";
1765
1765
  export const NETWORK_POLICY: "networking.k8s.io.networkpolicy";
1766
1766
  export const POD: "pod";
1767
1767
  export const POD_DISRUPTION_BUDGET: "policy.poddisruptionbudget";
1768
- export const PSP: "policy.podsecuritypolicy";
1769
- export const PSPS: "policy.podsecuritypolicies";
1770
1768
  export const PV: "persistentvolume";
1771
1769
  export const PVC: "persistentvolumeclaim";
1772
1770
  export const RESOURCE_QUOTA: "resourcequota";
@@ -1884,8 +1882,6 @@ export namespace MANAGEMENT {
1884
1882
  export { GLOBAL_ROLE_1 as GLOBAL_ROLE };
1885
1883
  const GLOBAL_ROLE_BINDING_1: string;
1886
1884
  export { GLOBAL_ROLE_BINDING_1 as GLOBAL_ROLE_BINDING };
1887
- export const POD_SECURITY_POLICY_TEMPLATE: string;
1888
- export const PSP_TEMPLATE_BINDING: string;
1889
1885
  export const PSA: string;
1890
1886
  export const MANAGED_CHART: string;
1891
1887
  export const USER_NOTIFICATION: string;
@@ -2869,7 +2865,6 @@ export const PLUGIN_DEVELOPER: any;
2869
2865
  export const _RKE1: "rke1";
2870
2866
  export const _RKE2: "rke2";
2871
2867
  export const PROVISIONER: any;
2872
- export const PSP_DEPRECATION_BANNER: any;
2873
2868
  export const MENU_MAX_CLUSTERS: 10;
2874
2869
  export const SCALE_POOL_PROMPT: any;
2875
2870
  export function state(): {
@@ -3301,7 +3296,6 @@ declare namespace _default {
3301
3296
  export { cronSchedule };
3302
3297
  export { podAffinity };
3303
3298
  export { roleTemplateRules };
3304
- export { isHttps };
3305
3299
  }
3306
3300
  export default _default;
3307
3301
  }
@@ -3361,8 +3355,17 @@ declare module '@shell/utils/error' {
3361
3355
  export function stringify(err: any): any;
3362
3356
  export function exceptionToErrorsArray(err: any): any;
3363
3357
  export class ClusterNotFoundError extends Error {
3358
+ static name: string;
3364
3359
  constructor(message: any);
3365
3360
  }
3361
+ /**
3362
+ * An error occurred and the user should be redirected to a certain location (where this is handled)
3363
+ */
3364
+ export class RedirectToError extends Error {
3365
+ static name: string;
3366
+ constructor(message: any, url: any);
3367
+ url: any;
3368
+ }
3366
3369
  export class ApiError extends Error {
3367
3370
  constructor(res: any);
3368
3371
  status: any;
@@ -3618,35 +3621,35 @@ export namespace KEY {
3618
3621
  }
3619
3622
  }
3620
3623
 
3621
- // @shell/utils/poller-sequential
3624
+ // @shell/utils/poller
3622
3625
 
3623
- declare module '@shell/utils/poller-sequential' {
3624
- export default class PollerSequential {
3626
+ declare module '@shell/utils/poller' {
3627
+ export default class Poller {
3625
3628
  constructor(fn: any, pollRateMs: any, maxRetries?: number);
3626
3629
  fn: any;
3627
3630
  pollRateMs: any;
3628
3631
  maxRetries: number;
3629
- timeoutId: any;
3632
+ intervalId: any;
3630
3633
  tryCount: number;
3631
3634
  start(): void;
3632
3635
  stop(): void;
3633
- _poll(): void;
3634
3636
  _intervalMethod(): Promise<void>;
3635
3637
  }
3636
3638
  }
3637
3639
 
3638
- // @shell/utils/poller
3640
+ // @shell/utils/poller-sequential
3639
3641
 
3640
- declare module '@shell/utils/poller' {
3641
- export default class Poller {
3642
+ declare module '@shell/utils/poller-sequential' {
3643
+ export default class PollerSequential {
3642
3644
  constructor(fn: any, pollRateMs: any, maxRetries?: number);
3643
3645
  fn: any;
3644
3646
  pollRateMs: any;
3645
3647
  maxRetries: number;
3646
- intervalId: any;
3648
+ timeoutId: any;
3647
3649
  tryCount: number;
3648
3650
  start(): void;
3649
3651
  stop(): void;
3652
+ _poll(): void;
3650
3653
  _intervalMethod(): Promise<void>;
3651
3654
  }
3652
3655
  }
@@ -4173,7 +4176,10 @@ export function externalName(spec: any, getters: any, errors: any, validatorArgs
4173
4176
  // @shell/utils/validators/setting
4174
4177
 
4175
4178
  declare module '@shell/utils/validators/setting' {
4176
- export function isHttps(value: any, getters: any, errors: any, validatorArgs: any, displayKey: any): any;
4179
+ export function isServerUrl(value: any): boolean;
4180
+ export function isHttps(value: any): any;
4181
+ export function isLocalhost(value: any): boolean;
4182
+ export function hasTrailingForwardSlash(value: any): any;
4177
4183
  }
4178
4184
 
4179
4185
  // @shell/utils/version
@@ -8,7 +8,6 @@ import { cronSchedule } from '@shell/utils/validators/cron-schedule';
8
8
  import { podAffinity } from '@shell/utils/validators/pod-affinity';
9
9
  import { roleTemplateRules } from '@shell/utils/validators/role-template';
10
10
  import { clusterName } from '@shell/utils/validators/cluster-name';
11
- import { isHttps } from '@shell/utils/validators/setting';
12
11
 
13
12
  /**
14
13
  * Custom validation functions beyond normal scalr types
@@ -30,5 +29,4 @@ export default {
30
29
  cronSchedule,
31
30
  podAffinity,
32
31
  roleTemplateRules,
33
- isHttps,
34
32
  };
package/utils/error.js CHANGED
@@ -1,9 +1,24 @@
1
1
  import { isArray } from '@shell/utils/array';
2
2
 
3
3
  export class ClusterNotFoundError extends Error {
4
+ static name = 'ClusterNotFoundError'
5
+
4
6
  constructor(message) {
5
7
  super(message);
6
- this.name = 'ClusterNotFoundError';
8
+ this.name = ClusterNotFoundError.name;
9
+ }
10
+ }
11
+
12
+ /**
13
+ * An error occurred and the user should be redirected to a certain location (where this is handled)
14
+ */
15
+ export class RedirectToError extends Error {
16
+ static name = 'RedirectToError'
17
+
18
+ constructor(message, url) {
19
+ super(message);
20
+ this.url = url;
21
+ this.name = RedirectToError.name;
7
22
  }
8
23
  }
9
24
 
@@ -43,21 +43,66 @@ describe('formRules', () => {
43
43
  expect(formRuleResult).toStrictEqual(expectedResult);
44
44
  });
45
45
 
46
- it('"isHttps" : returns undefined when valid https url value is supplied', () => {
46
+ it('"https" : returns undefined when valid https url value is supplied', () => {
47
47
  const testValue = 'https://url.com';
48
- const formRuleResult = formRules.isHttps('server-url')(testValue);
48
+ const formRuleResult = formRules.https(testValue);
49
49
 
50
50
  expect(formRuleResult).toBeUndefined();
51
51
  });
52
52
 
53
- it('"isHttps" : returns correct message when http url value is supplied', () => {
53
+ it('"https" : returns correct message when http url value is supplied', () => {
54
54
  const testValue = 'http://url.com';
55
- const formRuleResult = formRules.isHttps('server-url')(testValue);
55
+ const formRuleResult = formRules.https(testValue);
56
56
  const expectedResult = JSON.stringify({ message: 'validation.setting.serverUrl.https' });
57
57
 
58
58
  expect(formRuleResult).toStrictEqual(expectedResult);
59
59
  });
60
60
 
61
+ describe('localhost', () => {
62
+ const message = JSON.stringify({ message: 'validation.setting.serverUrl.localhost' });
63
+ const testCases = [
64
+ ['http://LOCALhosT:8005', message],
65
+ ['http://localhost:8005', message],
66
+ ['https://localhost:8005', message],
67
+ ['localhost', message],
68
+ ['http://127.0.0.1', message],
69
+ ['https://127.0.0.1', message],
70
+ ['127.0.0.1', message],
71
+ ['https://test.com', undefined],
72
+ ['https://test.com/localhost', undefined],
73
+ [undefined, undefined]
74
+ ];
75
+
76
+ it.each(testCases)(
77
+ 'should return undefined or correct message based on the provided url',
78
+ (url, expected) => {
79
+ const formRuleResult = formRules.localhost(url);
80
+
81
+ expect(formRuleResult).toStrictEqual(expected);
82
+ }
83
+ );
84
+ });
85
+
86
+ describe('trailingForwardSlash', () => {
87
+ const message = JSON.stringify({ message: 'validation.setting.serverUrl.trailingForwardSlash' });
88
+ const testCases = [
89
+ ['https://test.com', undefined],
90
+ ['https://test.com/', message],
91
+ ['https://', undefined],
92
+ ['/', undefined],
93
+ [undefined, undefined]
94
+ ];
95
+
96
+ it.each(testCases)(
97
+ 'should return undefined or correct message based on the provided url',
98
+ (url, expected) => {
99
+ const formRuleResult = formRules.trailingForwardSlash(url);
100
+
101
+ expect(formRuleResult).toStrictEqual(expected);
102
+ }
103
+ );
104
+ });
105
+
61
106
  it('"interval" : returns undefined when valid hour interval value is supplied', () => {
62
107
  const testValue = '5h';
63
108
  const formRuleResult = formRules.interval(testValue);
@@ -2,9 +2,11 @@ import { RBAC } from '@shell/config/types';
2
2
  import { HCI } from '@shell/config/labels-annotations';
3
3
  import isEmpty from 'lodash/isEmpty';
4
4
  import has from 'lodash/has';
5
+ import isUrl from 'is-url';
5
6
  // import uniq from 'lodash/uniq';
6
7
  import cronstrue from 'cronstrue';
7
8
  import { Translation } from '@shell/types/t';
9
+ import { isHttps, isLocalhost, hasTrailingForwardSlash } from '@shell/utils/validators/setting';
8
10
 
9
11
  // import uniq from 'lodash/uniq';
10
12
  export type Validator<T = undefined | string> = (val: any, arg?: any) => T;
@@ -34,10 +36,6 @@ export class Port {
34
36
  }
35
37
  }
36
38
 
37
- const httpsKeys = [
38
- 'server-url'
39
- ];
40
-
41
39
  const runValidators = (val: any, validators: Validator[]) => {
42
40
  for (const validator of validators) {
43
41
  const message = validator(val);
@@ -139,11 +137,13 @@ export default function(t: Translation, { key = 'Value' }: ValidationOptions): {
139
137
  }
140
138
  };
141
139
 
142
- const isHttps: ValidatorFactory = (key: string) => {
143
- const isHttps: Validator = (val: string) => httpsKeys.includes(key) && !val.toLowerCase().startsWith('https://') ? t('validation.setting.serverUrl.https') : undefined;
140
+ const https: Validator = (val: string) => val && !isHttps(val) ? t('validation.setting.serverUrl.https') : undefined;
144
141
 
145
- return isHttps;
146
- };
142
+ const localhost: Validator = (val: string) => isLocalhost(val) ? t('validation.setting.serverUrl.localhost') : undefined;
143
+
144
+ const trailingForwardSlash: Validator = (val: string) => hasTrailingForwardSlash(val) ? t('validation.setting.serverUrl.trailingForwardSlash') : undefined;
145
+
146
+ const url: Validator = (val: string) => val && !isUrl(val) ? t('validation.setting.serverUrl.url') : undefined;
147
147
 
148
148
  const interval: Validator = (val: string) => !/^\d+[hms]$/.test(val) ? t('validation.monitoring.route.interval', { key }) : undefined;
149
149
 
@@ -475,7 +475,10 @@ export default function(t: Translation, { key = 'Value' }: ValidationOptions): {
475
475
  hostname,
476
476
  imageUrl,
477
477
  interval,
478
- isHttps,
478
+ https,
479
+ localhost,
480
+ trailingForwardSlash,
481
+ url,
479
482
  matching,
480
483
  maxLength,
481
484
  maxValue,
@@ -1,13 +1,9 @@
1
- const httpsKeys = [
2
- 'server-url'
3
- ];
1
+ import isUrl from 'is-url';
4
2
 
5
- export function isHttps(value, getters, errors, validatorArgs, displayKey) {
6
- const key = validatorArgs[0];
3
+ export const isServerUrl = (value) => value === 'server-url';
7
4
 
8
- if (httpsKeys.includes(key) && !value.toLowerCase().startsWith('https://')) {
9
- errors.push(getters['i18n/t']('validation.setting.serverUrl.https'));
10
- }
5
+ export const isHttps = (value) => value.toLowerCase().startsWith('https://');
11
6
 
12
- return errors;
13
- }
7
+ export const isLocalhost = (value) => (/^(?:https?:\/\/)?(?:localhost|127\.0\.0\.1)/i).test(value);
8
+
9
+ export const hasTrailingForwardSlash = (value) => isUrl(value) && value?.toLowerCase().endsWith('/');
package/.DS_Store DELETED
Binary file
@@ -1,76 +0,0 @@
1
- <script>
2
- import { Checkbox } from '@components/Form/Checkbox';
3
- import { mapGetters } from 'vuex';
4
-
5
- export default {
6
- components: { Checkbox },
7
- props: {
8
- value: {
9
- type: Object,
10
- default: () => {
11
- return {};
12
- }
13
- },
14
- mode: {
15
- type: String,
16
- default: 'edit'
17
- },
18
-
19
- /**
20
- * Optional title section prior checkbox
21
- */
22
- title: {
23
- type: String,
24
- default: null
25
- },
26
-
27
- /**
28
- * Cluster information
29
- */
30
- cluster: {
31
- type: Object,
32
- default: null
33
- }
34
- },
35
- created() {
36
- if (!this.value.global.cattle) {
37
- this.$set(this.value.global, 'cattle', { psp: { enabled: false } });
38
- }
39
- if (!this.value.global.cattle.psp) {
40
- this.$set(this.value.global.cattle, 'psp', { enabled: false });
41
- }
42
- },
43
- computed: {
44
- ...mapGetters({ t: 'i18n/t' }),
45
-
46
- /**
47
- * Display checkbox only if contains PSP or K8S version is less than 1.25
48
- */
49
- hasCheckbox() {
50
- const clusterVersion = this.cluster?.kubernetesVersion || '';
51
- const version = clusterVersion.match(/\d+/g);
52
- const isRequiredVersion = version?.length ? +version[0] === 1 && +version[1] < 25 : false;
53
-
54
- return isRequiredVersion;
55
- }
56
- }
57
- };
58
- </script>
59
-
60
- <template>
61
- <div
62
- v-if="hasCheckbox"
63
- class="mt-10 mb-10"
64
- >
65
- <h3 v-if="title">
66
- {{ title }}
67
- </h3>
68
-
69
- <Checkbox
70
- v-model="value.global.cattle.psp.enabled"
71
- data-testid="psp-checkbox"
72
- :mode="mode"
73
- :label="t('catalog.chart.enablePSP')"
74
- />
75
- </div>
76
- </template>
@@ -1,75 +0,0 @@
1
- import { shallowMount, mount } from '@vue/test-utils';
2
- import ChartPsp from '@shell/components/ChartPsp.vue';
3
-
4
- describe('component: ChartPsp', () => {
5
- it.each([
6
- true, false
7
- ])('should render checkbox referencing value.global.cattle.psp.enabled as %p', (value) => {
8
- const version = 'v1.24.11+rke2r1';
9
- const wrapper = shallowMount(ChartPsp, {
10
- propsData: {
11
- value: { global: { cattle: { psp: { enabled: value } } } },
12
- cluster: { kubernetesVersion: version }
13
- }
14
- });
15
-
16
- expect(wrapper.findComponent({ name: 'Checkbox' }).props().value).toBe(value);
17
- });
18
-
19
- it.each([
20
- ['v1.24.11+rke2r1'],
21
- ])('should display the checkbox for cluster with k8s version %p', (version) => {
22
- const wrapper = shallowMount(ChartPsp, {
23
- propsData: {
24
- value: { global: { cattle: { psp: { enabled: false } } } },
25
- cluster: { kubernetesVersion: version }
26
- }
27
- });
28
-
29
- const input = wrapper.find(`[data-testid="psp-checkbox"]`).element as HTMLInputElement;
30
-
31
- expect(input).toBeDefined();
32
- });
33
-
34
- it.each([
35
- ['v1.25.11+rke2r1'],
36
- ])('should not display the checkbox for cluster with k8s version %p', (version) => {
37
- const wrapper = shallowMount(ChartPsp, {
38
- propsData: {
39
- value: { global: { cattle: { psp: { enabled: false } } } },
40
- cluster: { kubernetesVersion: version }
41
- }
42
- });
43
-
44
- const input = wrapper.find(`[data-testid="psp-checkbox"]`).element as HTMLInputElement;
45
-
46
- expect(input).toBeUndefined();
47
- });
48
-
49
- it('should update value.global.cattle.psp.enabled when checkbox is toggled', async() => {
50
- const chartValues = { global: {} } as any;
51
- const version = 'v1.24.11+rke2r1';
52
- const wrapper = mount(ChartPsp, {
53
- propsData: {
54
- value: chartValues,
55
- cluster: { kubernetesVersion: version }
56
- }
57
- });
58
-
59
- await wrapper.find('.checkbox-container').trigger('click');
60
-
61
- expect(chartValues.global.cattle.psp.enabled).toBe(true);
62
-
63
- await wrapper.find('.checkbox-container').trigger('click');
64
- expect(chartValues.global.cattle.psp.enabled).toBe(false);
65
- });
66
-
67
- it.each([
68
- { global: {} } as any,
69
- { global: { cattle: {} } } as any,
70
- ])('should define cattle.psp.enabled and set to false', (chartValues) => {
71
- shallowMount(ChartPsp, { propsData: { value: chartValues } });
72
-
73
- expect(chartValues.global.cattle.psp.enabled).toBe(false);
74
- });
75
- });
@@ -1,28 +0,0 @@
1
- import { mount } from '@vue/test-utils';
2
- import ClusterProvider from '@shell/components/formatter/ClusterProvider.vue';
3
-
4
- describe('component: ClusterProvider', () => {
5
- const importedGkeClusterInfo = { mgmt: { spec: { gkeConfig: { imported: true } } } };
6
- const importedAksClusterInfo = { mgmt: { spec: { aksConfig: { imported: true } } } };
7
- const importedEksClusterInfo = { mgmt: { spec: { eksConfig: { imported: true } } } };
8
- const notImportedGkeClusterInfo = { mgmt: { spec: { gkeConfig: { imported: false } } } };
9
- const importedClusterInfoWithProviderForEmberParam = { mgmt: { providerForEmberParam: 'import' } };
10
-
11
- describe('isImported', () => {
12
- const testCases = [
13
- [importedGkeClusterInfo, true],
14
- [importedAksClusterInfo, true],
15
- [importedEksClusterInfo, true],
16
- [notImportedGkeClusterInfo, false],
17
- [importedClusterInfoWithProviderForEmberParam, true],
18
- [{}, false],
19
- ];
20
-
21
- it.each(testCases)('should return the isImported value properly based on the props data', (row, expected) => {
22
- const wrapper = mount(ClusterProvider, { propsData: { row } });
23
-
24
- expect(wrapper.vm.$data.isImported).toBe(expected);
25
- }
26
- );
27
- });
28
- });
@@ -1,37 +0,0 @@
1
- import { mount } from '@vue/test-utils';
2
- import { Card } from './index';
3
-
4
- describe('component: Card', () => {
5
- const title = 'Card title';
6
- const body = 'Card body';
7
-
8
- it('should have a card title', () => {
9
- const wrapper = mount(Card, {
10
- propsData: { title },
11
- slots: { title: '<div>Card title</div>' }
12
- });
13
-
14
- const element = wrapper.find('[data-testid="card-title-slot"]');
15
-
16
- expect(element.exists()).toBe(true);
17
- expect(element.text()).toBe(title);
18
- });
19
-
20
- it('should have a card body', () => {
21
- const wrapper = mount(Card, {
22
- propsData: { body },
23
- slots: { body: '<div>Card body</div>' }
24
- });
25
- const element = wrapper.find('[data-testid="card-body-slot"]');
26
-
27
- expect(element.exists()).toBe(true);
28
- expect(element.text()).toBe(body);
29
- });
30
-
31
- it('should display the default card actions', () => {
32
- const wrapper = mount(Card);
33
- const element = wrapper.find('[data-testid="card-actions-slot"]');
34
-
35
- expect(element.exists()).toBe(true);
36
- });
37
- });
@@ -1,31 +0,0 @@
1
- import { shallowMount } from '@vue/test-utils';
2
- import { RadioButton } from './index';
3
- import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
4
-
5
- describe('radioButton.vue', () => {
6
- it('renders label slot contents', () => {
7
- const wrapper = shallowMount(RadioButton, { slots: { label: 'Test Label' } });
8
-
9
- expect(wrapper.find('.radio-label').text()).toBe('Test Label');
10
- });
11
-
12
- it('renders label prop contents', () => {
13
- const wrapper = shallowMount(
14
- RadioButton,
15
- {
16
- directives: { cleanHtmlDirective },
17
- propsData: { label: 'Test Label' }
18
- });
19
-
20
- expect(wrapper.find('.radio-label').text()).toBe('Test Label');
21
- });
22
-
23
- it('renders slot contents when both slot and label prop are provided', () => {
24
- const wrapper = shallowMount(RadioButton, {
25
- slots: { label: 'Test Label - Slot' },
26
- propsData: { label: 'Test Label - Props' },
27
- });
28
-
29
- expect(wrapper.find('.radio-label').text()).toBe('Test Label - Slot');
30
- });
31
- });