//
// 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/ExtensionService.go
//
// Generated by this command:
//
//	mockgen -destination=./cloudstack/ExtensionService_mock.go -package=cloudstack -copyright_file=header.txt -source=./cloudstack/ExtensionService.go
//

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

import (
	reflect "reflect"

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

// MockExtensionServiceIface is a mock of ExtensionServiceIface interface.
type MockExtensionServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockExtensionServiceIfaceMockRecorder
	isgomock struct{}
}

// MockExtensionServiceIfaceMockRecorder is the mock recorder for MockExtensionServiceIface.
type MockExtensionServiceIfaceMockRecorder struct {
	mock *MockExtensionServiceIface
}

// NewMockExtensionServiceIface creates a new mock instance.
func NewMockExtensionServiceIface(ctrl *gomock.Controller) *MockExtensionServiceIface {
	mock := &MockExtensionServiceIface{ctrl: ctrl}
	mock.recorder = &MockExtensionServiceIfaceMockRecorder{mock}
	return mock
}

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

// AddCustomAction mocks base method.
func (m *MockExtensionServiceIface) AddCustomAction(p *AddCustomActionParams) (*AddCustomActionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddCustomAction", p)
	ret0, _ := ret[0].(*AddCustomActionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// CreateExtension mocks base method.
func (m *MockExtensionServiceIface) CreateExtension(p *CreateExtensionParams) (*CreateExtensionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateExtension", p)
	ret0, _ := ret[0].(*CreateExtensionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteCustomAction mocks base method.
func (m *MockExtensionServiceIface) DeleteCustomAction(p *DeleteCustomActionParams) (*DeleteCustomActionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteCustomAction", p)
	ret0, _ := ret[0].(*DeleteCustomActionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteExtension mocks base method.
func (m *MockExtensionServiceIface) DeleteExtension(p *DeleteExtensionParams) (*DeleteExtensionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteExtension", p)
	ret0, _ := ret[0].(*DeleteExtensionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

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

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

// GetCustomActionID mocks base method.
func (m *MockExtensionServiceIface) GetCustomActionID(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, "GetCustomActionID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

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

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

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

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

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

// GetExtensionID mocks base method.
func (m *MockExtensionServiceIface) GetExtensionID(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, "GetExtensionID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

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

// ListCustomActions mocks base method.
func (m *MockExtensionServiceIface) ListCustomActions(p *ListCustomActionsParams) (*ListCustomActionsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListCustomActions", p)
	ret0, _ := ret[0].(*ListCustomActionsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListExtensions mocks base method.
func (m *MockExtensionServiceIface) ListExtensions(p *ListExtensionsParams) (*ListExtensionsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListExtensions", p)
	ret0, _ := ret[0].(*ListExtensionsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

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

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

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

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

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

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

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

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

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

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

// NewRegisterExtensionParams mocks base method.
func (m *MockExtensionServiceIface) NewRegisterExtensionParams(extensionid, resourceid, resourcetype string) *RegisterExtensionParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewRegisterExtensionParams", extensionid, resourceid, resourcetype)
	ret0, _ := ret[0].(*RegisterExtensionParams)
	return ret0
}

// NewRegisterExtensionParams indicates an expected call of NewRegisterExtensionParams.
func (mr *MockExtensionServiceIfaceMockRecorder) NewRegisterExtensionParams(extensionid, resourceid, resourcetype any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewRegisterExtensionParams", reflect.TypeOf((*MockExtensionServiceIface)(nil).NewRegisterExtensionParams), extensionid, resourceid, resourcetype)
}

// NewRunCustomActionParams mocks base method.
func (m *MockExtensionServiceIface) NewRunCustomActionParams(customactionid, resourceid string) *RunCustomActionParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewRunCustomActionParams", customactionid, resourceid)
	ret0, _ := ret[0].(*RunCustomActionParams)
	return ret0
}

// NewRunCustomActionParams indicates an expected call of NewRunCustomActionParams.
func (mr *MockExtensionServiceIfaceMockRecorder) NewRunCustomActionParams(customactionid, resourceid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewRunCustomActionParams", reflect.TypeOf((*MockExtensionServiceIface)(nil).NewRunCustomActionParams), customactionid, resourceid)
}

// NewUnregisterExtensionParams mocks base method.
func (m *MockExtensionServiceIface) NewUnregisterExtensionParams(extensionid, resourceid, resourcetype string) *UnregisterExtensionParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUnregisterExtensionParams", extensionid, resourceid, resourcetype)
	ret0, _ := ret[0].(*UnregisterExtensionParams)
	return ret0
}

// NewUnregisterExtensionParams indicates an expected call of NewUnregisterExtensionParams.
func (mr *MockExtensionServiceIfaceMockRecorder) NewUnregisterExtensionParams(extensionid, resourceid, resourcetype any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUnregisterExtensionParams", reflect.TypeOf((*MockExtensionServiceIface)(nil).NewUnregisterExtensionParams), extensionid, resourceid, resourcetype)
}

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

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

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

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

// RegisterExtension mocks base method.
func (m *MockExtensionServiceIface) RegisterExtension(p *RegisterExtensionParams) (*RegisterExtensionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RegisterExtension", p)
	ret0, _ := ret[0].(*RegisterExtensionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// RunCustomAction mocks base method.
func (m *MockExtensionServiceIface) RunCustomAction(p *RunCustomActionParams) (*RunCustomActionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RunCustomAction", p)
	ret0, _ := ret[0].(*RunCustomActionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UnregisterExtension mocks base method.
func (m *MockExtensionServiceIface) UnregisterExtension(p *UnregisterExtensionParams) (*UnregisterExtensionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UnregisterExtension", p)
	ret0, _ := ret[0].(*UnregisterExtensionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdateCustomAction mocks base method.
func (m *MockExtensionServiceIface) UpdateCustomAction(p *UpdateCustomActionParams) (*UpdateCustomActionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateCustomAction", p)
	ret0, _ := ret[0].(*UpdateCustomActionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdateExtension mocks base method.
func (m *MockExtensionServiceIface) UpdateExtension(p *UpdateExtensionParams) (*UpdateExtensionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateExtension", p)
	ret0, _ := ret[0].(*UpdateExtensionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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