From d50d22c9704f6cceca25b0b0f43aae681d87438b Mon Sep 17 00:00:00 2001 From: Khwaja Faraz Ahmed Date: Fri, 11 Jul 2025 17:09:23 +0500 Subject: [PATCH 1/5] Add test coverage for get_values/metadata.go Signed-off-by: Khwaja Faraz Ahmed Signed-off-by: Khwaja Faraz Ahmed --- pkg/action/get_metadata_test.go | 435 ++++++++++++++++++++++++++++++++ pkg/action/get_values_test.go | 228 +++++++++++++++++ 2 files changed, 663 insertions(+) create mode 100644 pkg/action/get_metadata_test.go create mode 100644 pkg/action/get_values_test.go diff --git a/pkg/action/get_metadata_test.go b/pkg/action/get_metadata_test.go new file mode 100644 index 000000000..bde71265d --- /dev/null +++ b/pkg/action/get_metadata_test.go @@ -0,0 +1,435 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package action + +import ( + "errors" + "io" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + chart "helm.sh/helm/v4/pkg/chart/v2" + kubefake "helm.sh/helm/v4/pkg/kube/fake" + release "helm.sh/helm/v4/pkg/release/v1" + helmtime "helm.sh/helm/v4/pkg/time" +) + +// unreachableKubeClient is a test client that always returns an error for IsReachable +type unreachableKubeClientForMetadata struct { + kubefake.PrintingKubeClient +} + +func (u *unreachableKubeClientForMetadata) IsReachable() error { + return errors.New("connection refused") +} + +func TestNewGetMetadata(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetMetadata(cfg) + + assert.NotNil(t, client) + assert.Equal(t, cfg, client.cfg) + assert.Equal(t, 0, client.Version) +} + +func TestGetMetadata_Run_BasicMetadata(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetMetadata(cfg) + + releaseName := "test-release" + deployedTime := helmtime.Now() + + rel := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusDeployed, + LastDeployed: deployedTime, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + AppVersion: "v1.2.3", + }, + }, + Version: 1, + Namespace: "default", + } + + cfg.Releases.Create(rel) + + result, err := client.Run(releaseName) + require.NoError(t, err) + + assert.Equal(t, releaseName, result.Name) + assert.Equal(t, "test-chart", result.Chart) + assert.Equal(t, "1.0.0", result.Version) + assert.Equal(t, "v1.2.3", result.AppVersion) + assert.Equal(t, "default", result.Namespace) + assert.Equal(t, 1, result.Revision) + assert.Equal(t, "deployed", result.Status) + assert.Equal(t, deployedTime.Format(time.RFC3339), result.DeployedAt) + assert.Empty(t, result.Dependencies) + assert.Empty(t, result.Annotations) +} + +func TestGetMetadata_Run_WithDependencies(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetMetadata(cfg) + + releaseName := "test-release" + deployedTime := helmtime.Now() + + dependencies := []*chart.Dependency{ + { + Name: "mysql", + Version: "8.0.25", + Repository: "https://charts.bitnami.com/bitnami", + }, + { + Name: "redis", + Version: "6.2.4", + Repository: "https://charts.bitnami.com/bitnami", + }, + } + + rel := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusDeployed, + LastDeployed: deployedTime, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + AppVersion: "v1.2.3", + Dependencies: dependencies, + }, + }, + Version: 1, + Namespace: "default", + } + + cfg.Releases.Create(rel) + + result, err := client.Run(releaseName) + require.NoError(t, err) + + assert.Equal(t, releaseName, result.Name) + assert.Equal(t, "test-chart", result.Chart) + assert.Equal(t, "1.0.0", result.Version) + assert.Equal(t, dependencies, result.Dependencies) + assert.Len(t, result.Dependencies, 2) + assert.Equal(t, "mysql", result.Dependencies[0].Name) + assert.Equal(t, "redis", result.Dependencies[1].Name) +} + +func TestGetMetadata_Run_WithAnnotations(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetMetadata(cfg) + + releaseName := "test-release" + deployedTime := helmtime.Now() + + annotations := map[string]string{ + "helm.sh/hook": "pre-install", + "helm.sh/hook-weight": "5", + "custom.annotation": "test-value", + } + + rel := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusDeployed, + LastDeployed: deployedTime, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + AppVersion: "v1.2.3", + Annotations: annotations, + }, + }, + Version: 1, + Namespace: "default", + } + + cfg.Releases.Create(rel) + + result, err := client.Run(releaseName) + require.NoError(t, err) + + assert.Equal(t, releaseName, result.Name) + assert.Equal(t, "test-chart", result.Chart) + assert.Equal(t, annotations, result.Annotations) + assert.Equal(t, "pre-install", result.Annotations["helm.sh/hook"]) + assert.Equal(t, "5", result.Annotations["helm.sh/hook-weight"]) + assert.Equal(t, "test-value", result.Annotations["custom.annotation"]) +} + +func TestGetMetadata_Run_SpecificVersion(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetMetadata(cfg) + client.Version = 2 + + releaseName := "test-release" + deployedTime := helmtime.Now() + + rel1 := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusSuperseded, + LastDeployed: helmtime.Time{Time: deployedTime.Time.Add(-time.Hour)}, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + AppVersion: "v1.0.0", + }, + }, + Version: 1, + Namespace: "default", + } + + rel2 := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusDeployed, + LastDeployed: deployedTime, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.1.0", + AppVersion: "v1.1.0", + }, + }, + Version: 2, + Namespace: "default", + } + + cfg.Releases.Create(rel1) + cfg.Releases.Create(rel2) + + result, err := client.Run(releaseName) + require.NoError(t, err) + + assert.Equal(t, releaseName, result.Name) + assert.Equal(t, "test-chart", result.Chart) + assert.Equal(t, "1.1.0", result.Version) + assert.Equal(t, "v1.1.0", result.AppVersion) + assert.Equal(t, 2, result.Revision) + assert.Equal(t, "deployed", result.Status) +} + +func TestGetMetadata_Run_DifferentStatuses(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetMetadata(cfg) + + testCases := []struct { + name string + status release.Status + expected string + }{ + {"deployed", release.StatusDeployed, "deployed"}, + {"failed", release.StatusFailed, "failed"}, + {"uninstalled", release.StatusUninstalled, "uninstalled"}, + {"pending-install", release.StatusPendingInstall, "pending-install"}, + {"pending-upgrade", release.StatusPendingUpgrade, "pending-upgrade"}, + {"pending-rollback", release.StatusPendingRollback, "pending-rollback"}, + {"superseded", release.StatusSuperseded, "superseded"}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + releaseName := "test-release-" + tc.name + deployedTime := helmtime.Now() + + rel := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: tc.status, + LastDeployed: deployedTime, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + AppVersion: "v1.0.0", + }, + }, + Version: 1, + Namespace: "default", + } + + cfg.Releases.Create(rel) + + result, err := client.Run(releaseName) + require.NoError(t, err) + + assert.Equal(t, tc.expected, result.Status) + }) + } +} + +func TestGetMetadata_Run_UnreachableKubeClient(t *testing.T) { + cfg := actionConfigFixture(t) + cfg.KubeClient = &unreachableKubeClientForMetadata{ + PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, + } + + client := NewGetMetadata(cfg) + + _, err := client.Run("test-release") + assert.Error(t, err) + assert.Contains(t, err.Error(), "connection refused") +} + +func TestGetMetadata_Run_ReleaseNotFound(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetMetadata(cfg) + + _, err := client.Run("non-existent-release") + assert.Error(t, err) + assert.Contains(t, err.Error(), "not found") +} + +func TestGetMetadata_Run_EmptyAppVersion(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetMetadata(cfg) + + releaseName := "test-release" + deployedTime := helmtime.Now() + + rel := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusDeployed, + LastDeployed: deployedTime, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + AppVersion: "", // Empty app version + }, + }, + Version: 1, + Namespace: "default", + } + + cfg.Releases.Create(rel) + + result, err := client.Run(releaseName) + require.NoError(t, err) + + assert.Equal(t, "", result.AppVersion) +} + +func TestMetadata_FormattedDepNames(t *testing.T) { + testCases := []struct { + name string + dependencies []*chart.Dependency + expected string + }{ + { + name: "no dependencies", + dependencies: []*chart.Dependency{}, + expected: "", + }, + { + name: "single dependency", + dependencies: []*chart.Dependency{ + {Name: "mysql"}, + }, + expected: "mysql", + }, + { + name: "multiple dependencies sorted", + dependencies: []*chart.Dependency{ + {Name: "redis"}, + {Name: "mysql"}, + {Name: "nginx"}, + }, + expected: "mysql,nginx,redis", + }, + { + name: "already sorted dependencies", + dependencies: []*chart.Dependency{ + {Name: "apache"}, + {Name: "mysql"}, + {Name: "zookeeper"}, + }, + expected: "apache,mysql,zookeeper", + }, + { + name: "duplicate names", + dependencies: []*chart.Dependency{ + {Name: "mysql"}, + {Name: "redis"}, + {Name: "mysql"}, + }, + expected: "mysql,mysql,redis", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + metadata := &Metadata{ + Dependencies: tc.dependencies, + } + + result := metadata.FormattedDepNames() + assert.Equal(t, tc.expected, result) + }) + } +} + +func TestMetadata_FormattedDepNames_WithComplexDependencies(t *testing.T) { + dependencies := []*chart.Dependency{ + { + Name: "zookeeper", + Version: "10.0.0", + Repository: "https://charts.bitnami.com/bitnami", + Condition: "zookeeper.enabled", + }, + { + Name: "apache", + Version: "9.0.0", + Repository: "https://charts.bitnami.com/bitnami", + }, + { + Name: "mysql", + Version: "8.0.25", + Repository: "https://charts.bitnami.com/bitnami", + Condition: "mysql.enabled", + }, + } + + metadata := &Metadata{ + Dependencies: dependencies, + } + + result := metadata.FormattedDepNames() + assert.Equal(t, "apache,mysql,zookeeper", result) +} diff --git a/pkg/action/get_values_test.go b/pkg/action/get_values_test.go new file mode 100644 index 000000000..30ee7ecee --- /dev/null +++ b/pkg/action/get_values_test.go @@ -0,0 +1,228 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package action + +import ( + "errors" + "io" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + chart "helm.sh/helm/v4/pkg/chart/v2" + kubefake "helm.sh/helm/v4/pkg/kube/fake" + release "helm.sh/helm/v4/pkg/release/v1" +) + +// unreachableKubeClient is a test client that always returns an error for IsReachable +type unreachableKubeClient struct { + kubefake.PrintingKubeClient +} + +func (u *unreachableKubeClient) IsReachable() error { + return errors.New("connection refused") +} + +func TestNewGetValues(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetValues(cfg) + + assert.NotNil(t, client) + assert.Equal(t, cfg, client.cfg) + assert.Equal(t, 0, client.Version) + assert.Equal(t, false, client.AllValues) +} + +func TestGetValues_Run_UserConfigOnly(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetValues(cfg) + + releaseName := "test-release" + userConfig := map[string]interface{}{ + "database": map[string]interface{}{ + "host": "localhost", + "port": 5432, + }, + "app": map[string]interface{}{ + "name": "my-app", + "replicas": 3, + }, + } + + rel := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusDeployed, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + }, + Values: map[string]interface{}{ + "defaultKey": "defaultValue", + "app": map[string]interface{}{ + "name": "default-app", + "timeout": 30, + }, + }, + }, + Config: userConfig, + Version: 1, + Namespace: "default", + } + + cfg.Releases.Create(rel) + + result, err := client.Run(releaseName) + require.NoError(t, err) + assert.Equal(t, userConfig, result) +} + +func TestGetValues_Run_AllValues(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetValues(cfg) + client.AllValues = true + + releaseName := "test-release" + userConfig := map[string]interface{}{ + "database": map[string]interface{}{ + "host": "localhost", + "port": 5432, + }, + "app": map[string]interface{}{ + "name": "my-app", + }, + } + + chartDefaultValues := map[string]interface{}{ + "defaultKey": "defaultValue", + "app": map[string]interface{}{ + "name": "default-app", + "timeout": 30, + }, + } + + rel := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusDeployed, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + }, + Values: chartDefaultValues, + }, + Config: userConfig, + Version: 1, + Namespace: "default", + } + + cfg.Releases.Create(rel) + + result, err := client.Run(releaseName) + require.NoError(t, err) + + assert.Equal(t, "my-app", result["app"].(map[string]interface{})["name"]) + assert.Equal(t, 30, result["app"].(map[string]interface{})["timeout"]) + assert.Equal(t, "defaultValue", result["defaultKey"]) + assert.Equal(t, "localhost", result["database"].(map[string]interface{})["host"]) + assert.Equal(t, 5432, result["database"].(map[string]interface{})["port"]) +} + +func TestGetValues_Run_EmptyValues(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetValues(cfg) + + releaseName := "test-release" + + rel := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusDeployed, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + }, + }, + Config: map[string]interface{}{}, + Version: 1, + Namespace: "default", + } + + cfg.Releases.Create(rel) + + result, err := client.Run(releaseName) + require.NoError(t, err) + assert.Equal(t, map[string]interface{}{}, result) +} + +func TestGetValues_Run_UnreachableKubeClient(t *testing.T) { + cfg := actionConfigFixture(t) + cfg.KubeClient = &unreachableKubeClient{ + PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, + } + + client := NewGetValues(cfg) + + _, err := client.Run("test-release") + assert.Error(t, err) + assert.Contains(t, err.Error(), "connection refused") +} + +func TestGetValues_Run_ReleaseNotFound(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetValues(cfg) + + _, err := client.Run("non-existent-release") + assert.Error(t, err) + assert.Contains(t, err.Error(), "not found") +} + +func TestGetValues_Run_NilConfig(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetValues(cfg) + + releaseName := "test-release" + + rel := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusDeployed, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + }, + }, + Config: nil, + Version: 1, + Namespace: "default", + } + + cfg.Releases.Create(rel) + + result, err := client.Run(releaseName) + require.NoError(t, err) + assert.Nil(t, result) +} From 2d2d4a868da0b1ee8bf0878134e31c44af067843 Mon Sep 17 00:00:00 2001 From: Faraz Khawaja Date: Sun, 20 Jul 2025 17:34:09 +0500 Subject: [PATCH 2/5] Fix struct declaration Signed-off-by: Faraz Khawaja Signed-off-by: Khwaja Faraz Ahmed --- pkg/action/get_metadata_test.go | 6 +++--- pkg/action/get_values_test.go | 10 ---------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/pkg/action/get_metadata_test.go b/pkg/action/get_metadata_test.go index f6c6346ec..1197a4635 100644 --- a/pkg/action/get_metadata_test.go +++ b/pkg/action/get_metadata_test.go @@ -32,11 +32,11 @@ import ( ) // unreachableKubeClient is a test client that always returns an error for IsReachable -type unreachableKubeClientForMetadata struct { +type unreachableKubeClient struct { kubefake.PrintingKubeClient } -func (u *unreachableKubeClientForMetadata) IsReachable() error { +func (u *unreachableKubeClient) IsReachable() error { return errors.New("connection refused") } @@ -294,7 +294,7 @@ func TestGetMetadata_Run_DifferentStatuses(t *testing.T) { func TestGetMetadata_Run_UnreachableKubeClient(t *testing.T) { cfg := actionConfigFixture(t) - cfg.KubeClient = &unreachableKubeClientForMetadata{ + cfg.KubeClient = &unreachableKubeClient{ PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, } diff --git a/pkg/action/get_values_test.go b/pkg/action/get_values_test.go index 30ee7ecee..ec785b5c7 100644 --- a/pkg/action/get_values_test.go +++ b/pkg/action/get_values_test.go @@ -17,7 +17,6 @@ limitations under the License. package action import ( - "errors" "io" "testing" @@ -29,15 +28,6 @@ import ( release "helm.sh/helm/v4/pkg/release/v1" ) -// unreachableKubeClient is a test client that always returns an error for IsReachable -type unreachableKubeClient struct { - kubefake.PrintingKubeClient -} - -func (u *unreachableKubeClient) IsReachable() error { - return errors.New("connection refused") -} - func TestNewGetValues(t *testing.T) { cfg := actionConfigFixture(t) client := NewGetValues(cfg) From a37934a89210f9facc9ccb30c024266674bf9b57 Mon Sep 17 00:00:00 2001 From: Khwaja Faraz Ahmed Date: Fri, 25 Jul 2025 20:27:47 +0500 Subject: [PATCH 3/5] fix linting issue Signed-off-by: Khwaja Faraz Ahmed --- pkg/action/get_metadata_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/action/get_metadata_test.go b/pkg/action/get_metadata_test.go index 1197a4635..c8e77fc0b 100644 --- a/pkg/action/get_metadata_test.go +++ b/pkg/action/get_metadata_test.go @@ -434,7 +434,6 @@ func TestMetadata_FormattedDepNames_WithComplexDependencies(t *testing.T) { assert.Equal(t, "apache,mysql,zookeeper", result) } - func TestGetMetadata_Labels(t *testing.T) { rel := releaseStub() rel.Info.Status = release.StatusDeployed From ded25c1908b1dc1baab0b7e5a33a809e81133a7d Mon Sep 17 00:00:00 2001 From: Khwaja Faraz Ahmed Date: Thu, 7 Aug 2025 18:30:19 +0500 Subject: [PATCH 4/5] Add tests for alias Signed-off-by: Khwaja Faraz Ahmed --- pkg/action/get_metadata_test.go | 183 ++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/pkg/action/get_metadata_test.go b/pkg/action/get_metadata_test.go index c8e77fc0b..20642f07a 100644 --- a/pkg/action/get_metadata_test.go +++ b/pkg/action/get_metadata_test.go @@ -142,6 +142,136 @@ func TestGetMetadata_Run_WithDependencies(t *testing.T) { assert.Equal(t, "redis", result.Dependencies[1].Name) } +func TestGetMetadata_Run_WithDependenciesAliases(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetMetadata(cfg) + + releaseName := "test-release" + deployedTime := helmtime.Now() + + dependencies := []*chart.Dependency{ + { + Name: "mysql", + Version: "8.0.25", + Repository: "https://charts.bitnami.com/bitnami", + Alias: "database", + }, + { + Name: "redis", + Version: "6.2.4", + Repository: "https://charts.bitnami.com/bitnami", + Alias: "cache", + }, + } + + rel := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusDeployed, + LastDeployed: deployedTime, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + AppVersion: "v1.2.3", + Dependencies: dependencies, + }, + }, + Version: 1, + Namespace: "default", + } + + cfg.Releases.Create(rel) + + result, err := client.Run(releaseName) + require.NoError(t, err) + + assert.Equal(t, releaseName, result.Name) + assert.Equal(t, "test-chart", result.Chart) + assert.Equal(t, "1.0.0", result.Version) + assert.Equal(t, dependencies, result.Dependencies) + assert.Len(t, result.Dependencies, 2) + assert.Equal(t, "mysql", result.Dependencies[0].Name) + assert.Equal(t, "database", result.Dependencies[0].Alias) + assert.Equal(t, "redis", result.Dependencies[1].Name) + assert.Equal(t, "cache", result.Dependencies[1].Alias) +} + +func TestGetMetadata_Run_WithMixedDependencies(t *testing.T) { + cfg := actionConfigFixture(t) + client := NewGetMetadata(cfg) + + releaseName := "test-release" + deployedTime := helmtime.Now() + + dependencies := []*chart.Dependency{ + { + Name: "mysql", + Version: "8.0.25", + Repository: "https://charts.bitnami.com/bitnami", + Alias: "database", + }, + { + Name: "nginx", + Version: "1.20.0", + Repository: "https://charts.bitnami.com/bitnami", + }, + { + Name: "redis", + Version: "6.2.4", + Repository: "https://charts.bitnami.com/bitnami", + Alias: "cache", + }, + { + Name: "postgresql", + Version: "11.0.0", + Repository: "https://charts.bitnami.com/bitnami", + }, + } + + rel := &release.Release{ + Name: releaseName, + Info: &release.Info{ + Status: release.StatusDeployed, + LastDeployed: deployedTime, + }, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + AppVersion: "v1.2.3", + Dependencies: dependencies, + }, + }, + Version: 1, + Namespace: "default", + } + + cfg.Releases.Create(rel) + + result, err := client.Run(releaseName) + require.NoError(t, err) + + assert.Equal(t, releaseName, result.Name) + assert.Equal(t, "test-chart", result.Chart) + assert.Equal(t, "1.0.0", result.Version) + assert.Equal(t, dependencies, result.Dependencies) + assert.Len(t, result.Dependencies, 4) + + // Verify dependencies with aliases + assert.Equal(t, "mysql", result.Dependencies[0].Name) + assert.Equal(t, "database", result.Dependencies[0].Alias) + assert.Equal(t, "redis", result.Dependencies[2].Name) + assert.Equal(t, "cache", result.Dependencies[2].Alias) + + // Verify dependencies without aliases + assert.Equal(t, "nginx", result.Dependencies[1].Name) + assert.Equal(t, "", result.Dependencies[1].Alias) + assert.Equal(t, "postgresql", result.Dependencies[3].Name) + assert.Equal(t, "", result.Dependencies[3].Alias) +} + func TestGetMetadata_Run_WithAnnotations(t *testing.T) { cfg := actionConfigFixture(t) client := NewGetMetadata(cfg) @@ -434,6 +564,59 @@ func TestMetadata_FormattedDepNames_WithComplexDependencies(t *testing.T) { assert.Equal(t, "apache,mysql,zookeeper", result) } +func TestMetadata_FormattedDepNames_WithAliases(t *testing.T) { + testCases := []struct { + name string + dependencies []*chart.Dependency + expected string + }{ + { + name: "dependencies with aliases", + dependencies: []*chart.Dependency{ + {Name: "mysql", Alias: "database"}, + {Name: "redis", Alias: "cache"}, + }, + expected: "mysql,redis", + }, + { + name: "mixed dependencies with and without aliases", + dependencies: []*chart.Dependency{ + {Name: "mysql", Alias: "database"}, + {Name: "nginx"}, + {Name: "redis", Alias: "cache"}, + }, + expected: "mysql,nginx,redis", + }, + { + name: "empty alias should use name", + dependencies: []*chart.Dependency{ + {Name: "mysql", Alias: ""}, + {Name: "redis", Alias: "cache"}, + }, + expected: "mysql,redis", + }, + { + name: "sorted by name not alias", + dependencies: []*chart.Dependency{ + {Name: "zookeeper", Alias: "a-service"}, + {Name: "apache", Alias: "z-service"}, + }, + expected: "apache,zookeeper", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + metadata := &Metadata{ + Dependencies: tc.dependencies, + } + + result := metadata.FormattedDepNames() + assert.Equal(t, tc.expected, result) + }) + } +} + func TestGetMetadata_Labels(t *testing.T) { rel := releaseStub() rel.Info.Status = release.StatusDeployed From 85164e5705e81b5ec175002600c4008195799c2b Mon Sep 17 00:00:00 2001 From: Khwaja Faraz Ahmed Date: Thu, 7 Aug 2025 19:35:36 +0500 Subject: [PATCH 5/5] fix lint errors Signed-off-by: Khwaja Faraz Ahmed --- pkg/action/get_metadata_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/action/get_metadata_test.go b/pkg/action/get_metadata_test.go index 20642f07a..6ceb34951 100644 --- a/pkg/action/get_metadata_test.go +++ b/pkg/action/get_metadata_test.go @@ -258,13 +258,13 @@ func TestGetMetadata_Run_WithMixedDependencies(t *testing.T) { assert.Equal(t, "1.0.0", result.Version) assert.Equal(t, dependencies, result.Dependencies) assert.Len(t, result.Dependencies, 4) - + // Verify dependencies with aliases assert.Equal(t, "mysql", result.Dependencies[0].Name) assert.Equal(t, "database", result.Dependencies[0].Alias) assert.Equal(t, "redis", result.Dependencies[2].Name) assert.Equal(t, "cache", result.Dependencies[2].Alias) - + // Verify dependencies without aliases assert.Equal(t, "nginx", result.Dependencies[1].Name) assert.Equal(t, "", result.Dependencies[1].Alias)