// Code generated by mockery v2.4.0. DO NOT EDIT.

package mocks

import (
	clstore "go.skia.org/infra/golden/go/clstore"
	code_review "go.skia.org/infra/golden/go/code_review"

	context "context"

	mock "github.com/stretchr/testify/mock"
)

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

// GetChangelist provides a mock function with given fields: ctx, id
func (_m *Store) GetChangelist(ctx context.Context, id string) (code_review.Changelist, error) {
	ret := _m.Called(ctx, id)

	var r0 code_review.Changelist
	if rf, ok := ret.Get(0).(func(context.Context, string) code_review.Changelist); ok {
		r0 = rf(ctx, id)
	} else {
		r0 = ret.Get(0).(code_review.Changelist)
	}

	var r1 error
	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
		r1 = rf(ctx, id)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// GetChangelists provides a mock function with given fields: ctx, opts
func (_m *Store) GetChangelists(ctx context.Context, opts clstore.SearchOptions) ([]code_review.Changelist, int, error) {
	ret := _m.Called(ctx, opts)

	var r0 []code_review.Changelist
	if rf, ok := ret.Get(0).(func(context.Context, clstore.SearchOptions) []code_review.Changelist); ok {
		r0 = rf(ctx, opts)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]code_review.Changelist)
		}
	}

	var r1 int
	if rf, ok := ret.Get(1).(func(context.Context, clstore.SearchOptions) int); ok {
		r1 = rf(ctx, opts)
	} else {
		r1 = ret.Get(1).(int)
	}

	var r2 error
	if rf, ok := ret.Get(2).(func(context.Context, clstore.SearchOptions) error); ok {
		r2 = rf(ctx, opts)
	} else {
		r2 = ret.Error(2)
	}

	return r0, r1, r2
}

// GetPatchset provides a mock function with given fields: ctx, clID, psID
func (_m *Store) GetPatchset(ctx context.Context, clID string, psID string) (code_review.Patchset, error) {
	ret := _m.Called(ctx, clID, psID)

	var r0 code_review.Patchset
	if rf, ok := ret.Get(0).(func(context.Context, string, string) code_review.Patchset); ok {
		r0 = rf(ctx, clID, psID)
	} else {
		r0 = ret.Get(0).(code_review.Patchset)
	}

	var r1 error
	if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
		r1 = rf(ctx, clID, psID)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// GetPatchsetByOrder provides a mock function with given fields: ctx, clID, psOrder
func (_m *Store) GetPatchsetByOrder(ctx context.Context, clID string, psOrder int) (code_review.Patchset, error) {
	ret := _m.Called(ctx, clID, psOrder)

	var r0 code_review.Patchset
	if rf, ok := ret.Get(0).(func(context.Context, string, int) code_review.Patchset); ok {
		r0 = rf(ctx, clID, psOrder)
	} else {
		r0 = ret.Get(0).(code_review.Patchset)
	}

	var r1 error
	if rf, ok := ret.Get(1).(func(context.Context, string, int) error); ok {
		r1 = rf(ctx, clID, psOrder)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// GetPatchsets provides a mock function with given fields: ctx, clID
func (_m *Store) GetPatchsets(ctx context.Context, clID string) ([]code_review.Patchset, error) {
	ret := _m.Called(ctx, clID)

	var r0 []code_review.Patchset
	if rf, ok := ret.Get(0).(func(context.Context, string) []code_review.Patchset); ok {
		r0 = rf(ctx, clID)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]code_review.Patchset)
		}
	}

	var r1 error
	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
		r1 = rf(ctx, clID)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// PutChangelist provides a mock function with given fields: ctx, cl
func (_m *Store) PutChangelist(ctx context.Context, cl code_review.Changelist) error {
	ret := _m.Called(ctx, cl)

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, code_review.Changelist) error); ok {
		r0 = rf(ctx, cl)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// PutPatchset provides a mock function with given fields: ctx, ps
func (_m *Store) PutPatchset(ctx context.Context, ps code_review.Patchset) error {
	ret := _m.Called(ctx, ps)

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, code_review.Patchset) error); ok {
		r0 = rf(ctx, ps)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}
