Skip to content

Commit

Permalink
feat: add get subcommand to flag (#180)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sunny Guduru authored Apr 16, 2024
1 parent 2d400bc commit 19443ab
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 0 deletions.
5 changes: 5 additions & 0 deletions cmd/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ func NewFlagsCmd(client flags.Client) (*cobra.Command, error) {
if err != nil {
return nil, err
}
getCmd, err := NewGetCmd(client)
if err != nil {
return nil, err
}
updateCmd, err := NewUpdateCmd(client)
if err != nil {
return nil, err
Expand All @@ -32,6 +36,7 @@ func NewFlagsCmd(client flags.Client) (*cobra.Command, error) {
}

cmd.AddCommand(createCmd)
cmd.AddCommand(getCmd)
cmd.AddCommand(updateCmd)
cmd.AddCommand(toggleOnUpdateCmd)
cmd.AddCommand(toggleOffUpdateCmd)
Expand Down
80 changes: 80 additions & 0 deletions cmd/flags/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package flags

import (
"context"
"fmt"

"github.com/spf13/cobra"
"github.com/spf13/viper"

"ldcli/cmd/cliflags"
"ldcli/cmd/validators"
"ldcli/internal/flags"
)

func NewGetCmd(client flags.Client) (*cobra.Command, error) {
cmd := &cobra.Command{
Args: validators.Validate(),
Long: "Get a flag to check its details",
RunE: runGet(client),
Short: "Get a flag",
Use: "get",
}

cmd.Flags().String(cliflags.FlagFlag, "", "Flag key")
err := cmd.MarkFlagRequired(cliflags.FlagFlag)
if err != nil {
return nil, err
}
err = viper.BindPFlag(cliflags.FlagFlag, cmd.Flags().Lookup(cliflags.FlagFlag))
if err != nil {
return nil, err
}

cmd.Flags().String(cliflags.ProjectFlag, "", "Project key")
err = cmd.MarkFlagRequired(cliflags.ProjectFlag)
if err != nil {
return nil, err
}
err = viper.BindPFlag(cliflags.ProjectFlag, cmd.Flags().Lookup(cliflags.ProjectFlag))
if err != nil {
return nil, err
}

cmd.Flags().String(cliflags.EnvironmentFlag, "", "Environment key")
err = cmd.MarkFlagRequired(cliflags.EnvironmentFlag)
if err != nil {
return nil, err
}
err = viper.BindPFlag(cliflags.EnvironmentFlag, cmd.Flags().Lookup(cliflags.EnvironmentFlag))
if err != nil {
return nil, err
}

return cmd, nil
}

func runGet(client flags.Client) func(*cobra.Command, []string) error {
return func(cmd *cobra.Command, args []string) error {
// rebind flags used in other subcommands
_ = viper.BindPFlag(cliflags.FlagFlag, cmd.Flags().Lookup(cliflags.FlagFlag))
_ = viper.BindPFlag(cliflags.ProjectFlag, cmd.Flags().Lookup(cliflags.ProjectFlag))
_ = viper.BindPFlag(cliflags.EnvironmentFlag, cmd.Flags().Lookup(cliflags.EnvironmentFlag))

response, err := client.Get(
context.Background(),
viper.GetString(cliflags.AccessTokenFlag),
viper.GetString(cliflags.BaseURIFlag),
viper.GetString(cliflags.FlagFlag),
viper.GetString(cliflags.ProjectFlag),
viper.GetString(cliflags.EnvironmentFlag),
)
if err != nil {
return err
}

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

return nil
}
}
106 changes: 106 additions & 0 deletions cmd/flags/get_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package flags_test

import (
"ldcli/cmd"
"ldcli/internal/errors"
"ldcli/internal/flags"
"testing"

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

func TestGet(t *testing.T) {
errorHelp := ". See `ldcli flags get --help` for supported flags and usage."
mockArgs := []interface{}{
"testAccessToken",
"http://test.com",
"test-key",
"test-proj-key",
"test-env-key",
}

t.Run("with valid flags calls API", func(t *testing.T) {
client := flags.MockClient{}
client.
On("Get", mockArgs...).
Return([]byte(cmd.ValidResponse), nil)
args := []string{
"flags", "get",
"--access-token", "testAccessToken",
"--base-uri", "http://test.com",
"--flag", "test-key",
"--project", "test-proj-key",
"--environment", "test-env-key",
}

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

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

t.Run("with valid flags from environment variables calls API", func(t *testing.T) {
teardownTest := cmd.SetupTestEnvVars(t)
defer teardownTest(t)
client := flags.MockClient{}
client.
On("Get", mockArgs...).
Return([]byte(cmd.ValidResponse), nil)
args := []string{
"flags", "get",
"--flag", "test-key",
"--project", "test-proj-key",
"--environment", "test-env-key",
}

output, err := cmd.CallCmd(t, nil, &client, nil, 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("Get", mockArgs...).
Return([]byte(`{}`), errors.NewError("An error"))
args := []string{
"flags", "get",
"--access-token", "testAccessToken",
"--base-uri", "http://test.com",
"--flag", "test-key",
"--project", "test-proj-key",
"--environment", "test-env-key",
}

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

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

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

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

assert.EqualError(t, err, `required flag(s) "access-token", "environment", "flag", "project" not set`+errorHelp)
})

t.Run("with invalid base-uri is an error", func(t *testing.T) {
args := []string{
"flags", "get",
"--access-token", "testAccessToken",
"--base-uri", "invalid",
"--flag", "test-key",
"--project", "test-proj-key",
"--environment", "test-env-key",
}

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

assert.EqualError(t, err, "base-uri is invalid"+errorHelp)
})
}
22 changes: 22 additions & 0 deletions internal/flags/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type UpdateInput struct {

type Client interface {
Create(ctx context.Context, accessToken, baseURI, name, key, projKey string) ([]byte, error)
Get(ctx context.Context, accessToken, baseURI, key, projKey, envKey string) ([]byte, error)
Update(
ctx context.Context,
accessToken,
Expand Down Expand Up @@ -54,7 +55,28 @@ func (c FlagsClient) Create(
flag, _, err := client.FeatureFlagsApi.PostFeatureFlag(ctx, projectKey).FeatureFlagBody(*post).Execute()
if err != nil {
return nil, errors.NewLDAPIError(err)
}

responseJSON, err := json.Marshal(flag)
if err != nil {
return nil, err
}

return responseJSON, nil
}

func (c FlagsClient) Get(
ctx context.Context,
accessToken,
baseURI,
key,
projectKey,
environmentKey string,
) ([]byte, error) {
client := client.New(accessToken, baseURI, c.cliVersion)
flag, _, err := client.FeatureFlagsApi.GetFeatureFlag(ctx, projectKey, key).Env(environmentKey).Execute()
if err != nil {
return nil, errors.NewLDAPIError(err)
}

responseJSON, err := json.Marshal(flag)
Expand Down
13 changes: 13 additions & 0 deletions internal/flags/mock_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ func (c *MockClient) Create(
return args.Get(0).([]byte), args.Error(1)
}

func (c *MockClient) Get(
ctx context.Context,
accessToken,
baseURI,
key,
projKey,
envKey string,
) ([]byte, error) {
args := c.Called(accessToken, baseURI, key, projKey, envKey)

return args.Get(0).([]byte), args.Error(1)
}

func (c *MockClient) Update(
ctx context.Context,
accessToken,
Expand Down

0 comments on commit 19443ab

Please sign in to comment.