//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//

// Code generated by MockGen. DO NOT EDIT.
// Source: ./cloudstack/RoleService.go
//
// Generated by this command:
//
//	mockgen -destination=./cloudstack/RoleService_mock.go -package=cloudstack -copyright_file=header.txt -source=./cloudstack/RoleService.go
//

// Package cloudstack is a generated GoMock package.
package cloudstack

import (
	reflect "reflect"

	gomock "go.uber.org/mock/gomock"
)

// MockRoleServiceIface is a mock of RoleServiceIface interface.
type MockRoleServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockRoleServiceIfaceMockRecorder
	isgomock struct{}
}

// MockRoleServiceIfaceMockRecorder is the mock recorder for MockRoleServiceIface.
type MockRoleServiceIfaceMockRecorder struct {
	mock *MockRoleServiceIface
}

// NewMockRoleServiceIface creates a new mock instance.
func NewMockRoleServiceIface(ctrl *gomock.Controller) *MockRoleServiceIface {
	mock := &MockRoleServiceIface{ctrl: ctrl}
	mock.recorder = &MockRoleServiceIfaceMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockRoleServiceIface) EXPECT() *MockRoleServiceIfaceMockRecorder {
	return m.recorder
}

// CreateRole mocks base method.
func (m *MockRoleServiceIface) CreateRole(p *CreateRoleParams) (*CreateRoleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateRole", p)
	ret0, _ := ret[0].(*CreateRoleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateRole indicates an expected call of CreateRole.
func (mr *MockRoleServiceIfaceMockRecorder) CreateRole(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRole", reflect.TypeOf((*MockRoleServiceIface)(nil).CreateRole), p)
}

// CreateRolePermission mocks base method.
func (m *MockRoleServiceIface) CreateRolePermission(p *CreateRolePermissionParams) (*CreateRolePermissionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateRolePermission", p)
	ret0, _ := ret[0].(*CreateRolePermissionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateRolePermission indicates an expected call of CreateRolePermission.
func (mr *MockRoleServiceIfaceMockRecorder) CreateRolePermission(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRolePermission", reflect.TypeOf((*MockRoleServiceIface)(nil).CreateRolePermission), p)
}

// DeleteRole mocks base method.
func (m *MockRoleServiceIface) DeleteRole(p *DeleteRoleParams) (*DeleteRoleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteRole", p)
	ret0, _ := ret[0].(*DeleteRoleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteRole indicates an expected call of DeleteRole.
func (mr *MockRoleServiceIfaceMockRecorder) DeleteRole(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRole", reflect.TypeOf((*MockRoleServiceIface)(nil).DeleteRole), p)
}

// DeleteRolePermission mocks base method.
func (m *MockRoleServiceIface) DeleteRolePermission(p *DeleteRolePermissionParams) (*DeleteRolePermissionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteRolePermission", p)
	ret0, _ := ret[0].(*DeleteRolePermissionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteRolePermission indicates an expected call of DeleteRolePermission.
func (mr *MockRoleServiceIfaceMockRecorder) DeleteRolePermission(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRolePermission", reflect.TypeOf((*MockRoleServiceIface)(nil).DeleteRolePermission), p)
}

// DisableRole mocks base method.
func (m *MockRoleServiceIface) DisableRole(p *DisableRoleParams) (*DisableRoleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DisableRole", p)
	ret0, _ := ret[0].(*DisableRoleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DisableRole indicates an expected call of DisableRole.
func (mr *MockRoleServiceIfaceMockRecorder) DisableRole(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableRole", reflect.TypeOf((*MockRoleServiceIface)(nil).DisableRole), p)
}

// EnableRole mocks base method.
func (m *MockRoleServiceIface) EnableRole(p *EnableRoleParams) (*EnableRoleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "EnableRole", p)
	ret0, _ := ret[0].(*EnableRoleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// EnableRole indicates an expected call of EnableRole.
func (mr *MockRoleServiceIfaceMockRecorder) EnableRole(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableRole", reflect.TypeOf((*MockRoleServiceIface)(nil).EnableRole), p)
}

// GetProjectRoleID mocks base method.
func (m *MockRoleServiceIface) GetProjectRoleID(name, projectid string, opts ...OptionFunc) (string, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name, projectid}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetProjectRoleID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetProjectRoleID indicates an expected call of GetProjectRoleID.
func (mr *MockRoleServiceIfaceMockRecorder) GetProjectRoleID(name, projectid any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name, projectid}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProjectRoleID", reflect.TypeOf((*MockRoleServiceIface)(nil).GetProjectRoleID), varargs...)
}

// GetRoleByID mocks base method.
func (m *MockRoleServiceIface) GetRoleByID(id string, opts ...OptionFunc) (*Role, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{id}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetRoleByID", varargs...)
	ret0, _ := ret[0].(*Role)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetRoleByID indicates an expected call of GetRoleByID.
func (mr *MockRoleServiceIfaceMockRecorder) GetRoleByID(id any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRoleByID", reflect.TypeOf((*MockRoleServiceIface)(nil).GetRoleByID), varargs...)
}

// GetRoleByName mocks base method.
func (m *MockRoleServiceIface) GetRoleByName(name string, opts ...OptionFunc) (*Role, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetRoleByName", varargs...)
	ret0, _ := ret[0].(*Role)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetRoleByName indicates an expected call of GetRoleByName.
func (mr *MockRoleServiceIfaceMockRecorder) GetRoleByName(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRoleByName", reflect.TypeOf((*MockRoleServiceIface)(nil).GetRoleByName), varargs...)
}

// GetRoleID mocks base method.
func (m *MockRoleServiceIface) GetRoleID(name string, opts ...OptionFunc) (string, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetRoleID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetRoleID indicates an expected call of GetRoleID.
func (mr *MockRoleServiceIfaceMockRecorder) GetRoleID(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRoleID", reflect.TypeOf((*MockRoleServiceIface)(nil).GetRoleID), varargs...)
}

// ImportRole mocks base method.
func (m *MockRoleServiceIface) ImportRole(p *ImportRoleParams) (*ImportRoleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ImportRole", p)
	ret0, _ := ret[0].(*ImportRoleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ImportRole indicates an expected call of ImportRole.
func (mr *MockRoleServiceIfaceMockRecorder) ImportRole(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImportRole", reflect.TypeOf((*MockRoleServiceIface)(nil).ImportRole), p)
}

// ListProjectRoles mocks base method.
func (m *MockRoleServiceIface) ListProjectRoles(p *ListProjectRolesParams) (*ListProjectRolesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListProjectRoles", p)
	ret0, _ := ret[0].(*ListProjectRolesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListProjectRoles indicates an expected call of ListProjectRoles.
func (mr *MockRoleServiceIfaceMockRecorder) ListProjectRoles(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListProjectRoles", reflect.TypeOf((*MockRoleServiceIface)(nil).ListProjectRoles), p)
}

// ListRolePermissions mocks base method.
func (m *MockRoleServiceIface) ListRolePermissions(p *ListRolePermissionsParams) (*ListRolePermissionsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListRolePermissions", p)
	ret0, _ := ret[0].(*ListRolePermissionsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListRolePermissions indicates an expected call of ListRolePermissions.
func (mr *MockRoleServiceIfaceMockRecorder) ListRolePermissions(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListRolePermissions", reflect.TypeOf((*MockRoleServiceIface)(nil).ListRolePermissions), p)
}

// ListRoles mocks base method.
func (m *MockRoleServiceIface) ListRoles(p *ListRolesParams) (*ListRolesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListRoles", p)
	ret0, _ := ret[0].(*ListRolesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListRoles indicates an expected call of ListRoles.
func (mr *MockRoleServiceIfaceMockRecorder) ListRoles(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListRoles", reflect.TypeOf((*MockRoleServiceIface)(nil).ListRoles), p)
}

// NewCreateRoleParams mocks base method.
func (m *MockRoleServiceIface) NewCreateRoleParams(name string) *CreateRoleParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateRoleParams", name)
	ret0, _ := ret[0].(*CreateRoleParams)
	return ret0
}

// NewCreateRoleParams indicates an expected call of NewCreateRoleParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewCreateRoleParams(name any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateRoleParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewCreateRoleParams), name)
}

// NewCreateRolePermissionParams mocks base method.
func (m *MockRoleServiceIface) NewCreateRolePermissionParams(permission, roleid, rule string) *CreateRolePermissionParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateRolePermissionParams", permission, roleid, rule)
	ret0, _ := ret[0].(*CreateRolePermissionParams)
	return ret0
}

// NewCreateRolePermissionParams indicates an expected call of NewCreateRolePermissionParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewCreateRolePermissionParams(permission, roleid, rule any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateRolePermissionParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewCreateRolePermissionParams), permission, roleid, rule)
}

// NewDeleteRoleParams mocks base method.
func (m *MockRoleServiceIface) NewDeleteRoleParams(id string) *DeleteRoleParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteRoleParams", id)
	ret0, _ := ret[0].(*DeleteRoleParams)
	return ret0
}

// NewDeleteRoleParams indicates an expected call of NewDeleteRoleParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewDeleteRoleParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteRoleParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewDeleteRoleParams), id)
}

// NewDeleteRolePermissionParams mocks base method.
func (m *MockRoleServiceIface) NewDeleteRolePermissionParams(id string) *DeleteRolePermissionParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteRolePermissionParams", id)
	ret0, _ := ret[0].(*DeleteRolePermissionParams)
	return ret0
}

// NewDeleteRolePermissionParams indicates an expected call of NewDeleteRolePermissionParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewDeleteRolePermissionParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteRolePermissionParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewDeleteRolePermissionParams), id)
}

// NewDisableRoleParams mocks base method.
func (m *MockRoleServiceIface) NewDisableRoleParams(id string) *DisableRoleParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDisableRoleParams", id)
	ret0, _ := ret[0].(*DisableRoleParams)
	return ret0
}

// NewDisableRoleParams indicates an expected call of NewDisableRoleParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewDisableRoleParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDisableRoleParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewDisableRoleParams), id)
}

// NewEnableRoleParams mocks base method.
func (m *MockRoleServiceIface) NewEnableRoleParams(id string) *EnableRoleParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewEnableRoleParams", id)
	ret0, _ := ret[0].(*EnableRoleParams)
	return ret0
}

// NewEnableRoleParams indicates an expected call of NewEnableRoleParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewEnableRoleParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewEnableRoleParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewEnableRoleParams), id)
}

// NewImportRoleParams mocks base method.
func (m *MockRoleServiceIface) NewImportRoleParams(name string, rules map[string]string) *ImportRoleParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewImportRoleParams", name, rules)
	ret0, _ := ret[0].(*ImportRoleParams)
	return ret0
}

// NewImportRoleParams indicates an expected call of NewImportRoleParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewImportRoleParams(name, rules any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewImportRoleParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewImportRoleParams), name, rules)
}

// NewListProjectRolesParams mocks base method.
func (m *MockRoleServiceIface) NewListProjectRolesParams(projectid string) *ListProjectRolesParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListProjectRolesParams", projectid)
	ret0, _ := ret[0].(*ListProjectRolesParams)
	return ret0
}

// NewListProjectRolesParams indicates an expected call of NewListProjectRolesParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewListProjectRolesParams(projectid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListProjectRolesParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewListProjectRolesParams), projectid)
}

// NewListRolePermissionsParams mocks base method.
func (m *MockRoleServiceIface) NewListRolePermissionsParams() *ListRolePermissionsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListRolePermissionsParams")
	ret0, _ := ret[0].(*ListRolePermissionsParams)
	return ret0
}

// NewListRolePermissionsParams indicates an expected call of NewListRolePermissionsParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewListRolePermissionsParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListRolePermissionsParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewListRolePermissionsParams))
}

// NewListRolesParams mocks base method.
func (m *MockRoleServiceIface) NewListRolesParams() *ListRolesParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListRolesParams")
	ret0, _ := ret[0].(*ListRolesParams)
	return ret0
}

// NewListRolesParams indicates an expected call of NewListRolesParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewListRolesParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListRolesParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewListRolesParams))
}

// NewUpdateRoleParams mocks base method.
func (m *MockRoleServiceIface) NewUpdateRoleParams(id string) *UpdateRoleParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateRoleParams", id)
	ret0, _ := ret[0].(*UpdateRoleParams)
	return ret0
}

// NewUpdateRoleParams indicates an expected call of NewUpdateRoleParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewUpdateRoleParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateRoleParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewUpdateRoleParams), id)
}

// NewUpdateRolePermissionParams mocks base method.
func (m *MockRoleServiceIface) NewUpdateRolePermissionParams(roleid string) *UpdateRolePermissionParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateRolePermissionParams", roleid)
	ret0, _ := ret[0].(*UpdateRolePermissionParams)
	return ret0
}

// NewUpdateRolePermissionParams indicates an expected call of NewUpdateRolePermissionParams.
func (mr *MockRoleServiceIfaceMockRecorder) NewUpdateRolePermissionParams(roleid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateRolePermissionParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewUpdateRolePermissionParams), roleid)
}

// UpdateRole mocks base method.
func (m *MockRoleServiceIface) UpdateRole(p *UpdateRoleParams) (*UpdateRoleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateRole", p)
	ret0, _ := ret[0].(*UpdateRoleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateRole indicates an expected call of UpdateRole.
func (mr *MockRoleServiceIfaceMockRecorder) UpdateRole(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateRole", reflect.TypeOf((*MockRoleServiceIface)(nil).UpdateRole), p)
}

// UpdateRolePermission mocks base method.
func (m *MockRoleServiceIface) UpdateRolePermission(p *UpdateRolePermissionParams) (*UpdateRolePermissionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateRolePermission", p)
	ret0, _ := ret[0].(*UpdateRolePermissionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateRolePermission indicates an expected call of UpdateRolePermission.
func (mr *MockRoleServiceIfaceMockRecorder) UpdateRolePermission(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateRolePermission", reflect.TypeOf((*MockRoleServiceIface)(nil).UpdateRolePermission), p)
}
