From 8b31fb0e6b7237ded22fd436f4ce014fbad05fae Mon Sep 17 00:00:00 2001 From: Anuj Khandelwal Date: Tue, 10 Sep 2024 12:35:27 +0530 Subject: [PATCH 1/4] chore: add unit test for permission get --- .mockery.yaml | 4 + core/permission/mocks/repository.go | 371 ++++++++++++++++++++++++++++ core/permission/service_test.go | 76 ++++++ 3 files changed, 451 insertions(+) create mode 100644 core/permission/mocks/repository.go create mode 100644 core/permission/service_test.go diff --git a/.mockery.yaml b/.mockery.yaml index edc3a9dc2..8b8a7f02f 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -58,4 +58,8 @@ packages: github.com/raystack/frontier/core/organization: config: dir: "core/organization/mocks" + all: true + github.com/raystack/frontier/core/permission: + config: + dir: "core/permission/mocks" all: true \ No newline at end of file diff --git a/core/permission/mocks/repository.go b/core/permission/mocks/repository.go new file mode 100644 index 000000000..3a7c97270 --- /dev/null +++ b/core/permission/mocks/repository.go @@ -0,0 +1,371 @@ +// Code generated by mockery v2.40.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + permission "github.com/raystack/frontier/core/permission" + mock "github.com/stretchr/testify/mock" +) + +// Repository is an autogenerated mock type for the Repository type +type Repository struct { + mock.Mock +} + +type Repository_Expecter struct { + mock *mock.Mock +} + +func (_m *Repository) EXPECT() *Repository_Expecter { + return &Repository_Expecter{mock: &_m.Mock} +} + +// Delete provides a mock function with given fields: ctx, id +func (_m *Repository) Delete(ctx context.Context, id string) error { + ret := _m.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for Delete") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, id) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Repository_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' +type Repository_Delete_Call struct { + *mock.Call +} + +// Delete is a helper method to define mock.On call +// - ctx context.Context +// - id string +func (_e *Repository_Expecter) Delete(ctx interface{}, id interface{}) *Repository_Delete_Call { + return &Repository_Delete_Call{Call: _e.mock.On("Delete", ctx, id)} +} + +func (_c *Repository_Delete_Call) Run(run func(ctx context.Context, id string)) *Repository_Delete_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *Repository_Delete_Call) Return(_a0 error) *Repository_Delete_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Repository_Delete_Call) RunAndReturn(run func(context.Context, string) error) *Repository_Delete_Call { + _c.Call.Return(run) + return _c +} + +// Get provides a mock function with given fields: ctx, id +func (_m *Repository) Get(ctx context.Context, id string) (permission.Permission, error) { + ret := _m.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 permission.Permission + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (permission.Permission, error)); ok { + return rf(ctx, id) + } + if rf, ok := ret.Get(0).(func(context.Context, string) permission.Permission); ok { + r0 = rf(ctx, id) + } else { + r0 = ret.Get(0).(permission.Permission) + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Repository_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' +type Repository_Get_Call struct { + *mock.Call +} + +// Get is a helper method to define mock.On call +// - ctx context.Context +// - id string +func (_e *Repository_Expecter) Get(ctx interface{}, id interface{}) *Repository_Get_Call { + return &Repository_Get_Call{Call: _e.mock.On("Get", ctx, id)} +} + +func (_c *Repository_Get_Call) Run(run func(ctx context.Context, id string)) *Repository_Get_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *Repository_Get_Call) Return(_a0 permission.Permission, _a1 error) *Repository_Get_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Repository_Get_Call) RunAndReturn(run func(context.Context, string) (permission.Permission, error)) *Repository_Get_Call { + _c.Call.Return(run) + return _c +} + +// GetBySlug provides a mock function with given fields: ctx, id +func (_m *Repository) GetBySlug(ctx context.Context, id string) (permission.Permission, error) { + ret := _m.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for GetBySlug") + } + + var r0 permission.Permission + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (permission.Permission, error)); ok { + return rf(ctx, id) + } + if rf, ok := ret.Get(0).(func(context.Context, string) permission.Permission); ok { + r0 = rf(ctx, id) + } else { + r0 = ret.Get(0).(permission.Permission) + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Repository_GetBySlug_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBySlug' +type Repository_GetBySlug_Call struct { + *mock.Call +} + +// GetBySlug is a helper method to define mock.On call +// - ctx context.Context +// - id string +func (_e *Repository_Expecter) GetBySlug(ctx interface{}, id interface{}) *Repository_GetBySlug_Call { + return &Repository_GetBySlug_Call{Call: _e.mock.On("GetBySlug", ctx, id)} +} + +func (_c *Repository_GetBySlug_Call) Run(run func(ctx context.Context, id string)) *Repository_GetBySlug_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *Repository_GetBySlug_Call) Return(_a0 permission.Permission, _a1 error) *Repository_GetBySlug_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Repository_GetBySlug_Call) RunAndReturn(run func(context.Context, string) (permission.Permission, error)) *Repository_GetBySlug_Call { + _c.Call.Return(run) + return _c +} + +// List provides a mock function with given fields: ctx, flt +func (_m *Repository) List(ctx context.Context, flt permission.Filter) ([]permission.Permission, error) { + ret := _m.Called(ctx, flt) + + if len(ret) == 0 { + panic("no return value specified for List") + } + + var r0 []permission.Permission + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, permission.Filter) ([]permission.Permission, error)); ok { + return rf(ctx, flt) + } + if rf, ok := ret.Get(0).(func(context.Context, permission.Filter) []permission.Permission); ok { + r0 = rf(ctx, flt) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]permission.Permission) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, permission.Filter) error); ok { + r1 = rf(ctx, flt) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Repository_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List' +type Repository_List_Call struct { + *mock.Call +} + +// List is a helper method to define mock.On call +// - ctx context.Context +// - flt permission.Filter +func (_e *Repository_Expecter) List(ctx interface{}, flt interface{}) *Repository_List_Call { + return &Repository_List_Call{Call: _e.mock.On("List", ctx, flt)} +} + +func (_c *Repository_List_Call) Run(run func(ctx context.Context, flt permission.Filter)) *Repository_List_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(permission.Filter)) + }) + return _c +} + +func (_c *Repository_List_Call) Return(_a0 []permission.Permission, _a1 error) *Repository_List_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Repository_List_Call) RunAndReturn(run func(context.Context, permission.Filter) ([]permission.Permission, error)) *Repository_List_Call { + _c.Call.Return(run) + return _c +} + +// Update provides a mock function with given fields: ctx, action +func (_m *Repository) Update(ctx context.Context, action permission.Permission) (permission.Permission, error) { + ret := _m.Called(ctx, action) + + if len(ret) == 0 { + panic("no return value specified for Update") + } + + var r0 permission.Permission + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, permission.Permission) (permission.Permission, error)); ok { + return rf(ctx, action) + } + if rf, ok := ret.Get(0).(func(context.Context, permission.Permission) permission.Permission); ok { + r0 = rf(ctx, action) + } else { + r0 = ret.Get(0).(permission.Permission) + } + + if rf, ok := ret.Get(1).(func(context.Context, permission.Permission) error); ok { + r1 = rf(ctx, action) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Repository_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update' +type Repository_Update_Call struct { + *mock.Call +} + +// Update is a helper method to define mock.On call +// - ctx context.Context +// - action permission.Permission +func (_e *Repository_Expecter) Update(ctx interface{}, action interface{}) *Repository_Update_Call { + return &Repository_Update_Call{Call: _e.mock.On("Update", ctx, action)} +} + +func (_c *Repository_Update_Call) Run(run func(ctx context.Context, action permission.Permission)) *Repository_Update_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(permission.Permission)) + }) + return _c +} + +func (_c *Repository_Update_Call) Return(_a0 permission.Permission, _a1 error) *Repository_Update_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Repository_Update_Call) RunAndReturn(run func(context.Context, permission.Permission) (permission.Permission, error)) *Repository_Update_Call { + _c.Call.Return(run) + return _c +} + +// Upsert provides a mock function with given fields: ctx, action +func (_m *Repository) Upsert(ctx context.Context, action permission.Permission) (permission.Permission, error) { + ret := _m.Called(ctx, action) + + if len(ret) == 0 { + panic("no return value specified for Upsert") + } + + var r0 permission.Permission + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, permission.Permission) (permission.Permission, error)); ok { + return rf(ctx, action) + } + if rf, ok := ret.Get(0).(func(context.Context, permission.Permission) permission.Permission); ok { + r0 = rf(ctx, action) + } else { + r0 = ret.Get(0).(permission.Permission) + } + + if rf, ok := ret.Get(1).(func(context.Context, permission.Permission) error); ok { + r1 = rf(ctx, action) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Repository_Upsert_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Upsert' +type Repository_Upsert_Call struct { + *mock.Call +} + +// Upsert is a helper method to define mock.On call +// - ctx context.Context +// - action permission.Permission +func (_e *Repository_Expecter) Upsert(ctx interface{}, action interface{}) *Repository_Upsert_Call { + return &Repository_Upsert_Call{Call: _e.mock.On("Upsert", ctx, action)} +} + +func (_c *Repository_Upsert_Call) Run(run func(ctx context.Context, action permission.Permission)) *Repository_Upsert_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(permission.Permission)) + }) + return _c +} + +func (_c *Repository_Upsert_Call) Return(_a0 permission.Permission, _a1 error) *Repository_Upsert_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Repository_Upsert_Call) RunAndReturn(run func(context.Context, permission.Permission) (permission.Permission, error)) *Repository_Upsert_Call { + _c.Call.Return(run) + return _c +} + +// NewRepository creates a new instance of Repository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewRepository(t interface { + mock.TestingT + Cleanup(func()) +}) *Repository { + mock := &Repository{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/permission/service_test.go b/core/permission/service_test.go new file mode 100644 index 000000000..05d41f76e --- /dev/null +++ b/core/permission/service_test.go @@ -0,0 +1,76 @@ +package permission_test + +import ( + "context" + "errors" + "testing" + + "github.com/google/uuid" + "github.com/raystack/frontier/core/permission" + "github.com/raystack/frontier/core/permission/mocks" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func TestService_Get(t *testing.T) { + mockRepo := mocks.NewRepository(t) + svc := permission.NewService(mockRepo) + + t.Run("should get permission by id", func(t *testing.T) { + inputID := uuid.New().String() + expectedPermission := permission.Permission{ + ID: inputID, + Name: "permissionname", + Slug: "app/permission_name", + } + + mockRepo.On("Get", mock.Anything, inputID).Return(expectedPermission, nil) + perm, err := svc.Get(context.Background(), inputID) + + assert.Nil(t, err) + assert.Equal(t, expectedPermission, perm) + }) + + t.Run("should get permission by slug", func(t *testing.T) { + inputSlug := "app/somepermission" + expectedPermission := permission.Permission{ + ID: uuid.New().String(), + Name: "permissionname", + Slug: inputSlug, + } + + mockRepo.On("GetBySlug", mock.Anything, inputSlug).Return(expectedPermission, nil) + perm, err := svc.Get(context.Background(), inputSlug) + + assert.Nil(t, err) + assert.Equal(t, expectedPermission, perm) + }) + + t.Run("should return an error if permission cannot be fetched", func(t *testing.T) { + inputID := uuid.New().String() + + expectedError := errors.New("An error occurred") + + mockRepo.On("Get", mock.Anything, inputID).Return(permission.Permission{}, expectedError) + _, err := svc.Get(context.Background(), inputID) + + assert.NotNil(t, err) + assert.Equal(t, expectedError, err) + }) +} + +func TestService_Upsert(t *testing.T) { + t.Run("should upsert permission", func(t *testing.T) {}) + + t.Run("should generate slug if not present in request", func(t *testing.T) {}) + + t.Run("should return an error if permission cannot be upserted", func(t *testing.T) {}) +} + +func TestService_List(t *testing.T) { + t.Run("should list permissions", func(t *testing.T) {}) + + t.Run("should list after applying filters", func(t *testing.T) {}) + + t.Run("should return an error if permissions cannot be list", func(t *testing.T) {}) +} From cd3386c74b9273c526f955f2b53a34c7b84964ba Mon Sep 17 00:00:00 2001 From: Anuj Khandelwal Date: Tue, 10 Sep 2024 14:09:38 +0530 Subject: [PATCH 2/4] chore: unit tests for permission upsert --- core/permission/service_test.go | 49 +++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/core/permission/service_test.go b/core/permission/service_test.go index 05d41f76e..8141470a8 100644 --- a/core/permission/service_test.go +++ b/core/permission/service_test.go @@ -60,11 +60,54 @@ func TestService_Get(t *testing.T) { } func TestService_Upsert(t *testing.T) { - t.Run("should upsert permission", func(t *testing.T) {}) + mockRepo := mocks.NewRepository(t) + svc := permission.NewService(mockRepo) + + t.Run("should upsert permission", func(t *testing.T) { + inputPermission := permission.Permission{ + ID: uuid.New().String(), + Name: "permissionname", + Slug: "app/permission_name", + } + + mockRepo.On("Upsert", mock.Anything, inputPermission).Return(inputPermission, nil) + perm, err := svc.Upsert(context.Background(), inputPermission) + + assert.Nil(t, err) + assert.Equal(t, inputPermission, perm) + }) + + t.Run("should generate slug if not present in request", func(t *testing.T) { + inputPermission := permission.Permission{ + ID: uuid.New().String(), + Name: "permissionname", + } + + expectedRepoInput := inputPermission + expectedRepoInput.Slug = inputPermission.GenerateSlug() + + mockRepo.On("Upsert", mock.Anything, expectedRepoInput).Return(expectedRepoInput, nil) + perm, err := svc.Upsert(context.Background(), inputPermission) + + assert.Nil(t, err) + assert.Equal(t, expectedRepoInput, perm) + }) + + t.Run("should return an error if permission cannot be upserted", func(t *testing.T) { + inputPermission := permission.Permission{ + ID: uuid.New().String(), + Name: "permissionname", + Slug: "app/permission_name", + } - t.Run("should generate slug if not present in request", func(t *testing.T) {}) + expectedErr := errors.New("An error occurred") - t.Run("should return an error if permission cannot be upserted", func(t *testing.T) {}) + mockRepo.On("Upsert", mock.Anything, inputPermission).Return(permission.Permission{}, expectedErr) + _, err := svc.Upsert(context.Background(), inputPermission) + + assert.NotNil(t, err) + assert.Equal(t, expectedErr, err) + }) } func TestService_List(t *testing.T) { From eefbff3064193af014d78576b6f78e58a8ad5364 Mon Sep 17 00:00:00 2001 From: Anuj Khandelwal Date: Tue, 10 Sep 2024 14:14:16 +0530 Subject: [PATCH 3/4] chore: unit tests for permission list --- core/permission/service_test.go | 56 +++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/core/permission/service_test.go b/core/permission/service_test.go index 8141470a8..64d772476 100644 --- a/core/permission/service_test.go +++ b/core/permission/service_test.go @@ -24,7 +24,7 @@ func TestService_Get(t *testing.T) { Slug: "app/permission_name", } - mockRepo.On("Get", mock.Anything, inputID).Return(expectedPermission, nil) + mockRepo.On("Get", mock.Anything, inputID).Return(expectedPermission, nil).Once() perm, err := svc.Get(context.Background(), inputID) assert.Nil(t, err) @@ -39,7 +39,7 @@ func TestService_Get(t *testing.T) { Slug: inputSlug, } - mockRepo.On("GetBySlug", mock.Anything, inputSlug).Return(expectedPermission, nil) + mockRepo.On("GetBySlug", mock.Anything, inputSlug).Return(expectedPermission, nil).Once() perm, err := svc.Get(context.Background(), inputSlug) assert.Nil(t, err) @@ -51,7 +51,7 @@ func TestService_Get(t *testing.T) { expectedError := errors.New("An error occurred") - mockRepo.On("Get", mock.Anything, inputID).Return(permission.Permission{}, expectedError) + mockRepo.On("Get", mock.Anything, inputID).Return(permission.Permission{}, expectedError).Once() _, err := svc.Get(context.Background(), inputID) assert.NotNil(t, err) @@ -70,7 +70,7 @@ func TestService_Upsert(t *testing.T) { Slug: "app/permission_name", } - mockRepo.On("Upsert", mock.Anything, inputPermission).Return(inputPermission, nil) + mockRepo.On("Upsert", mock.Anything, inputPermission).Return(inputPermission, nil).Once() perm, err := svc.Upsert(context.Background(), inputPermission) assert.Nil(t, err) @@ -86,7 +86,7 @@ func TestService_Upsert(t *testing.T) { expectedRepoInput := inputPermission expectedRepoInput.Slug = inputPermission.GenerateSlug() - mockRepo.On("Upsert", mock.Anything, expectedRepoInput).Return(expectedRepoInput, nil) + mockRepo.On("Upsert", mock.Anything, expectedRepoInput).Return(expectedRepoInput, nil).Once() perm, err := svc.Upsert(context.Background(), inputPermission) assert.Nil(t, err) @@ -102,7 +102,7 @@ func TestService_Upsert(t *testing.T) { expectedErr := errors.New("An error occurred") - mockRepo.On("Upsert", mock.Anything, inputPermission).Return(permission.Permission{}, expectedErr) + mockRepo.On("Upsert", mock.Anything, inputPermission).Return(permission.Permission{}, expectedErr).Once() _, err := svc.Upsert(context.Background(), inputPermission) assert.NotNil(t, err) @@ -111,9 +111,47 @@ func TestService_Upsert(t *testing.T) { } func TestService_List(t *testing.T) { - t.Run("should list permissions", func(t *testing.T) {}) + mockRepo := mocks.NewRepository(t) + svc := permission.NewService(mockRepo) + + t.Run("should list permissions", func(t *testing.T) { + filters := permission.Filter{ + Namespace: "app/organization", + } - t.Run("should list after applying filters", func(t *testing.T) {}) + expectedRes := []permission.Permission{ + { + ID: uuid.New().String(), + Name: "firstpermissionname", + Slug: "app/first_permission_name", + }, + { + ID: uuid.New().String(), + Name: "secondpermissionname", + Slug: "app/second_permission_name", + }, + } + + mockRepo.On("List", mock.Anything, filters).Return(expectedRes, nil).Once() + + perms, err := svc.List(context.Background(), filters) + + assert.Nil(t, err) + assert.Equal(t, expectedRes, perms) + }) - t.Run("should return an error if permissions cannot be list", func(t *testing.T) {}) + t.Run("should return an error if permissions cannot be list", func(t *testing.T) { + filters := permission.Filter{ + Namespace: "app/organization", + } + + expectedErr := errors.New("An error occurred") + + mockRepo.On("List", mock.Anything, filters).Return([]permission.Permission{}, expectedErr).Once() + + _, err := svc.List(context.Background(), filters) + + assert.NotNil(t, err) + assert.Equal(t, expectedErr, err) + }) } From 5ca50b63ede44f83f851c8a9987e1d1f29b31ada Mon Sep 17 00:00:00 2001 From: Anuj Khandelwal Date: Wed, 11 Sep 2024 13:22:14 +0530 Subject: [PATCH 4/4] chore: uni tests for permission update, delete --- core/permission/service_test.go | 85 +++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/core/permission/service_test.go b/core/permission/service_test.go index 64d772476..bc2a3decf 100644 --- a/core/permission/service_test.go +++ b/core/permission/service_test.go @@ -133,9 +133,9 @@ func TestService_List(t *testing.T) { } mockRepo.On("List", mock.Anything, filters).Return(expectedRes, nil).Once() - + perms, err := svc.List(context.Background(), filters) - + assert.Nil(t, err) assert.Equal(t, expectedRes, perms) }) @@ -148,9 +148,86 @@ func TestService_List(t *testing.T) { expectedErr := errors.New("An error occurred") mockRepo.On("List", mock.Anything, filters).Return([]permission.Permission{}, expectedErr).Once() - + _, err := svc.List(context.Background(), filters) - + + assert.NotNil(t, err) + assert.Equal(t, expectedErr, err) + }) +} +func TestService_Update(t *testing.T) { + mockRepo := mocks.NewRepository(t) + svc := permission.NewService(mockRepo) + + t.Run("should update permission", func(t *testing.T) { + inputPermission := permission.Permission{ + ID: uuid.New().String(), + Name: "permissionname", + Slug: "app/permission_name", + } + + mockRepo.On("Update", mock.Anything, inputPermission).Return(inputPermission, nil).Once() + perm, err := svc.Update(context.Background(), inputPermission) + + assert.Nil(t, err) + assert.Equal(t, inputPermission, perm) + }) + + t.Run("should generate slug if not present in request", func(t *testing.T) { + inputPermission := permission.Permission{ + ID: uuid.New().String(), + Name: "permissionname", + } + + expectedRepoInput := inputPermission + expectedRepoInput.Slug = inputPermission.GenerateSlug() + + mockRepo.On("Update", mock.Anything, expectedRepoInput).Return(expectedRepoInput, nil).Once() + perm, err := svc.Update(context.Background(), inputPermission) + + assert.Nil(t, err) + assert.Equal(t, expectedRepoInput, perm) + }) + + t.Run("should return an error if permission cannot be updated", func(t *testing.T) { + inputPermission := permission.Permission{ + ID: uuid.New().String(), + Name: "permissionname", + Slug: "app/permission_name", + } + + expectedErr := errors.New("An error occurred") + + mockRepo.On("Update", mock.Anything, inputPermission).Return(permission.Permission{}, expectedErr).Once() + _, err := svc.Update(context.Background(), inputPermission) + + assert.NotNil(t, err) + assert.Equal(t, expectedErr, err) + }) +} + +func TestService_Delete(t *testing.T) { + mockRepo := mocks.NewRepository(t) + svc := permission.NewService(mockRepo) + + t.Run("should delete permission", func(t *testing.T) { + permissionID := uuid.New().String() + + mockRepo.On("Delete", mock.Anything, permissionID).Return(nil).Once() + + err := svc.Delete(context.Background(), permissionID) + + assert.Nil(t, err) + }) + + t.Run("should return an error if permissions cannot be list", func(t *testing.T) { + permissionID := uuid.New().String() + expectedErr := errors.New("An error occurred") + + mockRepo.On("Delete", mock.Anything, permissionID).Return(expectedErr).Once() + + err := svc.Delete(context.Background(), permissionID) + assert.NotNil(t, err) assert.Equal(t, expectedErr, err) })