@rancher/shell 3.0.5-rc.6 → 3.0.5-rc.8
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.
- package/assets/brand/classic/metadata.json +3 -0
- package/assets/styles/app.scss +1 -0
- package/assets/styles/base/_color.scss +16 -0
- package/assets/styles/base/_helpers.scss +10 -0
- package/assets/styles/base/_variables.scss +18 -12
- package/assets/styles/fonts/_icons.scss +1 -32
- package/assets/styles/global/_layout.scss +1 -1
- package/assets/styles/themes/_dark.scss +262 -258
- package/assets/styles/themes/_light.scss +538 -509
- package/assets/styles/themes/_modern.scss +914 -0
- package/assets/translations/en-us.yaml +110 -29
- package/chart/__tests__/S3.test.ts +2 -1
- package/cloud-credential/generic.vue +18 -10
- package/cloud-credential/harvester.vue +1 -9
- package/components/AdvancedSection.vue +8 -0
- package/components/ChartReadme.vue +17 -7
- package/components/CodeMirror.vue +1 -1
- package/components/Drawer/Chrome.vue +0 -1
- package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +27 -28
- package/components/Drawer/ResourceDetailDrawer/composables.ts +4 -24
- package/components/Drawer/ResourceDetailDrawer/index.vue +18 -4
- package/components/InstallHelmCharts.vue +656 -0
- package/components/LazyImage.vue +60 -4
- package/components/Loading.vue +1 -1
- package/components/LocaleSelector.vue +7 -2
- package/components/Markdown.vue +4 -0
- package/components/PaginatedResourceTable.vue +46 -1
- package/components/PromptRestore.vue +22 -44
- package/components/Resource/Detail/Masthead/composable.ts +16 -0
- package/components/Resource/Detail/Masthead/index.vue +37 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +10 -2
- package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +26 -7
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +8 -1
- package/components/Resource/Detail/Metadata/KeyValue.vue +12 -10
- package/components/Resource/Detail/Metadata/Rectangle.vue +3 -1
- package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +10 -17
- package/components/Resource/Detail/Metadata/composables.ts +9 -7
- package/components/Resource/Detail/Metadata/index.vue +17 -2
- package/components/Resource/Detail/Page.vue +35 -21
- package/components/Resource/Detail/SpacedRow.vue +1 -1
- package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +8 -9
- package/components/Resource/Detail/TitleBar/composables.ts +5 -5
- package/components/Resource/Detail/TitleBar/index.vue +12 -3
- package/components/ResourceDetail/Masthead/legacy.vue +1 -1
- package/components/ResourceDetail/index.vue +569 -72
- package/components/ResourceList/index.vue +1 -0
- package/components/ResourceTable.vue +6 -1
- package/components/ResourceYaml.vue +1 -1
- package/components/RichTranslation.vue +106 -0
- package/components/SlideInPanelManager.vue +13 -10
- package/components/SortableTable/index.vue +5 -5
- package/components/SortableTable/selection.js +0 -1
- package/components/Tabbed/index.vue +35 -4
- package/components/__tests__/LazyImage.spec.ts +121 -0
- package/components/__tests__/PromptRestore.test.ts +1 -65
- package/components/__tests__/RichTranslation.test.ts +115 -0
- package/components/fleet/FleetStatus.vue +4 -0
- package/components/fleet/dashboard/ResourcePanel.vue +2 -1
- package/components/form/ClusterAppearance.vue +5 -0
- package/components/form/FileImageSelector.vue +1 -1
- package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
- package/components/form/NameNsDescription.vue +1 -0
- package/components/form/Networking.vue +24 -19
- package/components/form/ProjectMemberEditor.vue +1 -1
- package/components/form/ResourceLabeledSelect.vue +22 -8
- package/components/form/ResourceTabs/index.vue +20 -0
- package/components/form/SecretSelector.vue +9 -0
- package/components/form/SelectOrCreateAuthSecret.vue +6 -3
- package/components/form/__tests__/Networking.test.ts +116 -0
- package/components/form/labeled-select-utils/labeled-select-pagination.ts +3 -38
- package/components/formatter/FleetApplicationSource.vue +25 -17
- package/components/formatter/PodImages.vue +1 -1
- package/components/formatter/__tests__/LiveDate.test.ts +10 -2
- package/components/google/AccountAccess.vue +44 -46
- package/components/nav/Favorite.vue +4 -0
- package/components/nav/Group.vue +4 -1
- package/components/nav/NotificationCenter/Notification.vue +1 -27
- package/components/nav/WindowManager/index.vue +3 -3
- package/composables/resources.ts +2 -2
- package/config/labels-annotations.js +3 -2
- package/config/pagination-table-headers.js +8 -1
- package/config/product/explorer.js +27 -2
- package/config/product/manager.js +0 -1
- package/config/query-params.js +10 -0
- package/config/router/routes.js +21 -1
- package/config/system-namespaces.js +1 -1
- package/config/table-headers.js +30 -1
- package/config/types.js +1 -1
- package/config/version.js +1 -1
- package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +11 -0
- package/detail/__tests__/workload.test.ts +164 -0
- package/detail/configmap.vue +33 -75
- package/detail/projectsecret.vue +11 -0
- package/detail/provisioning.cattle.io.cluster.vue +351 -369
- package/detail/secret.vue +49 -308
- package/detail/workload/index.vue +38 -21
- package/dialog/InstallExtensionDialog.vue +8 -5
- package/dialog/RotateEncryptionKeyDialog.vue +10 -30
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
- package/edit/auth/ldap/__tests__/config.test.ts +14 -0
- package/edit/auth/ldap/config.vue +24 -0
- package/edit/compliance.cattle.io.clusterscan.vue +1 -1
- package/edit/configmap.vue +4 -1
- package/edit/fleet.cattle.io.gitrepo.vue +5 -6
- package/edit/fleet.cattle.io.helmop.vue +78 -56
- package/edit/logging.banzaicloud.io.output/index.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +5 -6
- package/edit/networking.k8s.io.ingress/Certificate.vue +20 -22
- package/edit/networking.k8s.io.ingress/DefaultBackend.vue +8 -3
- package/edit/networking.k8s.io.ingress/Rule.vue +2 -5
- package/edit/networking.k8s.io.ingress/RulePath.vue +17 -11
- package/edit/networking.k8s.io.ingress/__tests__/Certificate.test.ts +165 -0
- package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +11 -10
- package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -3
- package/edit/networking.k8s.io.networkpolicy/index.vue +17 -17
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +3 -2
- package/edit/provisioning.cattle.io.cluster/rke2.vue +123 -61
- package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +9 -7
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +22 -13
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +10 -12
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +39 -38
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +41 -19
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +16 -3
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +32 -33
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryMirrors.vue +9 -10
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +1 -3
- package/edit/provisioning.cattle.io.cluster/tabs/upgrade/DrainOptions.vue +16 -9
- package/edit/secret/basic.vue +1 -0
- package/edit/secret/index.vue +126 -15
- package/edit/workload/index.vue +5 -14
- package/list/projectsecret.vue +345 -0
- package/list/provisioning.cattle.io.cluster.vue +1 -69
- package/list/secret.vue +109 -0
- package/machine-config/__tests__/vmwarevsphere.test.ts +5 -7
- package/machine-config/google.vue +9 -1
- package/machine-config/vmwarevsphere.vue +7 -17
- package/mixins/__tests__/brand.spec.ts +2 -2
- package/mixins/chart.js +0 -2
- package/mixins/create-edit-view/impl.js +10 -1
- package/mixins/resource-fetch-api-pagination.js +11 -12
- package/mixins/resource-fetch.js +3 -1
- package/models/__tests__/chart.test.ts +111 -80
- package/models/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
- package/models/__tests__/node.test.ts +7 -63
- package/models/catalog.cattle.io.app.js +1 -1
- package/models/catalog.cattle.io.operation.js +1 -1
- package/models/chart.js +36 -20
- package/models/cloudcredential.js +2 -163
- package/models/cluster/node.js +7 -7
- package/models/cluster.x-k8s.io.machine.js +3 -3
- package/models/cluster.x-k8s.io.machinedeployment.js +11 -2
- package/models/compliance.cattle.io.clusterscan.js +2 -2
- package/models/configmap.js +4 -0
- package/models/constraints.gatekeeper.sh.constraint.js +1 -1
- package/models/fleet-application.js +0 -17
- package/models/fleet.cattle.io.cluster.js +2 -2
- package/models/fleet.cattle.io.gitrepo.js +15 -1
- package/models/fleet.cattle.io.helmop.js +26 -22
- package/models/management.cattle.io.setting.js +4 -0
- package/models/persistentvolumeclaim.js +1 -1
- package/models/pod.js +2 -2
- package/models/provisioning.cattle.io.cluster.js +39 -67
- package/models/rke.cattle.io.etcdsnapshot.js +1 -1
- package/models/secret.js +161 -2
- package/models/storage.k8s.io.storageclass.js +2 -2
- package/models/workload.js +3 -3
- package/package.json +11 -10
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +1 -0
- package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +4 -1
- package/pages/c/_cluster/apps/charts/__tests__/AppChartCardFooter.spec.js +41 -0
- package/pages/c/_cluster/apps/charts/chart.vue +422 -174
- package/pages/c/_cluster/apps/charts/index.vue +46 -35
- package/pages/c/_cluster/apps/charts/install.vue +1 -1
- package/pages/c/_cluster/explorer/projectsecret.vue +24 -0
- package/pages/c/_cluster/fleet/__tests__/index.test.ts +608 -314
- package/pages/c/_cluster/fleet/index.vue +103 -45
- package/pages/c/_cluster/manager/cloudCredential/index.vue +2 -59
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +10 -3
- package/pages/c/_cluster/uiplugins/index.vue +36 -25
- package/plugins/dashboard-store/__tests__/normalize.test.ts +223 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +191 -0
- package/plugins/dashboard-store/__tests__/utils/normalize-usecases.ts +1526 -0
- package/plugins/dashboard-store/actions.js +42 -22
- package/plugins/dashboard-store/normalize.js +29 -17
- package/plugins/dashboard-store/resource-class.js +83 -17
- package/plugins/steve/__tests__/getters.test.ts +1 -1
- package/plugins/steve/__tests__/subscribe.spec.ts +259 -1
- package/plugins/steve/getters.js +8 -2
- package/plugins/steve/resourceWatcher.js +10 -3
- package/plugins/steve/steve-pagination-utils.ts +14 -3
- package/plugins/steve/subscribe.js +192 -19
- package/plugins/steve/worker/web-worker.advanced.js +2 -0
- package/rancher-components/Card/Card.vue +0 -18
- package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.test.ts +15 -0
- package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +65 -0
- package/rancher-components/Pill/RcStatusBadge/index.ts +2 -0
- package/rancher-components/Pill/RcStatusBadge/types.ts +5 -0
- package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.test.ts +33 -0
- package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +75 -0
- package/rancher-components/Pill/RcStatusIndicator/index.ts +2 -0
- package/rancher-components/Pill/RcStatusIndicator/types.ts +7 -0
- package/rancher-components/Pill/types.ts +2 -0
- package/rancher-components/RcButton/RcButton.vue +1 -1
- package/rancher-components/RcDropdown/RcDropdown.test.ts +98 -0
- package/rancher-components/RcDropdown/RcDropdown.vue +5 -0
- package/rancher-components/RcDropdown/RcDropdownItem.vue +7 -1
- package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +2 -1
- package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +2 -1
- package/rancher-components/RcDropdown/useDropdownContext.ts +21 -0
- package/rancher-components/RcDropdown/useDropdownItem.ts +30 -1
- package/rancher-components/RcItemCard/RcItemCard.test.ts +20 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +40 -6
- package/store/__tests__/catalog.test.ts +93 -1
- package/store/aws.js +19 -8
- package/store/catalog.js +8 -3
- package/types/kube/kube-api.ts +12 -0
- package/types/resources/settings.d.ts +1 -1
- package/types/shell/index.d.ts +643 -585
- package/types/store/pagination.types.ts +16 -6
- package/types/uiplugins.ts +73 -0
- package/utils/__tests__/back-off.test.ts +354 -0
- package/utils/__tests__/create-yaml.test.ts +235 -0
- package/utils/__tests__/kontainer.test.ts +19 -0
- package/utils/__tests__/uiplugins.test.ts +84 -0
- package/utils/back-off.ts +176 -0
- package/utils/create-yaml.js +103 -9
- package/utils/dynamic-importer.js +8 -0
- package/utils/kontainer.ts +3 -5
- package/utils/pagination-utils.ts +18 -0
- package/utils/style.ts +3 -0
- package/utils/uiplugins.ts +29 -2
- package/utils/validators/__tests__/setting.test.js +92 -0
- package/utils/validators/formRules/__tests__/index.test.ts +88 -7
- package/utils/validators/formRules/index.ts +83 -8
- package/utils/validators/setting.js +17 -0
- package/cloud-credential/__tests__/harvester.test.ts +0 -18
- package/components/ResourceDetail/__tests__/index.test.ts +0 -135
- package/components/ResourceDetail/legacy.vue +0 -562
- package/components/formatter/CloudCredExpired.vue +0 -69
- package/models/etcdbackup.js +0 -45
- package/pages/explorer/resource/detail/configmap.vue +0 -42
- package/pages/explorer/resource/detail/secret.vue +0 -50
- package/utils/aws.js +0 -0
|
@@ -117,7 +117,16 @@ export default {
|
|
|
117
117
|
// If they are resolved, return a false-y value
|
|
118
118
|
// Else they can't be resolved, return an array of errors to show to the user.
|
|
119
119
|
async conflict() {
|
|
120
|
-
return await handleConflict(
|
|
120
|
+
return await handleConflict(
|
|
121
|
+
this.initialValue,
|
|
122
|
+
this.value,
|
|
123
|
+
this.liveValue,
|
|
124
|
+
{
|
|
125
|
+
dispatch: this.$store.dispatch,
|
|
126
|
+
getters: this.$store.getters
|
|
127
|
+
},
|
|
128
|
+
this.storeOverride || this.$store.getters['currentStore'](this.value.type)
|
|
129
|
+
);
|
|
121
130
|
},
|
|
122
131
|
|
|
123
132
|
async save(buttonDone, url, depth = 0) {
|
|
@@ -125,7 +125,7 @@ export default {
|
|
|
125
125
|
context: this.context,
|
|
126
126
|
};
|
|
127
127
|
|
|
128
|
-
return this.$store.getters[`${ this.inStore }/paginationEnabled`]?.(args);
|
|
128
|
+
return this.$store.getters[`${ this.overrideInStore || this.inStore }/paginationEnabled`]?.(args);
|
|
129
129
|
}
|
|
130
130
|
},
|
|
131
131
|
|
|
@@ -200,7 +200,7 @@ export default {
|
|
|
200
200
|
return;
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
return this.$store.getters[`${ this.inStore }/havePage`](this.resource);
|
|
203
|
+
return this.$store.getters[`${ this.overrideInStore || this.inStore }/havePage`](this.resource);
|
|
204
204
|
},
|
|
205
205
|
|
|
206
206
|
/**
|
|
@@ -280,12 +280,12 @@ export default {
|
|
|
280
280
|
projectsOrNamespaces,
|
|
281
281
|
filters
|
|
282
282
|
} = stevePaginationUtils.createParamsFromNsFilter({
|
|
283
|
-
allNamespaces:
|
|
284
|
-
selection:
|
|
285
|
-
isAllNamespaces:
|
|
286
|
-
isLocalCluster:
|
|
287
|
-
|
|
288
|
-
productHidesSystemNamespaces:
|
|
283
|
+
allNamespaces: this.$store.getters[`${ this.currentProduct?.inStore }/all`](NAMESPACE),
|
|
284
|
+
selection: neu,
|
|
285
|
+
isAllNamespaces: this.isAllNamespaces,
|
|
286
|
+
isLocalCluster: this.$store.getters['currentCluster'].isLocal,
|
|
287
|
+
showReservedRancherNamespaces: this.showDynamicRancherNamespaces,
|
|
288
|
+
productHidesSystemNamespaces: this.productHidesSystemNamespaces,
|
|
289
289
|
});
|
|
290
290
|
|
|
291
291
|
this.requestFilters.filters = filters;
|
|
@@ -352,7 +352,7 @@ export default {
|
|
|
352
352
|
}
|
|
353
353
|
},
|
|
354
354
|
|
|
355
|
-
|
|
355
|
+
async beforeUnmount() {
|
|
356
356
|
if (this.havePaginated) {
|
|
357
357
|
// of type @STEVE_WATCH_PARAMS
|
|
358
358
|
const watchArgs = {
|
|
@@ -360,9 +360,8 @@ export default {
|
|
|
360
360
|
mode: STEVE_WATCH_MODE.RESOURCE_CHANGES,
|
|
361
361
|
};
|
|
362
362
|
|
|
363
|
-
this.$store.dispatch(`${ this.inStore }/forgetType`, this.resource, (watchParams) => {
|
|
364
|
-
return watchParams.type === watchArgs.type &&
|
|
365
|
-
watchParams.mode === watchArgs.type.mode;
|
|
363
|
+
await this.$store.dispatch(`${ this.overrideInStore || this.inStore }/forgetType`, this.resource, (watchParams) => {
|
|
364
|
+
return watchParams.type === watchArgs.type && watchParams.mode === watchArgs.type.mode;
|
|
366
365
|
});
|
|
367
366
|
}
|
|
368
367
|
}
|
package/mixins/resource-fetch.js
CHANGED
|
@@ -242,7 +242,9 @@ export default {
|
|
|
242
242
|
},
|
|
243
243
|
|
|
244
244
|
__getCountForResource(resourceName, namespace, storeType) {
|
|
245
|
-
const
|
|
245
|
+
const currStore = storeType || this.$store.getters['currentStore']();
|
|
246
|
+
|
|
247
|
+
const resourceCounts = this.$store.getters[`${ currStore }/all`](COUNT)[0]?.counts[`${ resourceName }`]; // NB `rancher` store behaves differently, lacks counts but has resource
|
|
246
248
|
const resourceCount = namespace && resourceCounts?.namespaces ? resourceCounts?.namespaces[namespace]?.count : resourceCounts?.summary?.count;
|
|
247
249
|
|
|
248
250
|
return resourceCount || 0;
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import Chart from '@shell/models/chart';
|
|
2
2
|
import { APP_UPGRADE_STATUS } from '@shell/store/catalog';
|
|
3
3
|
import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations';
|
|
4
|
+
import { ZERO_TIME } from '@shell/config/types';
|
|
5
|
+
|
|
6
|
+
type MockChartContext = {
|
|
7
|
+
rootGetters: {
|
|
8
|
+
'cluster/all': () => any[];
|
|
9
|
+
'i18n/t': (key: string) => string;
|
|
10
|
+
};
|
|
11
|
+
dispatch?: jest.Mock;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
interface CardContent {
|
|
15
|
+
subHeaderItems: { label: string }[];
|
|
16
|
+
footerItems: { labels: string[]; icon?: string }[];
|
|
17
|
+
statuses: { tooltip: { key: string }; color: string }[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const t = jest.fn((key) => key); // mock translation function
|
|
21
|
+
const dispatch = jest.fn();
|
|
4
22
|
|
|
5
23
|
const base = {
|
|
6
24
|
chartName: 'my-app',
|
|
@@ -29,16 +47,31 @@ function makeInstalledApp(upgradeAvailable = APP_UPGRADE_STATUS.NO_UPGRADE) {
|
|
|
29
47
|
}
|
|
30
48
|
}
|
|
31
49
|
},
|
|
50
|
+
metadata: {},
|
|
32
51
|
upgradeAvailable
|
|
33
52
|
};
|
|
34
53
|
}
|
|
35
54
|
|
|
36
55
|
describe('class Chart', () => {
|
|
56
|
+
let ctx: MockChartContext;
|
|
57
|
+
|
|
58
|
+
beforeEach(() => {
|
|
59
|
+
ctx = {
|
|
60
|
+
rootGetters: {
|
|
61
|
+
'cluster/all': () => [],
|
|
62
|
+
'i18n/t': t
|
|
63
|
+
},
|
|
64
|
+
dispatch
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
|
|
37
68
|
describe('matchingInstalledApps', () => {
|
|
38
69
|
it('matches by name, repo, and home in latest version', () => {
|
|
39
70
|
const installedApp = makeInstalledApp();
|
|
40
71
|
|
|
41
|
-
|
|
72
|
+
ctx.rootGetters['cluster/all'] = () => [installedApp];
|
|
73
|
+
|
|
74
|
+
const chart = new Chart(base, ctx);
|
|
42
75
|
|
|
43
76
|
expect(chart.matchingInstalledApps).toHaveLength(1);
|
|
44
77
|
});
|
|
@@ -47,8 +80,9 @@ describe('class Chart', () => {
|
|
|
47
80
|
const installedApp = makeInstalledApp();
|
|
48
81
|
|
|
49
82
|
installedApp.spec.chart.metadata.name = 'different-app';
|
|
83
|
+
ctx.rootGetters['cluster/all'] = () => [installedApp];
|
|
50
84
|
|
|
51
|
-
const chart = new Chart(base,
|
|
85
|
+
const chart = new Chart(base, ctx);
|
|
52
86
|
|
|
53
87
|
expect(chart.matchingInstalledApps).toHaveLength(0);
|
|
54
88
|
});
|
|
@@ -57,8 +91,9 @@ describe('class Chart', () => {
|
|
|
57
91
|
const installedApp = makeInstalledApp();
|
|
58
92
|
|
|
59
93
|
installedApp.spec.chart.metadata.annotations[CATALOG_ANNOTATIONS.SOURCE_REPO_NAME] = 'different-repo';
|
|
94
|
+
ctx.rootGetters['cluster/all'] = () => [installedApp];
|
|
60
95
|
|
|
61
|
-
const chart = new Chart(base,
|
|
96
|
+
const chart = new Chart(base, ctx);
|
|
62
97
|
|
|
63
98
|
expect(chart.matchingInstalledApps).toHaveLength(0);
|
|
64
99
|
});
|
|
@@ -66,9 +101,10 @@ describe('class Chart', () => {
|
|
|
66
101
|
it('matches by version+home when not latest', () => {
|
|
67
102
|
const installedApp = makeInstalledApp();
|
|
68
103
|
|
|
69
|
-
installedApp.spec.chart.metadata.version = '1.2.3';
|
|
104
|
+
installedApp.spec.chart.metadata.version = '1.2.3';
|
|
105
|
+
ctx.rootGetters['cluster/all'] = () => [installedApp];
|
|
70
106
|
|
|
71
|
-
const chart = new Chart(base,
|
|
107
|
+
const chart = new Chart(base, ctx);
|
|
72
108
|
|
|
73
109
|
expect(chart.matchingInstalledApps).toHaveLength(1);
|
|
74
110
|
});
|
|
@@ -76,10 +112,11 @@ describe('class Chart', () => {
|
|
|
76
112
|
it('can use fallback repo from metadata labels', () => {
|
|
77
113
|
const installedApp = makeInstalledApp();
|
|
78
114
|
|
|
79
|
-
installedApp.spec.chart.metadata.annotations = {};
|
|
115
|
+
installedApp.spec.chart.metadata.annotations = {};
|
|
80
116
|
installedApp.metadata = { labels: { [CATALOG_ANNOTATIONS.CLUSTER_REPO_NAME]: 'my-repo' } };
|
|
117
|
+
ctx.rootGetters['cluster/all'] = () => [installedApp];
|
|
81
118
|
|
|
82
|
-
const chart = new Chart(base,
|
|
119
|
+
const chart = new Chart(base, ctx);
|
|
83
120
|
|
|
84
121
|
expect(chart.matchingInstalledApps).toHaveLength(1);
|
|
85
122
|
});
|
|
@@ -87,45 +124,29 @@ describe('class Chart', () => {
|
|
|
87
124
|
|
|
88
125
|
describe('isInstalled', () => {
|
|
89
126
|
it('is true when one app matches', () => {
|
|
90
|
-
const installedApp =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
name: 'my-app',
|
|
95
|
-
version: '1.2.3',
|
|
96
|
-
home: 'https://example.com',
|
|
97
|
-
annotations: { [CATALOG_ANNOTATIONS.SOURCE_REPO_NAME]: 'my-repo' }
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
};
|
|
127
|
+
const installedApp = makeInstalledApp();
|
|
128
|
+
|
|
129
|
+
installedApp.spec.chart.metadata.version = '1.2.3';
|
|
130
|
+
ctx.rootGetters['cluster/all'] = () => [installedApp];
|
|
102
131
|
|
|
103
|
-
const chart = new Chart(base,
|
|
132
|
+
const chart = new Chart(base, ctx);
|
|
104
133
|
|
|
105
134
|
expect(chart.isInstalled).toBe(true);
|
|
106
135
|
});
|
|
107
136
|
|
|
108
137
|
it('is false when no apps match', () => {
|
|
109
|
-
const chart = new Chart(base,
|
|
138
|
+
const chart = new Chart(base, ctx);
|
|
110
139
|
|
|
111
140
|
expect(chart.isInstalled).toBe(false);
|
|
112
141
|
});
|
|
113
142
|
|
|
114
143
|
it('is false when multiple apps match', () => {
|
|
115
|
-
const
|
|
116
|
-
spec: {
|
|
117
|
-
chart: {
|
|
118
|
-
metadata: {
|
|
119
|
-
name: 'my-app',
|
|
120
|
-
version: '1.2.3',
|
|
121
|
-
home: 'https://example.com',
|
|
122
|
-
annotations: { [CATALOG_ANNOTATIONS.SOURCE_REPO_NAME]: 'my-repo' }
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
};
|
|
144
|
+
const app = makeInstalledApp();
|
|
127
145
|
|
|
128
|
-
|
|
146
|
+
app.spec.chart.metadata.version = '1.2.3';
|
|
147
|
+
ctx.rootGetters['cluster/all'] = () => [app, app];
|
|
148
|
+
|
|
149
|
+
const chart = new Chart(base, ctx);
|
|
129
150
|
|
|
130
151
|
expect(chart.isInstalled).toBe(false);
|
|
131
152
|
});
|
|
@@ -133,47 +154,29 @@ describe('class Chart', () => {
|
|
|
133
154
|
|
|
134
155
|
describe('upgradeable', () => {
|
|
135
156
|
it('is true when installed and upgradeAvailable is SINGLE_UPGRADE', () => {
|
|
136
|
-
const installedApp =
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
name: 'my-app',
|
|
141
|
-
version: '1.2.3',
|
|
142
|
-
home: 'https://example.com',
|
|
143
|
-
annotations: { [CATALOG_ANNOTATIONS.SOURCE_REPO_NAME]: 'my-repo' }
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
upgradeAvailable: APP_UPGRADE_STATUS.SINGLE_UPGRADE
|
|
148
|
-
};
|
|
157
|
+
const installedApp = makeInstalledApp(APP_UPGRADE_STATUS.SINGLE_UPGRADE);
|
|
158
|
+
|
|
159
|
+
installedApp.spec.chart.metadata.version = '1.2.3';
|
|
160
|
+
ctx.rootGetters['cluster/all'] = () => [installedApp];
|
|
149
161
|
|
|
150
|
-
const chart = new Chart(base,
|
|
162
|
+
const chart = new Chart(base, ctx);
|
|
151
163
|
|
|
152
164
|
expect(chart.upgradeable).toBe(true);
|
|
153
165
|
});
|
|
154
166
|
|
|
155
167
|
it('is false if upgradeAvailable is different', () => {
|
|
156
|
-
const installedApp =
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
name: 'my-app',
|
|
161
|
-
version: '1.2.3',
|
|
162
|
-
home: 'https://example.com',
|
|
163
|
-
annotations: { [CATALOG_ANNOTATIONS.SOURCE_REPO_NAME]: 'my-repo' }
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
upgradeAvailable: APP_UPGRADE_STATUS.NO_UPGRADE
|
|
168
|
-
};
|
|
168
|
+
const installedApp = makeInstalledApp(APP_UPGRADE_STATUS.NO_UPGRADE);
|
|
169
|
+
|
|
170
|
+
installedApp.spec.chart.metadata.version = '1.2.3';
|
|
171
|
+
ctx.rootGetters['cluster/all'] = () => [installedApp];
|
|
169
172
|
|
|
170
|
-
const chart = new Chart(base,
|
|
173
|
+
const chart = new Chart(base, ctx);
|
|
171
174
|
|
|
172
175
|
expect(chart.upgradeable).toBe(false);
|
|
173
176
|
});
|
|
174
177
|
|
|
175
178
|
it('is false when not installed', () => {
|
|
176
|
-
const chart = new Chart(base,
|
|
179
|
+
const chart = new Chart(base, ctx);
|
|
177
180
|
|
|
178
181
|
expect(chart.upgradeable).toBe(false);
|
|
179
182
|
});
|
|
@@ -181,9 +184,9 @@ describe('class Chart', () => {
|
|
|
181
184
|
|
|
182
185
|
describe('cardContent', () => {
|
|
183
186
|
it('includes correct subHeader and footer info', () => {
|
|
184
|
-
const chart = new Chart(base,
|
|
187
|
+
const chart = new Chart(base, ctx);
|
|
185
188
|
|
|
186
|
-
const result = chart.cardContent;
|
|
189
|
+
const result = chart.cardContent as CardContent;
|
|
187
190
|
|
|
188
191
|
expect(result.subHeaderItems).toHaveLength(2);
|
|
189
192
|
expect(result.subHeaderItems[0].label).toBe('1.3.0');
|
|
@@ -200,66 +203,72 @@ describe('class Chart', () => {
|
|
|
200
203
|
...base,
|
|
201
204
|
categories: ['database'],
|
|
202
205
|
tags: ['linux', 'experimentl']
|
|
203
|
-
},
|
|
206
|
+
}, ctx);
|
|
204
207
|
|
|
205
|
-
const result = chart.cardContent;
|
|
208
|
+
const result = chart.cardContent as CardContent;
|
|
206
209
|
|
|
207
210
|
expect(result.footerItems).toHaveLength(3);
|
|
208
211
|
|
|
209
212
|
const categoryItem = result.footerItems.find((i) => i.icon === 'icon-category-alt');
|
|
210
213
|
|
|
211
214
|
expect(categoryItem).toBeDefined();
|
|
212
|
-
expect(categoryItem
|
|
215
|
+
expect(categoryItem?.labels).toContain('database');
|
|
213
216
|
|
|
214
217
|
const tagItem = result.footerItems.find((i) => i.icon === 'icon-tag-alt');
|
|
215
218
|
|
|
216
219
|
expect(tagItem).toBeDefined();
|
|
217
|
-
expect(tagItem
|
|
220
|
+
expect(tagItem?.labels).toStrictEqual(expect.arrayContaining(['linux', 'experimentl']));
|
|
218
221
|
});
|
|
219
222
|
|
|
220
223
|
it('includes deprecated status when deprecated is true', () => {
|
|
221
|
-
const chart = new Chart({ ...base, deprecated: true },
|
|
224
|
+
const chart = new Chart({ ...base, deprecated: true }, ctx);
|
|
222
225
|
|
|
223
|
-
const result = chart.cardContent;
|
|
226
|
+
const result = chart.cardContent as CardContent;
|
|
224
227
|
|
|
225
228
|
const deprecatedStatus = result.statuses.find((s) => s.tooltip.key === 'generic.deprecated');
|
|
226
229
|
|
|
227
230
|
expect(deprecatedStatus).toBeDefined();
|
|
228
|
-
expect(deprecatedStatus
|
|
231
|
+
expect(deprecatedStatus?.color).toBe('error');
|
|
229
232
|
});
|
|
230
233
|
|
|
231
234
|
it('includes installed status when app is installed', () => {
|
|
232
235
|
const installedApp = makeInstalledApp();
|
|
233
236
|
|
|
234
|
-
|
|
237
|
+
ctx.rootGetters['cluster/all'] = () => [installedApp];
|
|
235
238
|
|
|
236
|
-
const
|
|
239
|
+
const chart = new Chart(base, ctx);
|
|
240
|
+
|
|
241
|
+
const result = chart.cardContent as CardContent;
|
|
237
242
|
|
|
238
243
|
const installedStatus = result.statuses.find((s) => s.tooltip.key === 'generic.installed');
|
|
239
244
|
|
|
240
245
|
expect(installedStatus).toBeDefined();
|
|
241
|
-
expect(installedStatus
|
|
246
|
+
expect(installedStatus?.color).toBe('success');
|
|
242
247
|
});
|
|
243
248
|
|
|
244
249
|
it('includes upgradeable status when upgrade is available', () => {
|
|
245
250
|
const installedApp = makeInstalledApp(APP_UPGRADE_STATUS.SINGLE_UPGRADE);
|
|
246
251
|
|
|
247
|
-
|
|
252
|
+
ctx.rootGetters['cluster/all'] = () => [installedApp];
|
|
248
253
|
|
|
249
|
-
const
|
|
254
|
+
const chart = new Chart(base, ctx);
|
|
255
|
+
|
|
256
|
+
const result = chart.cardContent as CardContent;
|
|
250
257
|
|
|
251
258
|
const upgradeableStatus = result.statuses.find((s) => s.tooltip.key === 'generic.upgradeable');
|
|
252
259
|
|
|
253
260
|
expect(upgradeableStatus).toBeDefined();
|
|
254
|
-
expect(upgradeableStatus
|
|
261
|
+
expect(upgradeableStatus?.color).toBe('info');
|
|
255
262
|
});
|
|
256
263
|
|
|
257
264
|
it('shows all statuses together when all conditions are met', () => {
|
|
258
265
|
const installedApp = makeInstalledApp(APP_UPGRADE_STATUS.SINGLE_UPGRADE);
|
|
259
266
|
|
|
260
|
-
|
|
267
|
+
ctx.rootGetters['cluster/all'] = () => [installedApp];
|
|
261
268
|
|
|
262
|
-
const
|
|
269
|
+
const chart = new Chart({ ...base, deprecated: true }, ctx);
|
|
270
|
+
|
|
271
|
+
const result = chart.cardContent as CardContent;
|
|
263
272
|
|
|
264
273
|
const keys = result.statuses.map((s) => s.tooltip.key);
|
|
265
274
|
|
|
@@ -269,5 +278,27 @@ describe('class Chart', () => {
|
|
|
269
278
|
'generic.installed'
|
|
270
279
|
]));
|
|
271
280
|
});
|
|
281
|
+
|
|
282
|
+
it('handles zero time for last updated date', () => {
|
|
283
|
+
const chartWithZeroTime = {
|
|
284
|
+
...base,
|
|
285
|
+
versions: [{
|
|
286
|
+
...base.versions[0],
|
|
287
|
+
created: ZERO_TIME,
|
|
288
|
+
}]
|
|
289
|
+
};
|
|
290
|
+
const chart = new Chart(chartWithZeroTime, {
|
|
291
|
+
rootGetters: {
|
|
292
|
+
'cluster/all': () => [],
|
|
293
|
+
'i18n/t': (key) => key
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
const result = chart.cardContent;
|
|
298
|
+
const lastUpdatedItem = result.subHeaderItems[1];
|
|
299
|
+
|
|
300
|
+
expect(lastUpdatedItem.label).toBe('generic.na');
|
|
301
|
+
expect(lastUpdatedItem.labelTooltip).toBe('catalog.charts.appChartCard.subHeaderItem.missingVersionDate');
|
|
302
|
+
});
|
|
272
303
|
});
|
|
273
304
|
});
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import HelmOp from '@shell/models/fleet.cattle.io.helmop.js';
|
|
2
|
+
|
|
3
|
+
describe('class HelmOp', () => {
|
|
4
|
+
let instance;
|
|
5
|
+
|
|
6
|
+
describe('source getter', () => {
|
|
7
|
+
it('should return correct source for SOURCE_TYPE.REPO (HTTPS)', () => {
|
|
8
|
+
instance = new HelmOp({
|
|
9
|
+
spec: {
|
|
10
|
+
helm: {
|
|
11
|
+
repo: 'https://charts.rancher.io/fleet',
|
|
12
|
+
chart: 'fleet-agent'
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const source = instance.source;
|
|
18
|
+
|
|
19
|
+
expect(source.value).toBe('https://charts.rancher.io/fleet');
|
|
20
|
+
expect(source.display).toBe('charts.rancher.io/fleet');
|
|
21
|
+
expect(source.icon).toBe('icon icon-application');
|
|
22
|
+
expect(source.showLink).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should return correct source for SOURCE_TYPE.REPO (GitHub HTTPS .git)', () => {
|
|
26
|
+
instance = new HelmOp({
|
|
27
|
+
spec: {
|
|
28
|
+
helm: {
|
|
29
|
+
repo: 'https://github.com/rancher/fleet.git',
|
|
30
|
+
chart: 'fleet'
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const source = instance.source;
|
|
36
|
+
|
|
37
|
+
expect(source.value).toBe('https://github.com/rancher/fleet.git');
|
|
38
|
+
expect(source.display).toBe('rancher/fleet');
|
|
39
|
+
expect(source.icon).toBe('icon icon-application');
|
|
40
|
+
expect(source.showLink).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should return correct source for SOURCE_TYPE.REPO (GitHub SSH)', () => {
|
|
44
|
+
instance = new HelmOp({
|
|
45
|
+
spec: {
|
|
46
|
+
helm: {
|
|
47
|
+
repo: 'git@github.com:rancher/fleet.git',
|
|
48
|
+
chart: 'fleet'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const source = instance.source;
|
|
54
|
+
|
|
55
|
+
expect(source.value).toBe('https://github.com/rancher/fleet');
|
|
56
|
+
expect(source.display).toBe('rancher/fleet');
|
|
57
|
+
expect(source.icon).toBe('icon icon-application');
|
|
58
|
+
expect(source.showLink).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should return correct source for SOURCE_TYPE.OCI', () => {
|
|
62
|
+
instance = new HelmOp({ spec: { helm: { repo: 'oci://ghcr.io/rancher/some-chart' } } });
|
|
63
|
+
|
|
64
|
+
const source = instance.source;
|
|
65
|
+
|
|
66
|
+
expect(source.value).toBe('oci://ghcr.io');
|
|
67
|
+
expect(source.display).toBe('oci://ghcr.io');
|
|
68
|
+
expect(source.icon).toBe('icon icon-application');
|
|
69
|
+
expect(source.showLink).toBe(false);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should return correct source for SOURCE_TYPE.TARBALL', () => {
|
|
73
|
+
instance = new HelmOp({ spec: { helm: { chart: 'https://github.com/rancher/fleet-helm-charts/releases/download/fleet-0.12.1-beta.2/fleet-0.12.1-beta.2.tgz' } } });
|
|
74
|
+
|
|
75
|
+
const source = instance.source;
|
|
76
|
+
|
|
77
|
+
expect(source.value).toBe('https://github.com/rancher/fleet-helm-charts/releases/download/fleet-0.12.1-beta.2/fleet-0.12.1-beta.2.tgz');
|
|
78
|
+
expect(source.display).toBe('rancher/fleet-helm-charts/releases/download/fleet-0.12.1-beta.2/fleet-0.12.1-beta.2.tgz');
|
|
79
|
+
expect(source.icon).toBe('icon icon-application');
|
|
80
|
+
expect(source.showLink).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should handle missing helm spec gracefully', () => {
|
|
84
|
+
instance = new HelmOp({ spec: {} });
|
|
85
|
+
const source = instance.source;
|
|
86
|
+
|
|
87
|
+
expect(source.value).toBe('');
|
|
88
|
+
expect(source.display).toBeNull();
|
|
89
|
+
expect(source.icon).toBe('icon icon-application');
|
|
90
|
+
expect(source.showLink).toBe(false);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('sourceSub getter', () => {
|
|
95
|
+
it('should display chart name and desired version when both are present (SOURCE_TYPE.REPO)', () => {
|
|
96
|
+
instance = new HelmOp({
|
|
97
|
+
spec: {
|
|
98
|
+
helm: {
|
|
99
|
+
repo: 'https://charts.rancher.io/fleet',
|
|
100
|
+
chart: 'fleet-agent',
|
|
101
|
+
version: '0.12.x'
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const sourceSub = instance.sourceSub;
|
|
107
|
+
|
|
108
|
+
expect(sourceSub.value).toBe('fleet-agent : 0.12.x');
|
|
109
|
+
expect(sourceSub.display).toBe('fleet-agent : 0.12.x');
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should display chart name and desired version when both are present (SOURCE_TYPE.OCI)', () => {
|
|
113
|
+
instance = new HelmOp({
|
|
114
|
+
spec: {
|
|
115
|
+
helm: {
|
|
116
|
+
repo: 'oci://ghcr.io/rancher/some-chart',
|
|
117
|
+
version: '1.0.0'
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const sourceSub = instance.sourceSub;
|
|
123
|
+
|
|
124
|
+
expect(sourceSub.value).toBe('rancher/some-chart : 1.0.0');
|
|
125
|
+
expect(sourceSub.display).toBe('rancher/some-chart : 1.0.0');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should display only installed version when only it is present', () => {
|
|
129
|
+
instance = new HelmOp({
|
|
130
|
+
status: { version: '0.12.3' },
|
|
131
|
+
spec: { helm: {} }
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const sourceSub = instance.sourceSub;
|
|
135
|
+
|
|
136
|
+
expect(sourceSub.value).toBe('0.12.3');
|
|
137
|
+
expect(sourceSub.display).toBe('0.12.3');
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should display semantic version when installed version is missing', () => {
|
|
141
|
+
instance = new HelmOp({
|
|
142
|
+
spec: {
|
|
143
|
+
helm: {
|
|
144
|
+
version: '0.12.x',
|
|
145
|
+
chart: 'test-chart'
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const sourceSub = instance.sourceSub;
|
|
151
|
+
|
|
152
|
+
expect(sourceSub.value).toBe('0.12.x');
|
|
153
|
+
expect(sourceSub.display).toBe('0.12.x');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should display "semantic -> installed" when both versions are present (no chart)', () => {
|
|
157
|
+
instance = new HelmOp({
|
|
158
|
+
spec: { helm: { version: '0.12.x' } },
|
|
159
|
+
status: { version: '0.12.5' }
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const sourceSub = instance.sourceSub;
|
|
163
|
+
|
|
164
|
+
expect(sourceSub.value).toBe('0.12.x -> 0.12.5');
|
|
165
|
+
expect(sourceSub.display).toBe('0.12.x -> 0.12.5');
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should display chart and "semantic -> installed" when all are present', () => {
|
|
169
|
+
instance = new HelmOp({
|
|
170
|
+
spec: {
|
|
171
|
+
helm: {
|
|
172
|
+
repo: 'https://charts.rancher.io/fleet',
|
|
173
|
+
chart: 'fleet-agent',
|
|
174
|
+
version: '0.12.x'
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
status: { version: '0.12.5' }
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const sourceSub = instance.sourceSub;
|
|
181
|
+
|
|
182
|
+
expect(sourceSub.value).toBe('fleet-agent : 0.12.x -> 0.12.5');
|
|
183
|
+
expect(sourceSub.display).toBe('fleet-agent : 0.12.x -> 0.12.5');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('should display chart and only semantic version when all are present but semantic version is equal to installed version (no duplicate info)', () => {
|
|
187
|
+
instance = new HelmOp({
|
|
188
|
+
spec: {
|
|
189
|
+
helm: {
|
|
190
|
+
repo: 'https://charts.rancher.io/fleet',
|
|
191
|
+
chart: 'fleet-agent',
|
|
192
|
+
version: '0.12.3'
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
status: { version: '0.12.3' }
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const sourceSub = instance.sourceSub;
|
|
199
|
+
|
|
200
|
+
expect(sourceSub.value).toBe('fleet-agent : 0.12.3');
|
|
201
|
+
expect(sourceSub.display).toBe('fleet-agent : 0.12.3');
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('should return empty string when no version or chart information is available', () => {
|
|
205
|
+
instance = new HelmOp({
|
|
206
|
+
spec: { helm: {} },
|
|
207
|
+
status: {}
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const sourceSub = instance.sourceSub;
|
|
211
|
+
|
|
212
|
+
expect(sourceSub.value).toBe('');
|
|
213
|
+
expect(sourceSub.display).toBe('');
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it('should correctly handle missing helm spec', () => {
|
|
217
|
+
instance = new HelmOp({ spec: {}, status: {} });
|
|
218
|
+
const sourceSub = instance.sourceSub;
|
|
219
|
+
|
|
220
|
+
expect(sourceSub.value).toBe('');
|
|
221
|
+
expect(sourceSub.display).toBe('');
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
});
|