From 1e6139f1a1bf3e8a7d72c227afb502772d992c4a Mon Sep 17 00:00:00 2001 From: Kelly Hofmann Date: Wed, 27 Mar 2024 14:20:25 -0700 Subject: [PATCH 1/7] add top level environments cmd --- cmd/environments/environments.go | 15 +++++++++++++++ cmd/root.go | 6 ++++++ 2 files changed, 21 insertions(+) create mode 100644 cmd/environments/environments.go diff --git a/cmd/environments/environments.go b/cmd/environments/environments.go new file mode 100644 index 00000000..ae4c04dc --- /dev/null +++ b/cmd/environments/environments.go @@ -0,0 +1,15 @@ +package environments + +import ( + "github.com/spf13/cobra" +) + +func NewEnvironmentsCmd() (*cobra.Command, error) { + cmd := &cobra.Command{ + Use: "environments", + Short: "Make requests on environments", + Long: "Make requests (list, create, etc.) on environments", + } + + return cmd, nil +} diff --git a/cmd/root.go b/cmd/root.go index 1eda8fae..12bc5f85 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "ldcli/cmd/environments" "log" "os" @@ -60,6 +61,10 @@ func NewRootCommand(flagsClient flags.Client, membersClient members.Client, proj if err != nil { return nil, err } + environmentsCmd, err := environments.NewEnvironmentsCmd() + if err != nil { + return nil, err + } membersCmd, err := mbrscmd.NewMembersCmd(membersClient) if err != nil { return nil, err @@ -71,6 +76,7 @@ func NewRootCommand(flagsClient flags.Client, membersClient members.Client, proj cmd.AddCommand(NewQuickStartCmd(flagsClient)) cmd.AddCommand(flagsCmd) + cmd.AddCommand(environmentsCmd) cmd.AddCommand(membersCmd) cmd.AddCommand(projectsCmd) cmd.AddCommand(setupCmd) From bd38b9f4834e82d89f9ab7c41c42e25b2ee6553c Mon Sep 17 00:00:00 2001 From: Kelly Hofmann Date: Wed, 27 Mar 2024 15:08:14 -0700 Subject: [PATCH 2/7] refactor members create to accept list of emails --- cmd/members/create.go | 2 +- internal/members/members.go | 12 ++++++++---- internal/members/mock.go | 8 ++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/cmd/members/create.go b/cmd/members/create.go index f70e5d6c..08010d2c 100644 --- a/cmd/members/create.go +++ b/cmd/members/create.go @@ -52,7 +52,7 @@ func runCreate(client members.Client) func(*cobra.Command, []string) error { context.Background(), viper.GetString("accessToken"), viper.GetString("baseUri"), - data.Email, + []string{data.Email}, data.Role, ) if err != nil { diff --git a/internal/members/members.go b/internal/members/members.go index e050dddf..4cb57026 100644 --- a/internal/members/members.go +++ b/internal/members/members.go @@ -11,7 +11,7 @@ import ( ) type Client interface { - Create(ctx context.Context, accessToken, baseURI, email, role string) ([]byte, error) + Create(ctx context.Context, accessToken string, baseURI string, emails []string, role string) ([]byte, error) } type MembersClient struct{} @@ -20,10 +20,14 @@ func NewClient() Client { return MembersClient{} } -func (c MembersClient) Create(ctx context.Context, accessToken, baseURI, email, role string) ([]byte, error) { +func (c MembersClient) Create(ctx context.Context, accessToken string, baseURI string, emails []string, role string) ([]byte, error) { client := client.New(accessToken, baseURI) - memberForm := ldapi.NewMemberForm{Email: email, Role: &role} - members, _, err := client.AccountMembersApi.PostMembers(ctx).NewMemberForm([]ldapi.NewMemberForm{memberForm}).Execute() + memberForms := make([]ldapi.NewMemberForm, 0, len(emails)) + for _, e := range emails { + memberForms = append(memberForms, ldapi.NewMemberForm{Email: e, Role: &role}) + } + + members, _, err := client.AccountMembersApi.PostMembers(ctx).NewMemberForm(memberForms).Execute() if err != nil { return nil, errors.NewAPIError(err) } diff --git a/internal/members/mock.go b/internal/members/mock.go index d34b5190..de5874d6 100644 --- a/internal/members/mock.go +++ b/internal/members/mock.go @@ -14,12 +14,12 @@ var _ Client = &MockClient{} func (c *MockClient) Create( ctx context.Context, - accessToken, - baseURI, - email, + accessToken string, + baseURI string, + emails []string, role string, ) ([]byte, error) { - args := c.Called(accessToken, baseURI, email, role) + args := c.Called(accessToken, baseURI, emails, role) return args.Get(0).([]byte), args.Error(1) } From fc54dc28886f82439ad7599609d88dd7b63a943d Mon Sep 17 00:00:00 2001 From: Kelly Hofmann Date: Wed, 27 Mar 2024 15:21:38 -0700 Subject: [PATCH 3/7] add invite member command --- cmd/members/invite.go | 56 +++++++++++++++++++++++++++++++++++++ cmd/members/members.go | 6 ++++ internal/members/members.go | 2 +- 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 cmd/members/invite.go diff --git a/cmd/members/invite.go b/cmd/members/invite.go new file mode 100644 index 00000000..c8165d1d --- /dev/null +++ b/cmd/members/invite.go @@ -0,0 +1,56 @@ +package members + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "ldcli/cmd/validators" + "ldcli/internal/members" +) + +const defaultRole = "reader" + +func NewInviteCmd(client members.Client) (*cobra.Command, error) { + cmd := &cobra.Command{ + Args: validators.Validate(), + Long: "Invite new members", + RunE: runInvite(client), + Short: "Invite new members", + Use: "invite", + } + + cmd.Flags().StringSliceP("emails", "e", []string{}, "A comma separated list of emails") + err := cmd.MarkFlagRequired("emails") + if err != nil { + return nil, err + } + err = viper.BindPFlag("emails", cmd.Flags().Lookup("emails")) + if err != nil { + return nil, err + } + + return cmd, nil +} + +func runInvite(client members.Client) func(*cobra.Command, []string) error { + return func(cmd *cobra.Command, args []string) error { + + response, err := client.Create( + context.Background(), + viper.GetString("accessToken"), + viper.GetString("baseUri"), + viper.GetStringSlice("emails"), + defaultRole, + ) + if err != nil { + return err + } + + fmt.Fprintf(cmd.OutOrStdout(), string(response)+"\n") + + return nil + } +} diff --git a/cmd/members/members.go b/cmd/members/members.go index 5aa698b7..34a994cb 100644 --- a/cmd/members/members.go +++ b/cmd/members/members.go @@ -18,7 +18,13 @@ func NewMembersCmd(client members.Client) (*cobra.Command, error) { return nil, err } + inviteCmd, err := NewInviteCmd(client) + if err != nil { + return nil, err + } + cmd.AddCommand(createCmd) + cmd.AddCommand(inviteCmd) return cmd, nil diff --git a/internal/members/members.go b/internal/members/members.go index 4cb57026..16afb974 100644 --- a/internal/members/members.go +++ b/internal/members/members.go @@ -31,7 +31,7 @@ func (c MembersClient) Create(ctx context.Context, accessToken string, baseURI s if err != nil { return nil, errors.NewAPIError(err) } - memberJson, err := json.Marshal(members.Items[0]) + memberJson, err := json.Marshal(members.Items) if err != nil { return nil, err } From 3cd1092613b3b4a10603b107b6d95fd881e5d6a5 Mon Sep 17 00:00:00 2001 From: Kelly Hofmann Date: Wed, 27 Mar 2024 15:30:28 -0700 Subject: [PATCH 4/7] fix tests, imports --- cmd/members/create_test.go | 2 +- cmd/root.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/members/create_test.go b/cmd/members/create_test.go index e493c643..56d780fe 100644 --- a/cmd/members/create_test.go +++ b/cmd/members/create_test.go @@ -16,7 +16,7 @@ func TestCreate(t *testing.T) { mockArgs := []interface{}{ "testAccessToken", "http://test.com", - "testemail@test.com", + []string{"testemail@test.com"}, "writer", } t.Run("with valid flags calls members API", func(t *testing.T) { diff --git a/cmd/root.go b/cmd/root.go index 12bc5f85..0ba61dac 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -2,13 +2,13 @@ package cmd import ( "fmt" - "ldcli/cmd/environments" "log" "os" "github.com/spf13/cobra" "github.com/spf13/viper" + "ldcli/cmd/environments" flagscmd "ldcli/cmd/flags" mbrscmd "ldcli/cmd/members" projcmd "ldcli/cmd/projects" From 119d9b1c00ae50d76f80c15d4e246b98e6fcfd31 Mon Sep 17 00:00:00 2001 From: Kelly Hofmann Date: Wed, 27 Mar 2024 15:38:20 -0700 Subject: [PATCH 5/7] add tests --- cmd/members/invite_test.go | 87 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 cmd/members/invite_test.go diff --git a/cmd/members/invite_test.go b/cmd/members/invite_test.go new file mode 100644 index 00000000..9d741844 --- /dev/null +++ b/cmd/members/invite_test.go @@ -0,0 +1,87 @@ +package members_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "ldcli/cmd" + "ldcli/internal/errors" + "ldcli/internal/members" +) + +func TestInvite(t *testing.T) { + errorHelp := ". See `ldcli members invite --help` for supported flags and usage." + mockArgs := []interface{}{ + "testAccessToken", + "http://test.com", + []string{"testemail1@test.com", "testemail2@test.com"}, + "reader", + } + t.Run("with valid flags calls members API", func(t *testing.T) { + client := members.MockClient{} + client. + On("Create", mockArgs...). + Return([]byte(cmd.ValidResponse), nil) + args := []string{ + "members", + "invite", + "-t", + "testAccessToken", + "-u", + "http://test.com", + "-e", + `testemail1@test.com,testemail2@test.com`, + } + + output, err := cmd.CallCmd(t, nil, &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 := members.MockClient{} + client. + On("Create", mockArgs...). + Return([]byte(`{}`), errors.NewError("An error")) + args := []string{ + "members", + "invite", + "-t", + "testAccessToken", + "-u", + "http://test.com", + "-e", + `testemail1@test.com,testemail2@test.com`, + } + + _, err := cmd.CallCmd(t, nil, &client, nil, args) + + require.EqualError(t, err, "An error") + }) + + t.Run("with missing required flags is an error", func(t *testing.T) { + args := []string{ + "members", + "invite", + } + + _, err := cmd.CallCmd(t, nil, &members.MockClient{}, nil, args) + + assert.EqualError(t, err, `required flag(s) "accessToken", "emails" not set`+errorHelp) + }) + + t.Run("with invalid baseUri is an error", func(t *testing.T) { + args := []string{ + "members", + "invite", + "--baseUri", "invalid", + } + + _, err := cmd.CallCmd(t, nil, &members.MockClient{}, nil, args) + + assert.EqualError(t, err, "baseUri is invalid"+errorHelp) + }) +} From 49c339fb758cdea410ef495174582b786994635e Mon Sep 17 00:00:00 2001 From: Kelly Hofmann Date: Wed, 27 Mar 2024 15:39:36 -0700 Subject: [PATCH 6/7] oops remove environments stuff --- cmd/environments/environments.go | 15 --------------- cmd/root.go | 6 ------ 2 files changed, 21 deletions(-) delete mode 100644 cmd/environments/environments.go diff --git a/cmd/environments/environments.go b/cmd/environments/environments.go deleted file mode 100644 index ae4c04dc..00000000 --- a/cmd/environments/environments.go +++ /dev/null @@ -1,15 +0,0 @@ -package environments - -import ( - "github.com/spf13/cobra" -) - -func NewEnvironmentsCmd() (*cobra.Command, error) { - cmd := &cobra.Command{ - Use: "environments", - Short: "Make requests on environments", - Long: "Make requests (list, create, etc.) on environments", - } - - return cmd, nil -} diff --git a/cmd/root.go b/cmd/root.go index 0ba61dac..1eda8fae 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -8,7 +8,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "ldcli/cmd/environments" flagscmd "ldcli/cmd/flags" mbrscmd "ldcli/cmd/members" projcmd "ldcli/cmd/projects" @@ -61,10 +60,6 @@ func NewRootCommand(flagsClient flags.Client, membersClient members.Client, proj if err != nil { return nil, err } - environmentsCmd, err := environments.NewEnvironmentsCmd() - if err != nil { - return nil, err - } membersCmd, err := mbrscmd.NewMembersCmd(membersClient) if err != nil { return nil, err @@ -76,7 +71,6 @@ func NewRootCommand(flagsClient flags.Client, membersClient members.Client, proj cmd.AddCommand(NewQuickStartCmd(flagsClient)) cmd.AddCommand(flagsCmd) - cmd.AddCommand(environmentsCmd) cmd.AddCommand(membersCmd) cmd.AddCommand(projectsCmd) cmd.AddCommand(setupCmd) From 06ca2607180329f5dda89316a7a0e6156f84a832 Mon Sep 17 00:00:00 2001 From: Kelly Hofmann Date: Wed, 27 Mar 2024 15:54:13 -0700 Subject: [PATCH 7/7] update for new flags --- cmd/cliflags/flags.go | 1 + cmd/members/invite.go | 7 ++++--- cmd/members/invite_test.go | 16 ++++++++-------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/cmd/cliflags/flags.go b/cmd/cliflags/flags.go index bc2d5eea..448d41ac 100644 --- a/cmd/cliflags/flags.go +++ b/cmd/cliflags/flags.go @@ -5,4 +5,5 @@ const ( BaseURIFlag = "base-uri" FlagFlag = "flag" ProjectFlag = "project" + EmailsFlag = "emails" ) diff --git a/cmd/members/invite.go b/cmd/members/invite.go index c8165d1d..8a6a9c7d 100644 --- a/cmd/members/invite.go +++ b/cmd/members/invite.go @@ -7,6 +7,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + "ldcli/cmd/cliflags" "ldcli/cmd/validators" "ldcli/internal/members" ) @@ -40,9 +41,9 @@ func runInvite(client members.Client) func(*cobra.Command, []string) error { response, err := client.Create( context.Background(), - viper.GetString("accessToken"), - viper.GetString("baseUri"), - viper.GetStringSlice("emails"), + viper.GetString(cliflags.APITokenFlag), + viper.GetString(cliflags.BaseURIFlag), + viper.GetStringSlice(cliflags.EmailsFlag), defaultRole, ) if err != nil { diff --git a/cmd/members/invite_test.go b/cmd/members/invite_test.go index 9d741844..31ca8427 100644 --- a/cmd/members/invite_test.go +++ b/cmd/members/invite_test.go @@ -27,9 +27,9 @@ func TestInvite(t *testing.T) { args := []string{ "members", "invite", - "-t", + "--api-token", "testAccessToken", - "-u", + "--base-uri", "http://test.com", "-e", `testemail1@test.com,testemail2@test.com`, @@ -49,9 +49,9 @@ func TestInvite(t *testing.T) { args := []string{ "members", "invite", - "-t", + "--api-token", "testAccessToken", - "-u", + "--base-uri", "http://test.com", "-e", `testemail1@test.com,testemail2@test.com`, @@ -70,18 +70,18 @@ func TestInvite(t *testing.T) { _, err := cmd.CallCmd(t, nil, &members.MockClient{}, nil, args) - assert.EqualError(t, err, `required flag(s) "accessToken", "emails" not set`+errorHelp) + assert.EqualError(t, err, `required flag(s) "api-token", "emails" not set`+errorHelp) }) - t.Run("with invalid baseUri is an error", func(t *testing.T) { + t.Run("with invalid base-uri is an error", func(t *testing.T) { args := []string{ "members", "invite", - "--baseUri", "invalid", + "--base-uri", "invalid", } _, err := cmd.CallCmd(t, nil, &members.MockClient{}, nil, args) - assert.EqualError(t, err, "baseUri is invalid"+errorHelp) + assert.EqualError(t, err, "base-uri is invalid"+errorHelp) }) }