1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-04-26 13:48:53 +08:00
Mainflux.mainflux/pkg/sdk/go/things_test.go
Manuel Imperiale 9245e2593b
MF-1368 - Add internal http api package for query params reading (#1384)
* MF-1368 - Add internal http api package for query params reading

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* Fix comments

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* Fix comments

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* Fix reviews

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* Use internal/http and internalhttp alias

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* Mv errors types to pkg

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* Use httputil/query.go and remove aliases

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* Add blank lines after error definitions

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* Add ReadBoolValueQuery

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* Mv readBoolValueQuery

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* User ErrNotFoundParam instead of pointer

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* Revert ReadUintQuery to use default values

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>

* Use default values for all query readers

Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>
2021-03-23 11:48:05 +01:00

943 lines
24 KiB
Go

// Copyright (c) Mainflux
// SPDX-License-Identifier: Apache-2.0
package sdk_test
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
sdk "github.com/mainflux/mainflux/pkg/sdk/go"
"github.com/mainflux/mainflux/pkg/uuid"
"github.com/mainflux/mainflux/things"
httpapi "github.com/mainflux/mainflux/things/api/things/http"
"github.com/mainflux/mainflux/things/mocks"
"github.com/opentracing/opentracing-go/mocktracer"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const (
contentType = "application/senml+json"
email = "user@example.com"
otherEmail = "other_user@example.com"
token = "token"
otherToken = "other_token"
wrongValue = "wrong_value"
badID = "999"
emptyValue = ""
keyPrefix = "123e4567-e89b-12d3-a456-"
)
var (
metadata = map[string]interface{}{"meta": "data"}
metadata2 = map[string]interface{}{"meta": "data2"}
thing = sdk.Thing{ID: "001", Name: "test_device", Metadata: metadata}
emptyThing = sdk.Thing{}
)
func newThingsService(tokens map[string]string) things.Service {
auth := mocks.NewAuthService(tokens)
conns := make(chan mocks.Connection)
thingsRepo := mocks.NewThingRepository(conns)
channelsRepo := mocks.NewChannelRepository(thingsRepo, conns)
chanCache := mocks.NewChannelCache()
thingCache := mocks.NewThingCache()
idProvider := uuid.NewMock()
return things.New(auth, thingsRepo, channelsRepo, chanCache, thingCache, idProvider)
}
func newThingsServer(svc things.Service) *httptest.Server {
mux := httpapi.MakeHandler(mocktracer.New(), svc)
return httptest.NewServer(mux)
}
func TestCreateThing(t *testing.T) {
svc := newThingsService(map[string]string{token: email})
ts := newThingsServer(svc)
defer ts.Close()
sdkConf := sdk.Config{
BaseURL: ts.URL,
UsersPrefix: "",
GroupsPrefix: "",
ThingsPrefix: "",
HTTPAdapterPrefix: "",
MsgContentType: contentType,
TLSVerification: false,
}
mainfluxSDK := sdk.NewSDK(sdkConf)
cases := []struct {
desc string
thing sdk.Thing
token string
err error
location string
}{
{
desc: "create new thing",
thing: thing,
token: token,
err: nil,
location: "001",
},
{
desc: "create new empty thing",
thing: emptyThing,
token: token,
err: nil,
location: "002",
},
{
desc: "create new thing with empty token",
thing: thing,
token: "",
err: createError(sdk.ErrFailedCreation, http.StatusUnauthorized),
location: "",
},
{
desc: "create new thing with invalid token",
thing: thing,
token: wrongValue,
err: createError(sdk.ErrFailedCreation, http.StatusUnauthorized),
location: "",
},
}
for _, tc := range cases {
loc, err := mainfluxSDK.CreateThing(tc.thing, tc.token)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err))
assert.Equal(t, tc.location, loc, fmt.Sprintf("%s: expected location %s got %s", tc.desc, tc.location, loc))
}
}
func TestCreateThings(t *testing.T) {
svc := newThingsService(map[string]string{token: email})
ts := newThingsServer(svc)
defer ts.Close()
sdkConf := sdk.Config{
BaseURL: ts.URL,
UsersPrefix: "",
GroupsPrefix: "",
ThingsPrefix: "",
HTTPAdapterPrefix: "",
MsgContentType: contentType,
TLSVerification: false,
}
mainfluxSDK := sdk.NewSDK(sdkConf)
things := []sdk.Thing{
sdk.Thing{ID: "001", Name: "1", Key: "1"},
sdk.Thing{ID: "002", Name: "2", Key: "2"},
}
cases := []struct {
desc string
things []sdk.Thing
token string
err error
res []sdk.Thing
}{
{
desc: "create new things",
things: things,
token: token,
err: nil,
res: things,
},
{
desc: "create new things with empty things",
things: []sdk.Thing{},
token: token,
err: createError(sdk.ErrFailedCreation, http.StatusBadRequest),
res: []sdk.Thing{},
},
{
desc: "create new thing with empty token",
things: things,
token: "",
err: createError(sdk.ErrFailedCreation, http.StatusUnauthorized),
res: []sdk.Thing{},
},
{
desc: "create new thing with invalid token",
things: things,
token: wrongValue,
err: createError(sdk.ErrFailedCreation, http.StatusUnauthorized),
res: []sdk.Thing{},
},
}
for _, tc := range cases {
res, err := mainfluxSDK.CreateThings(tc.things, tc.token)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err))
for idx := range tc.res {
assert.Equal(t, tc.res[idx].ID, res[idx].ID, fmt.Sprintf("%s: expected response ID %s got %s", tc.desc, tc.res[idx].ID, res[idx].ID))
}
}
}
func TestThing(t *testing.T) {
svc := newThingsService(map[string]string{token: email})
ts := newThingsServer(svc)
defer ts.Close()
sdkConf := sdk.Config{
BaseURL: ts.URL,
UsersPrefix: "",
GroupsPrefix: "",
ThingsPrefix: "",
HTTPAdapterPrefix: "",
MsgContentType: contentType,
TLSVerification: false,
}
mainfluxSDK := sdk.NewSDK(sdkConf)
id, err := mainfluxSDK.CreateThing(thing, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
thing.Key = fmt.Sprintf("%s%012d", keyPrefix, 2)
cases := []struct {
desc string
thID string
token string
err error
response sdk.Thing
}{
{
desc: "get existing thing",
thID: id,
token: token,
err: nil,
response: thing,
},
{
desc: "get non-existent thing",
thID: "43",
token: token,
err: createError(sdk.ErrFailedFetch, http.StatusNotFound),
response: sdk.Thing{},
},
{
desc: "get thing with invalid token",
thID: id,
token: wrongValue,
err: createError(sdk.ErrFailedFetch, http.StatusUnauthorized),
response: sdk.Thing{},
},
}
for _, tc := range cases {
respTh, err := mainfluxSDK.Thing(tc.thID, tc.token)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err))
assert.Equal(t, tc.response, respTh, fmt.Sprintf("%s: expected response thing %s, got %s", tc.desc, tc.response, respTh))
}
}
func TestThings(t *testing.T) {
svc := newThingsService(map[string]string{token: email})
ts := newThingsServer(svc)
defer ts.Close()
sdkConf := sdk.Config{
BaseURL: ts.URL,
UsersPrefix: "",
GroupsPrefix: "",
ThingsPrefix: "",
HTTPAdapterPrefix: "",
MsgContentType: contentType,
TLSVerification: false,
}
var things []sdk.Thing
mainfluxSDK := sdk.NewSDK(sdkConf)
for i := 1; i < 101; i++ {
th := sdk.Thing{ID: fmt.Sprintf("%03d", i), Name: "test_device", Metadata: metadata}
mainfluxSDK.CreateThing(th, token)
th.Key = fmt.Sprintf("%s%012d", keyPrefix, 2*i)
things = append(things, th)
}
cases := []struct {
desc string
token string
offset uint64
limit uint64
err error
response []sdk.Thing
name string
}{
{
desc: "get a list of things",
token: token,
offset: 0,
limit: 5,
err: nil,
response: things[0:5],
},
{
desc: "get a list of things with invalid token",
token: wrongValue,
offset: 0,
limit: 5,
err: createError(sdk.ErrFailedFetch, http.StatusUnauthorized),
response: nil,
},
{
desc: "get a list of things with empty token",
token: "",
offset: 0,
limit: 5,
err: createError(sdk.ErrFailedFetch, http.StatusUnauthorized),
response: nil,
},
{
desc: "get a list of things with zero limit",
token: token,
offset: 0,
limit: 0,
err: nil,
response: things[0:10],
},
{
desc: "get a list of things with limit greater than max",
token: token,
offset: 0,
limit: 110,
err: createError(sdk.ErrFailedFetch, http.StatusBadRequest),
response: nil,
},
{
desc: "get a list of things with offset greater than max",
token: token,
offset: 110,
limit: 5,
err: nil,
response: []sdk.Thing{},
},
}
for _, tc := range cases {
page, err := mainfluxSDK.Things(tc.token, tc.offset, tc.limit, tc.name)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err))
assert.Equal(t, tc.response, page.Things, fmt.Sprintf("%s: expected response channel %s, got %s", tc.desc, tc.response, page.Things))
}
}
func TestThingsByChannel(t *testing.T) {
svc := newThingsService(map[string]string{token: email})
ts := newThingsServer(svc)
defer ts.Close()
sdkConf := sdk.Config{
BaseURL: ts.URL,
UsersPrefix: "",
GroupsPrefix: "",
ThingsPrefix: "",
HTTPAdapterPrefix: "",
MsgContentType: contentType,
TLSVerification: false,
}
mainfluxSDK := sdk.NewSDK(sdkConf)
ch := sdk.Channel{Name: "test_channel"}
cid, err := mainfluxSDK.CreateChannel(ch, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
var n = 10
var thsDiscoNum = 1
var things []sdk.Thing
for i := 1; i < n+1; i++ {
th := sdk.Thing{
ID: fmt.Sprintf("%03d", i),
Name: "test_device",
Metadata: metadata,
Key: fmt.Sprintf("%s%012d", keyPrefix, 2*i+1),
}
tid, err := mainfluxSDK.CreateThing(th, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
things = append(things, th)
// Don't connect last Thing
if i == n+1-thsDiscoNum {
break
}
// Don't connect last 2 Channels
conIDs := sdk.ConnectionIDs{
ChannelIDs: []string{cid},
ThingIDs: []string{tid},
}
err = mainfluxSDK.Connect(conIDs, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
}
cases := []struct {
desc string
channel string
token string
offset uint64
limit uint64
disconnected bool
err error
response []sdk.Thing
}{
{
desc: "get a list of things by channel",
channel: cid,
token: token,
offset: 0,
limit: 5,
err: nil,
response: things[0:5],
},
{
desc: "get a list of things by channel with invalid token",
channel: cid,
token: wrongValue,
offset: 0,
limit: 5,
err: createError(sdk.ErrFailedFetch, http.StatusUnauthorized),
response: nil,
},
{
desc: "get a list of things by channel with empty token",
channel: cid,
token: "",
offset: 0,
limit: 5,
err: createError(sdk.ErrFailedFetch, http.StatusUnauthorized),
response: nil,
},
{
desc: "get a list of things by channel with zero limit",
channel: cid,
token: token,
offset: 0,
limit: 0,
err: createError(sdk.ErrFailedFetch, http.StatusBadRequest),
response: nil,
},
{
desc: "get a list of things by channel with limit greater than max",
channel: cid,
token: token,
offset: 0,
limit: 110,
err: createError(sdk.ErrFailedFetch, http.StatusBadRequest),
response: nil,
},
{
desc: "get a list of things by channel with offset greater than max",
channel: cid,
token: token,
offset: 110,
limit: 5,
err: nil,
response: []sdk.Thing{},
},
{
desc: "get a list of things by channel with invalid args (zero limit) and invalid token",
channel: cid,
token: wrongValue,
offset: 0,
limit: 0,
err: createError(sdk.ErrFailedFetch, http.StatusBadRequest),
response: nil,
},
{
desc: "get a list of not connected things by channel",
channel: cid,
token: token,
offset: 0,
limit: 100,
disconnected: true,
err: nil,
response: []sdk.Thing{things[n-thsDiscoNum]},
},
}
for _, tc := range cases {
page, err := mainfluxSDK.ThingsByChannel(tc.token, tc.channel, tc.offset, tc.limit, tc.disconnected)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err))
assert.Equal(t, tc.response, page.Things, fmt.Sprintf("%s: expected response channel %s, got %s", tc.desc, tc.response, page.Things))
}
}
func TestUpdateThing(t *testing.T) {
svc := newThingsService(map[string]string{token: email})
ts := newThingsServer(svc)
defer ts.Close()
sdkConf := sdk.Config{
BaseURL: ts.URL,
UsersPrefix: "",
GroupsPrefix: "",
ThingsPrefix: "",
HTTPAdapterPrefix: "",
MsgContentType: contentType,
TLSVerification: false,
}
mainfluxSDK := sdk.NewSDK(sdkConf)
id, err := mainfluxSDK.CreateThing(thing, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
thing.Name = "test2"
cases := []struct {
desc string
thing sdk.Thing
token string
err error
}{
{
desc: "update existing thing",
thing: sdk.Thing{
ID: id,
Name: "test_app",
Metadata: metadata2,
},
token: token,
err: nil,
},
{
desc: "update non-existing thing",
thing: sdk.Thing{
ID: "0",
Name: "test_device",
Metadata: metadata,
},
token: token,
err: createError(sdk.ErrFailedUpdate, http.StatusNotFound),
},
{
desc: "update channel with invalid id",
thing: sdk.Thing{
ID: "",
Name: "test_device",
Metadata: metadata,
},
token: token,
err: createError(sdk.ErrFailedUpdate, http.StatusBadRequest),
},
{
desc: "update channel with invalid token",
thing: sdk.Thing{
ID: id,
Name: "test_app",
Metadata: metadata2,
},
token: wrongValue,
err: createError(sdk.ErrFailedUpdate, http.StatusUnauthorized),
},
{
desc: "update channel with empty token",
thing: sdk.Thing{
ID: id,
Name: "test_app",
Metadata: metadata2,
},
token: "",
err: createError(sdk.ErrFailedUpdate, http.StatusUnauthorized),
},
}
for _, tc := range cases {
err := mainfluxSDK.UpdateThing(tc.thing, tc.token)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err))
}
}
func TestDeleteThing(t *testing.T) {
svc := newThingsService(map[string]string{token: email})
ts := newThingsServer(svc)
defer ts.Close()
sdkConf := sdk.Config{
BaseURL: ts.URL,
UsersPrefix: "",
GroupsPrefix: "",
ThingsPrefix: "",
HTTPAdapterPrefix: "",
MsgContentType: contentType,
TLSVerification: false,
}
mainfluxSDK := sdk.NewSDK(sdkConf)
id, err := mainfluxSDK.CreateThing(thing, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
cases := []struct {
desc string
thingID string
token string
err error
}{
{
desc: "delete thing with invalid token",
thingID: id,
token: wrongValue,
err: createError(sdk.ErrFailedRemoval, http.StatusUnauthorized),
},
{
desc: "delete non-existing thing",
thingID: "2",
token: token,
err: nil,
},
{
desc: "delete thing with invalid id",
thingID: "",
token: token,
err: createError(sdk.ErrFailedRemoval, http.StatusBadRequest),
},
{
desc: "delete thing with empty token",
thingID: id,
token: "",
err: createError(sdk.ErrFailedRemoval, http.StatusUnauthorized),
},
{
desc: "delete existing thing",
thingID: id,
token: token,
err: nil,
},
{
desc: "delete deleted thing",
thingID: id,
token: token,
err: nil,
},
}
for _, tc := range cases {
err := mainfluxSDK.DeleteThing(tc.thingID, tc.token)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err))
}
}
func TestConnectThing(t *testing.T) {
svc := newThingsService(map[string]string{
token: email,
otherToken: otherEmail,
})
ts := newThingsServer(svc)
defer ts.Close()
sdkConf := sdk.Config{
BaseURL: ts.URL,
UsersPrefix: "",
GroupsPrefix: "",
ThingsPrefix: "",
HTTPAdapterPrefix: "",
MsgContentType: contentType,
TLSVerification: false,
}
mainfluxSDK := sdk.NewSDK(sdkConf)
thingID, err := mainfluxSDK.CreateThing(thing, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
chanID1, err := mainfluxSDK.CreateChannel(channel, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
chanID2, err := mainfluxSDK.CreateChannel(channel, otherToken)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
cases := []struct {
desc string
thingID string
chanID string
token string
err error
}{
{
desc: "connect existing thing to existing channel",
thingID: thingID,
chanID: chanID1,
token: token,
err: nil,
},
{
desc: "connect existing thing to non-existing channel",
thingID: thingID,
chanID: "9",
token: token,
err: createError(sdk.ErrFailedConnect, http.StatusNotFound),
},
{
desc: "connect non-existing thing to existing channel",
thingID: "9",
chanID: chanID1,
token: token,
err: createError(sdk.ErrFailedConnect, http.StatusNotFound),
},
{
desc: "connect existing thing to channel with invalid ID",
thingID: thingID,
chanID: "",
token: token,
err: createError(sdk.ErrFailedConnect, http.StatusBadRequest),
},
{
desc: "connect thing with invalid ID to existing channel",
thingID: "",
chanID: chanID1,
token: token,
err: createError(sdk.ErrFailedConnect, http.StatusBadRequest),
},
{
desc: "connect existing thing to existing channel with invalid token",
thingID: thingID,
chanID: chanID1,
token: wrongValue,
err: createError(sdk.ErrFailedConnect, http.StatusUnauthorized),
},
{
desc: "connect existing thing to existing channel with empty token",
thingID: thingID,
chanID: chanID1,
token: "",
err: createError(sdk.ErrFailedConnect, http.StatusUnauthorized),
},
{
desc: "connect thing from owner to channel of other user",
thingID: thingID,
chanID: chanID2,
token: token,
err: createError(sdk.ErrFailedConnect, http.StatusNotFound),
},
}
for _, tc := range cases {
conIDs := sdk.ConnectionIDs{
ChannelIDs: []string{tc.chanID},
ThingIDs: []string{tc.thingID},
}
err := mainfluxSDK.Connect(conIDs, tc.token)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err))
}
}
func TestConnect(t *testing.T) {
svc := newThingsService(map[string]string{
token: email,
otherToken: otherEmail,
})
ts := newThingsServer(svc)
defer ts.Close()
sdkConf := sdk.Config{
BaseURL: ts.URL,
UsersPrefix: "",
GroupsPrefix: "",
ThingsPrefix: "",
HTTPAdapterPrefix: "",
MsgContentType: contentType,
TLSVerification: false,
}
mainfluxSDK := sdk.NewSDK(sdkConf)
thingID, err := mainfluxSDK.CreateThing(thing, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
chanID1, err := mainfluxSDK.CreateChannel(channel, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
chanID2, err := mainfluxSDK.CreateChannel(channel, otherToken)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
cases := []struct {
desc string
thingID string
chanID string
token string
err error
}{
{
desc: "connect existing things to existing channels",
thingID: thingID,
chanID: chanID1,
token: token,
err: nil,
},
{
desc: "connect existing things to non-existing channels",
thingID: thingID,
chanID: badID,
token: token,
err: createError(sdk.ErrFailedConnect, http.StatusNotFound),
},
{
desc: "connect non-existing things to existing channels",
thingID: badID,
chanID: chanID1,
token: token,
err: createError(sdk.ErrFailedConnect, http.StatusNotFound),
},
{
desc: "connect existing things to channels with invalid ID",
thingID: thingID,
chanID: emptyValue,
token: token,
err: createError(sdk.ErrFailedConnect, http.StatusBadRequest),
},
{
desc: "connect things with invalid ID to existing channels",
thingID: emptyValue,
chanID: chanID1,
token: token,
err: createError(sdk.ErrFailedConnect, http.StatusBadRequest),
},
{
desc: "connect existing things to existing channels with invalid token",
thingID: thingID,
chanID: chanID1,
token: wrongValue,
err: createError(sdk.ErrFailedConnect, http.StatusUnauthorized),
},
{
desc: "connect existing things to existing channels with empty token",
thingID: thingID,
chanID: chanID1,
token: emptyValue,
err: createError(sdk.ErrFailedConnect, http.StatusUnauthorized),
},
{
desc: "connect things from owner to channels of other user",
thingID: thingID,
chanID: chanID2,
token: token,
err: createError(sdk.ErrFailedConnect, http.StatusNotFound),
},
}
for _, tc := range cases {
connIDs := sdk.ConnectionIDs{
[]string{tc.thingID},
[]string{tc.chanID},
}
err := mainfluxSDK.Connect(connIDs, tc.token)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err))
}
}
func TestDisconnectThing(t *testing.T) {
svc := newThingsService(map[string]string{
token: email,
otherToken: otherEmail,
})
ts := newThingsServer(svc)
defer ts.Close()
sdkConf := sdk.Config{
BaseURL: ts.URL,
UsersPrefix: "",
GroupsPrefix: "",
ThingsPrefix: "",
HTTPAdapterPrefix: "",
MsgContentType: contentType,
TLSVerification: false,
}
mainfluxSDK := sdk.NewSDK(sdkConf)
thingID, err := mainfluxSDK.CreateThing(thing, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
chanID1, err := mainfluxSDK.CreateChannel(channel, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
conIDs := sdk.ConnectionIDs{
ChannelIDs: []string{chanID1},
ThingIDs: []string{thingID},
}
err = mainfluxSDK.Connect(conIDs, token)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
chanID2, err := mainfluxSDK.CreateChannel(channel, otherToken)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
cases := []struct {
desc string
thingID string
chanID string
token string
err error
}{
{
desc: "disconnect connected thing from channel",
thingID: thingID,
chanID: chanID1,
token: token,
err: nil,
},
{
desc: "disconnect existing thing from non-existing channel",
thingID: thingID,
chanID: "9",
token: token,
err: createError(sdk.ErrFailedDisconnect, http.StatusNotFound),
},
{
desc: "disconnect non-existing thing from existing channel",
thingID: "9",
chanID: chanID1,
token: token,
err: createError(sdk.ErrFailedDisconnect, http.StatusNotFound),
},
{
desc: "disconnect existing thing from channel with invalid ID",
thingID: thingID,
chanID: "",
token: token,
err: createError(sdk.ErrFailedDisconnect, http.StatusBadRequest),
},
{
desc: "disconnect thing with invalid ID from existing channel",
thingID: "",
chanID: chanID1,
token: token,
err: createError(sdk.ErrFailedDisconnect, http.StatusBadRequest),
},
{
desc: "disconnect existing thing from existing channel with invalid token",
thingID: thingID,
chanID: chanID1,
token: wrongValue,
err: createError(sdk.ErrFailedDisconnect, http.StatusUnauthorized),
},
{
desc: "disconnect existing thing from existing channel with empty token",
thingID: thingID,
chanID: chanID1,
token: "",
err: createError(sdk.ErrFailedDisconnect, http.StatusUnauthorized),
},
{
desc: "disconnect owner's thing from someone elses channel",
thingID: thingID,
chanID: chanID2,
token: token,
err: createError(sdk.ErrFailedDisconnect, http.StatusNotFound),
},
}
for _, tc := range cases {
err := mainfluxSDK.DisconnectThing(tc.thingID, tc.chanID, tc.token)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err))
}
}