Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions cmd/cmdtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@ import (

"github.com/stretchr/testify/require"

"ldcli/internal/flags"
"ldcli/internal/projects"
)

var ValidResponse = `{"valid": true}`

func ArgsValidCreate() []string {
args := append(ArgsCreateCommand(), ArgsAccess()...)
func ArgsValidFlagsCreate() []string {
args := append(ArgsFlagsCreateCommand(), ArgsAccess()...)
args = append(args, ArgsData()...)

return args
}

func ArgsValidProjectsCreate() []string {

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.

Renamed these, but I think I'm going to replace them with the actual []string in the tests. See the flag cmd tests for examples -- I think they're easier to read.

args := append(ArgsProjectsCreateCommand(), ArgsAccess()...)
args = append(args, ArgsData()...)

return args
Expand All @@ -39,7 +47,14 @@ func ArgsAccess() []string {
}
}

func ArgsCreateCommand() []string {
func ArgsFlagsCreateCommand() []string {
return []string{
"flags",
"create",
}
}

func ArgsProjectsCreateCommand() []string {
return []string{
"projects",
"create",
Expand All @@ -53,8 +68,13 @@ func ArgsListCommand() []string {
}
}

func CallCmd(t *testing.T, client *projects.MockClient, args []string) ([]byte, error) {
rootCmd, err := NewRootCommand(client)
func CallCmd(
t *testing.T,
flagsClient *flags.MockClient,
projectsClient *projects.MockClient,
args []string,
) ([]byte, error) {
rootCmd, err := NewRootCommand(flagsClient, projectsClient)
require.NoError(t, err)
b := bytes.NewBufferString("")
rootCmd.SetOut(b)
Expand Down
51 changes: 26 additions & 25 deletions cmd/flags/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import (
"ldcli/internal/flags"
)

func NewCreateCmd() (*cobra.Command, error) {
func NewCreateCmd(client flags.Client) (*cobra.Command, error) {
cmd := &cobra.Command{
Use: "create",
Short: "Create a new flag",
Long: "Create a new flag",
PreRunE: validate,
RunE: runCreate,
RunE: runCreate(client),
}

cmd.Flags().StringP("data", "d", "", "Input data in JSON")
Expand Down Expand Up @@ -50,33 +50,34 @@ type inputData struct {
Key string `json:"key"`
}

func runCreate(cmd *cobra.Command, args []string) error {
client := flags.NewClient(
viper.GetString("accessToken"),
viper.GetString("baseUri"),
)
func runCreate(client flags.Client) func(*cobra.Command, []string) error {
return func(cmd *cobra.Command, args []string) error {

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.

Bind the client in a closure similar to projects.

// rebind flags used in other subcommands
_ = viper.BindPFlag("data", cmd.Flags().Lookup("data"))

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.

Rebind the common subcommand flags. We can refactor this later.

_ = viper.BindPFlag("projKey", cmd.Flags().Lookup("projKey"))

var data inputData
err := json.Unmarshal([]byte(cmd.Flags().Lookup("data").Value.String()), &data)
// err := json.Unmarshal([]byte(viper.GetString("data")), &data)
if err != nil {
return err
}
projKey := viper.GetString("projKey")
var data inputData
err := json.Unmarshal([]byte(viper.GetString("data")), &data)
if err != nil {
return err
}

response, err := client.Create(
context.Background(),
data.Name,
data.Key,
projKey,
)
if err != nil {
return err
}
response, err := client.Create(
context.Background(),
viper.GetString("accessToken"),
viper.GetString("baseUri"),
data.Name,
data.Key,
viper.GetString("projKey"),
)
if err != nil {
return err
}

fmt.Fprintf(cmd.OutOrStdout(), string(response)+"\n")
fmt.Fprintf(cmd.OutOrStdout(), string(response)+"\n")

return nil
return nil
}
}

// validate ensures the flags are valid before using them.
Expand Down
75 changes: 75 additions & 0 deletions cmd/flags/create_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package flags_test

import (
"ldcli/cmd"
"testing"

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

"ldcli/internal/errors"
"ldcli/internal/flags"
)

func TestCreate(t *testing.T) {
t.Run("with valid flags calls projects API", func(t *testing.T) {
client := flags.MockClient{}
client.
On("Create", "testAccessToken", "http://test.com", "test-name", "test-key", "test-proj-key").
Return([]byte(cmd.ValidResponse), nil)
args := []string{
"flags", "create",
"-t", "testAccessToken",
"-u", "http://test.com",
"-d", `{"key": "test-key", "name": "test-name"}`,
"--projKey", "test-proj-key",
}

output, err := cmd.CallCmd(t, &client, nil, args)

require.NoError(t, err)
assert.JSONEq(t, `{"valid": true}`, string(output))
})

t.Run("with an error response is an error", func(t *testing.T) {
client := flags.MockClient{}
client.
On("Create", "testAccessToken", "http://test.com", "test-name", "test-key", "test-proj-key").
Return([]byte(`{}`), errors.NewError("An error"))
args := []string{
"flags", "create",
"-t", "testAccessToken",
"-u", "http://test.com",
"-d", `{"key": "test-key", "name": "test-name"}`,
"--projKey", "test-proj-key",
}

_, err := cmd.CallCmd(t, &client, nil, args)

require.EqualError(t, err, "An error")
})

t.Run("with missing required flags is an error", func(t *testing.T) {
args := []string{
"flags", "create",
}

_, err := cmd.CallCmd(t, &flags.MockClient{}, nil, args)

assert.EqualError(t, err, `required flag(s) "accessToken", "data", "projKey" not set`)
})

t.Run("with invalid baseUri is an error", func(t *testing.T) {
args := []string{
"flags", "create",
"-t", "testAccessToken",
"-u", "invalid",
"-d", `{"key": "test-key", "name": "test-name"}`,
"--projKey", "test-proj-key",
}

_, err := cmd.CallCmd(t, &flags.MockClient{}, nil, args)

assert.EqualError(t, err, "baseUri is invalid")
})
}
14 changes: 9 additions & 5 deletions cmd/flags/flags.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
package flags

import "github.com/spf13/cobra"
import (
"github.com/spf13/cobra"

func NewFlagsCmd() (*cobra.Command, error) {
"ldcli/internal/flags"
)

func NewFlagsCmd(client flags.Client) (*cobra.Command, error) {
cmd := &cobra.Command{
Use: "flags",
Short: "Make requests (list, create, etc.) on flags",
Long: "Make requests (list, create, etc.) on flags",
}

updateCmd, err := NewUpdateCmd()
createCmd, err := NewCreateCmd(client)

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.

Swapped these to alphabetize and to check that the last one created binds the shared flags while the rest are set to the zero value.

if err != nil {
return nil, err
}
createCmd, err := NewCreateCmd()
updateCmd, err := NewUpdateCmd(client)
if err != nil {
return nil, err
}

cmd.AddCommand(updateCmd)
cmd.AddCommand(createCmd)
cmd.AddCommand(updateCmd)

return cmd, nil
}
50 changes: 26 additions & 24 deletions cmd/flags/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import (
"ldcli/internal/flags"
)

func NewUpdateCmd() (*cobra.Command, error) {
func NewUpdateCmd(client flags.Client) (*cobra.Command, error) {
cmd := &cobra.Command{
Use: "update",
Short: "Update a flag",
Long: "Update a flag",
PreRunE: validate,
RunE: runUpdate,
RunE: runUpdate(client),
}

var data string
Expand Down Expand Up @@ -61,30 +61,32 @@ func NewUpdateCmd() (*cobra.Command, error) {
return cmd, nil
}

func runUpdate(cmd *cobra.Command, args []string) error {
client := flags.NewClient(
viper.GetString("accessToken"),
viper.GetString("baseUri"),
)
func runUpdate(client flags.Client) func(*cobra.Command, []string) error {
return func(cmd *cobra.Command, args []string) error {
// rebind flags used in other subcommands
_ = viper.BindPFlag("data", cmd.Flags().Lookup("data"))
_ = viper.BindPFlag("projKey", cmd.Flags().Lookup("projKey"))

var patch []ldapi.PatchOperation
// err := json.Unmarshal([]byte(viper.GetString("data")), &patch)
err := json.Unmarshal([]byte(cmd.Flags().Lookup("data").Value.String()), &patch)
if err != nil {
return err
}
var patch []ldapi.PatchOperation
err := json.Unmarshal([]byte(viper.GetString("data")), &patch)
if err != nil {
return err
}

response, err := client.Update(
context.Background(),
viper.GetString("key"),
viper.GetString("projKey"),
patch,
)
if err != nil {
return err
}
response, err := client.Update(
context.Background(),
viper.GetString("accessToken"),
viper.GetString("baseUri"),
viper.GetString("key"),
viper.GetString("projKey"),
patch,
)
if err != nil {
return err
}

fmt.Fprintf(cmd.OutOrStdout(), string(response)+"\n")
fmt.Fprintf(cmd.OutOrStdout(), string(response)+"\n")

return nil
return nil
}
}
23 changes: 6 additions & 17 deletions cmd/projects/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestCreate(t *testing.T) {
On("Create", "testAccessToken", "http://test.com", "test-name", "test-key").
Return([]byte(cmd.ValidResponse), nil)

output, err := cmd.CallCmd(t, &client, cmd.ArgsValidCreate())
output, err := cmd.CallCmd(t, nil, &client, cmd.ArgsValidProjectsCreate())

require.NoError(t, err)
assert.JSONEq(t, `{"valid": true}`, string(output))
Expand All @@ -28,32 +28,21 @@ func TestCreate(t *testing.T) {
client := projects.MockClient{}
client.
On("Create", "testAccessToken", "http://test.com", "test-name", "test-key").
Return([]byte(`{}`), errors.NewError("You are not authorized to make this request"))
Return([]byte(`{}`), errors.NewError("An error"))

_, err := cmd.CallCmd(t, &client, cmd.ArgsValidCreate())
_, err := cmd.CallCmd(t, nil, &client, cmd.ArgsValidProjectsCreate())

require.EqualError(t, err, "You are not authorized to make this request")
})

t.Run("with a forbidden response is an error", func(t *testing.T) {
client := projects.MockClient{}
client.
On("Create", "testAccessToken", "http://test.com", "test-name", "test-key").
Return([]byte(`{}`), errors.NewError("You do not have permission to make this request"))

_, err := cmd.CallCmd(t, &client, cmd.ArgsValidCreate())

require.EqualError(t, err, "You do not have permission to make this request")
require.EqualError(t, err, "An error")
})

t.Run("with missing required flags is an error", func(t *testing.T) {
_, err := cmd.CallCmd(t, &projects.MockClient{}, cmd.ArgsCreateCommand())
_, err := cmd.CallCmd(t, nil, &projects.MockClient{}, cmd.ArgsProjectsCreateCommand())

assert.EqualError(t, err, `required flag(s) "accessToken", "data" not set`)
})

t.Run("with invalid baseUri is an error", func(t *testing.T) {
_, err := cmd.CallCmd(t, &projects.MockClient{}, append(cmd.ArgsCreateCommand(), "--baseUri", "invalid"))
_, err := cmd.CallCmd(t, nil, &projects.MockClient{}, append(cmd.ArgsProjectsCreateCommand(), "--baseUri", "invalid"))

assert.EqualError(t, err, "baseUri is invalid")
})
Expand Down
10 changes: 5 additions & 5 deletions cmd/projects/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestList(t *testing.T) {
On("List", "testAccessToken", "http://test.com").
Return([]byte(cmd.ValidResponse), nil)

output, err := cmd.CallCmd(t, &client, cmd.ArgsValidList())
output, err := cmd.CallCmd(t, nil, &client, cmd.ArgsValidList())

require.NoError(t, err)
assert.JSONEq(t, `{"valid": true}`, string(output))
Expand All @@ -30,7 +30,7 @@ func TestList(t *testing.T) {
On("List", "testAccessToken", "http://test.com").
Return([]byte(`{}`), errors.NewError("You are not authorized to make this request"))

_, err := cmd.CallCmd(t, &client, cmd.ArgsValidList())
_, err := cmd.CallCmd(t, nil, &client, cmd.ArgsValidList())

require.EqualError(t, err, "You are not authorized to make this request")
})
Expand All @@ -41,19 +41,19 @@ func TestList(t *testing.T) {
On("List", "testAccessToken", "http://test.com").
Return([]byte(`{}`), errors.NewError("You do not have permission to make this request"))

_, err := cmd.CallCmd(t, &client, cmd.ArgsValidList())
_, err := cmd.CallCmd(t, nil, &client, cmd.ArgsValidList())

require.EqualError(t, err, "You do not have permission to make this request")
})

t.Run("with missing required flags is an error", func(t *testing.T) {
_, err := cmd.CallCmd(t, &projects.MockClient{}, cmd.ArgsListCommand())
_, err := cmd.CallCmd(t, nil, &projects.MockClient{}, cmd.ArgsListCommand())

assert.EqualError(t, err, `required flag(s) "accessToken" not set`)
})

t.Run("with invalid baseUri is an error", func(t *testing.T) {
_, err := cmd.CallCmd(t, &projects.MockClient{}, append(cmd.ArgsListCommand(), "--baseUri", "invalid"))
_, err := cmd.CallCmd(t, nil, &projects.MockClient{}, append(cmd.ArgsListCommand(), "--baseUri", "invalid"))

assert.EqualError(t, err, "baseUri is invalid")
})
Expand Down
Loading