Skip to content

Commit

Permalink
fix: Fix plaintext output for a resource with only and ID (#263)
Browse files Browse the repository at this point in the history
Fix plaintext output for a resource with only an ID
  • Loading branch information
dbolson authored May 10, 2024
1 parent 9a71cfe commit e9139c0
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 36 deletions.
11 changes: 5 additions & 6 deletions cmd/resources/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@ import (

func getResourcesHelpTemplate() string {
// This template uses `.Parent` to access subcommands on the root command.
return fmt.Sprintf(`Available commands:{{range $index, $cmd := .Parent.Commands}}{{if (or (eq (index $.Parent.Annotations $cmd.Name) "resource"))}}
return `Available commands:{{range $index, $cmd := .Parent.Commands}}{{if (or (eq (index $.Parent.Annotations $cmd.Name) "resource"))}}
{{rpad $cmd.Name $cmd.NamePadding }} {{$cmd.Short}}{{end}}{{end}}
Use "ldcli [command] --help" for more information about a command.
`,
)
`
}

func NewResourcesCmd() *cobra.Command {
Expand Down Expand Up @@ -256,7 +255,7 @@ func (op *OperationCmd) initFlags() error {
if err != nil {
return err
}
op.cmd.Flags().SetAnnotation(flagName, "required", []string{"true"})
_ = op.cmd.Flags().SetAnnotation(flagName, "required", []string{"true"})
}

err := viper.BindPFlag(flagName, op.cmd.Flags().Lookup(flagName))
Expand Down Expand Up @@ -367,7 +366,7 @@ func NewOperationCmd(parentCmd *cobra.Command, client resources.Client, op Opera
}

func operationUsageTemplate() string {
return fmt.Sprint(`Usage:{{if .Runnable}}
return `Usage:{{if .Runnable}}
{{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
Expand Down Expand Up @@ -400,5 +399,5 @@ Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
`)
`
}
41 changes: 22 additions & 19 deletions internal/output/plaintext_fns.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,32 @@ var ErrorPlaintextOutputFn = func(r resource) string {
}
}

// MultipleEmailPlaintextOutputFn converts the resource to plain text specifically for member data.
var MultipleEmailPlaintextOutputFn = func(r resource) string {
return fmt.Sprintf("* %s (%s)", r["email"], r["_id"])
}

// MultipleIDPlaintextOutputFn converts the resource to plain text for data without a key.
var MultipleIDPlaintextOutputFn = func(r resource) string {
return fmt.Sprintf("* %s (%s)", r["name"], r["_id"])
}

// MultiplePlaintextOutputFn converts the resource to plain text based on its name and key in a list.
// MultiplePlaintextOutputFn converts the resource to plain text.
var MultiplePlaintextOutputFn = func(r resource) string {
return fmt.Sprintf("* %s (%s)", r["name"], r["key"])
return fmt.Sprintf("* %s", SingularPlaintextOutputFn(r))
}

// SingularPlaintextOutputFn converts the resource to plain text based on its name and key.
var SingularPlaintextOutputFn = func(r resource) string {
if r["name"] == nil {
return r["key"].(string)
}
if r["key"] == nil {
return r["name"].(string)
}
email := r["email"]
id := r["_id"]
key := r["key"]
name := r["name"]

return fmt.Sprintf("%s (%s)", r["name"], r["key"])
switch {
case name != nil && key != nil:
return fmt.Sprintf("%s (%s)", name.(string), key.(string))
case email != nil && id != nil:
return fmt.Sprintf("%s (%s)", email.(string), id.(string))
case name != nil && id != nil:
return fmt.Sprintf("%s (%s)", name.(string), id.(string))
case key != nil:
return key.(string)
case email != nil:
return email.(string)
case id != nil:
return id.(string)
default:
return "cannot read resource"
}
}
64 changes: 64 additions & 0 deletions internal/output/plaintext_fns_internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package output

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestSingularPlaintextOutputFn(t *testing.T) {
tests := map[string]struct {
resource resource
expected string
}{
"with a name and key": {
resource: resource{
"key": "test-key",
"name": "test-name",
},
expected: "test-name (test-key)",
},
"with only a key": {
resource: resource{
"key": "test-key",
},
expected: "test-key",
},
"with an ID and email": {
resource: resource{
"_id": "test-id",
"email": "test-email",
"name": "test-name",
},
expected: "test-email (test-id)",
},
"with a name and ID": {
resource: resource{
"_id": "test-id",
"name": "test-name",
},
expected: "test-name (test-id)",
},
"with only an ID": {
resource: resource{
"_id": "test-id",
},
expected: "test-id",
},
"without any valid field": {
resource: resource{
"other": "other-value",
},
expected: "cannot read resource",
},
}

for name, tt := range tests {
tt := tt
t.Run(name, func(t *testing.T) {
out := SingularPlaintextOutputFn(tt.resource)

assert.Equal(t, tt.expected, out)
})
}
}
12 changes: 1 addition & 11 deletions internal/output/resource_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,9 @@ func CmdOutput(action string, outputKind string, input []byte) (string, error) {
return "No items found", nil
}

// the response could have various properties we want to show
keyExists := func(key string) bool { _, ok := maybeResources.Items[0][key]; return ok }
outputFn := MultiplePlaintextOutputFn
switch {
case keyExists("email"):
outputFn = MultipleEmailPlaintextOutputFn
case keyExists("_id"):
outputFn = MultipleIDPlaintextOutputFn
}

items := make([]string, 0, len(maybeResources.Items))
for _, i := range maybeResources.Items {
items = append(items, outputFn(i))
items = append(items, MultiplePlaintextOutputFn(i))
}

var (
Expand Down
21 changes: 21 additions & 0 deletions internal/output/resource_output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,27 @@ import (
)

func TestCmdOutput(t *testing.T) {
t.Run("with multiple resources with only an ID", func(t *testing.T) {
input := `{
"items": [
{
"_id": "test-id"
}
]
}`

t.Run("with plaintext output", func(t *testing.T) {
t.Run("returns a success message", func(t *testing.T) {
expected := "* test-id"

result, err := output.CmdOutput("list", "plaintext", []byte(input))

require.NoError(t, err)
assert.Equal(t, expected, result)
})
})
})

t.Run("with paginated multiple resources", func(t *testing.T) {
tests := map[string]struct {
limit int
Expand Down

0 comments on commit e9139c0

Please sign in to comment.