diff --git a/internal/cli/repo_list.go b/internal/cli/repo_list.go index 58d3166..9621c7c 100644 --- a/internal/cli/repo_list.go +++ b/internal/cli/repo_list.go @@ -13,12 +13,12 @@ func newRepoListCommand(service *app.Service) *cobra.Command { Short: "List repositories owned by a Tangled user", Long: `List repositories owned by a Tangled user. -If no argument is given, the command detects the user from the "origin" -remote URL of the git repository in the current directory.`, +If no argument is given, lists the authenticated user's repositories +(run "tg auth login" first).`, Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - handle, err := resolveHandleArg(ctx, args, service) + handle, err := resolveHandleOrSelf(ctx, args, service) if err != nil { return err } diff --git a/internal/cli/target.go b/internal/cli/target.go index ac404a4..81bfce3 100644 --- a/internal/cli/target.go +++ b/internal/cli/target.go @@ -35,22 +35,13 @@ func resolveTargetFlag(ctx context.Context, repoFlag string, service *app.Servic return service.TargetFromCWD(ctx) } -// resolveHandleArg returns the handle from an explicit argument, or falls -// back to the handle of the CWD's git origin remote. -func resolveHandleArg(ctx context.Context, args []string, service *app.Service) (string, error) { - if len(args) == 1 { - return args[0], nil - } - target, err := service.TargetFromCWD(ctx) - if err != nil { - return "", err - } - return target.Handle, nil +type accountHandleResolver interface { + HandleOrSelf(context.Context, string) (string, error) } // resolveHandleOrSelf returns the handle from an explicit argument, or the // authenticated user's handle. It does not fall back to CWD git detection. -func resolveHandleOrSelf(ctx context.Context, args []string, service *app.Service) (string, error) { +func resolveHandleOrSelf(ctx context.Context, args []string, service accountHandleResolver) (string, error) { if len(args) == 1 { return args[0], nil } diff --git a/internal/cli/target_resolution_test.go b/internal/cli/target_resolution_test.go new file mode 100644 index 0000000..358bba4 --- /dev/null +++ b/internal/cli/target_resolution_test.go @@ -0,0 +1,69 @@ +package cli + +import ( + "context" + "errors" + "testing" +) + +func TestResolveHandleOrSelf(t *testing.T) { + tests := []struct { + name string + args []string + resolver fakeAccountHandleResolver + want string + wantCalls int + wantError bool + }{ + { + name: "explicit handle", + args: []string{"other.test"}, + resolver: fakeAccountHandleResolver{ + handle: "self.test", + }, + want: "other.test", + }, + { + name: "authenticated user", + resolver: fakeAccountHandleResolver{ + handle: "self.test", + }, + want: "self.test", + wantCalls: 1, + }, + { + name: "authentication failure", + resolver: fakeAccountHandleResolver{ + err: errors.New("not logged in"), + }, + wantCalls: 1, + wantError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := resolveHandleOrSelf(context.Background(), tt.args, &tt.resolver) + if (err != nil) != tt.wantError { + t.Fatalf("resolveHandleOrSelf() error = %v, want error %t", err, tt.wantError) + } + if got != tt.want { + t.Fatalf("resolveHandleOrSelf() = %q, want %q", got, tt.want) + } + if tt.resolver.calls != tt.wantCalls { + t.Fatalf("HandleOrSelf() calls = %d, want %d", tt.resolver.calls, tt.wantCalls) + } + }) + } +} + +type fakeAccountHandleResolver struct { + handle string + err error + calls int +} + +func (r *fakeAccountHandleResolver) HandleOrSelf(context.Context, string) (string, error) { + r.calls++ + return r.handle, r.err +}