// Code generated by mockery v1.0.0. DO NOT EDIT.

package mocks

import eventbus "go.skia.org/infra/go/eventbus"
import mock "github.com/stretchr/testify/mock"
import regexp "regexp"
import storage "cloud.google.com/go/storage"

// EventBus is an autogenerated mock type for the EventBus type
type EventBus struct {
	mock.Mock
}

// Publish provides a mock function with given fields: channelID, data, globally
func (_m *EventBus) Publish(channelID string, data interface{}, globally bool) {
	_m.Called(channelID, data, globally)
}

// PublishStorageEvent provides a mock function with given fields: evtData
func (_m *EventBus) PublishStorageEvent(evtData *eventbus.StorageEvent) {
	_m.Called(evtData)
}

// RegisterStorageEvents provides a mock function with given fields: bucketName, objectPrefix, objectRegEx, client
func (_m *EventBus) RegisterStorageEvents(bucketName string, objectPrefix string, objectRegEx *regexp.Regexp, client *storage.Client) (string, error) {
	ret := _m.Called(bucketName, objectPrefix, objectRegEx, client)

	var r0 string
	if rf, ok := ret.Get(0).(func(string, string, *regexp.Regexp, *storage.Client) string); ok {
		r0 = rf(bucketName, objectPrefix, objectRegEx, client)
	} else {
		r0 = ret.Get(0).(string)
	}

	var r1 error
	if rf, ok := ret.Get(1).(func(string, string, *regexp.Regexp, *storage.Client) error); ok {
		r1 = rf(bucketName, objectPrefix, objectRegEx, client)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// SubscribeAsync provides a mock function with given fields: channelID, callback
func (_m *EventBus) SubscribeAsync(channelID string, callback eventbus.CallbackFn) {
	_m.Called(channelID, callback)
}
