SMQ-3253 - Update CLI usage (#3252)

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
This commit is contained in:
Steve Munene
2025-11-25 22:02:23 +03:00
committed by GitHub
parent 5c12bc8c91
commit eb83edbcde
10 changed files with 351 additions and 151 deletions
+31 -18
View File
@@ -23,7 +23,7 @@ const (
sendVerification = "send-verification"
verifyEmail = "verify-email"
usageCreate = "cli channels <channel_id> create <JSON_channel> <domain_id> <user_auth_token>"
usageCreate = "cli channels create <JSON_channel> <domain_id> <user_auth_token>"
usageGet = "cli channels <channel_id|all> get <domain_id> <user_auth_token>"
usageUpdate = "cli channels <channel_id> update <JSON_string> <domain_id> <user_auth_token>"
usageDelete = "cli channels <channel_id> delete <domain_id> <user_auth_token>"
@@ -34,32 +34,45 @@ const (
func NewChannelsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "channels <channel_id_or_all> <operation> [args...]",
Use: "channels <channel_id|all|create> [operation] [args...]",
Short: "Channels management",
Long: `Format: <channel_id|all> <operation> [additional_args...]
Long: `Format:
channels create [args...]
channels <channel_id|all> <operation> [args...]
Operations (require channel_id/all): get, update, delete, enable, disable, users
Examples:
channels all get <domain_id> <user_auth_token> # Get all entities
channels <channel_id> get <domain_id> <user_auth_token> # Get specific entity
channels <channel_id> create <JSON_channel> <domain_id> <user_auth_token> # Create entity
channels <channel_id> update <JSON_string> <domain_id> <user_auth_token> # Update entity
channels <channel_id> delete <domain_id> <user_auth_token> # Delete entity
channels <channel_id> enable <domain_id> <user_auth_token> # Enable entity
channels <channel_id> disable <domain_id> <user_auth_token> # Disable entity
channels <channel_id> users <domain_id> <user_auth_token> # List entity users`,
channels create <JSON_channel> <domain_id> <user_auth_token>
channels all get <domain_id> <user_auth_token>
channels <channel_id> get <domain_id> <user_auth_token>
channels <channel_id> update <JSON_string> <domain_id> <user_auth_token>
channels <channel_id> delete <domain_id> <user_auth_token>
channels <channel_id> enable <domain_id> <user_auth_token>
channels <channel_id> disable <domain_id> <user_auth_token>
channels <channel_id> users <domain_id> <user_auth_token>`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) < 2 {
if len(args) == 0 {
logUsageCmd(*cmd, cmd.Use)
return
}
if args[0] == create {
handleCreate(cmd, args[1:])
return
}
if len(args) < 2 {
logUsageCmd(*cmd, "channels <channel_id|all> <get|update|delete|enable|disable|users> [args...]")
return
}
channelParams := args[0]
operation := args[1]
opArgs := args[2:]
switch operation {
case create:
handleCreate(cmd, channelParams, opArgs)
case get:
handleGet(cmd, channelParams, opArgs)
case update:
@@ -81,19 +94,19 @@ Examples:
return cmd
}
func handleCreate(cmd *cobra.Command, channelID string, args []string) {
if len(args) != 2 {
func handleCreate(cmd *cobra.Command, args []string) {
if len(args) != 3 {
logUsageCmd(*cmd, usageCreate)
return
}
var channel smqsdk.Channel
if err := json.Unmarshal([]byte(channelID), &channel); err != nil {
if err := json.Unmarshal([]byte(args[0]), &channel); err != nil {
logErrorCmd(*cmd, err)
return
}
channel, err := sdk.CreateChannel(cmd.Context(), channel, args[0], args[1])
channel, err := sdk.CreateChannel(cmd.Context(), channel, args[1], args[2])
if err != nil {
logErrorCmd(*cmd, err)
return
+12 -7
View File
@@ -44,8 +44,8 @@ func TestCreateChannelCmd(t *testing.T) {
{
desc: "create channel successfully",
args: []string{
channelJson,
createCmd,
channelJson,
domainID,
token,
},
@@ -55,8 +55,8 @@ func TestCreateChannelCmd(t *testing.T) {
{
desc: "create channel with invalid args",
args: []string{
channelJson,
createCmd,
channelJson,
domainID,
token,
extraArg,
@@ -66,8 +66,8 @@ func TestCreateChannelCmd(t *testing.T) {
{
desc: "create channel with invalid json",
args: []string{
"{\"name\":\"testchannel\", \"metadata\":{\"key1\":\"value1\"}",
createCmd,
"{\"name\":\"testchannel\", \"metadata\":{\"key1\":\"value1\"}",
domainID,
token,
},
@@ -78,8 +78,8 @@ func TestCreateChannelCmd(t *testing.T) {
{
desc: "create channel with invalid token",
args: []string{
channelJson,
createCmd,
channelJson,
domainID,
invalidToken,
},
@@ -91,7 +91,10 @@ func TestCreateChannelCmd(t *testing.T) {
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("CreateChannel", mock.Anything, mock.Anything, tc.args[2], tc.args[3]).Return(tc.channel, tc.sdkErr)
var sdkCall *mock.Call
if len(tc.args) >= 4 {
sdkCall = sdkMock.On("CreateChannel", mock.Anything, mock.Anything, tc.args[2], tc.args[3]).Return(tc.channel, tc.sdkErr)
}
out := executeCommand(t, rootCmd, tc.args...)
switch tc.logType {
@@ -100,11 +103,13 @@ func TestCreateChannelCmd(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, tc.channel, cp, fmt.Sprintf("%s unexpected response: expected: %v, got: %v", tc.desc, tc.channel, cp))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
assert.True(t, strings.Contains(out, "cli channels create"), fmt.Sprintf("%s invalid usage: expected to contain create usage, got: %s", tc.desc, out))
case errLog:
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
}
sdkCall.Unset()
if sdkCall != nil {
sdkCall.Unset()
}
})
}
}
+31 -19
View File
@@ -21,7 +21,7 @@ const (
secret = "secret"
// Usage strings for client operations.
usageClientCreate = "cli clients <client_id> create <JSON_client> <domain_id> <user_auth_token>"
usageClientCreate = "cli clients create <JSON_client> <domain_id> <user_auth_token>"
usageClientGet = "cli clients <client_id|all> get <domain_id> <user_auth_token>"
usageClientDelete = "cli clients <client_id> delete <domain_id> <user_auth_token>"
usageClientUpdate = "cli clients <client_id> update <JSON_string> <domain_id> <user_auth_token>"
@@ -53,34 +53,46 @@ const (
func NewClientsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "clients <client_id_or_all> <operation> [args...]",
Use: "clients <client_id|all|create> [operation] [args...]",
Short: "Clients management",
Long: `Format: <client_id|all> <operation> [additional_args...]
Long: `Format:
clients create [args...]
clients <client_id|all> <operation> [args...]
Operations (require client_id/all): get, update, delete, enable, disable, connect, disconnect, users, roles
Examples:
clients all get <domain_id> <user_auth_token> # Get all entities
clients <client_id> get <domain_id> <user_auth_token> # Get specific entity
clients <client_id> create <JSON_client> <domain_id> <user_auth_token> # Create entity
clients <client_id> update <JSON_string> <domain_id> <user_auth_token> # Update entity
clients <client_id> delete <domain_id> <user_auth_token> # Delete entity
clients <client_id> enable <domain_id> <user_auth_token> # Enable entity
clients <client_id> disable <domain_id> <user_auth_token> # Disable entity
clients <client_id> connect <channel_id> <conn_types_json_list> <domain_id> <user_auth_token> # Connect entity
clients <client_id> users <domain_id> <user_auth_token> # List entity users`,
clients create <JSON_client> <domain_id> <user_auth_token>
clients all get <domain_id> <user_auth_token>
clients <client_id> get <domain_id> <user_auth_token>
clients <client_id> update <JSON_string> <domain_id> <user_auth_token>
clients <client_id> delete <domain_id> <user_auth_token>
clients <client_id> enable <domain_id> <user_auth_token>
clients <client_id> disable <domain_id> <user_auth_token>
clients <client_id> connect <channel_id> <conn_types_json_list> <domain_id> <user_auth_token>
clients <client_id> users <domain_id> <user_auth_token>`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) < 2 {
if len(args) == 0 {
logUsageCmd(*cmd, cmd.Use)
return
}
if args[0] == create {
handleClientCreate(cmd, args[1:])
return
}
if len(args) < 2 {
logUsageCmd(*cmd, "clients <client_id|all> <get|update|delete|enable|disable|connect|disconnect|users|roles> [args...]")
return
}
clientParams := args[0]
operation := args[1]
opArgs := args[2:]
switch operation {
case create:
handleClientCreate(cmd, clientParams, opArgs)
case get:
handleClientGet(cmd, clientParams, opArgs)
case update:
@@ -108,20 +120,20 @@ Examples:
return cmd
}
func handleClientCreate(cmd *cobra.Command, clientParams string, args []string) {
if len(args) != 2 {
func handleClientCreate(cmd *cobra.Command, args []string) {
if len(args) != 3 {
logUsageCmd(*cmd, usageClientCreate)
return
}
var client smqsdk.Client
if err := json.Unmarshal([]byte(clientParams), &client); err != nil {
if err := json.Unmarshal([]byte(args[0]), &client); err != nil {
logErrorCmd(*cmd, err)
return
}
client.Status = clients.EnabledStatus.String()
client, err := sdk.CreateClient(cmd.Context(), client, args[0], args[1])
client, err := sdk.CreateClient(cmd.Context(), client, args[1], args[2])
if err != nil {
logErrorCmd(*cmd, err)
return
+6 -6
View File
@@ -60,8 +60,8 @@ func TestCreateClientsCmd(t *testing.T) {
{
desc: "create client successfully with token",
args: []string{
clientJson,
createCmd,
clientJson,
domainID,
token,
},
@@ -71,8 +71,8 @@ func TestCreateClientsCmd(t *testing.T) {
{
desc: "create client without token",
args: []string{
clientJson,
createCmd,
clientJson,
domainID,
},
logType: usageLog,
@@ -80,8 +80,8 @@ func TestCreateClientsCmd(t *testing.T) {
{
desc: "create client with invalid token",
args: []string{
clientJson,
createCmd,
clientJson,
domainID,
invalidToken,
},
@@ -92,8 +92,8 @@ func TestCreateClientsCmd(t *testing.T) {
{
desc: "failed to create client",
args: []string{
clientJson,
createCmd,
clientJson,
domainID,
token,
},
@@ -104,8 +104,8 @@ func TestCreateClientsCmd(t *testing.T) {
{
desc: "create client with invalid metadata",
args: []string{
"{\"name\":\"testclient\", \"metadata\":{\"key1\":value1}}",
createCmd,
"{\"name\":\"testclient\", \"metadata\":{\"key1\":value1}}",
domainID,
token,
},
@@ -131,7 +131,7 @@ func TestCreateClientsCmd(t *testing.T) {
case errLog:
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
assert.True(t, strings.Contains(out, "cli clients create"), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
}
if sdkCall != nil {
+31 -19
View File
@@ -15,7 +15,7 @@ const (
freeze = "freeze"
// Usage strings for domain operations.
usageDomainCreate = "cli domains <domain_name> create <route> <user_auth_token>"
usageDomainCreate = "cli domains create <domain_name> <route> <user_auth_token>"
usageDomainGet = "cli domains <domain_id|all> get <user_auth_token>"
usageDomainUpdate = "cli domains <domain_id> update <JSON_string> <user_auth_token>"
usageDomainEnable = "cli domains <domain_id> enable <user_auth_token>"
@@ -43,33 +43,45 @@ const (
func NewDomainsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "domains <domain_id_or_all> <operation> [args...]",
Use: "domains <domain_id|all|create> [operation] [args...]",
Short: "Domains management",
Long: `Format: <domain_id|all> <operation> [additional_args...]
Long: `Format:
domains create [args...]
domains <domain_id|all> <operation> [args...]
Operations (require domain_id/all): get, update, enable, disable, freeze, users, roles
Examples:
domains all get <user_auth_token> # Get all entities
domains <domain_id> get <user_auth_token> # Get specific entity
domains <domain_name> create <route> <user_auth_token> # Create entity
domains <domain_id> update <JSON_string> <user_auth_token> # Update entity
domains <domain_id> enable <user_auth_token> # Enable entity
domains <domain_id> disable <user_auth_token> # Disable entity
domains <domain_id> freeze <user_auth_token> # Freeze entity
domains <domain_id> users <user_auth_token> # List entity users`,
domains create <domain_name> <route> <user_auth_token>
domains all get <user_auth_token>
domains <domain_id> get <user_auth_token>
domains <domain_id> update <JSON_string> <user_auth_token>
domains <domain_id> enable <user_auth_token>
domains <domain_id> disable <user_auth_token>
domains <domain_id> freeze <user_auth_token>
domains <domain_id> users <user_auth_token>`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) < 2 {
if len(args) == 0 {
logUsageCmd(*cmd, cmd.Use)
return
}
if args[0] == create {
handleDomainCreate(cmd, args[1:])
return
}
if len(args) < 2 {
logUsageCmd(*cmd, "domains <domain_id|all> <get|update|enable|disable|freeze|users|roles> [args...]")
return
}
domainParams := args[0]
operation := args[1]
opArgs := args[2:]
switch operation {
case create:
handleDomainCreate(cmd, domainParams, opArgs)
case get:
handleDomainGet(cmd, domainParams, opArgs)
case update:
@@ -93,17 +105,17 @@ Examples:
return cmd
}
func handleDomainCreate(cmd *cobra.Command, domainName string, args []string) {
if len(args) != 2 {
func handleDomainCreate(cmd *cobra.Command, args []string) {
if len(args) != 3 {
logUsageCmd(*cmd, usageDomainCreate)
return
}
dom := smqsdk.Domain{
Name: domainName,
Route: args[0],
Name: args[0],
Route: args[1],
}
d, err := sdk.CreateDomain(cmd.Context(), dom, args[1])
d, err := sdk.CreateDomain(cmd.Context(), dom, args[2])
if err != nil {
logErrorCmd(*cmd, err)
return
+4 -4
View File
@@ -48,8 +48,8 @@ func TestCreateDomainsCmd(t *testing.T) {
{
desc: "create domain successfully",
args: []string{
dom.Name,
createCmd,
dom.Name,
dom.Route,
validToken,
},
@@ -59,8 +59,8 @@ func TestCreateDomainsCmd(t *testing.T) {
{
desc: "create domain with invalid args",
args: []string{
dom.Name,
createCmd,
dom.Name,
dom.Route,
validToken,
extraArg,
@@ -70,8 +70,8 @@ func TestCreateDomainsCmd(t *testing.T) {
{
desc: "create domain with invalid token",
args: []string{
dom.Name,
createCmd,
dom.Name,
dom.Route,
invalidToken,
},
@@ -94,7 +94,7 @@ func TestCreateDomainsCmd(t *testing.T) {
case errLog:
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
assert.True(t, strings.Contains(out, "cli domains create"), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
}
sdkCall.Unset()
})
+30 -18
View File
@@ -19,7 +19,7 @@ const (
availableActions = "available-actions"
// Usage strings for group operations.
usageGroupCreate = "cli groups <JSON_group> create <domain_id> <user_auth_token>"
usageGroupCreate = "cli groups create <JSON_group> <domain_id> <user_auth_token>"
usageGroupGet = "cli groups <group_id|all> get <domain_id> <user_auth_token>"
usageGroupUpdate = "cli groups <group_id> update <JSON_string> <domain_id> <user_auth_token>"
usageGroupUpdateTags = "cli groups <group_id> update tags <tags> <domain_id> <user_auth_token>"
@@ -47,33 +47,45 @@ const (
func NewGroupsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "groups <group_id_or_all> <operation> [args...]",
Use: "groups <group_id|all|create> [operation] [args...]",
Short: "Groups management",
Long: `Format: <group_id|all> <operation> [additional_args...]
Long: `Format:
groups create [args...]
groups <group_id|all> <operation> [args...]
Operations (require group_id/all): get, update, delete, enable, disable, roles
Examples:
groups all get <domain_id> <user_auth_token> # Get all entities
groups <group_id> get <domain_id> <user_auth_token> # Get specific entity
groups <JSON_group> create <domain_id> <user_auth_token> # Create entity
groups <group_id> update <JSON_string> <domain_id> <user_auth_token> # Update entity
groups <group_id> update tags <tags> <domain_id> <user_auth_token> # Update entity tags
groups <group_id> delete <domain_id> <user_auth_token> # Delete entity
groups <group_id> enable <domain_id> <user_auth_token> # Enable entity
groups <group_id> disable <domain_id> <user_auth_token> # Disable entity`,
groups create <JSON_group> <domain_id> <user_auth_token>
groups all get <domain_id> <user_auth_token>
groups <group_id> get <domain_id> <user_auth_token>
groups <group_id> update <JSON_string> <domain_id> <user_auth_token>
groups <group_id> update tags <tags> <domain_id> <user_auth_token>
groups <group_id> delete <domain_id> <user_auth_token>
groups <group_id> enable <domain_id> <user_auth_token>
groups <group_id> disable <domain_id> <user_auth_token>`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) < 2 {
if len(args) == 0 {
logUsageCmd(*cmd, cmd.Use)
return
}
if args[0] == create {
handleGroupCreate(cmd, args[1:])
return
}
if len(args) < 2 {
logUsageCmd(*cmd, "groups <group_id|all> <get|update|delete|enable|disable|roles> [args...]")
return
}
groupParams := args[0]
operation := args[1]
opArgs := args[2:]
switch operation {
case create:
handleGroupCreate(cmd, groupParams, opArgs)
case get:
handleGroupGet(cmd, groupParams, opArgs)
case update:
@@ -95,19 +107,19 @@ Examples:
return cmd
}
func handleGroupCreate(cmd *cobra.Command, groupJSON string, args []string) {
if len(args) != 2 {
func handleGroupCreate(cmd *cobra.Command, args []string) {
if len(args) != 3 {
logUsageCmd(*cmd, usageGroupCreate)
return
}
var group smqsdk.Group
if err := json.Unmarshal([]byte(groupJSON), &group); err != nil {
if err := json.Unmarshal([]byte(args[0]), &group); err != nil {
logErrorCmd(*cmd, err)
return
}
group.Status = groups.EnabledStatus.String()
group, err := sdk.CreateGroup(cmd.Context(), group, args[0], args[1])
group, err := sdk.CreateGroup(cmd.Context(), group, args[1], args[2])
if err != nil {
logErrorCmd(*cmd, err)
return
+6 -6
View File
@@ -49,8 +49,8 @@ func TestCreateGroupCmd(t *testing.T) {
{
desc: "create group successfully",
args: []string{
groupJson,
createCmd,
groupJson,
domainID,
token,
},
@@ -60,8 +60,8 @@ func TestCreateGroupCmd(t *testing.T) {
{
desc: "create group with invalid args",
args: []string{
groupJson,
createCmd,
groupJson,
domainID,
token,
extraArg,
@@ -71,8 +71,8 @@ func TestCreateGroupCmd(t *testing.T) {
{
desc: "create group with invalid json",
args: []string{
"{\"name\":\"testgroup\", \"metadata\":{\"key1\":\"value1\"}",
createCmd,
"{\"name\":\"testgroup\", \"metadata\":{\"key1\":\"value1\"}",
domainID,
token,
},
@@ -83,8 +83,8 @@ func TestCreateGroupCmd(t *testing.T) {
{
desc: "create group with invalid token",
args: []string{
groupJson,
createCmd,
groupJson,
domainID,
invalidToken,
},
@@ -95,8 +95,8 @@ func TestCreateGroupCmd(t *testing.T) {
{
desc: "create group with invalid domain",
args: []string{
groupJson,
createCmd,
groupJson,
domainID,
token,
},
@@ -117,7 +117,7 @@ func TestCreateGroupCmd(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, tc.group, gp, fmt.Sprintf("%s unexpected response: expected: %v, got: %v", tc.desc, tc.group, gp))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
assert.True(t, strings.Contains(out, "cli groups create"), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
case errLog:
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
}
+114 -32
View File
@@ -16,10 +16,10 @@ import (
const (
token = "token"
refreshtoken = "refreshtoken"
refreshToken = "refreshtoken"
profile = "profile"
resetpasswordrequest = "resetpasswordrequest"
resetpassword = "resetpassword"
resetPasswordRequest = "resetpasswordrequest"
resetPassword = "resetpassword"
password = "password"
search = "search"
username = "username"
@@ -27,15 +27,22 @@ const (
role = "role"
// Usage strings for user operations.
usageUserCreate = "cli users create <first_name> <last_name> <email> <username> <password> [user_auth_token]"
usageUserGet = "cli users <user_id|all> get <user_auth_token>"
usageUserToken = "cli users token <username> <password>"
usageUserRefreshToken = "cli users refreshtoken <token>"
usageUserUpdate = "cli users <user_id> update <JSON_string> <user_auth_token>"
usageUserUpdateTags = "cli users <user_id> update tags <tags> <user_auth_token>"
usageUserUpdateUsername = "cli users <user_id> update username <username> <user_auth_token>"
usageUserUpdateEmail = "cli users <user_id> update email <email> <user_auth_token>"
usageUserUpdateRole = "cli users <user_id> update role <role> <user_auth_token>"
usageUserCreate = "cli users create <first_name> <last_name> <email> <username> <password> [user_auth_token]"
usageUserGet = "cli users <user_id|all> get <user_auth_token>"
usageUserToken = "cli users token <username> <password>"
usageUserRefreshToken = "cli users refreshtoken <token>"
usageUserUpdate = "cli users <user_id> update <JSON_string> <user_auth_token>"
usageUserUpdateTags = "cli users <user_id> update tags <tags> <user_auth_token>"
usageUserUpdateUsername = "cli users <user_id> update username <username> <user_auth_token>"
usageUserUpdateEmail = "cli users <user_id> update email <email> <user_auth_token>"
usageUserUpdateRole = "cli users <user_id> update role <role> <user_auth_token>"
usageUserUpdateAll = `cli users <user_id> update <JSON_string|tags|username|email|role> [args...]
Available update options:
cli users <user_id> update <JSON_string> <user_auth_token>
cli users <user_id> update tags <tags> <user_auth_token>
cli users <user_id> update username <username> <user_auth_token>
cli users <user_id> update email <email> <user_auth_token>
cli users <user_id> update role <role> <user_auth_token>`
usageUserProfile = "cli users profile <user_auth_token>"
usageUserResetPasswordReq = "cli users resetpasswordrequest <email>"
usageUserResetPassword = "cli users resetpassword <password> <confpass> <password_request_token>"
@@ -44,67 +51,137 @@ const (
usageUserDisable = "cli users <user_id> disable <user_auth_token>"
usageUserDelete = "cli users <user_id> delete <user_auth_token>"
usageUserSearch = "cli users search <query> <user_auth_token>"
usageUserSendVerification = "cli users sendverification <user_auth_token>"
usageUserVerifyEmail = "cli users verifyemail <verification_token>"
)
func NewUsersCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "users <user_id_or_all> <operation> [args...]",
Use: "users <user_id|all|create|token|refreshtoken|profile|resetpasswordrequest|resetpassword|password|search|sendverification|verifyemail> [operation] [args...]",
Short: "Users management",
Long: `Format: <user_id|all> <operation> [additional_args...]
Long: `Format:
users <create|token|refreshtoken|profile|resetpasswordrequest|resetpassword|password|search|sendverification|verifyemail> [args...]
users <user_id|all> <operation> [args...]
Operations (require user_id/all): get, update, enable, disable, delete
Examples:
users all get <user_auth_token> # Get all entities
users <user_id> get <user_auth_token> # Get specific entity
users <user_id> update <JSON_string> <user_auth_token> # Update entity
users <user_id> update tags <tags> <user_auth_token> # Update entity tags
users <user_id> update username <username> <user_auth_token> # Update username
users <user_id> update email <email> <user_auth_token> # Update email
users <user_id> enable <user_auth_token> # Enable entity
users <user_id> disable <user_auth_token> # Disable entity
users <user_id> delete <user_auth_token> # Delete entity
users create <first_name> <last_name> <email> <username> <password> [user_auth_token] # Create entity
users token <username> <password> # Get token
users profile <user_auth_token> # Get entity profile
users search <query> <user_auth_token> # Search entities`,
users create <first_name> <last_name> <email> <username> <password> [user_auth_token]
users token <username> <password>
users refreshtoken <refresh_token>
users profile <user_auth_token>
users resetpasswordrequest <email>
users resetpassword <password> <confpass> <password_request_token>
users password <old_password> <new_password> <user_auth_token>
users search <query> <user_auth_token>
users sendverification <user_auth_token>
users verifyemail <verification_token>
users all get <user_auth_token>
users <user_id> get <user_auth_token>
users <user_id> update <JSON_string> <user_auth_token>
users <user_id> update tags <tags> <user_auth_token>
users <user_id> update username <username> <user_auth_token>
users <user_id> update email <email> <user_auth_token>
users <user_id> enable <user_auth_token>
users <user_id> disable <user_auth_token>
users <user_id> delete <user_auth_token>`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) < 2 {
if len(args) == 0 {
logUsageCmd(*cmd, cmd.Use)
return
}
switch args[0] {
case create:
handleUserCreate(cmd, args[1:])
return
case sendVerification:
if len(args) < 2 {
logUsageCmd(*cmd, usageUserSendVerification)
return
}
handleSendVerification(cmd, args[1])
return
case verifyEmail:
if len(args) < 2 {
logUsageCmd(*cmd, usageUserVerifyEmail)
return
}
handleVerify(cmd, args[1])
return
case token:
if len(args) < 2 {
logUsageCmd(*cmd, usageUserToken)
return
}
if len(args) < 3 {
logUsageCmd(*cmd, usageUserToken)
return
}
handleUserToken(cmd, args[1], args[2:])
return
case refreshtoken:
case refreshToken:
if len(args) < 2 {
logUsageCmd(*cmd, usageUserRefreshToken)
return
}
handleUserRefreshToken(cmd, args[1], args[2:])
return
case profile:
if len(args) < 2 {
logUsageCmd(*cmd, usageUserProfile)
return
}
handleUserProfile(cmd, args[1], args[2:])
return
case resetpasswordrequest:
case resetPasswordRequest:
if len(args) < 2 {
logUsageCmd(*cmd, usageUserResetPasswordReq)
return
}
handleUserResetPasswordRequest(cmd, args[1], args[2:])
return
case resetpassword:
case resetPassword:
if len(args) < 2 {
logUsageCmd(*cmd, usageUserResetPassword)
return
}
if len(args) < 4 {
logUsageCmd(*cmd, usageUserResetPassword)
return
}
handleUserResetPassword(cmd, args[1], args[2:])
return
case password:
if len(args) < 2 {
logUsageCmd(*cmd, usageUserPassword)
return
}
if len(args) < 4 {
logUsageCmd(*cmd, usageUserPassword)
return
}
handleUserPassword(cmd, args[1], args[2:])
return
case search:
if len(args) < 2 {
logUsageCmd(*cmd, usageUserSearch)
return
}
if len(args) < 3 {
logUsageCmd(*cmd, usageUserSearch)
return
}
handleUserSearch(cmd, args[1], args[2:])
return
}
if len(args) < 2 {
logUsageCmd(*cmd, "users <user_id|all> <get|update|enable|disable|delete> [args...]")
return
}
userParams := args[0]
operation := args[1]
opArgs := args[2:]
@@ -226,6 +303,11 @@ func handleUserGet(cmd *cobra.Command, userParams string, args []string) {
}
func handleUserUpdate(cmd *cobra.Command, userID string, args []string) {
if len(args) < 1 {
logUsageCmd(*cmd, usageUserUpdateAll)
return
}
if len(args) < 2 || len(args) > 3 {
if len(args) >= 1 {
switch args[0] {
@@ -243,7 +325,7 @@ func handleUserUpdate(cmd *cobra.Command, userID string, args []string) {
return
}
}
logUsageCmd(*cmd, usageUserUpdate)
logUsageCmd(*cmd, usageUserUpdateAll)
return
}
+86 -22
View File
@@ -25,6 +25,7 @@ var user = mgsdk.User{
ID: testsutil.GenerateUUID(&testing.T{}),
FirstName: "testuserfirstname",
LastName: "testuserfirstname",
Email: "testuser@example.com",
Credentials: mgsdk.Credentials{
Secret: "testpassword",
Username: "testusername",
@@ -246,7 +247,7 @@ func TestGetUsersCmd(t *testing.T) {
validToken,
extraArg,
},
errLogMessage: rootCmd.Use,
errLogMessage: "cli users <user_id|all> get <user_auth_token>",
logType: usageLog,
},
{
@@ -261,12 +262,23 @@ func TestGetUsersCmd(t *testing.T) {
user: mgsdk.User{},
logType: errLog,
},
{
desc: "get user without operation",
args: []string{
userID,
},
errLogMessage: "users <user_id|all> <get|update|enable|disable|delete> [args...]",
logType: usageLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("Users", mock.Anything, mock.Anything, mock.Anything).Return(tc.page, tc.sdkErr)
sdkCall1 := sdkMock.On("User", mock.Anything, tc.args[0], tc.args[2]).Return(tc.user, tc.sdkErr)
var sdkCall1 *mock.Call
if len(tc.args) >= 3 {
sdkCall1 = sdkMock.On("User", mock.Anything, tc.args[0], tc.args[2]).Return(tc.user, tc.sdkErr)
}
out = executeCommand(t, rootCmd, tc.args...)
@@ -289,7 +301,7 @@ func TestGetUsersCmd(t *testing.T) {
case errLog:
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
assert.True(t, strings.Contains(out, tc.errLogMessage), fmt.Sprintf("%s invalid usage: expected to contain %s, got: %s", tc.desc, tc.errLogMessage, out))
}
if tc.logType == entityLog {
@@ -301,7 +313,9 @@ func TestGetUsersCmd(t *testing.T) {
}
sdkCall.Unset()
sdkCall1.Unset()
if sdkCall1 != nil {
sdkCall1.Unset()
}
})
}
}
@@ -313,7 +327,7 @@ func TestIssueTokenCmd(t *testing.T) {
rootCmd := setFlags(usersCmd)
var tkn mgsdk.Token
invalidPassword := ""
invalidPassword := "wrong_password"
token := mgsdk.Token{
AccessToken: testsutil.GenerateUUID(t),
@@ -359,18 +373,38 @@ func TestIssueTokenCmd(t *testing.T) {
user.Credentials.Secret,
extraArg,
},
errLogMessage: rootCmd.Use,
errLogMessage: "cli users token <username> <password>",
logType: usageLog,
},
{
desc: "issue token with missing password",
args: []string{
tokCmd,
user.Email,
},
errLogMessage: "cli users token <username> <password>",
logType: usageLog,
},
{
desc: "issue token with missing username",
args: []string{
tokCmd,
},
errLogMessage: "cli users token <username> <password>",
logType: usageLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
lg := mgsdk.Login{
Username: tc.args[1],
Password: tc.args[2],
var sdkCall *mock.Call
if len(tc.args) >= 3 {
lg := mgsdk.Login{
Username: tc.args[1],
Password: tc.args[2],
}
sdkCall = sdkMock.On("CreateToken", mock.Anything, lg).Return(tc.token, tc.sdkErr)
}
sdkCall := sdkMock.On("CreateToken", mock.Anything, lg).Return(tc.token, tc.sdkErr)
out := executeCommand(t, rootCmd, tc.args...)
@@ -382,10 +416,12 @@ func TestIssueTokenCmd(t *testing.T) {
case errLog:
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
assert.True(t, strings.Contains(out, tc.errLogMessage), fmt.Sprintf("%s invalid usage: expected to contain %s, got: %s", tc.desc, tc.errLogMessage, out))
}
sdkCall.Unset()
if sdkCall != nil {
sdkCall.Unset()
}
})
}
}
@@ -626,9 +662,24 @@ func TestUpdateUserCmd(t *testing.T) {
validToken,
extraArg,
},
errLogMessage: rootCmd.Use,
errLogMessage: "cli users <user_id> update role <role> <user_auth_token>",
logType: usageLog,
},
{
desc: "update user without specifying what to update",
args: []string{
userID,
updateCmd,
},
errLogMessage: `cli users <user_id> update <JSON_string|tags|username|email|role> [args...]
Available update options:
cli users <user_id> update <JSON_string> <user_auth_token>
cli users <user_id> update tags <tags> <user_auth_token>
cli users <user_id> update username <username> <user_auth_token>
cli users <user_id> update email <email> <user_auth_token>
cli users <user_id> update role <role> <user_auth_token>`,
logType: usageLog,
},
}
for _, tc := range cases {
@@ -638,19 +689,19 @@ func TestUpdateUserCmd(t *testing.T) {
sdkCall2 := sdkMock.On("UpdateUserIdentity", mock.Anything, mock.Anything, mock.Anything).Return(tc.user, tc.sdkErr)
sdkCall3 := sdkMock.On("UpdateUserRole", mock.Anything, mock.Anything, mock.Anything).Return(tc.user, tc.sdkErr)
switch {
case tc.args[2] == tagUpdateType:
case len(tc.args) > 2 && tc.args[2] == tagUpdateType:
var u mgsdk.User
u.Tags = []string{"tag1", "tag2"}
u.ID = tc.args[0]
sdkCall1 = sdkMock.On("UpdateUserTags", mock.Anything, u, tc.args[4]).Return(tc.user, tc.sdkErr)
case tc.args[2] == emailUpdateType:
case len(tc.args) > 2 && tc.args[2] == emailUpdateType:
var u mgsdk.User
u.Email = tc.args[3]
u.ID = tc.args[0]
sdkCall2 = sdkMock.On("UpdateUserEmail", mock.Anything, u, tc.args[4]).Return(tc.user, tc.sdkErr)
case tc.args[2] == roleUpdateType && len(tc.args) >= 5:
case len(tc.args) > 2 && tc.args[2] == roleUpdateType && len(tc.args) >= 5:
sdkCall3 = sdkMock.On("UpdateUserRole", mock.Anything, mgsdk.User{
Role: tc.args[3],
}, tc.args[4]).Return(tc.user, tc.sdkErr)
@@ -672,7 +723,7 @@ func TestUpdateUserCmd(t *testing.T) {
case errLog:
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
assert.True(t, strings.Contains(out, tc.errLogMessage), fmt.Sprintf("%s invalid usage: expected to contain %s, got: %s", tc.desc, tc.errLogMessage, out))
}
sdkCall.Unset()
@@ -715,37 +766,50 @@ func TestGetUserProfileCmd(t *testing.T) {
validToken,
extraArg,
},
errLogMessage: rootCmd.Use,
errLogMessage: "cli users profile <user_auth_token>",
logType: usageLog,
},
{
desc: "get user profile with invalid token",
args: []string{
profCmd,
invalidToken,
"invalid_token_string",
},
logType: errLog,
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
{
desc: "get user profile with missing token",
args: []string{
profCmd,
},
errLogMessage: "cli users profile <user_auth_token>",
logType: usageLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("UserProfile", mock.Anything, tc.args[1]).Return(tc.user, tc.sdkErr)
var sdkCall *mock.Call
if len(tc.args) >= 2 {
sdkCall = sdkMock.On("UserProfile", mock.Anything, tc.args[1]).Return(tc.user, tc.sdkErr)
}
out := executeCommand(t, rootCmd, tc.args...)
switch tc.logType {
case errLog:
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
assert.True(t, strings.Contains(out, tc.errLogMessage), fmt.Sprintf("%s invalid usage: expected to contain %s, got: %s", tc.desc, tc.errLogMessage, out))
case entityLog:
err := json.Unmarshal([]byte(out), &usr)
assert.Nil(t, err)
assert.Equal(t, tc.user, usr, fmt.Sprintf("%s unexpected response: expected: %v, got: %v", tc.desc, tc.user, usr))
}
sdkCall.Unset()
if sdkCall != nil {
sdkCall.Unset()
}
})
}
}