diff --git a/cmd/members/create.go b/cmd/members/create.go index 119b13e1..f3d3406a 100644 --- a/cmd/members/create.go +++ b/cmd/members/create.go @@ -16,9 +16,9 @@ import ( func NewCreateCmd(client members.Client) (*cobra.Command, error) { cmd := &cobra.Command{ Args: validators.Validate(), - Long: "Create a new member and send them an invitation email", + Long: "Create new members and send them an invitation email", RunE: runCreate(client), - Short: "Create a new member", + Short: "Create new members", Use: "create", } @@ -35,14 +35,9 @@ func NewCreateCmd(client members.Client) (*cobra.Command, error) { return cmd, nil } -type inputData struct { - Email string `json:"email"` - Role string `json:"role"` -} - func runCreate(client members.Client) func(*cobra.Command, []string) error { return func(cmd *cobra.Command, args []string) error { - var data inputData + var data []members.MemberInput // TODO: why does viper.GetString(cliflags.DataFlag) not work? err := json.Unmarshal([]byte(cmd.Flags().Lookup(cliflags.DataFlag).Value.String()), &data) if err != nil { @@ -53,8 +48,7 @@ func runCreate(client members.Client) func(*cobra.Command, []string) error { context.Background(), viper.GetString(cliflags.AccessTokenFlag), viper.GetString(cliflags.BaseURIFlag), - []string{data.Email}, - data.Role, + data, ) if err != nil { return err diff --git a/cmd/members/create_test.go b/cmd/members/create_test.go index 1aa3bc82..3777aa16 100644 --- a/cmd/members/create_test.go +++ b/cmd/members/create_test.go @@ -13,11 +13,11 @@ import ( func TestCreate(t *testing.T) { errorHelp := ". See `ldcli members create --help` for supported flags and usage." + role := "writer" mockArgs := []interface{}{ "testAccessToken", "http://test.com", - []string{"testemail@test.com"}, - "writer", + []members.MemberInput{{Email: "testemail@test.com", Role: role}}, } t.Run("with valid flags calls members API", func(t *testing.T) { client := members.MockClient{} @@ -32,7 +32,7 @@ func TestCreate(t *testing.T) { "--base-uri", "http://test.com", "-d", - `{"email": "testemail@test.com", "role": "writer"}`, + `[{"email": "testemail@test.com", "role": "writer"}]`, } output, err := cmd.CallCmd(t, nil, nil, &client, nil, args) @@ -54,7 +54,7 @@ func TestCreate(t *testing.T) { "--base-uri", "http://test.com", "-d", - `{"email": "testemail@test.com", "role": "writer"}`, + `[{"email": "testemail@test.com", "role": "writer"}]`, } _, err := cmd.CallCmd(t, nil, nil, &client, nil, args) diff --git a/cmd/members/invite.go b/cmd/members/invite.go index fdf0fe6c..cc118e68 100644 --- a/cmd/members/invite.go +++ b/cmd/members/invite.go @@ -21,12 +21,12 @@ func NewInviteCmd(client members.Client) (*cobra.Command, error) { Use: "invite", } - cmd.Flags().StringSliceP("emails", "e", []string{}, "A comma separated list of emails") - err := cmd.MarkFlagRequired("emails") + cmd.Flags().StringSliceP(cliflags.EmailsFlag, "e", []string{}, "A comma separated list of emails") + err := cmd.MarkFlagRequired(cliflags.EmailsFlag) if err != nil { return nil, err } - err = viper.BindPFlag("emails", cmd.Flags().Lookup("emails")) + err = viper.BindPFlag(cliflags.EmailsFlag, cmd.Flags().Lookup(cliflags.EmailsFlag)) if err != nil { return nil, err } @@ -47,12 +47,17 @@ func NewInviteCmd(client members.Client) (*cobra.Command, error) { func runInvite(client members.Client) func(*cobra.Command, []string) error { return func(cmd *cobra.Command, args []string) error { + emails := viper.GetStringSlice(cliflags.EmailsFlag) + memberInputs := make([]members.MemberInput, 0, len(emails)) + for _, e := range emails { + role := viper.GetString(cliflags.RoleFlag) + memberInputs = append(memberInputs, members.MemberInput{Email: e, Role: role}) + } response, err := client.Create( context.Background(), viper.GetString(cliflags.AccessTokenFlag), viper.GetString(cliflags.BaseURIFlag), - viper.GetStringSlice(cliflags.EmailsFlag), - viper.GetString(cliflags.RoleFlag), + memberInputs, ) if err != nil { return err diff --git a/cmd/members/invite_test.go b/cmd/members/invite_test.go index 579f7d3b..dca67ebc 100644 --- a/cmd/members/invite_test.go +++ b/cmd/members/invite_test.go @@ -13,11 +13,14 @@ import ( func TestInvite(t *testing.T) { errorHelp := ". See `ldcli members invite --help` for supported flags and usage." + readerRole := "reader" mockArgs := []interface{}{ "testAccessToken", "http://test.com", - []string{"testemail1@test.com", "testemail2@test.com"}, - "reader", + []members.MemberInput{ + {Email: "testemail1@test.com", Role: readerRole}, + {Email: "testemail2@test.com", Role: readerRole}, + }, } t.Run("with valid flags calls members API", func(t *testing.T) { client := members.MockClient{} @@ -87,11 +90,14 @@ func TestInvite(t *testing.T) { } func TestInviteWithOptionalRole(t *testing.T) { + writerRole := "writer" mockArgs := []interface{}{ "testAccessToken", "http://test.com", - []string{"testemail1@test.com", "testemail2@test.com"}, - "writer", + []members.MemberInput{ + {Email: "testemail1@test.com", Role: writerRole}, + {Email: "testemail2@test.com", Role: writerRole}, + }, } t.Run("with valid optional long form flag calls members API", func(t *testing.T) { client := members.MockClient{} diff --git a/internal/members/members.go b/internal/members/members.go index 3680fc3a..31a2480b 100644 --- a/internal/members/members.go +++ b/internal/members/members.go @@ -3,7 +3,6 @@ package members import ( "context" "encoding/json" - ldapi "github.com/launchdarkly/api-client-go/v14" "ldcli/internal/client" @@ -11,7 +10,7 @@ import ( ) type Client interface { - Create(ctx context.Context, accessToken string, baseURI string, emails []string, role string) ([]byte, error) + Create(ctx context.Context, accessToken string, baseURI string, memberInputs []MemberInput) ([]byte, error) } type MembersClient struct { @@ -24,11 +23,16 @@ func NewClient(cliVersion string) Client { } } -func (c MembersClient) Create(ctx context.Context, accessToken string, baseURI string, emails []string, role string) ([]byte, error) { +type MemberInput struct { + Email string `json:"email"` + Role string `json:"role"` +} + +func (c MembersClient) Create(ctx context.Context, accessToken string, baseURI string, memberInputs []MemberInput) ([]byte, error) { client := client.New(accessToken, baseURI, c.cliVersion) - memberForms := make([]ldapi.NewMemberForm, 0, len(emails)) - for _, e := range emails { - memberForms = append(memberForms, ldapi.NewMemberForm{Email: e, Role: &role}) + memberForms := make([]ldapi.NewMemberForm, 0, len(memberInputs)) + for _, m := range memberInputs { + memberForms = append(memberForms, ldapi.NewMemberForm{Email: m.Email, Role: &m.Role}) } members, _, err := client.AccountMembersApi.PostMembers(ctx).NewMemberForm(memberForms).Execute() diff --git a/internal/members/mock.go b/internal/members/mock.go index de5874d6..415fc300 100644 --- a/internal/members/mock.go +++ b/internal/members/mock.go @@ -16,10 +16,9 @@ func (c *MockClient) Create( ctx context.Context, accessToken string, baseURI string, - emails []string, - role string, + memberInputs []MemberInput, ) ([]byte, error) { - args := c.Called(accessToken, baseURI, emails, role) + args := c.Called(accessToken, baseURI, memberInputs) return args.Get(0).([]byte), args.Error(1) }