// 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" 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{}), InviteeUserID: user.ID, DomainID: domain.ID, } func TestSendDomainInvitationCmd(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 domain invitation successfully", args: []string{ user.ID, domain.ID, relation, validToken, }, logType: okLog, }, { desc: "send domain invitation with invalid args", args: []string{ user.ID, domain.ID, relation, validToken, extraArg, }, logType: usageLog, }, { desc: "send domain 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, mock.Anything).Return(tc.sdkErr) out := executeCommand(t, rootCmd, append([]string{domainCmd, 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 TestGetUserInvitationsCmd(t *testing.T) { sdkMock := new(sdkmocks.SDK) cli.SetSDK(sdkMock) invCmd := cli.NewInvitationsCmd() rootCmd := setFlags(invCmd) var page mgsdk.InvitationPage cases := []struct { desc string args []string sdkErr errors.SDKError page mgsdk.InvitationPage logType outputLog errLogMessage string }{ { desc: "get user invitations successfully", args: []string{ token, }, page: mgsdk.InvitationPage{ Total: 1, Offset: 0, Limit: 10, Invitations: []mgsdk.Invitation{invitation}, }, logType: entityLog, }, { desc: "get user invitations with invalid args", args: []string{ token, extraArg, }, logType: usageLog, }, { desc: "get user invitations 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 { t.Run(tc.desc, func(t *testing.T) { sdkCall := sdkMock.On("Invitations", mock.Anything, mock.Anything, tc.args[0]).Return(tc.page, tc.sdkErr) out := executeCommand(t, rootCmd, append([]string{userCmd, 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() }) } } func TestGetDomainInvitationsCmd(t *testing.T) { sdkMock := new(sdkmocks.SDK) cli.SetSDK(sdkMock) invCmd := cli.NewInvitationsCmd() rootCmd := setFlags(invCmd) var page mgsdk.InvitationPage cases := []struct { desc string args []string sdkErr errors.SDKError page mgsdk.InvitationPage logType outputLog errLogMessage string }{ { desc: "get domain invitations successfully", args: []string{ domain.ID, token, }, page: mgsdk.InvitationPage{ Total: 1, Offset: 0, Limit: 10, Invitations: []mgsdk.Invitation{invitation}, }, logType: entityLog, }, { desc: "get domain invitations with invalid args", args: []string{ domain.ID, token, extraArg, }, logType: usageLog, }, { desc: "get domain invitations with invalid token", args: []string{ 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("DomainInvitations", mock.Anything, mock.Anything, tc.args[1], tc.args[0]).Return(tc.page, tc.sdkErr) out := executeCommand(t, rootCmd, append([]string{domainCmd, 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() }) } } func TestAcceptUserInvitationCmd(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 user invitation successfully", args: []string{ domain.ID, validToken, }, logType: okLog, }, { desc: "accept user invitation with invalid args", args: []string{ domain.ID, validToken, extraArg, }, logType: usageLog, }, { desc: "accept user 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, mock.Anything).Return(tc.sdkErr) out := executeCommand(t, rootCmd, append([]string{userCmd, 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 TestRejectUserInvitationCmd(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: "reject user invitation successfully", args: []string{ domain.ID, validToken, }, logType: okLog, }, { desc: "reject user invitation with invalid args", args: []string{ domain.ID, validToken, extraArg, }, logType: usageLog, }, { desc: "reject user 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("RejectInvitation", mock.Anything, mock.Anything, mock.Anything).Return(tc.sdkErr) out := executeCommand(t, rootCmd, append([]string{userCmd, rejectCmd}, 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 TestDeleteDomainInvitationCmd(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 domain invitation successfully", args: []string{ user.ID, domain.ID, validToken, }, logType: okLog, }, { desc: "delete domain invitation with invalid args", args: []string{ user.ID, domain.ID, validToken, extraArg, }, logType: usageLog, }, { desc: "delete domain 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, mock.Anything).Return(tc.sdkErr) out := executeCommand(t, rootCmd, append([]string{domainCmd, 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() }) } }