1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-05-11 19:29:16 +08:00
Mainflux.mainflux/users/groups/service_test.go
b1ackd0t 726e358187
NOISSUE - List Members or Memberships To Include Ownership Rights (#1820)
* List Members and Membership To also include Owner

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Add Member Repository Tests

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Add Service Tests

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Add More Test

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

---------

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>
2023-07-13 15:42:46 +02:00

838 lines
25 KiB
Go

// Copyright (c) Mainflux
// SPDX-License-Identifier: Apache-2.0
package groups_test
import (
context "context"
fmt "fmt"
"regexp"
"testing"
"time"
"github.com/mainflux/mainflux/internal/testsutil"
mfclients "github.com/mainflux/mainflux/pkg/clients"
"github.com/mainflux/mainflux/pkg/errors"
mfgroups "github.com/mainflux/mainflux/pkg/groups"
"github.com/mainflux/mainflux/pkg/uuid"
"github.com/mainflux/mainflux/users/clients"
cmocks "github.com/mainflux/mainflux/users/clients/mocks"
"github.com/mainflux/mainflux/users/groups"
"github.com/mainflux/mainflux/users/groups/mocks"
"github.com/mainflux/mainflux/users/hasher"
"github.com/mainflux/mainflux/users/jwt"
pmocks "github.com/mainflux/mainflux/users/policies/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"
validGMetadata = mfclients.Metadata{"role": "client"}
inValidToken = "invalidToken"
description = "shortdescription"
gName = "groupname"
group = mfgroups.Group{
Name: gName,
Description: description,
Metadata: validGMetadata,
Status: mfclients.EnabledStatus,
}
withinDuration = 5 * time.Second
passRegex = regexp.MustCompile("^.{8,}$")
accessDuration = time.Minute * 1
refreshDuration = time.Minute * 10
)
func TestCreateGroup(t *testing.T) {
cRepo := new(cmocks.Repository)
gRepo := new(mocks.Repository)
pRepo := new(pmocks.Repository)
tokenizer := jwt.NewRepository([]byte(secret), accessDuration, refreshDuration)
e := cmocks.NewEmailer()
csvc := clients.NewService(cRepo, pRepo, tokenizer, e, phasher, idProvider, passRegex)
svc := groups.NewService(gRepo, pRepo, tokenizer, idProvider)
cases := []struct {
desc string
group mfgroups.Group
err error
}{
{
desc: "create new group",
group: group,
err: nil,
},
{
desc: "create group with existing name",
group: group,
err: nil,
},
{
desc: "create group with parent",
group: mfgroups.Group{
Name: gName,
Parent: testsutil.GenerateUUID(t, idProvider),
Status: mfclients.EnabledStatus,
},
err: nil,
},
{
desc: "create group with invalid parent",
group: mfgroups.Group{
Name: gName,
Parent: mocks.WrongID,
},
err: errors.ErrCreateEntity,
},
{
desc: "create group with invalid owner",
group: mfgroups.Group{
Name: gName,
Owner: mocks.WrongID,
},
err: errors.ErrCreateEntity,
},
{
desc: "create group with missing name",
group: mfgroups.Group{},
err: errors.ErrMalformedEntity,
},
}
for _, tc := range cases {
repoCall := gRepo.On("Save", context.Background(), mock.Anything).Return(tc.group, tc.err)
createdAt := time.Now()
expected, err := svc.CreateGroup(context.Background(), testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher), tc.group)
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, createdAt, withinDuration, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, expected.CreatedAt, createdAt))
tc.group.ID = expected.ID
tc.group.CreatedAt = expected.CreatedAt
tc.group.UpdatedAt = expected.UpdatedAt
tc.group.UpdatedBy = expected.UpdatedBy
tc.group.Owner = expected.Owner
assert.Equal(t, tc.group, expected, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.group, expected))
ok := repoCall.Parent.AssertCalled(t, "Save", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("Save was not called on %s", tc.desc))
}
repoCall.Unset()
}
}
func TestUpdateGroup(t *testing.T) {
cRepo := new(cmocks.Repository)
gRepo := new(mocks.Repository)
pRepo := new(pmocks.Repository)
tokenizer := jwt.NewRepository([]byte(secret), accessDuration, refreshDuration)
e := cmocks.NewEmailer()
csvc := clients.NewService(cRepo, pRepo, tokenizer, e, phasher, idProvider, passRegex)
svc := groups.NewService(gRepo, pRepo, tokenizer, idProvider)
group.ID = testsutil.GenerateUUID(t, idProvider)
cases := []struct {
desc string
token string
group mfgroups.Group
response mfgroups.Group
err error
}{
{
desc: "update group name",
group: mfgroups.Group{
ID: group.ID,
Name: "NewName",
},
response: mfgroups.Group{
ID: group.ID,
Name: "NewName",
},
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
err: nil,
},
{
desc: "update group description",
group: mfgroups.Group{
ID: group.ID,
Description: "NewDescription",
},
response: mfgroups.Group{
ID: group.ID,
Description: "NewDescription",
},
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
err: nil,
},
{
desc: "update group metadata",
group: mfgroups.Group{
ID: group.ID,
Metadata: mfclients.Metadata{
"field": "value2",
},
},
response: mfgroups.Group{
ID: group.ID,
Metadata: mfclients.Metadata{
"field": "value2",
},
},
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
err: nil,
},
{
desc: "update group name with invalid group id",
group: mfgroups.Group{
ID: mocks.WrongID,
Name: "NewName",
},
response: mfgroups.Group{},
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
err: errors.ErrNotFound,
},
{
desc: "update group description with invalid group id",
group: mfgroups.Group{
ID: mocks.WrongID,
Description: "NewDescription",
},
response: mfgroups.Group{},
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
err: errors.ErrNotFound,
},
{
desc: "update group metadata with invalid group id",
group: mfgroups.Group{
ID: mocks.WrongID,
Metadata: mfclients.Metadata{
"field": "value2",
},
},
response: mfgroups.Group{},
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
err: errors.ErrNotFound,
},
{
desc: "update group name with invalid token",
group: mfgroups.Group{
ID: group.ID,
Name: "NewName",
},
response: mfgroups.Group{},
token: inValidToken,
err: errors.ErrAuthentication,
},
{
desc: "update group description with invalid token",
group: mfgroups.Group{
ID: group.ID,
Description: "NewDescription",
},
response: mfgroups.Group{},
token: inValidToken,
err: errors.ErrAuthentication,
},
{
desc: "update group metadata with invalid token",
group: mfgroups.Group{
ID: group.ID,
Metadata: mfclients.Metadata{
"field": "value2",
},
},
response: mfgroups.Group{},
token: inValidToken,
err: errors.ErrAuthentication,
},
}
for _, tc := range cases {
repoCall := pRepo.On("CheckAdmin", context.Background(), mock.Anything).Return(nil)
repoCall1 := gRepo.On("Update", context.Background(), mock.Anything).Return(tc.response, tc.err)
expectedGroup, err := svc.UpdateGroup(context.Background(), tc.token, tc.group)
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, expectedGroup, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.response, expectedGroup))
if tc.err == nil {
ok := repoCall.Parent.AssertCalled(t, "CheckAdmin", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("CheckAdmin was not called on %s", tc.desc))
ok = repoCall1.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()
}
}
func TestViewGroup(t *testing.T) {
cRepo := new(cmocks.Repository)
gRepo := new(mocks.Repository)
pRepo := new(pmocks.Repository)
tokenizer := jwt.NewRepository([]byte(secret), accessDuration, refreshDuration)
e := cmocks.NewEmailer()
csvc := clients.NewService(cRepo, pRepo, tokenizer, e, phasher, idProvider, passRegex)
svc := groups.NewService(gRepo, pRepo, tokenizer, idProvider)
group.ID = testsutil.GenerateUUID(t, idProvider)
cases := []struct {
desc string
token string
groupID string
response mfgroups.Group
err error
}{
{
desc: "view group",
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
groupID: group.ID,
response: group,
err: nil,
},
{
desc: "view group with invalid token",
token: "wrongtoken",
groupID: group.ID,
response: mfgroups.Group{},
err: errors.ErrAuthentication,
},
{
desc: "view group for wrong id",
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
groupID: mocks.WrongID,
response: mfgroups.Group{},
err: errors.ErrNotFound,
},
}
for _, tc := range cases {
repoCall := pRepo.On("CheckAdmin", context.Background(), mock.Anything).Return(nil)
repoCall1 := gRepo.On("RetrieveByID", context.Background(), tc.groupID).Return(tc.response, tc.err)
expected, err := svc.ViewGroup(context.Background(), tc.token, tc.groupID)
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
assert.Equal(t, expected, tc.response, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, expected, tc.response))
if tc.err == nil {
ok := repoCall.Parent.AssertCalled(t, "CheckAdmin", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("CheckAdmin was not called on %s", tc.desc))
ok = repoCall1.Parent.AssertCalled(t, "RetrieveByID", context.Background(), tc.groupID)
assert.True(t, ok, fmt.Sprintf("RetrieveByID was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
}
}
func TestListGroups(t *testing.T) {
cRepo := new(cmocks.Repository)
gRepo := new(mocks.Repository)
pRepo := new(pmocks.Repository)
tokenizer := jwt.NewRepository([]byte(secret), accessDuration, refreshDuration)
e := cmocks.NewEmailer()
csvc := clients.NewService(cRepo, pRepo, tokenizer, e, phasher, idProvider, passRegex)
svc := groups.NewService(gRepo, pRepo, tokenizer, idProvider)
nGroups := uint64(200)
parentID := ""
var aGroups = []mfgroups.Group{}
for i := uint64(0); i < nGroups; i++ {
group := mfgroups.Group{
ID: testsutil.GenerateUUID(t, idProvider),
Name: fmt.Sprintf("Group_%d", i),
Description: description,
Metadata: mfclients.Metadata{
"field": "value",
},
Parent: parentID,
}
parentID = group.ID
aGroups = append(aGroups, group)
}
cases := []struct {
desc string
token string
size uint64
response mfgroups.GroupsPage
page mfgroups.GroupsPage
err error
}{
{
desc: "list all groups",
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
size: nGroups,
err: nil,
page: mfgroups.GroupsPage{
Page: mfgroups.Page{
Offset: 0,
Total: nGroups,
Limit: nGroups,
},
},
response: mfgroups.GroupsPage{
Page: mfgroups.Page{
Offset: 0,
Total: nGroups,
Limit: nGroups,
},
Groups: aGroups,
},
},
{
desc: "list groups with an offset",
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
size: 150,
err: nil,
page: mfgroups.GroupsPage{
Page: mfgroups.Page{
Offset: 50,
Total: nGroups,
Limit: nGroups,
},
},
response: mfgroups.GroupsPage{
Page: mfgroups.Page{
Offset: 0,
Total: 150,
Limit: nGroups,
},
Groups: aGroups[50:nGroups],
},
},
}
for _, tc := range cases {
repoCall := pRepo.On("CheckAdmin", context.Background(), mock.Anything).Return(nil)
repoCall1 := gRepo.On("RetrieveAll", context.Background(), mock.Anything).Return(tc.response, tc.err)
page, err := svc.ListGroups(context.Background(), tc.token, tc.page)
assert.Equal(t, tc.response, page, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.response, page))
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 := 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 TestEnableGroup(t *testing.T) {
cRepo := new(cmocks.Repository)
gRepo := new(mocks.Repository)
pRepo := new(pmocks.Repository)
tokenizer := jwt.NewRepository([]byte(secret), accessDuration, refreshDuration)
e := cmocks.NewEmailer()
csvc := clients.NewService(cRepo, pRepo, tokenizer, e, phasher, idProvider, passRegex)
svc := groups.NewService(gRepo, pRepo, tokenizer, idProvider)
enabledGroup1 := mfgroups.Group{ID: testsutil.GenerateUUID(t, idProvider), Name: "group1", Status: mfclients.EnabledStatus}
disabledGroup := mfgroups.Group{ID: testsutil.GenerateUUID(t, idProvider), Name: "group2", Status: mfclients.DisabledStatus}
disabledGroup1 := disabledGroup
disabledGroup1.Status = mfclients.EnabledStatus
casesEnabled := []struct {
desc string
id string
token string
group mfgroups.Group
response mfgroups.Group
err error
}{
{
desc: "enable disabled group",
id: disabledGroup.ID,
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
group: disabledGroup,
response: disabledGroup1,
err: nil,
},
{
desc: "enable enabled group",
id: enabledGroup1.ID,
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
group: enabledGroup1,
response: enabledGroup1,
err: mfclients.ErrStatusAlreadyAssigned,
},
{
desc: "enable non-existing group",
id: mocks.WrongID,
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
group: mfgroups.Group{},
response: mfgroups.Group{},
err: errors.ErrNotFound,
},
}
for _, tc := range casesEnabled {
repoCall := pRepo.On("CheckAdmin", context.Background(), mock.Anything).Return(nil)
repoCall1 := gRepo.On("RetrieveByID", context.Background(), tc.id).Return(tc.group, tc.err)
repoCall2 := gRepo.On("ChangeStatus", context.Background(), mock.Anything).Return(tc.response, tc.err)
_, err := svc.EnableGroup(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 := repoCall1.Parent.AssertCalled(t, "RetrieveByID", context.Background(), tc.id)
assert.True(t, ok, fmt.Sprintf("RetrieveByID was not called on %s", tc.desc))
ok = repoCall2.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()
}
casesDisabled := []struct {
desc string
status mfclients.Status
size uint64
response mfgroups.GroupsPage
}{
{
desc: "list activated groups",
status: mfclients.EnabledStatus,
size: 2,
response: mfgroups.GroupsPage{
Page: mfgroups.Page{
Total: 2,
Offset: 0,
Limit: 100,
},
Groups: []mfgroups.Group{enabledGroup1, disabledGroup1},
},
},
{
desc: "list deactivated groups",
status: mfclients.DisabledStatus,
size: 1,
response: mfgroups.GroupsPage{
Page: mfgroups.Page{
Total: 1,
Offset: 0,
Limit: 100,
},
Groups: []mfgroups.Group{disabledGroup},
},
},
{
desc: "list activated and deactivated groups",
status: mfclients.AllStatus,
size: 3,
response: mfgroups.GroupsPage{
Page: mfgroups.Page{
Total: 3,
Offset: 0,
Limit: 100,
},
Groups: []mfgroups.Group{enabledGroup1, disabledGroup, disabledGroup1},
},
},
}
for _, tc := range casesDisabled {
pm := mfgroups.GroupsPage{
Page: mfgroups.Page{
Offset: 0,
Limit: 100,
Status: tc.status,
},
}
repoCall := pRepo.On("CheckAdmin", context.Background(), mock.Anything).Return(nil)
repoCall1 := gRepo.On("RetrieveAll", context.Background(), mock.Anything).Return(tc.response, nil)
page, err := svc.ListGroups(context.Background(), testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher), pm)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
size := uint64(len(page.Groups))
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 TestDisableGroup(t *testing.T) {
cRepo := new(cmocks.Repository)
gRepo := new(mocks.Repository)
pRepo := new(pmocks.Repository)
tokenizer := jwt.NewRepository([]byte(secret), accessDuration, refreshDuration)
e := cmocks.NewEmailer()
csvc := clients.NewService(cRepo, pRepo, tokenizer, e, phasher, idProvider, passRegex)
svc := groups.NewService(gRepo, pRepo, tokenizer, idProvider)
enabledGroup1 := mfgroups.Group{ID: testsutil.GenerateUUID(t, idProvider), Name: "group1", Status: mfclients.EnabledStatus}
disabledGroup := mfgroups.Group{ID: testsutil.GenerateUUID(t, idProvider), Name: "group2", Status: mfclients.DisabledStatus}
disabledGroup1 := enabledGroup1
disabledGroup1.Status = mfclients.DisabledStatus
casesDisabled := []struct {
desc string
id string
token string
group mfgroups.Group
response mfgroups.Group
err error
}{
{
desc: "disable enabled group",
id: enabledGroup1.ID,
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
group: enabledGroup1,
response: disabledGroup1,
err: nil,
},
{
desc: "disable disabled group",
id: disabledGroup.ID,
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
group: disabledGroup,
response: mfgroups.Group{},
err: mfclients.ErrStatusAlreadyAssigned,
},
{
desc: "disable non-existing group",
id: mocks.WrongID,
group: mfgroups.Group{},
token: testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher),
response: mfgroups.Group{},
err: errors.ErrNotFound,
},
}
for _, tc := range casesDisabled {
repoCall := pRepo.On("CheckAdmin", context.Background(), mock.Anything).Return(nil)
repoCall1 := gRepo.On("RetrieveByID", context.Background(), tc.id).Return(tc.group, tc.err)
repoCall2 := gRepo.On("ChangeStatus", context.Background(), mock.Anything).Return(tc.response, tc.err)
_, err := svc.DisableGroup(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 := repoCall1.Parent.AssertCalled(t, "RetrieveByID", context.Background(), tc.id)
assert.True(t, ok, fmt.Sprintf("RetrieveByID was not called on %s", tc.desc))
ok = repoCall2.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()
}
casesEnabled := []struct {
desc string
status mfclients.Status
size uint64
response mfgroups.GroupsPage
}{
{
desc: "list activated groups",
status: mfclients.EnabledStatus,
size: 1,
response: mfgroups.GroupsPage{
Page: mfgroups.Page{
Total: 1,
Offset: 0,
Limit: 100,
},
Groups: []mfgroups.Group{enabledGroup1},
},
},
{
desc: "list deactivated groups",
status: mfclients.DisabledStatus,
size: 2,
response: mfgroups.GroupsPage{
Page: mfgroups.Page{
Total: 2,
Offset: 0,
Limit: 100,
},
Groups: []mfgroups.Group{disabledGroup1, disabledGroup},
},
},
{
desc: "list activated and deactivated groups",
status: mfclients.AllStatus,
size: 3,
response: mfgroups.GroupsPage{
Page: mfgroups.Page{
Total: 3,
Offset: 0,
Limit: 100,
},
Groups: []mfgroups.Group{enabledGroup1, disabledGroup, disabledGroup1},
},
},
}
for _, tc := range casesEnabled {
pm := mfgroups.GroupsPage{
Page: mfgroups.Page{
Offset: 0,
Limit: 100,
Status: tc.status,
},
}
repoCall := pRepo.On("CheckAdmin", context.Background(), mock.Anything).Return(nil)
repoCall1 := gRepo.On("RetrieveAll", context.Background(), mock.Anything).Return(tc.response, nil)
page, err := svc.ListGroups(context.Background(), testsutil.GenerateValidToken(t, testsutil.GenerateUUID(t, idProvider), csvc, cRepo, phasher), pm)
require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err))
size := uint64(len(page.Groups))
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 TestListMemberships(t *testing.T) {
cRepo := new(cmocks.Repository)
gRepo := new(mocks.Repository)
pRepo := new(pmocks.Repository)
tokenizer := jwt.NewRepository([]byte(secret), accessDuration, refreshDuration)
e := cmocks.NewEmailer()
csvc := clients.NewService(cRepo, pRepo, tokenizer, e, phasher, idProvider, passRegex)
svc := groups.NewService(gRepo, pRepo, tokenizer, idProvider)
var nGroups = uint64(100)
var aGroups = []mfgroups.Group{}
owner := testsutil.GenerateUUID(t, idProvider)
for i := uint64(1); i < nGroups; i++ {
group := mfgroups.Group{
Name: fmt.Sprintf("membership_%d@example.com", i),
Metadata: mfclients.Metadata{"role": "group"},
}
if i%3 == 0 {
group.Owner = owner
}
aGroups = append(aGroups, group)
}
validID := testsutil.GenerateUUID(t, idProvider)
validToken := testsutil.GenerateValidToken(t, validID, csvc, cRepo, phasher)
cases := []struct {
desc string
token string
clientID string
page mfgroups.GroupsPage
response mfgroups.MembershipsPage
err error
}{
{
desc: "list clients with authorized token",
token: validToken,
clientID: testsutil.GenerateUUID(t, idProvider),
page: mfgroups.GroupsPage{
Page: mfgroups.Page{
Action: "g_list",
Subject: validID,
},
},
response: mfgroups.MembershipsPage{
Page: mfgroups.Page{
Total: nGroups,
Offset: 0,
Limit: 0,
},
Memberships: aGroups,
},
err: nil,
},
{
desc: "list clients with offset and limit",
token: validToken,
clientID: testsutil.GenerateUUID(t, idProvider),
page: mfgroups.GroupsPage{
Page: mfgroups.Page{
Offset: 6,
Total: nGroups,
Limit: nGroups,
Status: mfclients.AllStatus,
Subject: validID,
Action: "g_list",
},
},
response: mfgroups.MembershipsPage{
Page: mfgroups.Page{
Total: nGroups - 6,
},
Memberships: aGroups[6:nGroups],
},
},
{
desc: "list clients with an invalid token",
token: inValidToken,
clientID: testsutil.GenerateUUID(t, idProvider),
page: mfgroups.GroupsPage{
Page: mfgroups.Page{
Action: "g_list",
Subject: validID,
},
},
response: mfgroups.MembershipsPage{
Page: mfgroups.Page{
Total: 0,
Offset: 0,
Limit: 0,
},
},
err: errors.ErrAuthentication,
},
{
desc: "list clients with an invalid id",
token: validToken,
clientID: mocks.WrongID,
page: mfgroups.GroupsPage{
Page: mfgroups.Page{
Action: "g_list",
Subject: validID,
},
},
response: mfgroups.MembershipsPage{
Page: mfgroups.Page{
Total: 0,
Offset: 0,
Limit: 0,
},
},
err: errors.ErrNotFound,
},
{
desc: "list clients with an owner",
token: validToken,
clientID: testsutil.GenerateUUID(t, idProvider),
page: mfgroups.GroupsPage{
Page: mfgroups.Page{
Offset: 0,
Total: nGroups,
Limit: nGroups,
Status: mfclients.AllStatus,
Subject: owner,
Action: "g_list",
},
},
response: mfgroups.MembershipsPage{
Page: mfgroups.Page{
Total: 4,
},
Memberships: []mfgroups.Group{aGroups[0], aGroups[3], aGroups[6], aGroups[9]},
},
},
}
for _, tc := range cases {
repoCall := pRepo.On("CheckAdmin", context.Background(), mock.Anything).Return(nil)
repoCall1 := gRepo.On("Memberships", context.Background(), tc.clientID, tc.page).Return(tc.response, tc.err)
page, err := svc.ListMemberships(context.Background(), tc.token, tc.clientID, 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 := repoCall.Parent.AssertCalled(t, "CheckAdmin", context.Background(), mock.Anything)
assert.True(t, ok, fmt.Sprintf("CheckAdmin was not called on %s", tc.desc))
ok = repoCall1.Parent.AssertCalled(t, "Memberships", context.Background(), tc.clientID, tc.page)
assert.True(t, ok, fmt.Sprintf("Memberships was not called on %s", tc.desc))
}
repoCall.Unset()
repoCall1.Unset()
}
}