MG-887 - Create Bootstrap, Invitations, and Journal CLI tests (#2352)

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
This commit is contained in:
Steve Munene
2024-07-19 10:40:08 +03:00
committed by GitHub
parent 66fe5f1483
commit c4c037f839
6 changed files with 1211 additions and 4 deletions
+3 -3
View File
@@ -87,7 +87,7 @@ var cmdBootstrap = []cobra.Command{
}
if args[0] == "config" {
var cfg mgxsdk.BootstrapConfig
if err := json.Unmarshal([]byte(args[0]), &cfg); err != nil {
if err := json.Unmarshal([]byte(args[1]), &cfg); err != nil {
logErrorCmd(*cmd, err)
return
}
@@ -102,11 +102,11 @@ var cmdBootstrap = []cobra.Command{
}
if args[0] == "connection" {
var ids []string
if err := json.Unmarshal([]byte(args[1]), &ids); err != nil {
if err := json.Unmarshal([]byte(args[2]), &ids); err != nil {
logErrorCmd(*cmd, err)
return
}
if err := sdk.UpdateBootstrapConnection(args[0], ids, args[2]); err != nil {
if err := sdk.UpdateBootstrapConnection(args[1], ids, args[3]); err != nil {
logErrorCmd(*cmd, err)
return
}
+596
View File
@@ -0,0 +1,596 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package cli_test
import (
"encoding/json"
"fmt"
"net/http"
"strings"
"testing"
"github.com/absmach/magistrala/cli"
"github.com/absmach/magistrala/pkg/errors"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
mgsdk "github.com/absmach/magistrala/pkg/sdk/go"
sdkmocks "github.com/absmach/magistrala/pkg/sdk/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
var bootConfig = mgsdk.BootstrapConfig{
ThingID: thing.ID,
Channels: []string{channel.ID},
Name: "Test Bootstrap",
ExternalID: "09:6:0:sb:sa",
ExternalKey: "key",
}
func TestCreateBootstrapConfigCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
bootCmd := cli.NewBootstrapCmd()
rootCmd := setFlags(bootCmd)
jsonConfig := fmt.Sprintf("{\"external_id\":\"09:6:0:sb:sa\", \"thing_id\": \"%s\", \"external_key\":\"key\", \"name\": \"%s\", \"channels\":[\"%s\"]}", thing.ID, "Test Bootstrap", channel.ID)
invalidJson := fmt.Sprintf("{\"external_id\":\"09:6:0:sb:sa\", \"thing_id\": \"%s\", \"external_key\":\"key\", \"name\": \"%s\", \"channels\":[\"%s\"]", thing.ID, "Test Bootdtrap", channel.ID)
cases := []struct {
desc string
args []string
logType outputLog
response string
sdkErr errors.SDKError
errLogMessage string
id string
}{
{
desc: "create bootstrap config successfully",
args: []string{
jsonConfig,
validToken,
},
logType: createLog,
id: thing.ID,
response: fmt.Sprintf("\ncreated: %s\n\n", thing.ID),
},
{
desc: "create bootstrap config with invald args",
args: []string{
jsonConfig,
validToken,
extraArg,
},
logType: usageLog,
},
{
desc: "create bootstrap config with invald json",
args: []string{
invalidJson,
validToken,
},
sdkErr: errors.NewSDKError(errors.New("unexpected end of JSON input")),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.New("unexpected end of JSON input")),
logType: errLog,
},
{
desc: "create bootstrap config with invald token",
args: []string{
jsonConfig,
invalidToken,
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized)),
logType: errLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("AddBootstrap", mock.Anything, mock.Anything).Return(tc.id, tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{createCmd}, tc.args...)...)
switch tc.logType {
case createLog:
assert.Equal(t, tc.response, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.response, 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))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
}
sdkCall.Unset()
})
}
}
func TestGetBootstrapConfigCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
bootCmd := cli.NewBootstrapCmd()
rootCmd := setFlags(bootCmd)
var boot mgsdk.BootstrapConfig
var page mgsdk.BootstrapPage
cases := []struct {
desc string
args []string
sdkErr errors.SDKError
page mgsdk.BootstrapPage
boot mgsdk.BootstrapConfig
logType outputLog
errLogMessage string
}{
{
desc: "get all bootstrap config successfully",
args: []string{
all,
token,
},
page: mgsdk.BootstrapPage{
PageRes: mgsdk.PageRes{
Total: 1,
Offset: 0,
Limit: 10,
},
Configs: []mgsdk.BootstrapConfig{bootConfig},
},
logType: entityLog,
},
{
desc: "get bootstrap config with id",
args: []string{
channel.ID,
token,
},
logType: entityLog,
boot: bootConfig,
},
{
desc: "get bootstrap config with invalid args",
args: []string{
all,
token,
extraArg,
},
logType: usageLog,
},
{
desc: "get all bootstrap config with invalid token",
args: []string{
all,
invalidToken,
},
logType: errLog,
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
{
desc: "get bootstrap config with invalid id",
args: []string{
invalidID,
token,
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
logType: errLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("ViewBootstrap", tc.args[0], tc.args[1]).Return(tc.boot, tc.sdkErr)
sdkCall1 := sdkMock.On("Bootstraps", mock.Anything, tc.args[1]).Return(tc.page, tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{getCmd}, tc.args...)...)
switch tc.logType {
case entityLog:
if tc.args[0] == all {
err := json.Unmarshal([]byte(out), &page)
assert.Nil(t, err)
assert.Equal(t, tc.page, page, fmt.Sprintf("%v unexpected response, expected: %v, got: %v", tc.desc, tc.page, page))
} else {
err := json.Unmarshal([]byte(out), &boot)
assert.Nil(t, err)
assert.Equal(t, tc.boot, boot, fmt.Sprintf("%v unexpected response, expected: %v, got: %v", tc.desc, tc.boot, boot))
}
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))
}
sdkCall.Unset()
sdkCall1.Unset()
})
}
}
func TestRemoveBootstrapConfigCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
bootCmd := cli.NewBootstrapCmd()
rootCmd := setFlags(bootCmd)
cases := []struct {
desc string
args []string
sdkErr errors.SDKError
logType outputLog
errLogMessage string
}{
{
desc: "remove bootstrap config successfully",
args: []string{
thing.ID,
token,
},
logType: okLog,
},
{
desc: "remove bootstrap config with invalid args",
args: []string{
thing.ID,
token,
extraArg,
},
logType: usageLog,
},
{
desc: "remove bootstrap config with invalid thing id",
args: []string{
invalidID,
token,
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
logType: errLog,
},
{
desc: "remove bootstrap config with invalid token",
args: []string{
thing.ID,
invalidToken,
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
logType: errLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("RemoveBootstrap", tc.args[0], tc.args[1]).Return(tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{rmCmd}, tc.args...)...)
switch tc.logType {
case okLog:
assert.True(t, strings.Contains(out, "ok"), fmt.Sprintf("%s unexpected response: expected success message, got: %v", 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))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
}
sdkCall.Unset()
})
}
}
func TestUpdateBootstrapConfigCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
bootCmd := cli.NewBootstrapCmd()
rootCmd := setFlags(bootCmd)
config := "config"
connection := "connection"
newConfigJson := "{\"name\" : \"New Bootstrap\"}"
chanIDsJson := fmt.Sprintf("[\"%s\"]", channel.ID)
cases := []struct {
desc string
args []string
boot mgsdk.BootstrapConfig
sdkErr errors.SDKError
errLogMessage string
logType outputLog
}{
{
desc: "update bootstrap config successfully",
args: []string{
config,
newConfigJson,
token,
},
logType: okLog,
},
{
desc: "update bootstrap config with invalid token",
args: []string{
config,
newConfigJson,
invalidToken,
},
logType: errLog,
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
{
desc: "update bootstrap connections successfully",
args: []string{
connection,
thing.ID,
chanIDsJson,
token,
},
logType: okLog,
},
{
desc: "update bootstrap connections with invalid json",
args: []string{
connection,
thing.ID,
fmt.Sprintf("[\"%s\"", thing.ID),
token,
},
sdkErr: errors.NewSDKError(errors.New("unexpected end of JSON input")),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.New("unexpected end of JSON input")),
logType: errLog,
},
{
desc: "update bootstrap connections with invalid token",
args: []string{
connection,
thing.ID,
chanIDsJson,
invalidToken,
},
logType: errLog,
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
{
desc: "update bootstrap certs successfully",
args: []string{
"certs",
thing.ID,
"client cert",
"client key",
"ca",
token,
},
boot: bootConfig,
logType: entityLog,
},
{
desc: "update bootstrap certs with invalid token",
args: []string{
"certs",
thing.ID,
"client cert",
"client key",
"ca",
invalidToken,
},
logType: errLog,
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
{
desc: "update bootstrap config with invalid args",
args: []string{
newConfigJson,
token,
},
logType: usageLog,
},
{
desc: "update bootstrap config with invalid json",
args: []string{
config,
"{\"name\" : \"New Bootstrap\"",
token,
},
sdkErr: errors.NewSDKError(errors.New("unexpected end of JSON input")),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.New("unexpected end of JSON input")),
logType: errLog,
},
{
desc: "update bootstrap with invalid args",
args: []string{
extraArg,
extraArg,
extraArg,
extraArg,
extraArg,
},
logType: usageLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
var boot mgsdk.BootstrapConfig
sdkCall := sdkMock.On("UpdateBootstrap", mock.Anything, mock.Anything).Return(tc.sdkErr)
sdkCall1 := sdkMock.On("UpdateBootstrapConnection", mock.Anything, mock.Anything, mock.Anything).Return(tc.sdkErr)
sdkCall2 := sdkMock.On("UpdateBootstrapCerts", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.boot, tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{updCmd}, tc.args...)...)
switch tc.logType {
case entityLog:
err := json.Unmarshal([]byte(out), &boot)
assert.Nil(t, err)
assert.Equal(t, tc.boot, boot, fmt.Sprintf("%s unexpected response: expected: %v, got: %v", tc.desc, tc.boot, boot))
case okLog:
assert.True(t, strings.Contains(out, "ok"), fmt.Sprintf("%s unexpected response: expected success message, got: %v", tc.desc, out))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), 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))
}
sdkCall.Unset()
sdkCall1.Unset()
sdkCall2.Unset()
})
}
}
func TestWhitelistConfigCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
bootCmd := cli.NewBootstrapCmd()
rootCmd := setFlags(bootCmd)
jsonConfig := fmt.Sprintf("{\"thing_id\": \"%s\", \"state\":%d}", thing.ID, 1)
cases := []struct {
desc string
args []string
logType outputLog
errLogMessage string
sdkErr errors.SDKError
}{
{
desc: "whitelist config successfully",
args: []string{
jsonConfig,
validToken,
},
logType: okLog,
},
{
desc: "whitelist config with invalid args",
args: []string{
jsonConfig,
validToken,
extraArg,
},
logType: usageLog,
},
{
desc: "whitelist config with invalid json",
args: []string{
fmt.Sprintf("{\"thing_id\": \"%s\", \"state\":%d", thing.ID, 1),
validToken,
},
sdkErr: errors.NewSDKError(errors.New("unexpected end of JSON input")),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.New("unexpected end of JSON input")),
logType: errLog,
},
{
desc: "whitelist config with invalid token",
args: []string{
jsonConfig,
invalidToken,
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized)),
logType: errLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("Whitelist", mock.Anything, mock.Anything, tc.args[1]).Return(tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{whitelistCmd}, tc.args...)...)
switch tc.logType {
case okLog:
assert.True(t, strings.Contains(out, "ok"), fmt.Sprintf("%s unexpected response: expected success message, got: %v", tc.desc, out))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), 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))
}
sdkCall.Unset()
})
}
}
func TestBootstrapConfigCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
bootCmd := cli.NewBootstrapCmd()
rootCmd := setFlags(bootCmd)
var boot mgsdk.BootstrapConfig
crptoKey := "v7aT0HGxJxt2gULzr3RHwf4WIf6DusPp"
invalidKey := "invalid key"
cases := []struct {
desc string
args []string
logType outputLog
errLogMessage string
sdkErr errors.SDKError
boot mgsdk.BootstrapConfig
}{
{
desc: "bootstrap secure config successfully",
args: []string{
"secure",
bootConfig.ExternalID,
bootConfig.ExternalKey,
crptoKey,
},
boot: bootConfig,
logType: entityLog,
},
{
desc: "bootstrap config successfully",
args: []string{
bootConfig.ExternalID,
bootConfig.ExternalKey,
},
boot: bootConfig,
logType: entityLog,
},
{
desc: "bootstrap secure config with invalid args",
args: []string{
crptoKey,
},
logType: usageLog,
},
{
desc: "bootstrap secure config with invalid key",
args: []string{
"secure",
bootConfig.ExternalID,
invalidKey,
crptoKey,
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized)),
logType: errLog,
},
{
desc: "bootstrap config with invalid key",
args: []string{
bootConfig.ExternalID,
invalidKey,
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized)),
logType: errLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("BootstrapSecure", mock.Anything, mock.Anything, mock.Anything).Return(tc.boot, tc.sdkErr)
sdkCall1 := sdkMock.On("Bootstrap", mock.Anything, mock.Anything).Return(tc.boot, tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{bootStrapCmd}, tc.args...)...)
switch tc.logType {
case entityLog:
err := json.Unmarshal([]byte(out), &boot)
assert.Nil(t, err)
assert.Equal(t, tc.boot, boot, fmt.Sprintf("%s unexpected response: expected: %v, got: %v", tc.desc, tc.boot, boot))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), 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))
}
sdkCall.Unset()
sdkCall1.Unset()
})
}
}
+11
View File
@@ -58,3 +58,14 @@ const (
sendCmd = "send"
readCmd = "read"
)
// Bootstrap commands
const (
whitelistCmd = "whitelist"
bootStrapCmd = "bootstrap"
)
// Invitations commands
const (
acceptCmd = "accept"
)
+317
View File
@@ -0,0 +1,317 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package cli_test
import (
"encoding/json"
"fmt"
"net/http"
"strings"
"testing"
"github.com/absmach/magistrala/cli"
"github.com/absmach/magistrala/internal/testsutil"
"github.com/absmach/magistrala/pkg/errors"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
mgsdk "github.com/absmach/magistrala/pkg/sdk/go"
sdkmocks "github.com/absmach/magistrala/pkg/sdk/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
var invitation = mgsdk.Invitation{
InvitedBy: testsutil.GenerateUUID(&testing.T{}),
UserID: user.ID,
DomainID: domain.ID,
}
func TestSendUserInvitationCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
invCmd := cli.NewInvitationsCmd()
rootCmd := setFlags(invCmd)
cases := []struct {
desc string
args []string
logType outputLog
errLogMessage string
sdkErr errors.SDKError
}{
{
desc: "send invitation successfully",
args: []string{
user.ID,
domain.ID,
relation,
validToken,
},
logType: okLog,
},
{
desc: "send invitation with invalid args",
args: []string{
user.ID,
domain.ID,
relation,
validToken,
extraArg,
},
logType: usageLog,
},
{
desc: "send invitation with invalid token",
args: []string{
user.ID,
domain.ID,
relation,
invalidToken,
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized)),
logType: errLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("SendInvitation", mock.Anything, mock.Anything).Return(tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{sendCmd}, tc.args...)...)
switch tc.logType {
case okLog:
assert.True(t, strings.Contains(out, "ok"), fmt.Sprintf("%s unexpected response: expected success message, got: %v", 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))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
}
sdkCall.Unset()
})
}
}
func TestGetInvitationCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
invCmd := cli.NewInvitationsCmd()
rootCmd := setFlags(invCmd)
var inv mgsdk.Invitation
var page mgsdk.InvitationPage
cases := []struct {
desc string
args []string
sdkErr errors.SDKError
page mgsdk.InvitationPage
inv mgsdk.Invitation
logType outputLog
errLogMessage string
}{
{
desc: "get all invitations successfully",
args: []string{
all,
token,
},
page: mgsdk.InvitationPage{
Total: 1,
Offset: 0,
Limit: 10,
Invitations: []mgsdk.Invitation{invitation},
},
logType: entityLog,
},
{
desc: "get invitation with user id",
args: []string{
user.ID,
domain.ID,
token,
},
logType: entityLog,
inv: invitation,
},
{
desc: "get invitation with invalid args",
args: []string{
all,
token,
extraArg,
extraArg,
},
logType: usageLog,
},
{
desc: "get all invitations with invalid token",
args: []string{
all,
invalidToken,
},
logType: errLog,
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
{
desc: "get invitation with invalid token",
args: []string{
user.ID,
domain.ID,
invalidToken,
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
logType: errLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("Invitation", tc.args[0], tc.args[1], mock.Anything).Return(tc.inv, tc.sdkErr)
sdkCall1 := sdkMock.On("Invitations", mock.Anything, tc.args[1]).Return(tc.page, tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{getCmd}, tc.args...)...)
switch tc.logType {
case entityLog:
if tc.args[0] == all {
err := json.Unmarshal([]byte(out), &page)
assert.Nil(t, err)
assert.Equal(t, tc.page, page, fmt.Sprintf("%v unexpected response, expected: %v, got: %v", tc.desc, tc.page, page))
} else {
err := json.Unmarshal([]byte(out), &inv)
assert.Nil(t, err)
assert.Equal(t, tc.inv, inv, fmt.Sprintf("%v unexpected response, expected: %v, got: %v", tc.desc, tc.inv, inv))
}
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))
}
sdkCall.Unset()
sdkCall1.Unset()
})
}
}
func TestAcceptInvitationCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
invCmd := cli.NewInvitationsCmd()
rootCmd := setFlags(invCmd)
cases := []struct {
desc string
args []string
logType outputLog
errLogMessage string
sdkErr errors.SDKError
}{
{
desc: "accept invitation successfully",
args: []string{
domain.ID,
validToken,
},
logType: okLog,
},
{
desc: "accept invitation with invalid args",
args: []string{
domain.ID,
validToken,
extraArg,
},
logType: usageLog,
},
{
desc: "accept invitation with invalid token",
args: []string{
domain.ID,
invalidToken,
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized)),
logType: errLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("AcceptInvitation", mock.Anything, mock.Anything).Return(tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{acceptCmd}, tc.args...)...)
switch tc.logType {
case okLog:
assert.True(t, strings.Contains(out, "ok"), fmt.Sprintf("%s unexpected response: expected success message, got: %v", 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))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
}
sdkCall.Unset()
})
}
}
func TestDeleteInvitationCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
invCmd := cli.NewInvitationsCmd()
rootCmd := setFlags(invCmd)
cases := []struct {
desc string
args []string
logType outputLog
errLogMessage string
sdkErr errors.SDKError
}{
{
desc: "delete invitation successfully",
args: []string{
user.ID,
domain.ID,
validToken,
},
logType: okLog,
},
{
desc: "delete invitation with invalid args",
args: []string{
user.ID,
domain.ID,
validToken,
extraArg,
},
logType: usageLog,
},
{
desc: "delete invitation with invalid token",
args: []string{
user.ID,
domain.ID,
invalidToken,
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized)),
logType: errLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("DeleteInvitation", mock.Anything, mock.Anything, mock.Anything).Return(tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{delCmd}, tc.args...)...)
switch tc.logType {
case okLog:
assert.True(t, strings.Contains(out, "ok"), fmt.Sprintf("%s unexpected response: expected success message, got: %v", 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))
case usageLog:
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
}
sdkCall.Unset()
})
}
}
+102
View File
@@ -0,0 +1,102 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package cli_test
import (
"encoding/json"
"fmt"
"net/http"
"strings"
"testing"
"github.com/absmach/magistrala/cli"
"github.com/absmach/magistrala/internal/testsutil"
"github.com/absmach/magistrala/pkg/errors"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
mgsdk "github.com/absmach/magistrala/pkg/sdk/go"
sdkmocks "github.com/absmach/magistrala/pkg/sdk/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
var journal = mgsdk.Journal{
ID: testsutil.GenerateUUID(&testing.T{}),
}
func TestGetJournalCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
invCmd := cli.NewJournalCmd()
rootCmd := setFlags(invCmd)
var page mgsdk.JournalsPage
entityType := "entity_type"
entityId := journal.ID
cases := []struct {
desc string
args []string
sdkErr errors.SDKError
page mgsdk.JournalsPage
logType outputLog
errLogMessage string
}{
{
desc: "get journal with journal id",
args: []string{
entityType,
entityId,
token,
},
logType: entityLog,
page: mgsdk.JournalsPage{
Total: 1,
Offset: 0,
Limit: 10,
Journals: []mgsdk.Journal{journal},
},
},
{
desc: "get journal with invalid args",
args: []string{
entityType,
entityId,
token,
extraArg,
},
logType: usageLog,
},
{
desc: "get journal with invalid token",
args: []string{
entityType,
entityId,
invalidToken,
},
logType: errLog,
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("Journal", tc.args[0], tc.args[1], mock.Anything, tc.args[2]).Return(tc.page, tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{getCmd}, tc.args...)...)
switch tc.logType {
case entityLog:
err := json.Unmarshal([]byte(out), &page)
assert.Nil(t, err)
assert.Equal(t, tc.page, page, fmt.Sprintf("%v unexpected response, expected: %v, got: %v", tc.desc, tc.page, page))
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))
}
sdkCall.Unset()
})
}
}
+182 -1
View File
@@ -507,6 +507,30 @@ func TestUpdateUserCmd(t *testing.T) {
logType: entityLog,
user: user,
},
{
desc: "update user tags with invalid json",
args: []string{
tagUpdateType,
userID,
"[\"tag1\", \"tag2\"",
validToken,
},
sdkerr: errors.NewSDKError(errors.New("unexpected end of JSON input")),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.New("unexpected end of JSON input")),
logType: errLog,
},
{
desc: "update user tags with invalid token",
args: []string{
tagUpdateType,
userID,
newTagsJSON,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
{
desc: "update user identity successfully",
args: []string{
@@ -518,6 +542,18 @@ func TestUpdateUserCmd(t *testing.T) {
logType: entityLog,
user: user,
},
{
desc: "update user identity with invalid token",
args: []string{
identityUpdateType,
userID,
newIdentity,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
{
desc: "update user successfully",
args: []string{
@@ -528,6 +564,28 @@ func TestUpdateUserCmd(t *testing.T) {
logType: entityLog,
user: user,
},
{
desc: "update user with invalid token",
args: []string{
userID,
newNameMetadataJSON,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
{
desc: "update user with invalid json",
args: []string{
userID,
"{\"name\":\"new name\", \"metadata\":{\"key\": \"value\"}",
validToken,
},
sdkerr: errors.NewSDKError(errors.New("unexpected end of JSON input")),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.New("unexpected end of JSON input")),
logType: errLog,
},
{
desc: "update user role successfully",
args: []string{
@@ -539,6 +597,18 @@ func TestUpdateUserCmd(t *testing.T) {
logType: entityLog,
user: user,
},
{
desc: "update user role with invalid token",
args: []string{
roleUpdateType,
userID,
newRole,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
{
desc: "update user with invalid args",
args: []string{
@@ -636,6 +706,15 @@ func TestGetUserProfileCmd(t *testing.T) {
},
logType: usageLog,
},
{
desc: "get user profile with invalid token",
args: []string{
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
}
for _, tc := range cases {
@@ -688,18 +767,29 @@ func TestResetPasswordRequestCmd(t *testing.T) {
},
logType: usageLog,
},
{
desc: "failed request password reset",
args: []string{
exampleEmail,
},
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrUpdateEntity, http.StatusUnprocessableEntity),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrUpdateEntity, http.StatusUnprocessableEntity).Error()),
logType: errLog,
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
sdkCall := sdkMock.On("ResetPasswordRequest", tc.args[0]).Return(tc.sdkerr)
out := executeCommand(t, rootCmd, append([]string{resPassCmd}, tc.args...)...)
out := executeCommand(t, rootCmd, append([]string{resPassReqCmd}, 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))
case okLog:
assert.True(t, strings.Contains(out, "ok"), fmt.Sprintf("%s unexpected response: expected success message, got: %v", tc.desc, out))
}
sdkCall.Unset()
})
@@ -740,6 +830,17 @@ func TestResetPasswordCmd(t *testing.T) {
},
logType: usageLog,
},
{
desc: "reset password with invalid token",
args: []string{
newPassword,
newPassword,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
}
for _, tc := range cases {
@@ -801,6 +902,17 @@ func TestUpdatePasswordCmd(t *testing.T) {
logType: usageLog,
user: user,
},
{
desc: "update password with invalid token",
args: []string{
oldPassword,
newPassword,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
}
for _, tc := range cases {
@@ -858,6 +970,16 @@ func TestEnableUserCmd(t *testing.T) {
},
logType: usageLog,
},
{
desc: "enable user with invalid token",
args: []string{
user.ID,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
}
for _, tc := range cases {
@@ -916,6 +1038,16 @@ func TestDisableUserCmd(t *testing.T) {
},
logType: usageLog,
},
{
desc: "disable user with invalid token",
args: []string{
user.ID,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
}
for _, tc := range cases {
@@ -962,6 +1094,15 @@ func TestDeleteUserCmd(t *testing.T) {
},
logType: okLog,
},
{
desc: "delete user with invalid args",
args: []string{
user.ID,
validToken,
extraArg,
},
logType: usageLog,
},
{
desc: "delete user with invalid token",
args: []string{
@@ -1078,6 +1219,16 @@ func TestListUserChannelsCmd(t *testing.T) {
},
logType: usageLog,
},
{
desc: "list user channels with invalid token",
args: []string{
user.ID,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
}
for _, tc := range cases {
@@ -1145,6 +1296,16 @@ func TestListUserThingsCmd(t *testing.T) {
},
logType: usageLog,
},
{
desc: "list user things with invalid token",
args: []string{
user.ID,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
}
for _, tc := range cases {
@@ -1209,6 +1370,16 @@ func TestListUserDomainsCmd(t *testing.T) {
},
logType: usageLog,
},
{
desc: "list user domains with invalid token",
args: []string{
user.ID,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
}
for _, tc := range cases {
@@ -1274,6 +1445,16 @@ func TestListUserGroupsCmd(t *testing.T) {
},
logType: usageLog,
},
{
desc: "list user groups with invalid token",
args: []string{
user.ID,
invalidToken,
},
logType: errLog,
sdkerr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
},
}
for _, tc := range cases {