Skip to content

tests: Added unit tests for user elevate command#686

Merged
bupd merged 2 commits into
goharbor:mainfrom
rkcoder101:test/user-elevate
Mar 17, 2026
Merged

tests: Added unit tests for user elevate command#686
bupd merged 2 commits into
goharbor:mainfrom
rkcoder101:test/user-elevate

Conversation

@rkcoder101

@rkcoder101 rkcoder101 commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

Description

This PR introduces unit tests for the user elevate command (cmd/harbor/root/user/elevate.go)

Note

No changes have been done to the core logic of the application, only a little refactoring for the purpose of writing some nice and clean test code :)

Copilot AI review requested due to automatic review settings February 7, 2026 09:10
@codecov

codecov Bot commented Feb 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.18919% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 7.79%. Comparing base (60ad0bd) to head (4eef00d).
⚠️ Report is 117 commits behind head on main.

Files with missing lines Patch % Lines
cmd/harbor/root/user/elevate.go 89.18% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##             main    #686      +/-   ##
=========================================
- Coverage   10.99%   7.79%   -3.20%     
=========================================
  Files         173     265      +92     
  Lines        8671   13175    +4504     
=========================================
+ Hits          953    1027      +74     
- Misses       7612   12035    +4423     
- Partials      106     113       +7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds unit tests around the user elevate CLI command and refactors the command implementation to be more testable by introducing an injectable dependency interface.

Changes:

  • Introduces a UserElevator interface + DefaultUserElevator implementation and extracts command logic into ElevateUser(...).
  • Adds table-driven unit tests covering success and several failure/confirmation flows for ElevateUser, plus a basic ElevateUserCmd() shape test.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
cmd/harbor/root/user/elevate.go Refactors elevate command logic into an injectable function to support unit testing.
cmd/harbor/root/user/elevate_test.go Adds unit tests for elevate command logic and command definition.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 87 to 96
func ElevateUserCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "elevate",
Short: "elevate user",
Long: "elevate user to admin role",
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
var err error
var userId int64
if len(args) > 0 {
userId, err = api.GetUsersIdByName(args[0])
if err != nil {
log.Errorf("failed to get user id for '%s': %v", args[0], err)
return
}
if userId == 0 {
log.Errorf("User with name '%s' not found", args[0])
return
}
} else {
userId = prompt.GetUserIdFromUser()
}
confirm, err := views.ConfirmElevation()
if err != nil {
log.Errorf("failed to confirm elevation: %v", err)
return
}
if !confirm {
log.Error("User did not confirm elevation. Aborting command.")
return
}

err = api.ElevateUser(userId)
if err != nil {
if isUnauthorizedError(err) {
log.Error("Permission denied: Admin privileges are required to execute this command.")
} else {
log.Errorf("failed to elevate user: %v", err)
}
}
d := &DefaultUserElevator{}
ElevateUser(args, d)
},

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description says it adds unit tests for the "user list" command, but the actual changes are for the "user elevate" command (elevate.go / elevate_test.go). Please update the PR description/title to match the scope to avoid confusion when tracking coverage work.

Copilot uses AI. Check for mistakes.
Comment thread cmd/harbor/root/user/elevate_test.go Outdated
Comment on lines +94 to +97
setup: func() *MockUserElevator {
m := initMockUserElevator(5, false, true, nil)
m.id["promptuser"] = 999
return m

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "elevate user via interactive prompt" test setup writes to m.id["promptuser"], but MockUserElevator.GetUserIDFromUser() always returns 999 and never consults m.id. This line is currently redundant/misleading; either remove it or have the mock's GetUserIDFromUser return a configurable value so the test reflects the intended behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +113
{
name: "user not found logs error",
setup: func() *MockUserElevator {
return initMockUserElevator(5, false, true, nil)
},
args: []string{"nonexistent"},
expectedAdminID: []int64{},
expectedErr: "failed to get user id",
},
{
name: "permission denied error",

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests cover the GetUserIDByName error path, but not the (userID==0, err==nil) "not found" branch that ElevateUser explicitly handles. Since pkg/api.GetUsersIdByName returns (0, nil) when a user is not found, consider adding a test case where GetUserIDByName returns 0 with no error and assert the "User with name ... not found" log message.

Copilot uses AI. Check for mistakes.
Comment thread cmd/harbor/root/user/elevate.go Outdated
Comment on lines +24 to +52
type UserElevator interface {
GetUserIDByName(username string) (int64, error)
GetUserIDFromUser() int64
ConfirmElevation() (bool, error)
ElevateUser(userID int64) error
}

type DefaultUserElevator struct{}

func (d *DefaultUserElevator) GetUserIDByName(username string) (int64, error) {
return api.GetUsersIdByName(username)
}

func (d *DefaultUserElevator) GetUserIDFromUser() int64 {
return prompt.GetUserIdFromUser()
}

func (d *DefaultUserElevator) ConfirmElevation() (bool, error) {
return views.ConfirmElevation()
}

func (d *DefaultUserElevator) ElevateUser(userID int64) error {
return api.ElevateUser(userID)
}

func ElevateUser(args []string, userElevator UserElevator) {
var err error
var userID int64

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UserElevator, DefaultUserElevator, and ElevateUser are exported but appear to be used only within this package (and tests are in the same package). Consider making these identifiers unexported (e.g., userElevator/defaultUserElevator/elevateUser) to avoid expanding the public surface area of the cmd package unnecessarily.

Copilot uses AI. Check for mistakes.
@rkcoder101 rkcoder101 mentioned this pull request Feb 7, 2026
5 tasks
@rkcoder101

Copy link
Copy Markdown
Contributor Author

@bupd please review this whenever u get the time. Thanks!

@qcserestipy qcserestipy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this contribution. The tests work. In general I think adding additional interfaces in the production code for testability only is technical overhead. Please restructure the test to work without this interface.

Comment thread cmd/harbor/root/user/elevate.go Outdated
"github.com/spf13/cobra"
)

type UserElevator interface {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Introducing a UserElevator interface in production code solely for test mockability adds unnecessary complexity. There's only one real implementation (DefaultUserElevator), and this pattern isn't used elsewhere in the codebase. Consider restructuring the tests to avoid altering the production code's API surface, or extracting only the testable logic into a separate function.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @qcserestipy I have tried to adapt a different design of test code. I have tried using global functional variables. Kindly review it, and please let me know if there are any changes required in the approach. Thanks!

@qcserestipy qcserestipy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rkcoder101 Thank you for incorporating the changes! LGTM, but please fix the lint issues.

@rkcoder101

Copy link
Copy Markdown
Contributor Author

@rkcoder101 Thank you for incorporating the changes! LGTM, but please fix the lint issues.

All the PRs opened lately are facing linting issues. Actually there have been some linting issues on the main recently #711 . Fellow contributors have raised PRs to solve them, I will rebase as soon as they get merged.

@bupd bupd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/goharbor/harbor-cli/actions/runs/22251606412/attempts/1#summary-64376129514

@rkcoder101 Please fix the lint issues - I believe we can make gosec nolint rule on all _test.go files

Please feel free to update it.

@bupd bupd added the Changes Requesed feedback that must be addressed before merging. label Mar 3, 2026
…commits)

Signed-off-by: Rayyan Khan <rayyanrehman101@gmail.com>
Signed-off-by: Rayyan Khan <rayyanrehman101@gmail.com>
@bupd bupd merged commit 3c40c79 into goharbor:main Mar 17, 2026
7 of 8 checks passed
AMAN-sharma07 pushed a commit to AMAN-sharma07/harbor-cli that referenced this pull request Mar 26, 2026
NishchayRajput pushed a commit to NishchayRajput/harbor-cli that referenced this pull request Mar 28, 2026
Signed-off-by: Nishchay Rajput <nishchayr@iitbhilai.ac.in>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Changes Requesed feedback that must be addressed before merging.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incrementally improve unit test coverage

4 participants