Skip to content

Commit

Permalink
feat: alias command to invite members (#84)
Browse files Browse the repository at this point in the history
* add top level environments cmd

* refactor members create to accept list of emails

* add invite member command

* fix tests, imports

* add tests

* oops remove environments stuff

* update for new flags
  • Loading branch information
k3llymariee authored Mar 28, 2024
1 parent 708925b commit 7002866
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 11 deletions.
1 change: 1 addition & 0 deletions cmd/cliflags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ const (
BaseURIFlag = "base-uri"
FlagFlag = "flag"
ProjectFlag = "project"
EmailsFlag = "emails"
)
2 changes: 1 addition & 1 deletion cmd/members/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func runCreate(client members.Client) func(*cobra.Command, []string) error {
context.Background(),
viper.GetString(cliflags.APITokenFlag),
viper.GetString(cliflags.BaseURIFlag),
data.Email,
[]string{data.Email},
data.Role,
)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/members/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
57 changes: 57 additions & 0 deletions cmd/members/invite.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package members

import (
"context"
"fmt"

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

"ldcli/cmd/cliflags"
"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(cliflags.APITokenFlag),
viper.GetString(cliflags.BaseURIFlag),
viper.GetStringSlice(cliflags.EmailsFlag),
defaultRole,
)
if err != nil {
return err
}

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

return nil
}
}
87 changes: 87 additions & 0 deletions cmd/members/invite_test.go
Original file line number Diff line number Diff line change
@@ -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",
"--api-token",
"testAccessToken",
"--base-uri",
"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",
"--api-token",
"testAccessToken",
"--base-uri",
"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) "api-token", "emails" not set`+errorHelp)
})

t.Run("with invalid base-uri is an error", func(t *testing.T) {
args := []string{
"members",
"invite",
"--base-uri", "invalid",
}

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

assert.EqualError(t, err, "base-uri is invalid"+errorHelp)
})
}
6 changes: 6 additions & 0 deletions cmd/members/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
14 changes: 9 additions & 5 deletions internal/members/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
Expand All @@ -20,14 +20,18 @@ 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.NewLDAPIError(err)
}
memberJson, err := json.Marshal(members.Items[0])
memberJson, err := json.Marshal(members.Items)
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions internal/members/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

0 comments on commit 7002866

Please sign in to comment.