1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-04-24 13:48:49 +08:00
Mainflux.mainflux/users/service_test.go
Arvindh cd82cc5a43
NOISSUE: Listing of shared things with users & Update SDK (#1923)
* NOISSUE - Fix Bugs (#20)

* fix bugs

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix bugs

Signed-off-by: Arvindh <arvindh91@gmail.com>

---------

Signed-off-by: Arvindh <arvindh91@gmail.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Add Connect Disconnect endpoints (#23)

* fix bugs

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix bugs

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix list of things in a channel and Add connect disconnect endpoint

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix list of things in a channel and Add connect disconnect endpoint

Signed-off-by: Arvindh <arvindh91@gmail.com>

---------

Signed-off-by: Arvindh <arvindh91@gmail.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Add: Things share with users (#25)

* fix list of things in a channel and Add connect disconnect endpoint

Signed-off-by: Arvindh <arvindh91@gmail.com>

* add: things share with other users

Signed-off-by: Arvindh <arvindh91@gmail.com>

---------

Signed-off-by: Arvindh <arvindh91@gmail.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Add: Listing of things, channels, groups, users  (#26)

* add: listing of channels, users, groups, things

Signed-off-by: Arvindh <arvindh91@gmail.com>

* add: listing of channels, users, groups, things

Signed-off-by: Arvindh <arvindh91@gmail.com>

* add: listing of channels, users, groups, things

Signed-off-by: Arvindh <arvindh91@gmail.com>

* add: listing of channels, users, groups, things

Signed-off-by: Arvindh <arvindh91@gmail.com>

---------

Signed-off-by: Arvindh <arvindh91@gmail.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Add: List of user groups & removed repeating code in groups (#29)

* removed repeating code in list groups

Signed-off-by: Arvindh <arvindh91@gmail.com>

* add: list of user group

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix: otel handler operator name for endpoints

Signed-off-by: Arvindh <arvindh91@gmail.com>

---------

Signed-off-by: Arvindh <arvindh91@gmail.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* add: listing of shared things and users

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix: listing of shared things and users

Signed-off-by: Arvindh <arvindh91@gmail.com>

* add: new SDK

Signed-off-by: Arvindh <arvindh91@gmail.com>

* add: new SDK

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix: comment

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix: sdk function names

Signed-off-by: Arvindh <arvindh91@gmail.com>

* update: api spec

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix: channels connect request

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix: listing of clients and groups

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix: CLI

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix: array len comparision

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix: nginx

Signed-off-by: Arvindh <arvindh91@gmail.com>

---------

Signed-off-by: Arvindh <arvindh91@gmail.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Co-authored-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
2023-10-17 15:38:06 +02:00

1451 lines
44 KiB
Go

// Copyright (c) Mainflux
// SPDX-License-Identifier: Apache-2.0
package users_test
import (
"context"
"fmt"
"regexp"
"testing"
"time"
"github.com/mainflux/mainflux"
authmocks "github.com/mainflux/mainflux/auth/mocks"
"github.com/mainflux/mainflux/internal/apiutil"
"github.com/mainflux/mainflux/internal/testsutil"
mfclients "github.com/mainflux/mainflux/pkg/clients"
"github.com/mainflux/mainflux/pkg/errors"
"github.com/mainflux/mainflux/pkg/uuid"
"github.com/mainflux/mainflux/users"
"github.com/mainflux/mainflux/users/hasher"
"github.com/mainflux/mainflux/users/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
var (
idProvider = uuid.New()
phasher = hasher.New()
secret = "strongsecret"
validCMetadata = mfclients.Metadata{"role": "client"}
client = mfclients.Client{
ID: testsutil.GenerateUUID(&testing.T{}, idProvider),
Name: "clientname",
Tags: []string{"tag1", "tag2"},
Credentials: mfclients.Credentials{Identity: "clientidentity", Secret: secret},
Metadata: validCMetadata,
Status: mfclients.EnabledStatus,
}
withinDuration = 5 * time.Second
passRegex = regexp.MustCompile("^.{8,}$")
myKey = "mine"
validToken = "token"
inValidToken = "invalidToken"
validID = "d4ebb847-5d0e-4e46-bdd9-b6aceaaa3a22"
)
func TestRegisterClient(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
cases := []struct {
desc string
client mfclients.Client
token string
err error
}{
{
desc: "register new client",
client: client,
token: validToken,
err: nil,
},
{
desc: "register existing client",
client: client,
token: validToken,
err: errors.ErrConflict,
},
{
desc: "register a new enabled client with name",
client: mfclients.Client{
Name: "clientWithName",
Credentials: mfclients.Credentials{
Identity: "newclientwithname@example.com",
Secret: secret,
},
Status: mfclients.EnabledStatus,
},
err: nil,
token: validToken,
},
{
desc: "register a new disabled client with name",
client: mfclients.Client{
Name: "clientWithName",
Credentials: mfclients.Credentials{
Identity: "newclientwithname@example.com",
Secret: secret,
},
},
err: nil,
token: validToken,
},
{
desc: "register a new enabled client with tags",
client: mfclients.Client{
Tags: []string{"tag1", "tag2"},
Credentials: mfclients.Credentials{
Identity: "newclientwithtags@example.com",
Secret: secret,
},
Status: mfclients.EnabledStatus,
},
err: nil,
token: validToken,
},
{
desc: "register a new disabled client with tags",
client: mfclients.Client{
Tags: []string{"tag1", "tag2"},
Credentials: mfclients.Credentials{
Identity: "newclientwithtags@example.com",
Secret: secret,
},
Status: mfclients.DisabledStatus,
},
err: nil,
token: validToken,
},
{
desc: "register a new enabled client with metadata",
client: mfclients.Client{
Credentials: mfclients.Credentials{
Identity: "newclientwithmetadata@example.com",
Secret: secret,
},
Metadata: validCMetadata,
Status: mfclients.EnabledStatus,
},
err: nil,
token: validToken,
},
{
desc: "register a new disabled client with metadata",
client: mfclients.Client{
Credentials: mfclients.Credentials{
Identity: "newclientwithmetadata@example.com",
Secret: secret,
},
Metadata: validCMetadata,
},
err: nil,
token: validToken,
},
{
desc: "register a new disabled client",
client: mfclients.Client{
Credentials: mfclients.Credentials{
Identity: "newclientwithvalidstatus@example.com",
Secret: secret,
},
},
err: nil,
token: validToken,
},
{
desc: "register a new client with valid disabled status",
client: mfclients.Client{
Credentials: mfclients.Credentials{
Identity: "newclientwithvalidstatus@example.com",
Secret: secret,
},
Status: mfclients.DisabledStatus,
},
err: nil,
token: validToken,
},
{
desc: "register a new client with all fields",
client: mfclients.Client{
Name: "newclientwithallfields",
Tags: []string{"tag1", "tag2"},
Credentials: mfclients.Credentials{
Identity: "newclientwithallfields@example.com",
Secret: secret,
},
Metadata: mfclients.Metadata{
"name": "newclientwithallfields",
},
Status: mfclients.EnabledStatus,
},
err: nil,
token: validToken,
},
{
desc: "register a new client with missing identity",
client: mfclients.Client{
Name: "clientWithMissingIdentity",
Credentials: mfclients.Credentials{
Secret: secret,
},
},
err: errors.ErrMalformedEntity,
token: validToken,
},
{
desc: "register a new client with invalid owner",
client: mfclients.Client{
Owner: mocks.WrongID,
Credentials: mfclients.Credentials{
Identity: "newclientwithinvalidowner@example.com",
Secret: secret,
},
},
err: errors.ErrMalformedEntity,
token: validToken,
},
{
desc: "register a new client with empty secret",
client: mfclients.Client{
Owner: testsutil.GenerateUUID(t, idProvider),
Credentials: mfclients.Credentials{
Identity: "newclientwithemptysecret@example.com",
},
},
err: apiutil.ErrMissingSecret,
token: validToken,
},
{
desc: "register a new client with invalid status",
client: mfclients.Client{
Credentials: mfclients.Credentials{
Identity: "newclientwithinvalidstatus@example.com",
Secret: secret,
},
Status: mfclients.AllStatus,
},
err: apiutil.ErrInvalidStatus,
token: validToken,
},
}
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: validID}, nil)
if tc.token == inValidToken {
repoCall = auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: inValidToken}).Return(&mainflux.IdentityRes{}, errors.ErrAuthentication)
}
repoCall1 := cRepo.On("Save", context.Background(), mock.Anything).Return(&mfclients.Client{}, tc.err)
registerTime := time.Now()
expected, err := svc.RegisterClient(context.Background(), tc.token, tc.client)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
if err == nil {
assert.NotEmpty(t, expected.ID, fmt.Sprintf("%s: expected %s not to be empty\n", tc.desc, expected.ID))
assert.WithinDuration(t, expected.CreatedAt, registerTime, withinDuration, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, expected.CreatedAt, registerTime))
tc.client.ID = expected.ID
tc.client.CreatedAt = expected.CreatedAt
tc.client.UpdatedAt = expected.UpdatedAt
tc.client.Credentials.Secret = expected.Credentials.Secret
tc.client.Owner = expected.Owner
tc.client.UpdatedBy = expected.UpdatedBy
assert.Equal(t, tc.client, expected, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.client, expected))
ok := repoCall1.Parent.AssertCalled(t, "Save", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("Save was not called on %s", tc.desc))
}
repoCall1.Unset()
repoCall.Unset()
}
}
func TestViewClient(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
cases := []struct {
desc string
token string
clientID string
response mfclients.Client
err error
}{
{
desc: "view client successfully",
response: client,
token: validToken,
clientID: client.ID,
err: nil,
},
{
desc: "view client with an invalid token",
response: mfclients.Client{},
token: inValidToken,
clientID: client.ID,
err: errors.ErrAuthentication,
},
{
desc: "view client with valid token and invalid client id",
response: mfclients.Client{},
token: validToken,
clientID: mocks.WrongID,
err: errors.ErrNotFound,
},
{
desc: "view client with an invalid token and invalid client id",
response: mfclients.Client{},
token: inValidToken,
clientID: mocks.WrongID,
err: errors.ErrAuthentication,
},
}
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: validID}, nil)
repoCall1 := cRepo.On("IsOwner", context.Background(), tc.clientID, validID).Return(nil)
if tc.token == inValidToken {
repoCall = auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: inValidToken}).Return(&mainflux.IdentityRes{}, errors.ErrAuthentication)
repoCall1 = cRepo.On("IsOwner", context.Background(), tc.clientID, validID).Return(errors.ErrAuthentication)
}
repoCall2 := cRepo.On("RetrieveByID", context.Background(), tc.clientID).Return(tc.response, tc.err)
rClient, err := svc.ViewClient(context.Background(), tc.token, tc.clientID)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
tc.response.Credentials.Secret = ""
assert.Equal(t, tc.response, rClient, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.response, rClient))
if tc.err == nil {
ok := repoCall2.Parent.AssertCalled(t, "RetrieveByID", context.Background(), tc.clientID)
assert.True(t, ok, fmt.Sprintf("RetrieveByID was not called on %s", tc.desc))
}
repoCall2.Unset()
repoCall1.Unset()
repoCall.Unset()
}
}
func TestListClients(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
nClients := uint64(200)
aClients := []mfclients.Client{}
OwnerID := testsutil.GenerateUUID(t, idProvider)
for i := uint64(1); i < nClients; i++ {
identity := fmt.Sprintf("TestListClients_%d@example.com", i)
client := mfclients.Client{
Name: identity,
Credentials: mfclients.Credentials{
Identity: identity,
Secret: "password",
},
Tags: []string{"tag1", "tag2"},
Metadata: mfclients.Metadata{"role": "client"},
}
if i%50 == 0 {
client.Owner = OwnerID
client.Owner = testsutil.GenerateUUID(t, idProvider)
}
aClients = append(aClients, client)
}
cases := []struct {
desc string
token string
page mfclients.Page
response mfclients.ClientsPage
size uint64
err error
}{
{
desc: "list clients with authorized token",
token: validToken,
page: mfclients.Page{
Status: mfclients.AllStatus,
},
size: 0,
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 0,
Offset: 0,
Limit: 0,
},
Clients: []mfclients.Client{},
},
err: nil,
},
{
desc: "list clients with an invalid token",
token: inValidToken,
page: mfclients.Page{
Status: mfclients.AllStatus,
},
size: 0,
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 0,
Offset: 0,
Limit: 0,
},
},
err: errors.ErrAuthentication,
},
{
desc: "list clients that are shared with me",
token: validToken,
page: mfclients.Page{
Offset: 6,
Limit: nClients,
Status: mfclients.EnabledStatus,
},
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 4,
Offset: 0,
Limit: 0,
},
Clients: []mfclients.Client{aClients[0], aClients[50], aClients[100], aClients[150]},
},
size: 4,
},
{
desc: "list clients that are shared with me with a specific name",
token: validToken,
page: mfclients.Page{
Offset: 6,
Limit: nClients,
Name: "TestListClients3",
Status: mfclients.EnabledStatus,
},
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 4,
Offset: 0,
Limit: 0,
},
Clients: []mfclients.Client{aClients[0], aClients[50], aClients[100], aClients[150]},
},
size: 4,
},
{
desc: "list clients that are shared with me with an invalid name",
token: validToken,
page: mfclients.Page{
Offset: 6,
Limit: nClients,
Name: "notpresentclient",
Status: mfclients.EnabledStatus,
},
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 0,
Offset: 0,
Limit: 0,
},
Clients: []mfclients.Client{},
},
size: 0,
},
{
desc: "list clients that I own",
token: validToken,
page: mfclients.Page{
Offset: 6,
Limit: nClients,
Owner: myKey,
Status: mfclients.EnabledStatus,
},
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 4,
Offset: 0,
Limit: 0,
},
Clients: []mfclients.Client{aClients[0], aClients[50], aClients[100], aClients[150]},
},
size: 4,
},
{
desc: "list clients that I own with a specific name",
token: validToken,
page: mfclients.Page{
Offset: 6,
Limit: nClients,
Owner: myKey,
Name: "TestListClients3",
Status: mfclients.AllStatus,
},
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 4,
Offset: 0,
Limit: 0,
},
Clients: []mfclients.Client{aClients[0], aClients[50], aClients[100], aClients[150]},
},
size: 4,
},
{
desc: "list clients that I own with an invalid name",
token: validToken,
page: mfclients.Page{
Offset: 6,
Limit: nClients,
Owner: myKey,
Name: "notpresentclient",
Status: mfclients.AllStatus,
},
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 0,
Offset: 0,
Limit: 0,
},
Clients: []mfclients.Client{},
},
size: 0,
},
{
desc: "list clients that I own and are shared with me",
token: validToken,
page: mfclients.Page{
Offset: 6,
Limit: nClients,
Owner: myKey,
Status: mfclients.AllStatus,
},
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 4,
Offset: 0,
Limit: 0,
},
Clients: []mfclients.Client{aClients[0], aClients[50], aClients[100], aClients[150]},
},
size: 4,
},
{
desc: "list clients that I own and are shared with me with a specific name",
token: validToken,
page: mfclients.Page{
Offset: 6,
Limit: nClients,
Owner: myKey,
Name: "TestListClients3",
Status: mfclients.AllStatus,
},
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 4,
Offset: 0,
Limit: 0,
},
Clients: []mfclients.Client{aClients[0], aClients[50], aClients[100], aClients[150]},
},
size: 4,
},
{
desc: "list clients that I own and are shared with me with an invalid name",
token: validToken,
page: mfclients.Page{
Offset: 6,
Limit: nClients,
Owner: myKey,
Name: "notpresentclient",
Status: mfclients.AllStatus,
},
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 0,
Offset: 0,
Limit: 0,
},
Clients: []mfclients.Client{},
},
size: 0,
},
{
desc: "list clients with offset and limit",
token: validToken,
page: mfclients.Page{
Offset: 6,
Limit: nClients,
Status: mfclients.AllStatus,
},
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: nClients - 6,
Offset: 0,
Limit: 0,
},
Clients: aClients[6:nClients],
},
size: nClients - 6,
},
}
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: validID}, nil)
if tc.token == inValidToken {
repoCall = auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: inValidToken}).Return(&mainflux.IdentityRes{}, errors.ErrAuthentication)
}
repoCall1 := cRepo.On("RetrieveAll", context.Background(), mock.Anything).Return(tc.response, tc.err)
page, err := svc.ListClients(context.Background(), tc.token, tc.page)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
assert.Equal(t, tc.response, page, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.response, page))
if tc.err == nil {
ok := repoCall1.Parent.AssertCalled(t, "RetrieveAll", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("RetrieveAll was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
}
}
func TestUpdateClient(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
client1 := client
client2 := client
client1.Name = "Updated client"
client2.Metadata = mfclients.Metadata{"role": "test"}
cases := []struct {
desc string
client mfclients.Client
response mfclients.Client
token string
err error
}{
{
desc: "update client name with valid token",
client: client1,
response: client1,
token: validToken,
err: nil,
},
{
desc: "update client name with invalid token",
client: client1,
response: mfclients.Client{},
token: inValidToken,
err: errors.ErrAuthentication,
},
{
desc: "update client name with invalid ID",
client: mfclients.Client{
ID: mocks.WrongID,
Name: "Updated Client",
},
response: mfclients.Client{},
token: inValidToken,
err: errors.ErrAuthentication,
},
{
desc: "update client metadata with valid token",
client: client2,
response: client2,
token: validToken,
err: nil,
},
{
desc: "update client metadata with invalid token",
client: client2,
response: mfclients.Client{},
token: inValidToken,
err: errors.ErrAuthentication,
},
}
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: validID}, nil)
repoCall1 := cRepo.On("IsOwner", context.Background(), tc.client.ID, validID).Return(nil)
if tc.token == inValidToken {
repoCall = auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: inValidToken}).Return(&mainflux.IdentityRes{}, errors.ErrAuthentication)
repoCall1 = cRepo.On("IsOwner", context.Background(), tc.client.ID, validID).Return(errors.ErrAuthentication)
}
repoCall2 := cRepo.On("Update", context.Background(), mock.Anything).Return(tc.response, tc.err)
updatedClient, err := svc.UpdateClient(context.Background(), tc.token, tc.client)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
assert.Equal(t, tc.response, updatedClient, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.response, updatedClient))
if tc.err == nil {
ok := repoCall2.Parent.AssertCalled(t, "Update", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("Update was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
}
}
func TestUpdateClientTags(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
client.Tags = []string{"updated"}
cases := []struct {
desc string
client mfclients.Client
response mfclients.Client
token string
err error
}{
{
desc: "update client tags with valid token",
client: client,
token: validToken,
response: client,
err: nil,
},
{
desc: "update client tags with invalid token",
client: client,
token: inValidToken,
response: mfclients.Client{},
err: errors.ErrAuthentication,
},
{
desc: "update client name with invalid ID",
client: mfclients.Client{
ID: mocks.WrongID,
Name: "Updated name",
},
response: mfclients.Client{},
token: inValidToken,
err: errors.ErrAuthentication,
},
}
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: validID}, nil)
repoCall1 := cRepo.On("IsOwner", context.Background(), tc.client.ID, validID).Return(nil)
if tc.token == inValidToken {
repoCall = auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: inValidToken}).Return(&mainflux.IdentityRes{}, errors.ErrAuthentication)
repoCall1 = cRepo.On("IsOwner", context.Background(), tc.client.ID, validID).Return(errors.ErrAuthentication)
}
repoCall2 := cRepo.On("UpdateTags", context.Background(), mock.Anything).Return(tc.response, tc.err)
updatedClient, err := svc.UpdateClientTags(context.Background(), tc.token, tc.client)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
assert.Equal(t, tc.response, updatedClient, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.response, updatedClient))
if tc.err == nil {
ok := repoCall2.Parent.AssertCalled(t, "UpdateTags", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("UpdateTags was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
}
}
func TestUpdateClientIdentity(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
client2 := client
client2.Credentials.Identity = "updated@example.com"
cases := []struct {
desc string
identity string
response mfclients.Client
token string
id string
err error
}{
{
desc: "update client identity with valid token",
identity: "updated@example.com",
token: validToken,
id: client.ID,
response: client2,
err: nil,
},
{
desc: "update client identity with invalid id",
identity: "updated@example.com",
token: validToken,
id: mocks.WrongID,
response: mfclients.Client{},
err: errors.ErrNotFound,
},
{
desc: "update client identity with invalid token",
identity: "updated@example.com",
token: inValidToken,
id: client2.ID,
response: mfclients.Client{},
err: errors.ErrAuthentication,
},
}
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: validID}, nil)
repoCall1 := cRepo.On("IsOwner", context.Background(), tc.id, validID).Return(nil)
if tc.token == inValidToken {
repoCall = auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: inValidToken}).Return(&mainflux.IdentityRes{}, errors.ErrAuthentication)
repoCall1 = cRepo.On("IsOwner", context.Background(), tc.id, validID).Return(errors.ErrAuthentication)
}
repoCall2 := cRepo.On("UpdateIdentity", context.Background(), mock.Anything).Return(tc.response, tc.err)
updatedClient, err := svc.UpdateClientIdentity(context.Background(), tc.token, tc.id, tc.identity)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
assert.Equal(t, tc.response, updatedClient, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.response, updatedClient))
if tc.err == nil {
ok := repoCall2.Parent.AssertCalled(t, "UpdateIdentity", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("UpdateIdentity was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
}
}
func TestUpdateClientOwner(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
client.Owner = "newowner@mail.com"
cases := []struct {
desc string
client mfclients.Client
response mfclients.Client
token string
err error
}{
{
desc: "update client owner with valid token",
client: client,
token: validToken,
response: client,
err: nil,
},
{
desc: "update client owner with invalid token",
client: client,
token: inValidToken,
response: mfclients.Client{},
err: errors.ErrAuthentication,
},
{
desc: "update client owner with invalid ID",
client: mfclients.Client{
ID: mocks.WrongID,
Owner: "updatedowner@mail.com",
},
response: mfclients.Client{},
token: inValidToken,
err: errors.ErrAuthentication,
},
}
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: validID}, nil)
repoCall1 := cRepo.On("IsOwner", context.Background(), tc.client.ID, validID).Return(nil)
if tc.token == inValidToken {
repoCall = auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: inValidToken}).Return(&mainflux.IdentityRes{}, errors.ErrAuthentication)
repoCall1 = cRepo.On("IsOwner", context.Background(), tc.client.ID, validID).Return(errors.ErrAuthentication)
}
repoCall2 := cRepo.On("UpdateOwner", context.Background(), mock.Anything).Return(tc.response, tc.err)
updatedClient, err := svc.UpdateClientOwner(context.Background(), tc.token, tc.client)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
assert.Equal(t, tc.response, updatedClient, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.response, updatedClient))
if tc.err == nil {
ok := repoCall2.Parent.AssertCalled(t, "UpdateOwner", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("UpdateOwner was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
}
}
func TestUpdateClientSecret(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
rClient := client
rClient.Credentials.Secret, _ = phasher.Hash(client.Credentials.Secret)
cases := []struct {
desc string
oldSecret string
newSecret string
token string
response mfclients.Client
err error
}{
{
desc: "update client secret with valid token",
oldSecret: client.Credentials.Secret,
newSecret: "newSecret",
token: validToken,
response: rClient,
err: nil,
},
{
desc: "update client secret with invalid token",
oldSecret: client.Credentials.Secret,
newSecret: "newPassword",
token: inValidToken,
response: mfclients.Client{},
err: errors.ErrAuthentication,
},
{
desc: "update client secret with wrong old secret",
oldSecret: "oldSecret",
newSecret: "newSecret",
token: validToken,
response: mfclients.Client{},
err: apiutil.ErrInvalidSecret,
},
}
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: client.ID}, nil)
if tc.token == inValidToken {
repoCall = auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: inValidToken}).Return(&mainflux.IdentityRes{}, errors.ErrAuthentication)
}
repoCall1 := cRepo.On("RetrieveByID", context.Background(), client.ID).Return(tc.response, tc.err)
repoCall2 := cRepo.On("RetrieveByIdentity", context.Background(), client.Credentials.Identity).Return(tc.response, tc.err)
repoCall3 := cRepo.On("UpdateSecret", context.Background(), mock.Anything).Return(tc.response, tc.err)
repoCall4 := auth.On("Issue", mock.Anything, mock.Anything).Return(&mainflux.Token{}, nil)
updatedClient, err := svc.UpdateClientSecret(context.Background(), tc.token, tc.oldSecret, tc.newSecret)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
assert.Equal(t, tc.response, updatedClient, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.response, updatedClient))
if tc.err == nil {
ok := repoCall1.Parent.AssertCalled(t, "RetrieveByID", context.Background(), tc.response.ID)
assert.True(t, ok, fmt.Sprintf("RetrieveByID was not called on %s", tc.desc))
ok = repoCall2.Parent.AssertCalled(t, "RetrieveByIdentity", context.Background(), tc.response.Credentials.Identity)
assert.True(t, ok, fmt.Sprintf("RetrieveByIdentity was not called on %s", tc.desc))
ok = repoCall3.Parent.AssertCalled(t, "UpdateSecret", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("UpdateSecret was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
repoCall4.Unset()
}
}
func TestEnableClient(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
enabledClient1 := mfclients.Client{ID: testsutil.GenerateUUID(t, idProvider), Credentials: mfclients.Credentials{Identity: "client1@example.com", Secret: "password"}, Status: mfclients.EnabledStatus}
disabledClient1 := mfclients.Client{ID: testsutil.GenerateUUID(t, idProvider), Credentials: mfclients.Credentials{Identity: "client3@example.com", Secret: "password"}, Status: mfclients.DisabledStatus}
endisabledClient1 := disabledClient1
endisabledClient1.Status = mfclients.EnabledStatus
cases := []struct {
desc string
id string
token string
client mfclients.Client
response mfclients.Client
err error
}{
{
desc: "enable disabled client",
id: disabledClient1.ID,
token: validToken,
client: disabledClient1,
response: endisabledClient1,
err: nil,
},
{
desc: "enable enabled client",
id: enabledClient1.ID,
token: validToken,
client: enabledClient1,
response: enabledClient1,
err: mfclients.ErrStatusAlreadyAssigned,
},
{
desc: "enable non-existing client",
id: mocks.WrongID,
token: validToken,
client: mfclients.Client{},
response: mfclients.Client{},
err: errors.ErrNotFound,
},
}
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: validID}, nil)
repoCall1 := cRepo.On("IsOwner", context.Background(), tc.id, validID).Return(nil)
repoCall2 := cRepo.On("RetrieveByID", context.Background(), tc.id).Return(tc.client, tc.err)
repoCall3 := cRepo.On("ChangeStatus", context.Background(), mock.Anything).Return(tc.response, tc.err)
_, err := svc.EnableClient(context.Background(), tc.token, tc.id)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
if tc.err == nil {
ok := repoCall2.Parent.AssertCalled(t, "RetrieveByID", context.Background(), tc.id)
assert.True(t, ok, fmt.Sprintf("RetrieveByID was not called on %s", tc.desc))
ok = repoCall3.Parent.AssertCalled(t, "ChangeStatus", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("ChangeStatus was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
}
cases2 := []struct {
desc string
status mfclients.Status
size uint64
response mfclients.ClientsPage
}{
{
desc: "list enabled clients",
status: mfclients.EnabledStatus,
size: 2,
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 2,
Offset: 0,
Limit: 100,
},
Clients: []mfclients.Client{enabledClient1, endisabledClient1},
},
},
{
desc: "list disabled clients",
status: mfclients.DisabledStatus,
size: 1,
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 1,
Offset: 0,
Limit: 100,
},
Clients: []mfclients.Client{disabledClient1},
},
},
{
desc: "list enabled and disabled clients",
status: mfclients.AllStatus,
size: 3,
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 3,
Offset: 0,
Limit: 100,
},
Clients: []mfclients.Client{enabledClient1, disabledClient1, endisabledClient1},
},
},
}
for _, tc := range cases2 {
pm := mfclients.Page{
Offset: 0,
Limit: 100,
Status: tc.status,
}
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: client.ID}, nil)
repoCall1 := cRepo.On("RetrieveAll", context.Background(), mock.Anything).Return(tc.response, nil)
page, err := svc.ListClients(context.Background(), validToken, pm)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
size := uint64(len(page.Clients))
assert.Equal(t, tc.size, size, fmt.Sprintf("%s: expected size %d got %d\n", tc.desc, tc.size, size))
repoCall.Unset()
repoCall1.Unset()
}
}
func TestDisableClient(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
enabledClient1 := mfclients.Client{ID: testsutil.GenerateUUID(t, idProvider), Credentials: mfclients.Credentials{Identity: "client1@example.com", Secret: "password"}, Status: mfclients.EnabledStatus}
disabledClient1 := mfclients.Client{ID: testsutil.GenerateUUID(t, idProvider), Credentials: mfclients.Credentials{Identity: "client3@example.com", Secret: "password"}, Status: mfclients.DisabledStatus}
disenabledClient1 := enabledClient1
disenabledClient1.Status = mfclients.DisabledStatus
cases := []struct {
desc string
id string
token string
client mfclients.Client
response mfclients.Client
err error
}{
{
desc: "disable enabled client",
id: enabledClient1.ID,
token: validToken,
client: enabledClient1,
response: disenabledClient1,
err: nil,
},
{
desc: "disable disabled client",
id: disabledClient1.ID,
token: validToken,
client: disabledClient1,
response: mfclients.Client{},
err: mfclients.ErrStatusAlreadyAssigned,
},
{
desc: "disable non-existing client",
id: mocks.WrongID,
client: mfclients.Client{},
token: validToken,
response: mfclients.Client{},
err: errors.ErrNotFound,
},
}
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: validID}, nil)
repoCall1 := cRepo.On("IsOwner", context.Background(), tc.id, validID).Return(nil)
repoCall2 := cRepo.On("RetrieveByID", context.Background(), tc.id).Return(tc.client, tc.err)
repoCall3 := cRepo.On("ChangeStatus", context.Background(), mock.Anything).Return(tc.response, tc.err)
_, err := svc.DisableClient(context.Background(), tc.token, tc.id)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
if tc.err == nil {
ok := repoCall2.Parent.AssertCalled(t, "RetrieveByID", context.Background(), tc.id)
assert.True(t, ok, fmt.Sprintf("RetrieveByID was not called on %s", tc.desc))
ok = repoCall3.Parent.AssertCalled(t, "ChangeStatus", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("ChangeStatus was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
}
cases2 := []struct {
desc string
status mfclients.Status
size uint64
response mfclients.ClientsPage
}{
{
desc: "list enabled clients",
status: mfclients.EnabledStatus,
size: 1,
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 1,
Offset: 0,
Limit: 100,
},
Clients: []mfclients.Client{enabledClient1},
},
},
{
desc: "list disabled clients",
status: mfclients.DisabledStatus,
size: 2,
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 2,
Offset: 0,
Limit: 100,
},
Clients: []mfclients.Client{disenabledClient1, disabledClient1},
},
},
{
desc: "list enabled and disabled clients",
status: mfclients.AllStatus,
size: 3,
response: mfclients.ClientsPage{
Page: mfclients.Page{
Total: 3,
Offset: 0,
Limit: 100,
},
Clients: []mfclients.Client{enabledClient1, disabledClient1, disenabledClient1},
},
},
}
for _, tc := range cases2 {
pm := mfclients.Page{
Offset: 0,
Limit: 100,
Status: tc.status,
}
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: client.ID}, nil)
repoCall1 := cRepo.On("RetrieveAll", context.Background(), mock.Anything).Return(tc.response, nil)
page, err := svc.ListClients(context.Background(), validToken, pm)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
size := uint64(len(page.Clients))
assert.Equal(t, tc.size, size, fmt.Sprintf("%s: expected size %d got %d\n", tc.desc, tc.size, size))
repoCall.Unset()
repoCall1.Unset()
}
}
func TestListMembers(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
nClients := uint64(10)
aClients := []mfclients.Client{}
owner := testsutil.GenerateUUID(t, idProvider)
for i := uint64(0); i < nClients; i++ {
identity := fmt.Sprintf("member_%d@example.com", i)
client := mfclients.Client{
ID: testsutil.GenerateUUID(t, idProvider),
Name: identity,
Credentials: mfclients.Credentials{
Identity: identity,
Secret: "password",
},
Tags: []string{"tag1", "tag2"},
Metadata: mfclients.Metadata{"role": "client"},
}
if i%3 == 0 {
client.Owner = owner
}
aClients = append(aClients, client)
}
cases := []struct {
desc string
token string
groupID string
page mfclients.Page
response mfclients.MembersPage
err error
}{
{
desc: "list clients with authorized token",
token: validToken,
groupID: testsutil.GenerateUUID(t, idProvider),
page: mfclients.Page{},
response: mfclients.MembersPage{
Page: mfclients.Page{
Total: 0,
Offset: 0,
Limit: 0,
},
Members: []mfclients.Client{},
},
err: nil,
},
{
desc: "list clients with offset and limit",
token: validToken,
groupID: testsutil.GenerateUUID(t, idProvider),
page: mfclients.Page{
Offset: 6,
Limit: nClients,
Status: mfclients.AllStatus,
},
response: mfclients.MembersPage{
Page: mfclients.Page{
Total: nClients - 6 - 1,
},
Members: aClients[6 : nClients-1],
},
},
{
desc: "list clients with an invalid token",
token: inValidToken,
groupID: testsutil.GenerateUUID(t, idProvider),
page: mfclients.Page{},
response: mfclients.MembersPage{
Page: mfclients.Page{
Total: 0,
Offset: 0,
Limit: 0,
},
},
err: errors.ErrAuthentication,
},
{
desc: "list clients with an invalid id",
token: validToken,
groupID: mocks.WrongID,
page: mfclients.Page{},
response: mfclients.MembersPage{
Page: mfclients.Page{
Total: 0,
Offset: 0,
Limit: 0,
},
},
err: errors.ErrNotFound,
},
{
desc: "list clients for an owner",
token: validToken,
groupID: testsutil.GenerateUUID(t, idProvider),
page: mfclients.Page{},
response: mfclients.MembersPage{
Page: mfclients.Page{
Total: 4,
},
Members: []mfclients.Client{aClients[0], aClients[3], aClients[6], aClients[9]},
},
err: nil,
},
}
for _, tc := range cases {
repoCall := auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: validToken}).Return(&mainflux.IdentityRes{Id: validID}, nil)
if tc.token == inValidToken {
repoCall = auth.On("Identify", mock.Anything, &mainflux.IdentityReq{Token: inValidToken}).Return(&mainflux.IdentityRes{}, errors.ErrAuthentication)
}
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&mainflux.AuthorizeRes{Authorized: true}, nil)
repoCall2 := auth.On("ListAllSubjects", mock.Anything, mock.Anything).Return(&mainflux.ListSubjectsRes{}, nil)
repoCall3 := cRepo.On("RetrieveAll", context.Background(), tc.page).Return(mfclients.ClientsPage{Page: tc.response.Page, Clients: tc.response.Members}, tc.err)
page, err := svc.ListMembers(context.Background(), tc.token, "groups", tc.groupID, tc.page)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
assert.Equal(t, tc.response, page, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.response, page))
if tc.err == nil {
ok := repoCall3.Parent.AssertCalled(t, "RetrieveAll", context.Background(), tc.page)
assert.True(t, ok, fmt.Sprintf("RetrieveAll was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
repoCall2.Unset()
repoCall3.Unset()
}
}
func TestIssueToken(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
rClient := client
rClient2 := client
rClient3 := client
rClient.Credentials.Secret, _ = phasher.Hash(client.Credentials.Secret)
rClient2.Credentials.Secret = "wrongsecret"
rClient3.Credentials.Secret, _ = phasher.Hash("wrongsecret")
cases := []struct {
desc string
client mfclients.Client
rClient mfclients.Client
err error
}{
{
desc: "issue token for an existing client",
client: client,
rClient: rClient,
err: nil,
},
{
desc: "issue token for a non-existing client",
client: client,
rClient: mfclients.Client{},
err: errors.ErrAuthentication,
},
{
desc: "issue token for a client with wrong secret",
client: rClient2,
rClient: rClient3,
err: errors.ErrAuthentication,
},
}
for _, tc := range cases {
repoCall := auth.On("Issue", mock.Anything, mock.Anything).Return(&mainflux.Token{AccessToken: validToken, RefreshToken: &validToken, AccessType: "3"}, tc.err)
repoCall1 := cRepo.On("RetrieveByIdentity", context.Background(), tc.client.Credentials.Identity).Return(tc.rClient, tc.err)
token, err := svc.IssueToken(context.Background(), tc.client.Credentials.Identity, tc.client.Credentials.Secret)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
if err == nil {
assert.NotEmpty(t, token.GetAccessToken(), fmt.Sprintf("%s: expected %s not to be empty\n", tc.desc, token.GetAccessToken()))
assert.NotEmpty(t, token.GetRefreshToken(), fmt.Sprintf("%s: expected %s not to be empty\n", tc.desc, token.GetRefreshToken()))
ok := repoCall1.Parent.AssertCalled(t, "RetrieveByIdentity", context.Background(), tc.client.Credentials.Identity)
assert.True(t, ok, fmt.Sprintf("RetrieveByIdentity was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
}
}
func TestRefreshToken(t *testing.T) {
cRepo := new(mocks.Repository)
auth := new(authmocks.Service)
e := mocks.NewEmailer()
svc := users.NewService(cRepo, auth, e, phasher, idProvider, passRegex)
rClient := client
rClient.Credentials.Secret, _ = phasher.Hash(client.Credentials.Secret)
cases := []struct {
desc string
token string
client mfclients.Client
err error
}{
{
desc: "refresh token with refresh token for an existing client",
token: validToken,
client: client,
err: nil,
},
{
desc: "refresh token with refresh token for a non-existing client",
token: validToken,
client: mfclients.Client{},
err: errors.ErrAuthentication,
},
{
desc: "refresh token with access token for an existing client",
token: validToken,
client: client,
err: errors.ErrAuthentication,
},
{
desc: "refresh token with access token for a non-existing client",
token: validToken,
client: mfclients.Client{},
err: errors.ErrAuthentication,
},
{
desc: "refresh token with invalid token for an existing client",
token: inValidToken,
client: client,
err: errors.ErrAuthentication,
},
}
for _, tc := range cases {
repoCall := auth.On("Refresh", mock.Anything, mock.Anything).Return(&mainflux.Token{AccessToken: validToken, RefreshToken: &validToken, AccessType: "3"}, tc.err)
token, err := svc.RefreshToken(context.Background(), tc.token)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
if err == nil {
assert.NotEmpty(t, token.GetAccessToken(), fmt.Sprintf("%s: expected %s not to be empty\n", tc.desc, token.GetAccessToken()))
assert.NotEmpty(t, token.GetRefreshToken(), fmt.Sprintf("%s: expected %s not to be empty\n", tc.desc, token.GetRefreshToken()))
}
repoCall.Unset()
}
}