Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: members create cmd should invite multiple members #103

Merged
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
14 changes: 4 additions & 10 deletions cmd/members/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
}

Expand All @@ -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 {
Expand All @@ -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
Expand Down
8 changes: 4 additions & 4 deletions cmd/members/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
Expand All @@ -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, &client, nil, args)
Expand All @@ -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, &client, nil, args)
Expand Down
15 changes: 10 additions & 5 deletions cmd/members/invite.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
Expand Down
14 changes: 10 additions & 4 deletions cmd/members/invite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
Expand Down Expand Up @@ -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{}
Expand Down
16 changes: 10 additions & 6 deletions internal/members/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ package members
import (
"context"
"encoding/json"

ldapi "github.com/launchdarkly/api-client-go/v14"

"ldcli/internal/client"
"ldcli/internal/errors"
)

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 {
Expand All @@ -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()
Expand Down
5 changes: 2 additions & 3 deletions internal/members/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Loading