NOISSUE - Add reject to SDK (#2431)

Signed-off-by: Sammy Oina <sammyoina@gmail.com>
This commit is contained in:
Sammy Kerata Oina
2024-09-17 23:51:36 +03:00
committed by GitHub
parent 2098c85287
commit c32b802a07
7 changed files with 175 additions and 36 deletions
+1
View File
@@ -68,4 +68,5 @@ const (
// Invitations commands
const (
acceptCmd = "accept"
rejectCmd = "reject"
)
+20
View File
@@ -90,6 +90,26 @@ var cmdInvitations = []cobra.Command{
logOKCmd(*cmd)
},
},
{
Use: "reject <domain_id> <user_auth_token>",
Short: "Reject invitation",
Long: "Reject invitation to domain\n" +
"Usage:\n" +
"\tmagistrala-cli invitations reject 39f97daf-d6b6-40f4-b229-2697be8006ef $USER_AUTH_TOKEN\n",
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
logUsageCmd(*cmd, cmd.Use)
return
}
if err := sdk.RejectInvitation(args[0], args[1]); err != nil {
logErrorCmd(*cmd, err)
return
}
logOKCmd(*cmd)
},
},
{
Use: "delete <user_id> <domain_id> <user_auth_token>",
Short: "Delete invitation",
+59
View File
@@ -254,6 +254,65 @@ func TestAcceptInvitationCmd(t *testing.T) {
}
}
func TestRejectInvitationCmd(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 invitation successfully",
args: []string{
domain.ID,
validToken,
},
logType: okLog,
},
{
desc: "reject invitation with invalid args",
args: []string{
domain.ID,
validToken,
extraArg,
},
logType: usageLog,
},
{
desc: "reject 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).Return(tc.sdkErr)
out := executeCommand(t, rootCmd, append([]string{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 TestDeleteInvitationCmd(t *testing.T) {
sdkMock := new(sdkmocks.SDK)
cli.SetSDK(sdkMock)
+32 -33
View File
@@ -16,7 +16,6 @@ import (
mgclients "github.com/absmach/magistrala/pkg/clients"
"github.com/absmach/magistrala/pkg/errors"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
mgsdk "github.com/absmach/magistrala/pkg/sdk/go"
sdk "github.com/absmach/magistrala/pkg/sdk/go"
sdkmocks "github.com/absmach/magistrala/pkg/sdk/mocks"
"github.com/stretchr/testify/assert"
@@ -30,10 +29,10 @@ var (
all = "all"
)
var thing = mgsdk.Thing{
var thing = sdk.Thing{
ID: testsutil.GenerateUUID(&testing.T{}),
Name: "testthing",
Credentials: mgsdk.Credentials{
Credentials: sdk.Credentials{
Secret: "secret",
},
DomainID: testsutil.GenerateUUID(&testing.T{}),
@@ -47,14 +46,14 @@ func TestCreateThingsCmd(t *testing.T) {
thingsCmd := cli.NewThingsCmd()
rootCmd := setFlags(thingsCmd)
var tg mgsdk.Thing
var tg sdk.Thing
cases := []struct {
desc string
args []string
sdkErr errors.SDKError
errLogMessage string
thing mgsdk.Thing
thing sdk.Thing
logType outputLog
}{
{
@@ -142,16 +141,16 @@ func TestGetThingsCmd(t *testing.T) {
thingsCmd := cli.NewThingsCmd()
rootCmd := setFlags(thingsCmd)
var tg mgsdk.Thing
var page mgsdk.ThingsPage
var tg sdk.Thing
var page sdk.ThingsPage
cases := []struct {
desc string
args []string
sdkErr errors.SDKError
errLogMessage string
thing mgsdk.Thing
page mgsdk.ThingsPage
thing sdk.Thing
page sdk.ThingsPage
logType outputLog
}{
{
@@ -161,8 +160,8 @@ func TestGetThingsCmd(t *testing.T) {
token,
},
logType: entityLog,
page: mgsdk.ThingsPage{
Things: []mgsdk.Thing{thing},
page: sdk.ThingsPage{
Things: []sdk.Thing{thing},
},
},
{
@@ -182,7 +181,7 @@ func TestGetThingsCmd(t *testing.T) {
},
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
page: mgsdk.ThingsPage{},
page: sdk.ThingsPage{},
logType: errLog,
},
{
@@ -289,7 +288,7 @@ func TestUpdateThingCmd(t *testing.T) {
args []string
sdkErr errors.SDKError
errLogMessage string
thing mgsdk.Thing
thing sdk.Thing
logType outputLog
}{
{
@@ -299,7 +298,7 @@ func TestUpdateThingCmd(t *testing.T) {
newNameandMeta,
token,
},
thing: mgsdk.Thing{
thing: sdk.Thing{
Name: "thingName",
Metadata: map[string]interface{}{
"metadata": map[string]interface{}{
@@ -342,7 +341,7 @@ func TestUpdateThingCmd(t *testing.T) {
newTagsJson,
token,
},
thing: mgsdk.Thing{
thing: sdk.Thing{
Name: thing.Name,
ID: thing.ID,
DomainID: thing.DomainID,
@@ -383,7 +382,7 @@ func TestUpdateThingCmd(t *testing.T) {
newSecret,
token,
},
thing: mgsdk.Thing{
thing: sdk.Thing{
Name: thing.Name,
ID: thing.ID,
DomainID: thing.DomainID,
@@ -433,20 +432,20 @@ func TestUpdateThingCmd(t *testing.T) {
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
var tg mgsdk.Thing
var tg sdk.Thing
sdkCall := sdkMock.On("UpdateThing", mock.Anything, mock.Anything).Return(tc.thing, tc.sdkErr)
sdkCall1 := sdkMock.On("UpdateThingTags", mock.Anything, mock.Anything).Return(tc.thing, tc.sdkErr)
sdkCall2 := sdkMock.On("UpdateThingSecret", mock.Anything, mock.Anything, mock.Anything).Return(tc.thing, tc.sdkErr)
switch {
case tc.args[0] == tagUpdateType:
var th mgsdk.Thing
var th sdk.Thing
th.Tags = []string{"tag1", "tag2"}
th.ID = tc.args[1]
sdkCall1 = sdkMock.On("UpdateThingTags", th, tc.args[3]).Return(tc.thing, tc.sdkErr)
case tc.args[0] == secretUpdateType:
var th mgsdk.Thing
var th sdk.Thing
th.Credentials.Secret = tc.args[2]
th.ID = tc.args[1]
@@ -547,14 +546,14 @@ func TestEnableThingCmd(t *testing.T) {
cli.SetSDK(sdkMock)
thingsCmd := cli.NewThingsCmd()
rootCmd := setFlags(thingsCmd)
var tg mgsdk.Thing
var tg sdk.Thing
cases := []struct {
desc string
args []string
sdkErr errors.SDKError
errLogMessage string
thing mgsdk.Thing
thing sdk.Thing
logType outputLog
}{
{
@@ -625,14 +624,14 @@ func TestDisablethingCmd(t *testing.T) {
thingsCmd := cli.NewThingsCmd()
rootCmd := setFlags(thingsCmd)
var tg mgsdk.Thing
var tg sdk.Thing
cases := []struct {
desc string
args []string
sdkErr errors.SDKError
errLogMessage string
thing mgsdk.Thing
thing sdk.Thing
logType outputLog
}{
{
@@ -704,14 +703,14 @@ func TestUsersThingCmd(t *testing.T) {
thingsCmd := cli.NewThingsCmd()
rootCmd := setFlags(thingsCmd)
page := mgsdk.UsersPage{}
page := sdk.UsersPage{}
cases := []struct {
desc string
args []string
logType outputLog
errLogMessage string
page mgsdk.UsersPage
page sdk.UsersPage
sdkErr errors.SDKError
}{
{
@@ -720,13 +719,13 @@ func TestUsersThingCmd(t *testing.T) {
thing.ID,
token,
},
page: mgsdk.UsersPage{
PageRes: mgsdk.PageRes{
page: sdk.UsersPage{
PageRes: sdk.PageRes{
Total: 1,
Offset: 0,
Limit: 10,
},
Users: []mgsdk.User{user},
Users: []sdk.User{user},
},
logType: entityLog,
},
@@ -969,12 +968,12 @@ func TestListConnectionCmd(t *testing.T) {
thingsCmd := cli.NewThingsCmd()
rootCmd := setFlags(thingsCmd)
cp := mgsdk.ChannelsPage{}
cp := sdk.ChannelsPage{}
cases := []struct {
desc string
args []string
logType outputLog
page mgsdk.ChannelsPage
page sdk.ChannelsPage
errLogMessage string
sdkErr errors.SDKError
}{
@@ -984,13 +983,13 @@ func TestListConnectionCmd(t *testing.T) {
thing.ID,
token,
},
page: mgsdk.ChannelsPage{
PageRes: mgsdk.PageRes{
page: sdk.ChannelsPage{
PageRes: sdk.PageRes{
Total: 1,
Offset: 0,
Limit: 10,
},
Channels: []mgsdk.Channel{channel},
Channels: []sdk.Channel{channel},
},
logType: entityLog,
},
+2 -2
View File
@@ -36,7 +36,7 @@ func (repo *repository) Create(ctx context.Context, invitation invitations.Invit
}
func (repo *repository) Retrieve(ctx context.Context, userID, domainID string) (invitations.Invitation, error) {
q := `SELECT invited_by, user_id, domain_id, token, relation, created_at, updated_at, confirmed_at FROM invitations WHERE user_id = :user_id AND domain_id = :domain_id;`
q := `SELECT invited_by, user_id, domain_id, token, relation, created_at, updated_at, confirmed_at, rejected_at FROM invitations WHERE user_id = :user_id AND domain_id = :domain_id;`
dbinv := dbInvitation{
UserID: userID,
@@ -63,7 +63,7 @@ func (repo *repository) Retrieve(ctx context.Context, userID, domainID string) (
func (repo *repository) RetrieveAll(ctx context.Context, page invitations.Page) (invitations.InvitationPage, error) {
query := pageQuery(page)
q := fmt.Sprintf("SELECT invited_by, user_id, domain_id, relation, created_at, updated_at, confirmed_at FROM invitations %s LIMIT :limit OFFSET :offset;", query)
q := fmt.Sprintf("SELECT invited_by, user_id, domain_id, relation, created_at, updated_at, confirmed_at, rejected_at FROM invitations %s LIMIT :limit OFFSET :offset;", query)
rows, err := repo.db.NamedQueryContext(ctx, q, page)
if err != nil {
+2 -1
View File
@@ -26,6 +26,7 @@ type Invitation struct {
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
ConfirmedAt time.Time `json:"confirmed_at,omitempty"`
RejectedAt time.Time `json:"rejected_at,omitempty"`
Resend bool `json:"resend,omitempty"`
}
@@ -114,7 +115,7 @@ func (sdk mgSDK) RejectInvitation(domainID, token string) (err error) {
url := sdk.invitationsURL + "/" + invitationsEndpoint + "/" + rejectEndpoint
_, _, sdkerr := sdk.processRequest(http.MethodDelete, url, token, data, nil, http.StatusNoContent)
_, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, data, nil, http.StatusNoContent)
return sdkerr
}
+59
View File
@@ -383,6 +383,65 @@ func TestAcceptInvitation(t *testing.T) {
}
}
func TestRejectInvitation(t *testing.T) {
is, svc := setupInvitations()
defer is.Close()
conf := sdk.Config{
InvitationsURL: is.URL,
}
mgsdk := sdk.NewSDK(conf)
cases := []struct {
desc string
token string
domainID string
svcErr error
err error
}{
{
desc: "reject invitation successfully",
token: validToken,
domainID: invitation.DomainID,
svcErr: nil,
err: nil,
},
{
desc: "reject invitation with invalid token",
token: invalidToken,
domainID: invitation.DomainID,
svcErr: svcerr.ErrAuthentication,
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
{
desc: "reject invitation with empty token",
token: "",
domainID: invitation.DomainID,
svcErr: nil,
err: errors.NewSDKErrorWithStatus(errors.Wrap(apiutil.ErrValidation, apiutil.ErrBearerToken), http.StatusUnauthorized),
},
{
desc: "reject invitation with invalid domainID",
token: validToken,
domainID: wrongID,
svcErr: svcerr.ErrNotFound,
err: errors.NewSDKErrorWithStatus(svcerr.ErrNotFound, http.StatusNotFound),
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
svcCall := svc.On("RejectInvitation", mock.Anything, tc.token, tc.domainID).Return(tc.svcErr)
err := mgsdk.RejectInvitation(tc.domainID, tc.token)
assert.Equal(t, tc.err, err)
if tc.err == nil {
ok := svcCall.Parent.AssertCalled(t, "RejectInvitation", mock.Anything, tc.token, tc.domainID)
assert.True(t, ok)
}
svcCall.Unset()
})
}
}
func TestDeleteInvitation(t *testing.T) {
is, svc := setupInvitations()
defer is.Close()