Skip to content

tests: Added unit tests for user elevate command#686

Open
rkcoder101 wants to merge 2 commits intogoharbor:mainfrom
rkcoder101:test/user-elevate
Open

tests: Added unit tests for user elevate command#686
rkcoder101 wants to merge 2 commits intogoharbor:mainfrom
rkcoder101:test/user-elevate

Conversation

@rkcoder101
Copy link
Contributor

@rkcoder101 rkcoder101 commented Feb 7, 2026

Description

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

Relates to #591

Is a sub-part of #653

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 :)

Signed-off-by: Rayyan Khan <rayyanrehman101@gmail.com>
Copilot AI review requested due to automatic review settings February 7, 2026 09:10
@codecov
Copy link

codecov bot commented Feb 7, 2026

Codecov Report

❌ Patch coverage is 72.22222% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 7.44%. Comparing base (60ad0bd) to head (459434b).
⚠️ Report is 83 commits behind head on main.

Files with missing lines Patch % Lines
cmd/harbor/root/user/elevate.go 72.22% 10 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##             main    #686      +/-   ##
=========================================
- Coverage   10.99%   7.44%   -3.55%     
=========================================
  Files         173     260      +87     
  Lines        8671   12859    +4188     
=========================================
+ Hits          953     957       +4     
- Misses       7612   11793    +4181     
- Partials      106     109       +3     

☔ 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.

Copy link
Contributor

Copilot AI left a comment

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)
},
Copy link

Copilot AI Feb 7, 2026

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 on lines +94 to +97
setup: func() *MockUserElevator {
m := initMockUserElevator(5, false, true, nil)
m.id["promptuser"] = 999
return m
Copy link

Copilot AI Feb 7, 2026

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",
Copy link

Copilot AI Feb 7, 2026

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 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

Copy link

Copilot AI Feb 7, 2026

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
Signed-off-by: Rayyan Khan <rayyanrehman101@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant