From 7e5aa32ad6bdcfd7bd5f70f6d0f9dbcdf0d6a62e Mon Sep 17 00:00:00 2001 From: shellyco-code Date: Thu, 25 Jun 2026 10:37:28 +0530 Subject: [PATCH 1/3] fix(preheat): handle nil payload during policy update Signed-off-by: shellyco-code --- .../root/project/preheat/policy/update.go | 10 ++- .../project/preheat/policy/update_test.go | 65 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 cmd/harbor/root/project/preheat/policy/update_test.go diff --git a/cmd/harbor/root/project/preheat/policy/update.go b/cmd/harbor/root/project/preheat/policy/update.go index abdb21da0..6ea400eb7 100644 --- a/cmd/harbor/root/project/preheat/policy/update.go +++ b/cmd/harbor/root/project/preheat/policy/update.go @@ -26,6 +26,10 @@ import ( "github.com/spf13/cobra" ) +var ( + getPreheatPolicyFunc = api.GetPreheatPolicy +) + func UpdatePolicyCommand() *cobra.Command { var isID bool @@ -75,7 +79,7 @@ func UpdatePolicyCommand() *cobra.Command { } log.Debug("Fetching preheat policy...") - existingPolicy, err := api.GetPreheatPolicy(projectName, policyName) + existingPolicy, err := getPreheatPolicyFunc(projectName, policyName) if err != nil { if utils.ParseHarborErrorCode(err) == "404" { return fmt.Errorf("preheat policy %s not found in project %s", policyName, projectName) @@ -83,6 +87,10 @@ func UpdatePolicyCommand() *cobra.Command { return fmt.Errorf("failed to get preheat policy: %v", utils.ParseHarborErrorMsg(err)) } + if existingPolicy == nil || existingPolicy.Payload == nil { + return fmt.Errorf("preheat policy %s payload is empty", policyName) + } + log.Debug("Fetching available providers...") providers, err := api.ListProvidersUnderProject(projectName) if err != nil { diff --git a/cmd/harbor/root/project/preheat/policy/update_test.go b/cmd/harbor/root/project/preheat/policy/update_test.go new file mode 100644 index 000000000..9b7118c43 --- /dev/null +++ b/cmd/harbor/root/project/preheat/policy/update_test.go @@ -0,0 +1,65 @@ +// Copyright Project Harbor 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 policy + +import ( + "bytes" + "testing" + + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/preheat" + "github.com/stretchr/testify/assert" +) + +func TestUpdatePolicyCommand_NilPolicy(t *testing.T) { + originalGetPreheatPolicy := getPreheatPolicyFunc + t.Cleanup(func() { + getPreheatPolicyFunc = originalGetPreheatPolicy + }) + + getPreheatPolicyFunc = func(projectName, policyName string) (*preheat.GetPolicyOK, error) { + return nil, nil + } + + cmd := UpdatePolicyCommand() + var buf bytes.Buffer + cmd.SetOut(&buf) + cmd.SetErr(&buf) + cmd.SetArgs([]string{"my-project", "my-policy"}) + + err := cmd.Execute() + assert.Error(t, err) + assert.Contains(t, err.Error(), "payload is empty") +} + +func TestUpdatePolicyCommand_NilPayload(t *testing.T) { + originalGetPreheatPolicy := getPreheatPolicyFunc + t.Cleanup(func() { + getPreheatPolicyFunc = originalGetPreheatPolicy + }) + + getPreheatPolicyFunc = func(projectName, policyName string) (*preheat.GetPolicyOK, error) { + return &preheat.GetPolicyOK{Payload: nil}, nil + } + + cmd := UpdatePolicyCommand() + var buf bytes.Buffer + cmd.SetOut(&buf) + cmd.SetErr(&buf) + cmd.SetArgs([]string{"my-project", "my-policy"}) + + err := cmd.Execute() + assert.Error(t, err) + assert.Contains(t, err.Error(), "payload is empty") +} From 7610a7e989b57dd5b77beed408f368e180f00059 Mon Sep 17 00:00:00 2001 From: shellyco-code Date: Thu, 25 Jun 2026 13:34:40 +0530 Subject: [PATCH 2/3] test(preheat): align tests with Harbor CLI conventions Signed-off-by: shellyco-code --- .../root/project/preheat/policy/update_test.go | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/cmd/harbor/root/project/preheat/policy/update_test.go b/cmd/harbor/root/project/preheat/policy/update_test.go index 9b7118c43..064c23ec5 100644 --- a/cmd/harbor/root/project/preheat/policy/update_test.go +++ b/cmd/harbor/root/project/preheat/policy/update_test.go @@ -15,10 +15,10 @@ package policy import ( - "bytes" "testing" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/preheat" + "github.com/goharbor/harbor-cli/pkg/testutil" "github.com/stretchr/testify/assert" ) @@ -32,13 +32,7 @@ func TestUpdatePolicyCommand_NilPolicy(t *testing.T) { return nil, nil } - cmd := UpdatePolicyCommand() - var buf bytes.Buffer - cmd.SetOut(&buf) - cmd.SetErr(&buf) - cmd.SetArgs([]string{"my-project", "my-policy"}) - - err := cmd.Execute() + err := testutil.TestCmd(t, UpdatePolicyCommand, "my-project", "my-policy") assert.Error(t, err) assert.Contains(t, err.Error(), "payload is empty") } @@ -53,13 +47,7 @@ func TestUpdatePolicyCommand_NilPayload(t *testing.T) { return &preheat.GetPolicyOK{Payload: nil}, nil } - cmd := UpdatePolicyCommand() - var buf bytes.Buffer - cmd.SetOut(&buf) - cmd.SetErr(&buf) - cmd.SetArgs([]string{"my-project", "my-policy"}) - - err := cmd.Execute() + err := testutil.TestCmd(t, UpdatePolicyCommand, "my-project", "my-policy") assert.Error(t, err) assert.Contains(t, err.Error(), "payload is empty") } From fed49bc80d18a386e957756150e470079fddf4e8 Mon Sep 17 00:00:00 2001 From: shellyco-code Date: Thu, 25 Jun 2026 13:52:08 +0530 Subject: [PATCH 3/3] test(preheat): align tests with Harbor CLI conventions Signed-off-by: shellyco-code --- .../root/project/preheat/policy/update.go | 6 +-- .../project/preheat/policy/update_test.go | 53 ++++++++++--------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/cmd/harbor/root/project/preheat/policy/update.go b/cmd/harbor/root/project/preheat/policy/update.go index 6ea400eb7..874a43882 100644 --- a/cmd/harbor/root/project/preheat/policy/update.go +++ b/cmd/harbor/root/project/preheat/policy/update.go @@ -26,10 +26,6 @@ import ( "github.com/spf13/cobra" ) -var ( - getPreheatPolicyFunc = api.GetPreheatPolicy -) - func UpdatePolicyCommand() *cobra.Command { var isID bool @@ -79,7 +75,7 @@ func UpdatePolicyCommand() *cobra.Command { } log.Debug("Fetching preheat policy...") - existingPolicy, err := getPreheatPolicyFunc(projectName, policyName) + existingPolicy, err := api.GetPreheatPolicy(projectName, policyName) if err != nil { if utils.ParseHarborErrorCode(err) == "404" { return fmt.Errorf("preheat policy %s not found in project %s", policyName, projectName) diff --git a/cmd/harbor/root/project/preheat/policy/update_test.go b/cmd/harbor/root/project/preheat/policy/update_test.go index 064c23ec5..ffc047852 100644 --- a/cmd/harbor/root/project/preheat/policy/update_test.go +++ b/cmd/harbor/root/project/preheat/policy/update_test.go @@ -17,37 +17,40 @@ package policy import ( "testing" - "github.com/goharbor/go-client/pkg/sdk/v2.0/client/preheat" "github.com/goharbor/harbor-cli/pkg/testutil" - "github.com/stretchr/testify/assert" ) -func TestUpdatePolicyCommand_NilPolicy(t *testing.T) { - originalGetPreheatPolicy := getPreheatPolicyFunc - t.Cleanup(func() { - getPreheatPolicyFunc = originalGetPreheatPolicy - }) - - getPreheatPolicyFunc = func(projectName, policyName string) (*preheat.GetPolicyOK, error) { - return nil, nil +// TestUpdatePolicyCommand_Errors tests the custom CLI-level validations in the +// update command. API responses are not tested here. +func TestUpdatePolicyCommand_Errors(t *testing.T) { + tests := []struct { + name string + flags []string + expectError bool + }{ + { + name: "--id flag without arguments", + flags: []string{"--id"}, + expectError: true, + }, + { + name: "too many arguments", + flags: []string{"project", "policy", "extra"}, + expectError: true, + }, } - err := testutil.TestCmd(t, UpdatePolicyCommand, "my-project", "my-policy") - assert.Error(t, err) - assert.Contains(t, err.Error(), "payload is empty") -} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := testutil.TestCmd(t, UpdatePolicyCommand, tt.flags...) -func TestUpdatePolicyCommand_NilPayload(t *testing.T) { - originalGetPreheatPolicy := getPreheatPolicyFunc - t.Cleanup(func() { - getPreheatPolicyFunc = originalGetPreheatPolicy - }) + if tt.expectError && err == nil { + t.Fatalf("expected error but got nil") + } - getPreheatPolicyFunc = func(projectName, policyName string) (*preheat.GetPolicyOK, error) { - return &preheat.GetPolicyOK{Payload: nil}, nil + if !tt.expectError && err != nil { + t.Fatalf("unexpected error: %v", err) + } + }) } - - err := testutil.TestCmd(t, UpdatePolicyCommand, "my-project", "my-policy") - assert.Error(t, err) - assert.Contains(t, err.Error(), "payload is empty") }