diff --git a/cmd/serve/command.go b/cmd/serve/command.go index 669b2ea..b9696bc 100644 --- a/cmd/serve/command.go +++ b/cmd/serve/command.go @@ -9,6 +9,7 @@ import ( const ( flagAddr = "addr" + flagTTL = "ttl" flagGHToken = "github-token" flagTraceServiceURL = "trace-service-url" @@ -36,6 +37,11 @@ func Command() *cli.Command { Usage: "Addr to listen on.", EnvVars: []string{strcase.ToSNAKE(flagAddr)}, }, + &cli.StringFlag{ + Name: flagTTL, + Usage: "Control TTL of download responses.", + EnvVars: []string{strcase.ToSNAKE(flagTTL)}, + }, &cli.StringFlag{ Name: flagGHToken, Usage: "GitHub Token", @@ -79,6 +85,7 @@ func buildConfig(cliCtx *cli.Context) Config { Username: cliCtx.String(flagGoProxyUsername), Password: cliCtx.String(flagGoProxyPassword), }, + TTL: cliCtx.Duration(flagTTL), } } diff --git a/cmd/serve/config.go b/cmd/serve/config.go index d1d4563..870edcd 100644 --- a/cmd/serve/config.go +++ b/cmd/serve/config.go @@ -1,6 +1,8 @@ package serve import ( + "time" + "github.com/traefik/plugin-service/pkg/db/mongodb" "github.com/traefik/plugin-service/pkg/tracer" ) @@ -15,6 +17,8 @@ type Config struct { MongoDB mongodb.Config Tracing tracer.Config GoProxy GoProxy + + TTL time.Duration } // GoProxy holds the go-proxy configuration. diff --git a/cmd/serve/serve.go b/cmd/serve/serve.go index c6d0654..985d589 100644 --- a/cmd/serve/serve.go +++ b/cmd/serve/serve.go @@ -5,10 +5,8 @@ import ( "fmt" "net/http" - "github.com/google/go-github/v57/github" "github.com/gorilla/mux" "github.com/julienschmidt/httprouter" - "github.com/ldez/grignotin/goproxy" "github.com/traefik/hub-trace-kpi/trace" "github.com/traefik/plugin-service/cmd/internal" "github.com/traefik/plugin-service/pkg/handlers" @@ -17,7 +15,6 @@ import ( "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/propagation" - "golang.org/x/oauth2" ) func run(ctx context.Context, cfg Config) error { @@ -37,17 +34,18 @@ func run(ctx context.Context, cfg Config) error { return fmt.Errorf("unable to bootstrap database: %w", err) } - gpClient, err := newGoProxyClient(cfg.GoProxy) + var gpClient handlers.GoproxyPluginClient + gpClient, err = handlers.NewGoproxyClient(cfg.GoProxy.URL, cfg.GoProxy.Username, cfg.GoProxy.Password) if err != nil { return fmt.Errorf("unable to create go proxy client: %w", err) } - var ghClient *github.Client + var ghClient handlers.GithubPluginClient if cfg.GitHubToken != "" { - ghClient = newGitHubClient(context.Background(), cfg.GitHubToken) + ghClient = handlers.NewGithubClient(context.Background(), cfg.GitHubToken) } - handler := handlers.New(store, gpClient, ghClient) + handler := handlers.New(store, gpClient, ghClient, cfg.TTL) healthChecker := healthcheck.Client{DB: store} @@ -101,32 +99,6 @@ func buildExternalRouter(handler handlers.Handlers) http.Handler { return http.StripPrefix("/external", r) } -func newGoProxyClient(cfg GoProxy) (*goproxy.Client, error) { - gpClient := goproxy.NewClient(cfg.URL) - - if cfg.URL != "" && cfg.Username != "" && cfg.Password != "" { - tr, err := goproxy.NewBasicAuthTransport(cfg.Username, cfg.Password) - if err != nil { - return nil, err - } - - gpClient.HTTPClient = tr.Client() - } - - return gpClient, nil -} - -func newGitHubClient(ctx context.Context, tk string) *github.Client { - if tk == "" { - return github.NewClient(nil) - } - - ts := oauth2.StaticTokenSource( - &oauth2.Token{AccessToken: tk}, - ) - return github.NewClient(oauth2.NewClient(ctx, ts)) -} - func setupTracing(ctx context.Context, cfg tracer.Config, traceServiceURL string) (func(), error) { tracePropagator := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}) traceProvider, err := tracer.NewOTLPProvider(ctx, cfg) diff --git a/go.mod b/go.mod index b33f51b..7aaf79c 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 + golang.org/x/mod v0.18.0 golang.org/x/oauth2 v0.21.0 ) @@ -39,6 +40,7 @@ require ( github.com/montanaflynn/stats v0.7.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect @@ -47,7 +49,6 @@ require ( go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect golang.org/x/crypto v0.24.0 // indirect - golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.21.0 // indirect diff --git a/go.sum b/go.sum index 019f9f2..45aeae6 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,8 @@ github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/traefik/hub-trace-kpi v0.13.0 h1:2iWUgt77TVBW0XRm02IxNtlathBNO1gtCgTGESUn0SY= diff --git a/pkg/handlers/dbmock_test.go b/pkg/handlers/dbmock_test.go deleted file mode 100644 index eeeecd1..0000000 --- a/pkg/handlers/dbmock_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package handlers - -import ( - "context" - - "github.com/traefik/plugin-service/pkg/db" -) - -type mockDB struct { - getFn func(ctx context.Context, id string) (db.Plugin, error) - deleteFn func(ctx context.Context, id string) error - createFn func(context.Context, db.Plugin) (db.Plugin, error) - listFn func(context.Context, db.Pagination) ([]db.Plugin, string, error) - getByNameFn func(context.Context, string, bool) (db.Plugin, error) - searchByNameFn func(context.Context, string, db.Pagination) ([]db.Plugin, string, error) - updateFn func(context.Context, string, db.Plugin) (db.Plugin, error) - - deleteHashFn func(ctx context.Context, id string) error - createHashFn func(ctx context.Context, module, version, hash string) (db.PluginHash, error) - getHashByNameFn func(ctx context.Context, module, version string) (db.PluginHash, error) -} - -func (m mockDB) Get(ctx context.Context, id string) (db.Plugin, error) { - return m.getFn(ctx, id) -} - -func (m mockDB) Delete(ctx context.Context, id string) error { - return m.deleteFn(ctx, id) -} - -func (m mockDB) Create(ctx context.Context, plugin db.Plugin) (db.Plugin, error) { - return m.createFn(ctx, plugin) -} - -func (m mockDB) List(ctx context.Context, pagination db.Pagination) ([]db.Plugin, string, error) { - return m.listFn(ctx, pagination) -} - -func (m mockDB) GetByName(ctx context.Context, name string, _, filterHidden bool) (db.Plugin, error) { - return m.getByNameFn(ctx, name, filterHidden) -} - -func (m mockDB) SearchByName(ctx context.Context, query string, pagination db.Pagination) ([]db.Plugin, string, error) { - return m.searchByNameFn(ctx, query, pagination) -} - -func (m mockDB) Update(ctx context.Context, id string, plugin db.Plugin) (db.Plugin, error) { - return m.updateFn(ctx, id, plugin) -} - -func (m mockDB) DeleteHash(ctx context.Context, id string) error { - return m.deleteHashFn(ctx, id) -} - -func (m mockDB) CreateHash(ctx context.Context, module, version, hash string) (db.PluginHash, error) { - return m.createHashFn(ctx, module, version, hash) -} - -func (m mockDB) GetHashByName(ctx context.Context, module, version string) (db.PluginHash, error) { - return m.getHashByNameFn(ctx, module, version) -} diff --git a/pkg/handlers/github.go b/pkg/handlers/github.go new file mode 100644 index 0000000..f38eb3f --- /dev/null +++ b/pkg/handlers/github.go @@ -0,0 +1,45 @@ +package handlers + +import ( + "context" + "net/http" + "net/url" + + "github.com/google/go-github/v57/github" + "golang.org/x/oauth2" +) + +type GithubClient struct { + client *github.Client +} + +type GithubPluginClient interface { + Do(ctx context.Context, req *http.Request, v interface{}) (*github.Response, error) + GetArchiveLink(ctx context.Context, owner, repo string, archiveformat github.ArchiveFormat, opts *github.RepositoryContentGetOptions, maxRedirects int) (*url.URL, *github.Response, error) + GetReleaseByTag(ctx context.Context, owner, repo, tag string) (*github.RepositoryRelease, *github.Response, error) +} + +// NewGithubClient create a new GitHub client. +func NewGithubClient(ctx context.Context, token string) *GithubClient { + if token == "" { + return &GithubClient{github.NewClient(nil)} + } + + ts := oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: token}, + ) + + return &GithubClient{github.NewClient(oauth2.NewClient(ctx, ts))} +} + +func (c GithubClient) Do(ctx context.Context, req *http.Request, v interface{}) (*github.Response, error) { + return c.client.Do(ctx, req, v) +} + +func (c GithubClient) GetArchiveLink(ctx context.Context, owner, repo string, archiveformat github.ArchiveFormat, opts *github.RepositoryContentGetOptions, maxRedirects int) (*url.URL, *github.Response, error) { + return c.client.Repositories.GetArchiveLink(ctx, owner, repo, archiveformat, opts, maxRedirects) +} + +func (c GithubClient) GetReleaseByTag(ctx context.Context, owner, repo, tag string) (*github.RepositoryRelease, *github.Response, error) { + return c.client.Repositories.GetReleaseByTag(ctx, owner, repo, tag) +} diff --git a/pkg/handlers/goproxy.go b/pkg/handlers/goproxy.go new file mode 100644 index 0000000..80a2270 --- /dev/null +++ b/pkg/handlers/goproxy.go @@ -0,0 +1,41 @@ +package handlers + +import ( + "io" + + "github.com/ldez/grignotin/goproxy" + "golang.org/x/mod/modfile" +) + +type GoproxyClient struct { + client *goproxy.Client +} + +type GoproxyPluginClient interface { + DownloadSources(moduleName, version string) (io.ReadCloser, error) + GetModFile(moduleName, version string) (*modfile.File, error) +} + +// NewGoproxyClient creates a new Goproxy client. +func NewGoproxyClient(url, username, password string) (*GoproxyClient, error) { + gpClient := goproxy.NewClient(url) + + if url != "" && username != "" && password != "" { + tr, err := goproxy.NewBasicAuthTransport(username, password) + if err != nil { + return nil, err + } + + gpClient.HTTPClient = tr.Client() + } + + return &GoproxyClient{client: gpClient}, nil +} + +func (c GoproxyClient) DownloadSources(moduleName, version string) (io.ReadCloser, error) { + return c.client.DownloadSources(moduleName, version) +} + +func (c GoproxyClient) GetModFile(moduleName, version string) (*modfile.File, error) { + return c.client.GetModFile(moduleName, version) +} diff --git a/pkg/handlers/handlers.go b/pkg/handlers/handlers.go index bc3e277..e0b3b67 100644 --- a/pkg/handlers/handlers.go +++ b/pkg/handlers/handlers.go @@ -9,9 +9,8 @@ import ( "net/url" "regexp" "strconv" + "time" - "github.com/google/go-github/v57/github" - "github.com/ldez/grignotin/goproxy" "github.com/rs/zerolog/log" "github.com/traefik/plugin-service/pkg/db" "go.opentelemetry.io/otel" @@ -40,18 +39,20 @@ type PluginStorer interface { // Handlers a set of handlers. type Handlers struct { store PluginStorer - goProxy *goproxy.Client - gh *github.Client + goProxy GoproxyPluginClient + gh GithubPluginClient tracer trace.Tracer + ttl int } // New creates all HTTP handlers. -func New(store PluginStorer, goProxy *goproxy.Client, gh *github.Client) Handlers { +func New(store PluginStorer, goProxy GoproxyPluginClient, gh GithubPluginClient, ttl time.Duration) Handlers { return Handlers{ store: store, goProxy: goProxy, gh: gh, tracer: otel.GetTracerProvider().Tracer("handler"), + ttl: int(ttl.Seconds()), } } diff --git a/pkg/handlers/handlers_test.go b/pkg/handlers/handlers_test.go index 6b31f41..32e7630 100644 --- a/pkg/handlers/handlers_test.go +++ b/pkg/handlers/handlers_test.go @@ -1,7 +1,6 @@ package handlers import ( - "context" "net/http" "net/http/httptest" "os" @@ -49,17 +48,16 @@ func TestHandlers_List(t *testing.T) { }, } - testDB := mockDB{ - listFn: func(_ context.Context, _ db.Pagination) ([]db.Plugin, string, error) { - return data, "next", nil - }, - } + testDB := NewPluginStorerMock(t).OnList(db.Pagination{ + Start: "", + Size: 200, + }).Once().TypedReturns(data, "next", nil).Parent rw := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/", http.NoBody) - New(testDB, nil, nil).List(rw, req) + New(testDB, nil, nil, 0).List(rw, req) assert.Equal(t, http.StatusOK, rw.Code) assert.Equal(t, "next", rw.Header().Get(nextPageHeader)) @@ -88,17 +86,13 @@ func TestHandlers_List_GetByName(t *testing.T) { Versions: []string{"v0.2.1", "v0.2.0", "v0.1.0"}, } - testDB := mockDB{ - getByNameFn: func(_ context.Context, _ string, _ bool) (db.Plugin, error) { - return data, nil - }, - } + testDB := NewPluginStorerMock(t).OnGetByName("Demo Plugin", true, false).Once().TypedReturns(data, nil).Parent rw := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/?name=Demo%20Plugin", http.NoBody) - New(testDB, nil, nil).getByName(rw, req) + New(testDB, nil, nil, 0).getByName(rw, req) assert.Equal(t, http.StatusOK, rw.Code) @@ -127,20 +121,17 @@ func TestHandlers_List_GetByName_hidden(t *testing.T) { Hidden: true, } - testDB := mockDB{ - getByNameFn: func(_ context.Context, _ string, filterHidden bool) (db.Plugin, error) { - if filterHidden { - return data, nil - } - return db.Plugin{}, db.NotFoundError{} - }, - } + _ = data + + testDB := NewPluginStorerMock(t). + OnGetByName("Demo Plugin", true, true).Once().TypedReturns(data, nil). + OnGetByName("Demo Plugin", true, false).Once().TypedReturns(db.Plugin{}, db.NotFoundError{}).Parent rw := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/?name=Demo%20Plugin", http.NoBody) - New(testDB, nil, nil).getByName(rw, req) + New(testDB, nil, nil, 0).getByName(rw, req) assert.Equal(t, http.StatusNotFound, rw.Code) @@ -148,7 +139,7 @@ func TestHandlers_List_GetByName_hidden(t *testing.T) { req = httptest.NewRequest(http.MethodGet, "/?name=Demo%20Plugin&filterHidden=true", http.NoBody) - New(testDB, nil, nil).getByName(rw, req) + New(testDB, nil, nil, 0).getByName(rw, req) assert.Equal(t, http.StatusOK, rw.Code) @@ -176,17 +167,13 @@ func TestHandlers_List_SearchByName(t *testing.T) { Versions: []string{"v0.2.1", "v0.2.0", "v0.1.0"}, } - testDB := mockDB{ - getByNameFn: func(_ context.Context, _ string, _ bool) (db.Plugin, error) { - return data, nil - }, - } + testDB := NewPluginStorerMock(t).OnGetByName("", true, false).Once().TypedReturns(data, nil).Parent rw := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/?query=demo", http.NoBody) - New(testDB, nil, nil).getByName(rw, req) + New(testDB, nil, nil, 0).getByName(rw, req) assert.Equal(t, http.StatusOK, rw.Code) diff --git a/pkg/handlers/mock_gen.go b/pkg/handlers/mock_gen.go new file mode 100644 index 0000000..777fbf5 --- /dev/null +++ b/pkg/handlers/mock_gen.go @@ -0,0 +1,2009 @@ +// Code generated by mocktail; DO NOT EDIT. + +package handlers + +import ( + "context" + "io" + "net/http" + "net/url" + "testing" + "time" + + "github.com/google/go-github/v57/github" + "github.com/stretchr/testify/mock" + "github.com/traefik/plugin-service/pkg/db" + "golang.org/x/mod/modfile" +) + +// githubPluginClientMock mock of GithubPluginClient. +type githubPluginClientMock struct{ mock.Mock } + +// NewGithubPluginClientMock creates a new githubPluginClientMock. +func NewGithubPluginClientMock(tb testing.TB) *githubPluginClientMock { + tb.Helper() + + m := &githubPluginClientMock{} + m.Mock.Test(tb) + + tb.Cleanup(func() { m.AssertExpectations(tb) }) + + return m +} + +func (_m *githubPluginClientMock) Do(_ context.Context, req *http.Request, v interface{}) (*github.Response, error) { + _ret := _m.Called(req, v) + + if _rf, ok := _ret.Get(0).(func(*http.Request, interface{}) (*github.Response, error)); ok { + return _rf(req, v) + } + + _ra0, _ := _ret.Get(0).(*github.Response) + _rb1 := _ret.Error(1) + + return _ra0, _rb1 +} + +func (_m *githubPluginClientMock) OnDo(req *http.Request, v interface{}) *githubPluginClientDoCall { + return &githubPluginClientDoCall{Call: _m.Mock.On("Do", req, v), Parent: _m} +} + +func (_m *githubPluginClientMock) OnDoRaw(req interface{}, v interface{}) *githubPluginClientDoCall { + return &githubPluginClientDoCall{Call: _m.Mock.On("Do", req, v), Parent: _m} +} + +type githubPluginClientDoCall struct { + *mock.Call + Parent *githubPluginClientMock +} + +func (_c *githubPluginClientDoCall) Panic(msg string) *githubPluginClientDoCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *githubPluginClientDoCall) Once() *githubPluginClientDoCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *githubPluginClientDoCall) Twice() *githubPluginClientDoCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *githubPluginClientDoCall) Times(i int) *githubPluginClientDoCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *githubPluginClientDoCall) WaitUntil(w <-chan time.Time) *githubPluginClientDoCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *githubPluginClientDoCall) After(d time.Duration) *githubPluginClientDoCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *githubPluginClientDoCall) Run(fn func(args mock.Arguments)) *githubPluginClientDoCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *githubPluginClientDoCall) Maybe() *githubPluginClientDoCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *githubPluginClientDoCall) TypedReturns(a *github.Response, b error) *githubPluginClientDoCall { + _c.Call = _c.Return(a, b) + return _c +} + +func (_c *githubPluginClientDoCall) ReturnsFn(fn func(*http.Request, interface{}) (*github.Response, error)) *githubPluginClientDoCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *githubPluginClientDoCall) TypedRun(fn func(*http.Request, interface{})) *githubPluginClientDoCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _req, _ := args.Get(0).(*http.Request) + _v, _ := args.Get(1).(interface{}) + fn(_req, _v) + }) + return _c +} + +func (_c *githubPluginClientDoCall) OnDo(req *http.Request, v interface{}) *githubPluginClientDoCall { + return _c.Parent.OnDo(req, v) +} + +func (_c *githubPluginClientDoCall) OnGetArchiveLink(owner string, repo string, archiveformat github.ArchiveFormat, opts *github.RepositoryContentGetOptions, maxRedirects int) *githubPluginClientGetArchiveLinkCall { + return _c.Parent.OnGetArchiveLink(owner, repo, archiveformat, opts, maxRedirects) +} + +func (_c *githubPluginClientDoCall) OnGetReleaseByTag(owner string, repo string, tag string) *githubPluginClientGetReleaseByTagCall { + return _c.Parent.OnGetReleaseByTag(owner, repo, tag) +} + +func (_c *githubPluginClientDoCall) OnDoRaw(req interface{}, v interface{}) *githubPluginClientDoCall { + return _c.Parent.OnDoRaw(req, v) +} + +func (_c *githubPluginClientDoCall) OnGetArchiveLinkRaw(owner interface{}, repo interface{}, archiveformat interface{}, opts interface{}, maxRedirects interface{}) *githubPluginClientGetArchiveLinkCall { + return _c.Parent.OnGetArchiveLinkRaw(owner, repo, archiveformat, opts, maxRedirects) +} + +func (_c *githubPluginClientDoCall) OnGetReleaseByTagRaw(owner interface{}, repo interface{}, tag interface{}) *githubPluginClientGetReleaseByTagCall { + return _c.Parent.OnGetReleaseByTagRaw(owner, repo, tag) +} + +func (_m *githubPluginClientMock) GetArchiveLink(_ context.Context, owner string, repo string, archiveformat github.ArchiveFormat, opts *github.RepositoryContentGetOptions, maxRedirects int) (*url.URL, *github.Response, error) { + _ret := _m.Called(owner, repo, archiveformat, opts, maxRedirects) + + if _rf, ok := _ret.Get(0).(func(string, string, github.ArchiveFormat, *github.RepositoryContentGetOptions, int) (*url.URL, *github.Response, error)); ok { + return _rf(owner, repo, archiveformat, opts, maxRedirects) + } + + _ra0, _ := _ret.Get(0).(*url.URL) + _rb1, _ := _ret.Get(1).(*github.Response) + _rc2 := _ret.Error(2) + + return _ra0, _rb1, _rc2 +} + +func (_m *githubPluginClientMock) OnGetArchiveLink(owner string, repo string, archiveformat github.ArchiveFormat, opts *github.RepositoryContentGetOptions, maxRedirects int) *githubPluginClientGetArchiveLinkCall { + return &githubPluginClientGetArchiveLinkCall{Call: _m.Mock.On("GetArchiveLink", owner, repo, archiveformat, opts, maxRedirects), Parent: _m} +} + +func (_m *githubPluginClientMock) OnGetArchiveLinkRaw(owner interface{}, repo interface{}, archiveformat interface{}, opts interface{}, maxRedirects interface{}) *githubPluginClientGetArchiveLinkCall { + return &githubPluginClientGetArchiveLinkCall{Call: _m.Mock.On("GetArchiveLink", owner, repo, archiveformat, opts, maxRedirects), Parent: _m} +} + +type githubPluginClientGetArchiveLinkCall struct { + *mock.Call + Parent *githubPluginClientMock +} + +func (_c *githubPluginClientGetArchiveLinkCall) Panic(msg string) *githubPluginClientGetArchiveLinkCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *githubPluginClientGetArchiveLinkCall) Once() *githubPluginClientGetArchiveLinkCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *githubPluginClientGetArchiveLinkCall) Twice() *githubPluginClientGetArchiveLinkCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *githubPluginClientGetArchiveLinkCall) Times(i int) *githubPluginClientGetArchiveLinkCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *githubPluginClientGetArchiveLinkCall) WaitUntil(w <-chan time.Time) *githubPluginClientGetArchiveLinkCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *githubPluginClientGetArchiveLinkCall) After(d time.Duration) *githubPluginClientGetArchiveLinkCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *githubPluginClientGetArchiveLinkCall) Run(fn func(args mock.Arguments)) *githubPluginClientGetArchiveLinkCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *githubPluginClientGetArchiveLinkCall) Maybe() *githubPluginClientGetArchiveLinkCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *githubPluginClientGetArchiveLinkCall) TypedReturns(a *url.URL, b *github.Response, c error) *githubPluginClientGetArchiveLinkCall { + _c.Call = _c.Return(a, b, c) + return _c +} + +func (_c *githubPluginClientGetArchiveLinkCall) ReturnsFn(fn func(string, string, github.ArchiveFormat, *github.RepositoryContentGetOptions, int) (*url.URL, *github.Response, error)) *githubPluginClientGetArchiveLinkCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *githubPluginClientGetArchiveLinkCall) TypedRun(fn func(string, string, github.ArchiveFormat, *github.RepositoryContentGetOptions, int)) *githubPluginClientGetArchiveLinkCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _owner := args.String(0) + _repo := args.String(1) + _archiveformat, _ := args.Get(2).(github.ArchiveFormat) + _opts, _ := args.Get(3).(*github.RepositoryContentGetOptions) + _maxRedirects := args.Int(4) + fn(_owner, _repo, _archiveformat, _opts, _maxRedirects) + }) + return _c +} + +func (_c *githubPluginClientGetArchiveLinkCall) OnDo(req *http.Request, v interface{}) *githubPluginClientDoCall { + return _c.Parent.OnDo(req, v) +} + +func (_c *githubPluginClientGetArchiveLinkCall) OnGetArchiveLink(owner string, repo string, archiveformat github.ArchiveFormat, opts *github.RepositoryContentGetOptions, maxRedirects int) *githubPluginClientGetArchiveLinkCall { + return _c.Parent.OnGetArchiveLink(owner, repo, archiveformat, opts, maxRedirects) +} + +func (_c *githubPluginClientGetArchiveLinkCall) OnGetReleaseByTag(owner string, repo string, tag string) *githubPluginClientGetReleaseByTagCall { + return _c.Parent.OnGetReleaseByTag(owner, repo, tag) +} + +func (_c *githubPluginClientGetArchiveLinkCall) OnDoRaw(req interface{}, v interface{}) *githubPluginClientDoCall { + return _c.Parent.OnDoRaw(req, v) +} + +func (_c *githubPluginClientGetArchiveLinkCall) OnGetArchiveLinkRaw(owner interface{}, repo interface{}, archiveformat interface{}, opts interface{}, maxRedirects interface{}) *githubPluginClientGetArchiveLinkCall { + return _c.Parent.OnGetArchiveLinkRaw(owner, repo, archiveformat, opts, maxRedirects) +} + +func (_c *githubPluginClientGetArchiveLinkCall) OnGetReleaseByTagRaw(owner interface{}, repo interface{}, tag interface{}) *githubPluginClientGetReleaseByTagCall { + return _c.Parent.OnGetReleaseByTagRaw(owner, repo, tag) +} + +func (_m *githubPluginClientMock) GetReleaseByTag(_ context.Context, owner string, repo string, tag string) (*github.RepositoryRelease, *github.Response, error) { + _ret := _m.Called(owner, repo, tag) + + if _rf, ok := _ret.Get(0).(func(string, string, string) (*github.RepositoryRelease, *github.Response, error)); ok { + return _rf(owner, repo, tag) + } + + _ra0, _ := _ret.Get(0).(*github.RepositoryRelease) + _rb1, _ := _ret.Get(1).(*github.Response) + _rc2 := _ret.Error(2) + + return _ra0, _rb1, _rc2 +} + +func (_m *githubPluginClientMock) OnGetReleaseByTag(owner string, repo string, tag string) *githubPluginClientGetReleaseByTagCall { + return &githubPluginClientGetReleaseByTagCall{Call: _m.Mock.On("GetReleaseByTag", owner, repo, tag), Parent: _m} +} + +func (_m *githubPluginClientMock) OnGetReleaseByTagRaw(owner interface{}, repo interface{}, tag interface{}) *githubPluginClientGetReleaseByTagCall { + return &githubPluginClientGetReleaseByTagCall{Call: _m.Mock.On("GetReleaseByTag", owner, repo, tag), Parent: _m} +} + +type githubPluginClientGetReleaseByTagCall struct { + *mock.Call + Parent *githubPluginClientMock +} + +func (_c *githubPluginClientGetReleaseByTagCall) Panic(msg string) *githubPluginClientGetReleaseByTagCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *githubPluginClientGetReleaseByTagCall) Once() *githubPluginClientGetReleaseByTagCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *githubPluginClientGetReleaseByTagCall) Twice() *githubPluginClientGetReleaseByTagCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *githubPluginClientGetReleaseByTagCall) Times(i int) *githubPluginClientGetReleaseByTagCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *githubPluginClientGetReleaseByTagCall) WaitUntil(w <-chan time.Time) *githubPluginClientGetReleaseByTagCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *githubPluginClientGetReleaseByTagCall) After(d time.Duration) *githubPluginClientGetReleaseByTagCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *githubPluginClientGetReleaseByTagCall) Run(fn func(args mock.Arguments)) *githubPluginClientGetReleaseByTagCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *githubPluginClientGetReleaseByTagCall) Maybe() *githubPluginClientGetReleaseByTagCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *githubPluginClientGetReleaseByTagCall) TypedReturns(a *github.RepositoryRelease, b *github.Response, c error) *githubPluginClientGetReleaseByTagCall { + _c.Call = _c.Return(a, b, c) + return _c +} + +func (_c *githubPluginClientGetReleaseByTagCall) ReturnsFn(fn func(string, string, string) (*github.RepositoryRelease, *github.Response, error)) *githubPluginClientGetReleaseByTagCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *githubPluginClientGetReleaseByTagCall) TypedRun(fn func(string, string, string)) *githubPluginClientGetReleaseByTagCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _owner := args.String(0) + _repo := args.String(1) + _tag := args.String(2) + fn(_owner, _repo, _tag) + }) + return _c +} + +func (_c *githubPluginClientGetReleaseByTagCall) OnDo(req *http.Request, v interface{}) *githubPluginClientDoCall { + return _c.Parent.OnDo(req, v) +} + +func (_c *githubPluginClientGetReleaseByTagCall) OnGetArchiveLink(owner string, repo string, archiveformat github.ArchiveFormat, opts *github.RepositoryContentGetOptions, maxRedirects int) *githubPluginClientGetArchiveLinkCall { + return _c.Parent.OnGetArchiveLink(owner, repo, archiveformat, opts, maxRedirects) +} + +func (_c *githubPluginClientGetReleaseByTagCall) OnGetReleaseByTag(owner string, repo string, tag string) *githubPluginClientGetReleaseByTagCall { + return _c.Parent.OnGetReleaseByTag(owner, repo, tag) +} + +func (_c *githubPluginClientGetReleaseByTagCall) OnDoRaw(req interface{}, v interface{}) *githubPluginClientDoCall { + return _c.Parent.OnDoRaw(req, v) +} + +func (_c *githubPluginClientGetReleaseByTagCall) OnGetArchiveLinkRaw(owner interface{}, repo interface{}, archiveformat interface{}, opts interface{}, maxRedirects interface{}) *githubPluginClientGetArchiveLinkCall { + return _c.Parent.OnGetArchiveLinkRaw(owner, repo, archiveformat, opts, maxRedirects) +} + +func (_c *githubPluginClientGetReleaseByTagCall) OnGetReleaseByTagRaw(owner interface{}, repo interface{}, tag interface{}) *githubPluginClientGetReleaseByTagCall { + return _c.Parent.OnGetReleaseByTagRaw(owner, repo, tag) +} + +// pluginStorerMock mock of PluginStorer. +type pluginStorerMock struct{ mock.Mock } + +// NewPluginStorerMock creates a new pluginStorerMock. +func NewPluginStorerMock(tb testing.TB) *pluginStorerMock { + tb.Helper() + + m := &pluginStorerMock{} + m.Mock.Test(tb) + + tb.Cleanup(func() { m.AssertExpectations(tb) }) + + return m +} + +func (_m *pluginStorerMock) Create(_ context.Context, bParam db.Plugin) (db.Plugin, error) { + _ret := _m.Called(bParam) + + if _rf, ok := _ret.Get(0).(func(db.Plugin) (db.Plugin, error)); ok { + return _rf(bParam) + } + + _ra0, _ := _ret.Get(0).(db.Plugin) + _rb1 := _ret.Error(1) + + return _ra0, _rb1 +} + +func (_m *pluginStorerMock) OnCreate(bParam db.Plugin) *pluginStorerCreateCall { + return &pluginStorerCreateCall{Call: _m.Mock.On("Create", bParam), Parent: _m} +} + +func (_m *pluginStorerMock) OnCreateRaw(bParam interface{}) *pluginStorerCreateCall { + return &pluginStorerCreateCall{Call: _m.Mock.On("Create", bParam), Parent: _m} +} + +type pluginStorerCreateCall struct { + *mock.Call + Parent *pluginStorerMock +} + +func (_c *pluginStorerCreateCall) Panic(msg string) *pluginStorerCreateCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *pluginStorerCreateCall) Once() *pluginStorerCreateCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *pluginStorerCreateCall) Twice() *pluginStorerCreateCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *pluginStorerCreateCall) Times(i int) *pluginStorerCreateCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *pluginStorerCreateCall) WaitUntil(w <-chan time.Time) *pluginStorerCreateCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *pluginStorerCreateCall) After(d time.Duration) *pluginStorerCreateCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *pluginStorerCreateCall) Run(fn func(args mock.Arguments)) *pluginStorerCreateCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *pluginStorerCreateCall) Maybe() *pluginStorerCreateCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *pluginStorerCreateCall) TypedReturns(a db.Plugin, b error) *pluginStorerCreateCall { + _c.Call = _c.Return(a, b) + return _c +} + +func (_c *pluginStorerCreateCall) ReturnsFn(fn func(db.Plugin) (db.Plugin, error)) *pluginStorerCreateCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *pluginStorerCreateCall) TypedRun(fn func(db.Plugin)) *pluginStorerCreateCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _bParam, _ := args.Get(0).(db.Plugin) + fn(_bParam) + }) + return _c +} + +func (_c *pluginStorerCreateCall) OnCreate(bParam db.Plugin) *pluginStorerCreateCall { + return _c.Parent.OnCreate(bParam) +} + +func (_c *pluginStorerCreateCall) OnCreateHash(module string, version string, hash string) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHash(module, version, hash) +} + +func (_c *pluginStorerCreateCall) OnDelete(id string) *pluginStorerDeleteCall { + return _c.Parent.OnDelete(id) +} + +func (_c *pluginStorerCreateCall) OnGet(id string) *pluginStorerGetCall { + return _c.Parent.OnGet(id) +} + +func (_c *pluginStorerCreateCall) OnGetByName(bParam string, cParam bool, dParam bool) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByName(bParam, cParam, dParam) +} + +func (_c *pluginStorerCreateCall) OnGetHashByName(module string, version string) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByName(module, version) +} + +func (_c *pluginStorerCreateCall) OnList(bParam db.Pagination) *pluginStorerListCall { + return _c.Parent.OnList(bParam) +} + +func (_c *pluginStorerCreateCall) OnSearchByName(bParam string, cParam db.Pagination) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByName(bParam, cParam) +} + +func (_c *pluginStorerCreateCall) OnUpdate(bParam string, cParam db.Plugin) *pluginStorerUpdateCall { + return _c.Parent.OnUpdate(bParam, cParam) +} + +func (_c *pluginStorerCreateCall) OnCreateRaw(bParam interface{}) *pluginStorerCreateCall { + return _c.Parent.OnCreateRaw(bParam) +} + +func (_c *pluginStorerCreateCall) OnCreateHashRaw(module interface{}, version interface{}, hash interface{}) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHashRaw(module, version, hash) +} + +func (_c *pluginStorerCreateCall) OnDeleteRaw(id interface{}) *pluginStorerDeleteCall { + return _c.Parent.OnDeleteRaw(id) +} + +func (_c *pluginStorerCreateCall) OnGetRaw(id interface{}) *pluginStorerGetCall { + return _c.Parent.OnGetRaw(id) +} + +func (_c *pluginStorerCreateCall) OnGetByNameRaw(bParam interface{}, cParam interface{}, dParam interface{}) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByNameRaw(bParam, cParam, dParam) +} + +func (_c *pluginStorerCreateCall) OnGetHashByNameRaw(module interface{}, version interface{}) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByNameRaw(module, version) +} + +func (_c *pluginStorerCreateCall) OnListRaw(bParam interface{}) *pluginStorerListCall { + return _c.Parent.OnListRaw(bParam) +} + +func (_c *pluginStorerCreateCall) OnSearchByNameRaw(bParam interface{}, cParam interface{}) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByNameRaw(bParam, cParam) +} + +func (_c *pluginStorerCreateCall) OnUpdateRaw(bParam interface{}, cParam interface{}) *pluginStorerUpdateCall { + return _c.Parent.OnUpdateRaw(bParam, cParam) +} + +func (_m *pluginStorerMock) CreateHash(_ context.Context, module string, version string, hash string) (db.PluginHash, error) { + _ret := _m.Called(module, version, hash) + + if _rf, ok := _ret.Get(0).(func(string, string, string) (db.PluginHash, error)); ok { + return _rf(module, version, hash) + } + + _ra0, _ := _ret.Get(0).(db.PluginHash) + _rb1 := _ret.Error(1) + + return _ra0, _rb1 +} + +func (_m *pluginStorerMock) OnCreateHash(module string, version string, hash string) *pluginStorerCreateHashCall { + return &pluginStorerCreateHashCall{Call: _m.Mock.On("CreateHash", module, version, hash), Parent: _m} +} + +func (_m *pluginStorerMock) OnCreateHashRaw(module interface{}, version interface{}, hash interface{}) *pluginStorerCreateHashCall { + return &pluginStorerCreateHashCall{Call: _m.Mock.On("CreateHash", module, version, hash), Parent: _m} +} + +type pluginStorerCreateHashCall struct { + *mock.Call + Parent *pluginStorerMock +} + +func (_c *pluginStorerCreateHashCall) Panic(msg string) *pluginStorerCreateHashCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *pluginStorerCreateHashCall) Once() *pluginStorerCreateHashCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *pluginStorerCreateHashCall) Twice() *pluginStorerCreateHashCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *pluginStorerCreateHashCall) Times(i int) *pluginStorerCreateHashCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *pluginStorerCreateHashCall) WaitUntil(w <-chan time.Time) *pluginStorerCreateHashCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *pluginStorerCreateHashCall) After(d time.Duration) *pluginStorerCreateHashCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *pluginStorerCreateHashCall) Run(fn func(args mock.Arguments)) *pluginStorerCreateHashCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *pluginStorerCreateHashCall) Maybe() *pluginStorerCreateHashCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *pluginStorerCreateHashCall) TypedReturns(a db.PluginHash, b error) *pluginStorerCreateHashCall { + _c.Call = _c.Return(a, b) + return _c +} + +func (_c *pluginStorerCreateHashCall) ReturnsFn(fn func(string, string, string) (db.PluginHash, error)) *pluginStorerCreateHashCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *pluginStorerCreateHashCall) TypedRun(fn func(string, string, string)) *pluginStorerCreateHashCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _module := args.String(0) + _version := args.String(1) + _hash := args.String(2) + fn(_module, _version, _hash) + }) + return _c +} + +func (_c *pluginStorerCreateHashCall) OnCreate(bParam db.Plugin) *pluginStorerCreateCall { + return _c.Parent.OnCreate(bParam) +} + +func (_c *pluginStorerCreateHashCall) OnCreateHash(module string, version string, hash string) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHash(module, version, hash) +} + +func (_c *pluginStorerCreateHashCall) OnDelete(id string) *pluginStorerDeleteCall { + return _c.Parent.OnDelete(id) +} + +func (_c *pluginStorerCreateHashCall) OnGet(id string) *pluginStorerGetCall { + return _c.Parent.OnGet(id) +} + +func (_c *pluginStorerCreateHashCall) OnGetByName(bParam string, cParam bool, dParam bool) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByName(bParam, cParam, dParam) +} + +func (_c *pluginStorerCreateHashCall) OnGetHashByName(module string, version string) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByName(module, version) +} + +func (_c *pluginStorerCreateHashCall) OnList(bParam db.Pagination) *pluginStorerListCall { + return _c.Parent.OnList(bParam) +} + +func (_c *pluginStorerCreateHashCall) OnSearchByName(bParam string, cParam db.Pagination) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByName(bParam, cParam) +} + +func (_c *pluginStorerCreateHashCall) OnUpdate(bParam string, cParam db.Plugin) *pluginStorerUpdateCall { + return _c.Parent.OnUpdate(bParam, cParam) +} + +func (_c *pluginStorerCreateHashCall) OnCreateRaw(bParam interface{}) *pluginStorerCreateCall { + return _c.Parent.OnCreateRaw(bParam) +} + +func (_c *pluginStorerCreateHashCall) OnCreateHashRaw(module interface{}, version interface{}, hash interface{}) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHashRaw(module, version, hash) +} + +func (_c *pluginStorerCreateHashCall) OnDeleteRaw(id interface{}) *pluginStorerDeleteCall { + return _c.Parent.OnDeleteRaw(id) +} + +func (_c *pluginStorerCreateHashCall) OnGetRaw(id interface{}) *pluginStorerGetCall { + return _c.Parent.OnGetRaw(id) +} + +func (_c *pluginStorerCreateHashCall) OnGetByNameRaw(bParam interface{}, cParam interface{}, dParam interface{}) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByNameRaw(bParam, cParam, dParam) +} + +func (_c *pluginStorerCreateHashCall) OnGetHashByNameRaw(module interface{}, version interface{}) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByNameRaw(module, version) +} + +func (_c *pluginStorerCreateHashCall) OnListRaw(bParam interface{}) *pluginStorerListCall { + return _c.Parent.OnListRaw(bParam) +} + +func (_c *pluginStorerCreateHashCall) OnSearchByNameRaw(bParam interface{}, cParam interface{}) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByNameRaw(bParam, cParam) +} + +func (_c *pluginStorerCreateHashCall) OnUpdateRaw(bParam interface{}, cParam interface{}) *pluginStorerUpdateCall { + return _c.Parent.OnUpdateRaw(bParam, cParam) +} + +func (_m *pluginStorerMock) Delete(_ context.Context, id string) error { + _ret := _m.Called(id) + + if _rf, ok := _ret.Get(0).(func(string) error); ok { + return _rf(id) + } + + _ra0 := _ret.Error(0) + + return _ra0 +} + +func (_m *pluginStorerMock) OnDelete(id string) *pluginStorerDeleteCall { + return &pluginStorerDeleteCall{Call: _m.Mock.On("Delete", id), Parent: _m} +} + +func (_m *pluginStorerMock) OnDeleteRaw(id interface{}) *pluginStorerDeleteCall { + return &pluginStorerDeleteCall{Call: _m.Mock.On("Delete", id), Parent: _m} +} + +type pluginStorerDeleteCall struct { + *mock.Call + Parent *pluginStorerMock +} + +func (_c *pluginStorerDeleteCall) Panic(msg string) *pluginStorerDeleteCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *pluginStorerDeleteCall) Once() *pluginStorerDeleteCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *pluginStorerDeleteCall) Twice() *pluginStorerDeleteCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *pluginStorerDeleteCall) Times(i int) *pluginStorerDeleteCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *pluginStorerDeleteCall) WaitUntil(w <-chan time.Time) *pluginStorerDeleteCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *pluginStorerDeleteCall) After(d time.Duration) *pluginStorerDeleteCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *pluginStorerDeleteCall) Run(fn func(args mock.Arguments)) *pluginStorerDeleteCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *pluginStorerDeleteCall) Maybe() *pluginStorerDeleteCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *pluginStorerDeleteCall) TypedReturns(a error) *pluginStorerDeleteCall { + _c.Call = _c.Return(a) + return _c +} + +func (_c *pluginStorerDeleteCall) ReturnsFn(fn func(string) error) *pluginStorerDeleteCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *pluginStorerDeleteCall) TypedRun(fn func(string)) *pluginStorerDeleteCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _id := args.String(0) + fn(_id) + }) + return _c +} + +func (_c *pluginStorerDeleteCall) OnCreate(bParam db.Plugin) *pluginStorerCreateCall { + return _c.Parent.OnCreate(bParam) +} + +func (_c *pluginStorerDeleteCall) OnCreateHash(module string, version string, hash string) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHash(module, version, hash) +} + +func (_c *pluginStorerDeleteCall) OnDelete(id string) *pluginStorerDeleteCall { + return _c.Parent.OnDelete(id) +} + +func (_c *pluginStorerDeleteCall) OnGet(id string) *pluginStorerGetCall { + return _c.Parent.OnGet(id) +} + +func (_c *pluginStorerDeleteCall) OnGetByName(bParam string, cParam bool, dParam bool) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByName(bParam, cParam, dParam) +} + +func (_c *pluginStorerDeleteCall) OnGetHashByName(module string, version string) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByName(module, version) +} + +func (_c *pluginStorerDeleteCall) OnList(bParam db.Pagination) *pluginStorerListCall { + return _c.Parent.OnList(bParam) +} + +func (_c *pluginStorerDeleteCall) OnSearchByName(bParam string, cParam db.Pagination) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByName(bParam, cParam) +} + +func (_c *pluginStorerDeleteCall) OnUpdate(bParam string, cParam db.Plugin) *pluginStorerUpdateCall { + return _c.Parent.OnUpdate(bParam, cParam) +} + +func (_c *pluginStorerDeleteCall) OnCreateRaw(bParam interface{}) *pluginStorerCreateCall { + return _c.Parent.OnCreateRaw(bParam) +} + +func (_c *pluginStorerDeleteCall) OnCreateHashRaw(module interface{}, version interface{}, hash interface{}) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHashRaw(module, version, hash) +} + +func (_c *pluginStorerDeleteCall) OnDeleteRaw(id interface{}) *pluginStorerDeleteCall { + return _c.Parent.OnDeleteRaw(id) +} + +func (_c *pluginStorerDeleteCall) OnGetRaw(id interface{}) *pluginStorerGetCall { + return _c.Parent.OnGetRaw(id) +} + +func (_c *pluginStorerDeleteCall) OnGetByNameRaw(bParam interface{}, cParam interface{}, dParam interface{}) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByNameRaw(bParam, cParam, dParam) +} + +func (_c *pluginStorerDeleteCall) OnGetHashByNameRaw(module interface{}, version interface{}) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByNameRaw(module, version) +} + +func (_c *pluginStorerDeleteCall) OnListRaw(bParam interface{}) *pluginStorerListCall { + return _c.Parent.OnListRaw(bParam) +} + +func (_c *pluginStorerDeleteCall) OnSearchByNameRaw(bParam interface{}, cParam interface{}) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByNameRaw(bParam, cParam) +} + +func (_c *pluginStorerDeleteCall) OnUpdateRaw(bParam interface{}, cParam interface{}) *pluginStorerUpdateCall { + return _c.Parent.OnUpdateRaw(bParam, cParam) +} + +func (_m *pluginStorerMock) Get(_ context.Context, id string) (db.Plugin, error) { + _ret := _m.Called(id) + + if _rf, ok := _ret.Get(0).(func(string) (db.Plugin, error)); ok { + return _rf(id) + } + + _ra0, _ := _ret.Get(0).(db.Plugin) + _rb1 := _ret.Error(1) + + return _ra0, _rb1 +} + +func (_m *pluginStorerMock) OnGet(id string) *pluginStorerGetCall { + return &pluginStorerGetCall{Call: _m.Mock.On("Get", id), Parent: _m} +} + +func (_m *pluginStorerMock) OnGetRaw(id interface{}) *pluginStorerGetCall { + return &pluginStorerGetCall{Call: _m.Mock.On("Get", id), Parent: _m} +} + +type pluginStorerGetCall struct { + *mock.Call + Parent *pluginStorerMock +} + +func (_c *pluginStorerGetCall) Panic(msg string) *pluginStorerGetCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *pluginStorerGetCall) Once() *pluginStorerGetCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *pluginStorerGetCall) Twice() *pluginStorerGetCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *pluginStorerGetCall) Times(i int) *pluginStorerGetCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *pluginStorerGetCall) WaitUntil(w <-chan time.Time) *pluginStorerGetCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *pluginStorerGetCall) After(d time.Duration) *pluginStorerGetCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *pluginStorerGetCall) Run(fn func(args mock.Arguments)) *pluginStorerGetCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *pluginStorerGetCall) Maybe() *pluginStorerGetCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *pluginStorerGetCall) TypedReturns(a db.Plugin, b error) *pluginStorerGetCall { + _c.Call = _c.Return(a, b) + return _c +} + +func (_c *pluginStorerGetCall) ReturnsFn(fn func(string) (db.Plugin, error)) *pluginStorerGetCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *pluginStorerGetCall) TypedRun(fn func(string)) *pluginStorerGetCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _id := args.String(0) + fn(_id) + }) + return _c +} + +func (_c *pluginStorerGetCall) OnCreate(bParam db.Plugin) *pluginStorerCreateCall { + return _c.Parent.OnCreate(bParam) +} + +func (_c *pluginStorerGetCall) OnCreateHash(module string, version string, hash string) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHash(module, version, hash) +} + +func (_c *pluginStorerGetCall) OnDelete(id string) *pluginStorerDeleteCall { + return _c.Parent.OnDelete(id) +} + +func (_c *pluginStorerGetCall) OnGet(id string) *pluginStorerGetCall { + return _c.Parent.OnGet(id) +} + +func (_c *pluginStorerGetCall) OnGetByName(bParam string, cParam bool, dParam bool) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByName(bParam, cParam, dParam) +} + +func (_c *pluginStorerGetCall) OnGetHashByName(module string, version string) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByName(module, version) +} + +func (_c *pluginStorerGetCall) OnList(bParam db.Pagination) *pluginStorerListCall { + return _c.Parent.OnList(bParam) +} + +func (_c *pluginStorerGetCall) OnSearchByName(bParam string, cParam db.Pagination) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByName(bParam, cParam) +} + +func (_c *pluginStorerGetCall) OnUpdate(bParam string, cParam db.Plugin) *pluginStorerUpdateCall { + return _c.Parent.OnUpdate(bParam, cParam) +} + +func (_c *pluginStorerGetCall) OnCreateRaw(bParam interface{}) *pluginStorerCreateCall { + return _c.Parent.OnCreateRaw(bParam) +} + +func (_c *pluginStorerGetCall) OnCreateHashRaw(module interface{}, version interface{}, hash interface{}) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHashRaw(module, version, hash) +} + +func (_c *pluginStorerGetCall) OnDeleteRaw(id interface{}) *pluginStorerDeleteCall { + return _c.Parent.OnDeleteRaw(id) +} + +func (_c *pluginStorerGetCall) OnGetRaw(id interface{}) *pluginStorerGetCall { + return _c.Parent.OnGetRaw(id) +} + +func (_c *pluginStorerGetCall) OnGetByNameRaw(bParam interface{}, cParam interface{}, dParam interface{}) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByNameRaw(bParam, cParam, dParam) +} + +func (_c *pluginStorerGetCall) OnGetHashByNameRaw(module interface{}, version interface{}) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByNameRaw(module, version) +} + +func (_c *pluginStorerGetCall) OnListRaw(bParam interface{}) *pluginStorerListCall { + return _c.Parent.OnListRaw(bParam) +} + +func (_c *pluginStorerGetCall) OnSearchByNameRaw(bParam interface{}, cParam interface{}) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByNameRaw(bParam, cParam) +} + +func (_c *pluginStorerGetCall) OnUpdateRaw(bParam interface{}, cParam interface{}) *pluginStorerUpdateCall { + return _c.Parent.OnUpdateRaw(bParam, cParam) +} + +func (_m *pluginStorerMock) GetByName(_ context.Context, bParam string, cParam bool, dParam bool) (db.Plugin, error) { + _ret := _m.Called(bParam, cParam, dParam) + + if _rf, ok := _ret.Get(0).(func(string, bool, bool) (db.Plugin, error)); ok { + return _rf(bParam, cParam, dParam) + } + + _ra0, _ := _ret.Get(0).(db.Plugin) + _rb1 := _ret.Error(1) + + return _ra0, _rb1 +} + +func (_m *pluginStorerMock) OnGetByName(bParam string, cParam bool, dParam bool) *pluginStorerGetByNameCall { + return &pluginStorerGetByNameCall{Call: _m.Mock.On("GetByName", bParam, cParam, dParam), Parent: _m} +} + +func (_m *pluginStorerMock) OnGetByNameRaw(bParam interface{}, cParam interface{}, dParam interface{}) *pluginStorerGetByNameCall { + return &pluginStorerGetByNameCall{Call: _m.Mock.On("GetByName", bParam, cParam, dParam), Parent: _m} +} + +type pluginStorerGetByNameCall struct { + *mock.Call + Parent *pluginStorerMock +} + +func (_c *pluginStorerGetByNameCall) Panic(msg string) *pluginStorerGetByNameCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *pluginStorerGetByNameCall) Once() *pluginStorerGetByNameCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *pluginStorerGetByNameCall) Twice() *pluginStorerGetByNameCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *pluginStorerGetByNameCall) Times(i int) *pluginStorerGetByNameCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *pluginStorerGetByNameCall) WaitUntil(w <-chan time.Time) *pluginStorerGetByNameCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *pluginStorerGetByNameCall) After(d time.Duration) *pluginStorerGetByNameCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *pluginStorerGetByNameCall) Run(fn func(args mock.Arguments)) *pluginStorerGetByNameCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *pluginStorerGetByNameCall) Maybe() *pluginStorerGetByNameCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *pluginStorerGetByNameCall) TypedReturns(a db.Plugin, b error) *pluginStorerGetByNameCall { + _c.Call = _c.Return(a, b) + return _c +} + +func (_c *pluginStorerGetByNameCall) ReturnsFn(fn func(string, bool, bool) (db.Plugin, error)) *pluginStorerGetByNameCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *pluginStorerGetByNameCall) TypedRun(fn func(string, bool, bool)) *pluginStorerGetByNameCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _bParam := args.String(0) + _cParam := args.Bool(1) + _dParam := args.Bool(2) + fn(_bParam, _cParam, _dParam) + }) + return _c +} + +func (_c *pluginStorerGetByNameCall) OnCreate(bParam db.Plugin) *pluginStorerCreateCall { + return _c.Parent.OnCreate(bParam) +} + +func (_c *pluginStorerGetByNameCall) OnCreateHash(module string, version string, hash string) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHash(module, version, hash) +} + +func (_c *pluginStorerGetByNameCall) OnDelete(id string) *pluginStorerDeleteCall { + return _c.Parent.OnDelete(id) +} + +func (_c *pluginStorerGetByNameCall) OnGet(id string) *pluginStorerGetCall { + return _c.Parent.OnGet(id) +} + +func (_c *pluginStorerGetByNameCall) OnGetByName(bParam string, cParam bool, dParam bool) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByName(bParam, cParam, dParam) +} + +func (_c *pluginStorerGetByNameCall) OnGetHashByName(module string, version string) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByName(module, version) +} + +func (_c *pluginStorerGetByNameCall) OnList(bParam db.Pagination) *pluginStorerListCall { + return _c.Parent.OnList(bParam) +} + +func (_c *pluginStorerGetByNameCall) OnSearchByName(bParam string, cParam db.Pagination) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByName(bParam, cParam) +} + +func (_c *pluginStorerGetByNameCall) OnUpdate(bParam string, cParam db.Plugin) *pluginStorerUpdateCall { + return _c.Parent.OnUpdate(bParam, cParam) +} + +func (_c *pluginStorerGetByNameCall) OnCreateRaw(bParam interface{}) *pluginStorerCreateCall { + return _c.Parent.OnCreateRaw(bParam) +} + +func (_c *pluginStorerGetByNameCall) OnCreateHashRaw(module interface{}, version interface{}, hash interface{}) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHashRaw(module, version, hash) +} + +func (_c *pluginStorerGetByNameCall) OnDeleteRaw(id interface{}) *pluginStorerDeleteCall { + return _c.Parent.OnDeleteRaw(id) +} + +func (_c *pluginStorerGetByNameCall) OnGetRaw(id interface{}) *pluginStorerGetCall { + return _c.Parent.OnGetRaw(id) +} + +func (_c *pluginStorerGetByNameCall) OnGetByNameRaw(bParam interface{}, cParam interface{}, dParam interface{}) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByNameRaw(bParam, cParam, dParam) +} + +func (_c *pluginStorerGetByNameCall) OnGetHashByNameRaw(module interface{}, version interface{}) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByNameRaw(module, version) +} + +func (_c *pluginStorerGetByNameCall) OnListRaw(bParam interface{}) *pluginStorerListCall { + return _c.Parent.OnListRaw(bParam) +} + +func (_c *pluginStorerGetByNameCall) OnSearchByNameRaw(bParam interface{}, cParam interface{}) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByNameRaw(bParam, cParam) +} + +func (_c *pluginStorerGetByNameCall) OnUpdateRaw(bParam interface{}, cParam interface{}) *pluginStorerUpdateCall { + return _c.Parent.OnUpdateRaw(bParam, cParam) +} + +func (_m *pluginStorerMock) GetHashByName(_ context.Context, module string, version string) (db.PluginHash, error) { + _ret := _m.Called(module, version) + + if _rf, ok := _ret.Get(0).(func(string, string) (db.PluginHash, error)); ok { + return _rf(module, version) + } + + _ra0, _ := _ret.Get(0).(db.PluginHash) + _rb1 := _ret.Error(1) + + return _ra0, _rb1 +} + +func (_m *pluginStorerMock) OnGetHashByName(module string, version string) *pluginStorerGetHashByNameCall { + return &pluginStorerGetHashByNameCall{Call: _m.Mock.On("GetHashByName", module, version), Parent: _m} +} + +func (_m *pluginStorerMock) OnGetHashByNameRaw(module interface{}, version interface{}) *pluginStorerGetHashByNameCall { + return &pluginStorerGetHashByNameCall{Call: _m.Mock.On("GetHashByName", module, version), Parent: _m} +} + +type pluginStorerGetHashByNameCall struct { + *mock.Call + Parent *pluginStorerMock +} + +func (_c *pluginStorerGetHashByNameCall) Panic(msg string) *pluginStorerGetHashByNameCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *pluginStorerGetHashByNameCall) Once() *pluginStorerGetHashByNameCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *pluginStorerGetHashByNameCall) Twice() *pluginStorerGetHashByNameCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *pluginStorerGetHashByNameCall) Times(i int) *pluginStorerGetHashByNameCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *pluginStorerGetHashByNameCall) WaitUntil(w <-chan time.Time) *pluginStorerGetHashByNameCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *pluginStorerGetHashByNameCall) After(d time.Duration) *pluginStorerGetHashByNameCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *pluginStorerGetHashByNameCall) Run(fn func(args mock.Arguments)) *pluginStorerGetHashByNameCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *pluginStorerGetHashByNameCall) Maybe() *pluginStorerGetHashByNameCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *pluginStorerGetHashByNameCall) TypedReturns(a db.PluginHash, b error) *pluginStorerGetHashByNameCall { + _c.Call = _c.Return(a, b) + return _c +} + +func (_c *pluginStorerGetHashByNameCall) ReturnsFn(fn func(string, string) (db.PluginHash, error)) *pluginStorerGetHashByNameCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *pluginStorerGetHashByNameCall) TypedRun(fn func(string, string)) *pluginStorerGetHashByNameCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _module := args.String(0) + _version := args.String(1) + fn(_module, _version) + }) + return _c +} + +func (_c *pluginStorerGetHashByNameCall) OnCreate(bParam db.Plugin) *pluginStorerCreateCall { + return _c.Parent.OnCreate(bParam) +} + +func (_c *pluginStorerGetHashByNameCall) OnCreateHash(module string, version string, hash string) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHash(module, version, hash) +} + +func (_c *pluginStorerGetHashByNameCall) OnDelete(id string) *pluginStorerDeleteCall { + return _c.Parent.OnDelete(id) +} + +func (_c *pluginStorerGetHashByNameCall) OnGet(id string) *pluginStorerGetCall { + return _c.Parent.OnGet(id) +} + +func (_c *pluginStorerGetHashByNameCall) OnGetByName(bParam string, cParam bool, dParam bool) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByName(bParam, cParam, dParam) +} + +func (_c *pluginStorerGetHashByNameCall) OnGetHashByName(module string, version string) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByName(module, version) +} + +func (_c *pluginStorerGetHashByNameCall) OnList(bParam db.Pagination) *pluginStorerListCall { + return _c.Parent.OnList(bParam) +} + +func (_c *pluginStorerGetHashByNameCall) OnSearchByName(bParam string, cParam db.Pagination) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByName(bParam, cParam) +} + +func (_c *pluginStorerGetHashByNameCall) OnUpdate(bParam string, cParam db.Plugin) *pluginStorerUpdateCall { + return _c.Parent.OnUpdate(bParam, cParam) +} + +func (_c *pluginStorerGetHashByNameCall) OnCreateRaw(bParam interface{}) *pluginStorerCreateCall { + return _c.Parent.OnCreateRaw(bParam) +} + +func (_c *pluginStorerGetHashByNameCall) OnCreateHashRaw(module interface{}, version interface{}, hash interface{}) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHashRaw(module, version, hash) +} + +func (_c *pluginStorerGetHashByNameCall) OnDeleteRaw(id interface{}) *pluginStorerDeleteCall { + return _c.Parent.OnDeleteRaw(id) +} + +func (_c *pluginStorerGetHashByNameCall) OnGetRaw(id interface{}) *pluginStorerGetCall { + return _c.Parent.OnGetRaw(id) +} + +func (_c *pluginStorerGetHashByNameCall) OnGetByNameRaw(bParam interface{}, cParam interface{}, dParam interface{}) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByNameRaw(bParam, cParam, dParam) +} + +func (_c *pluginStorerGetHashByNameCall) OnGetHashByNameRaw(module interface{}, version interface{}) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByNameRaw(module, version) +} + +func (_c *pluginStorerGetHashByNameCall) OnListRaw(bParam interface{}) *pluginStorerListCall { + return _c.Parent.OnListRaw(bParam) +} + +func (_c *pluginStorerGetHashByNameCall) OnSearchByNameRaw(bParam interface{}, cParam interface{}) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByNameRaw(bParam, cParam) +} + +func (_c *pluginStorerGetHashByNameCall) OnUpdateRaw(bParam interface{}, cParam interface{}) *pluginStorerUpdateCall { + return _c.Parent.OnUpdateRaw(bParam, cParam) +} + +func (_m *pluginStorerMock) List(_ context.Context, bParam db.Pagination) ([]db.Plugin, string, error) { + _ret := _m.Called(bParam) + + if _rf, ok := _ret.Get(0).(func(db.Pagination) ([]db.Plugin, string, error)); ok { + return _rf(bParam) + } + + _ra0, _ := _ret.Get(0).([]db.Plugin) + _rb1 := _ret.String(1) + _rc2 := _ret.Error(2) + + return _ra0, _rb1, _rc2 +} + +func (_m *pluginStorerMock) OnList(bParam db.Pagination) *pluginStorerListCall { + return &pluginStorerListCall{Call: _m.Mock.On("List", bParam), Parent: _m} +} + +func (_m *pluginStorerMock) OnListRaw(bParam interface{}) *pluginStorerListCall { + return &pluginStorerListCall{Call: _m.Mock.On("List", bParam), Parent: _m} +} + +type pluginStorerListCall struct { + *mock.Call + Parent *pluginStorerMock +} + +func (_c *pluginStorerListCall) Panic(msg string) *pluginStorerListCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *pluginStorerListCall) Once() *pluginStorerListCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *pluginStorerListCall) Twice() *pluginStorerListCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *pluginStorerListCall) Times(i int) *pluginStorerListCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *pluginStorerListCall) WaitUntil(w <-chan time.Time) *pluginStorerListCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *pluginStorerListCall) After(d time.Duration) *pluginStorerListCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *pluginStorerListCall) Run(fn func(args mock.Arguments)) *pluginStorerListCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *pluginStorerListCall) Maybe() *pluginStorerListCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *pluginStorerListCall) TypedReturns(a []db.Plugin, b string, c error) *pluginStorerListCall { + _c.Call = _c.Return(a, b, c) + return _c +} + +func (_c *pluginStorerListCall) ReturnsFn(fn func(db.Pagination) ([]db.Plugin, string, error)) *pluginStorerListCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *pluginStorerListCall) TypedRun(fn func(db.Pagination)) *pluginStorerListCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _bParam, _ := args.Get(0).(db.Pagination) + fn(_bParam) + }) + return _c +} + +func (_c *pluginStorerListCall) OnCreate(bParam db.Plugin) *pluginStorerCreateCall { + return _c.Parent.OnCreate(bParam) +} + +func (_c *pluginStorerListCall) OnCreateHash(module string, version string, hash string) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHash(module, version, hash) +} + +func (_c *pluginStorerListCall) OnDelete(id string) *pluginStorerDeleteCall { + return _c.Parent.OnDelete(id) +} + +func (_c *pluginStorerListCall) OnGet(id string) *pluginStorerGetCall { + return _c.Parent.OnGet(id) +} + +func (_c *pluginStorerListCall) OnGetByName(bParam string, cParam bool, dParam bool) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByName(bParam, cParam, dParam) +} + +func (_c *pluginStorerListCall) OnGetHashByName(module string, version string) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByName(module, version) +} + +func (_c *pluginStorerListCall) OnList(bParam db.Pagination) *pluginStorerListCall { + return _c.Parent.OnList(bParam) +} + +func (_c *pluginStorerListCall) OnSearchByName(bParam string, cParam db.Pagination) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByName(bParam, cParam) +} + +func (_c *pluginStorerListCall) OnUpdate(bParam string, cParam db.Plugin) *pluginStorerUpdateCall { + return _c.Parent.OnUpdate(bParam, cParam) +} + +func (_c *pluginStorerListCall) OnCreateRaw(bParam interface{}) *pluginStorerCreateCall { + return _c.Parent.OnCreateRaw(bParam) +} + +func (_c *pluginStorerListCall) OnCreateHashRaw(module interface{}, version interface{}, hash interface{}) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHashRaw(module, version, hash) +} + +func (_c *pluginStorerListCall) OnDeleteRaw(id interface{}) *pluginStorerDeleteCall { + return _c.Parent.OnDeleteRaw(id) +} + +func (_c *pluginStorerListCall) OnGetRaw(id interface{}) *pluginStorerGetCall { + return _c.Parent.OnGetRaw(id) +} + +func (_c *pluginStorerListCall) OnGetByNameRaw(bParam interface{}, cParam interface{}, dParam interface{}) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByNameRaw(bParam, cParam, dParam) +} + +func (_c *pluginStorerListCall) OnGetHashByNameRaw(module interface{}, version interface{}) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByNameRaw(module, version) +} + +func (_c *pluginStorerListCall) OnListRaw(bParam interface{}) *pluginStorerListCall { + return _c.Parent.OnListRaw(bParam) +} + +func (_c *pluginStorerListCall) OnSearchByNameRaw(bParam interface{}, cParam interface{}) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByNameRaw(bParam, cParam) +} + +func (_c *pluginStorerListCall) OnUpdateRaw(bParam interface{}, cParam interface{}) *pluginStorerUpdateCall { + return _c.Parent.OnUpdateRaw(bParam, cParam) +} + +func (_m *pluginStorerMock) SearchByName(_ context.Context, bParam string, cParam db.Pagination) ([]db.Plugin, string, error) { + _ret := _m.Called(bParam, cParam) + + if _rf, ok := _ret.Get(0).(func(string, db.Pagination) ([]db.Plugin, string, error)); ok { + return _rf(bParam, cParam) + } + + _ra0, _ := _ret.Get(0).([]db.Plugin) + _rb1 := _ret.String(1) + _rc2 := _ret.Error(2) + + return _ra0, _rb1, _rc2 +} + +func (_m *pluginStorerMock) OnSearchByName(bParam string, cParam db.Pagination) *pluginStorerSearchByNameCall { + return &pluginStorerSearchByNameCall{Call: _m.Mock.On("SearchByName", bParam, cParam), Parent: _m} +} + +func (_m *pluginStorerMock) OnSearchByNameRaw(bParam interface{}, cParam interface{}) *pluginStorerSearchByNameCall { + return &pluginStorerSearchByNameCall{Call: _m.Mock.On("SearchByName", bParam, cParam), Parent: _m} +} + +type pluginStorerSearchByNameCall struct { + *mock.Call + Parent *pluginStorerMock +} + +func (_c *pluginStorerSearchByNameCall) Panic(msg string) *pluginStorerSearchByNameCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *pluginStorerSearchByNameCall) Once() *pluginStorerSearchByNameCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *pluginStorerSearchByNameCall) Twice() *pluginStorerSearchByNameCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *pluginStorerSearchByNameCall) Times(i int) *pluginStorerSearchByNameCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *pluginStorerSearchByNameCall) WaitUntil(w <-chan time.Time) *pluginStorerSearchByNameCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *pluginStorerSearchByNameCall) After(d time.Duration) *pluginStorerSearchByNameCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *pluginStorerSearchByNameCall) Run(fn func(args mock.Arguments)) *pluginStorerSearchByNameCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *pluginStorerSearchByNameCall) Maybe() *pluginStorerSearchByNameCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *pluginStorerSearchByNameCall) TypedReturns(a []db.Plugin, b string, c error) *pluginStorerSearchByNameCall { + _c.Call = _c.Return(a, b, c) + return _c +} + +func (_c *pluginStorerSearchByNameCall) ReturnsFn(fn func(string, db.Pagination) ([]db.Plugin, string, error)) *pluginStorerSearchByNameCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *pluginStorerSearchByNameCall) TypedRun(fn func(string, db.Pagination)) *pluginStorerSearchByNameCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _bParam := args.String(0) + _cParam, _ := args.Get(1).(db.Pagination) + fn(_bParam, _cParam) + }) + return _c +} + +func (_c *pluginStorerSearchByNameCall) OnCreate(bParam db.Plugin) *pluginStorerCreateCall { + return _c.Parent.OnCreate(bParam) +} + +func (_c *pluginStorerSearchByNameCall) OnCreateHash(module string, version string, hash string) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHash(module, version, hash) +} + +func (_c *pluginStorerSearchByNameCall) OnDelete(id string) *pluginStorerDeleteCall { + return _c.Parent.OnDelete(id) +} + +func (_c *pluginStorerSearchByNameCall) OnGet(id string) *pluginStorerGetCall { + return _c.Parent.OnGet(id) +} + +func (_c *pluginStorerSearchByNameCall) OnGetByName(bParam string, cParam bool, dParam bool) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByName(bParam, cParam, dParam) +} + +func (_c *pluginStorerSearchByNameCall) OnGetHashByName(module string, version string) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByName(module, version) +} + +func (_c *pluginStorerSearchByNameCall) OnList(bParam db.Pagination) *pluginStorerListCall { + return _c.Parent.OnList(bParam) +} + +func (_c *pluginStorerSearchByNameCall) OnSearchByName(bParam string, cParam db.Pagination) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByName(bParam, cParam) +} + +func (_c *pluginStorerSearchByNameCall) OnUpdate(bParam string, cParam db.Plugin) *pluginStorerUpdateCall { + return _c.Parent.OnUpdate(bParam, cParam) +} + +func (_c *pluginStorerSearchByNameCall) OnCreateRaw(bParam interface{}) *pluginStorerCreateCall { + return _c.Parent.OnCreateRaw(bParam) +} + +func (_c *pluginStorerSearchByNameCall) OnCreateHashRaw(module interface{}, version interface{}, hash interface{}) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHashRaw(module, version, hash) +} + +func (_c *pluginStorerSearchByNameCall) OnDeleteRaw(id interface{}) *pluginStorerDeleteCall { + return _c.Parent.OnDeleteRaw(id) +} + +func (_c *pluginStorerSearchByNameCall) OnGetRaw(id interface{}) *pluginStorerGetCall { + return _c.Parent.OnGetRaw(id) +} + +func (_c *pluginStorerSearchByNameCall) OnGetByNameRaw(bParam interface{}, cParam interface{}, dParam interface{}) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByNameRaw(bParam, cParam, dParam) +} + +func (_c *pluginStorerSearchByNameCall) OnGetHashByNameRaw(module interface{}, version interface{}) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByNameRaw(module, version) +} + +func (_c *pluginStorerSearchByNameCall) OnListRaw(bParam interface{}) *pluginStorerListCall { + return _c.Parent.OnListRaw(bParam) +} + +func (_c *pluginStorerSearchByNameCall) OnSearchByNameRaw(bParam interface{}, cParam interface{}) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByNameRaw(bParam, cParam) +} + +func (_c *pluginStorerSearchByNameCall) OnUpdateRaw(bParam interface{}, cParam interface{}) *pluginStorerUpdateCall { + return _c.Parent.OnUpdateRaw(bParam, cParam) +} + +func (_m *pluginStorerMock) Update(_ context.Context, bParam string, cParam db.Plugin) (db.Plugin, error) { + _ret := _m.Called(bParam, cParam) + + if _rf, ok := _ret.Get(0).(func(string, db.Plugin) (db.Plugin, error)); ok { + return _rf(bParam, cParam) + } + + _ra0, _ := _ret.Get(0).(db.Plugin) + _rb1 := _ret.Error(1) + + return _ra0, _rb1 +} + +func (_m *pluginStorerMock) OnUpdate(bParam string, cParam db.Plugin) *pluginStorerUpdateCall { + return &pluginStorerUpdateCall{Call: _m.Mock.On("Update", bParam, cParam), Parent: _m} +} + +func (_m *pluginStorerMock) OnUpdateRaw(bParam interface{}, cParam interface{}) *pluginStorerUpdateCall { + return &pluginStorerUpdateCall{Call: _m.Mock.On("Update", bParam, cParam), Parent: _m} +} + +type pluginStorerUpdateCall struct { + *mock.Call + Parent *pluginStorerMock +} + +func (_c *pluginStorerUpdateCall) Panic(msg string) *pluginStorerUpdateCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *pluginStorerUpdateCall) Once() *pluginStorerUpdateCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *pluginStorerUpdateCall) Twice() *pluginStorerUpdateCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *pluginStorerUpdateCall) Times(i int) *pluginStorerUpdateCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *pluginStorerUpdateCall) WaitUntil(w <-chan time.Time) *pluginStorerUpdateCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *pluginStorerUpdateCall) After(d time.Duration) *pluginStorerUpdateCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *pluginStorerUpdateCall) Run(fn func(args mock.Arguments)) *pluginStorerUpdateCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *pluginStorerUpdateCall) Maybe() *pluginStorerUpdateCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *pluginStorerUpdateCall) TypedReturns(a db.Plugin, b error) *pluginStorerUpdateCall { + _c.Call = _c.Return(a, b) + return _c +} + +func (_c *pluginStorerUpdateCall) ReturnsFn(fn func(string, db.Plugin) (db.Plugin, error)) *pluginStorerUpdateCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *pluginStorerUpdateCall) TypedRun(fn func(string, db.Plugin)) *pluginStorerUpdateCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _bParam := args.String(0) + _cParam, _ := args.Get(1).(db.Plugin) + fn(_bParam, _cParam) + }) + return _c +} + +func (_c *pluginStorerUpdateCall) OnCreate(bParam db.Plugin) *pluginStorerCreateCall { + return _c.Parent.OnCreate(bParam) +} + +func (_c *pluginStorerUpdateCall) OnCreateHash(module string, version string, hash string) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHash(module, version, hash) +} + +func (_c *pluginStorerUpdateCall) OnDelete(id string) *pluginStorerDeleteCall { + return _c.Parent.OnDelete(id) +} + +func (_c *pluginStorerUpdateCall) OnGet(id string) *pluginStorerGetCall { + return _c.Parent.OnGet(id) +} + +func (_c *pluginStorerUpdateCall) OnGetByName(bParam string, cParam bool, dParam bool) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByName(bParam, cParam, dParam) +} + +func (_c *pluginStorerUpdateCall) OnGetHashByName(module string, version string) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByName(module, version) +} + +func (_c *pluginStorerUpdateCall) OnList(bParam db.Pagination) *pluginStorerListCall { + return _c.Parent.OnList(bParam) +} + +func (_c *pluginStorerUpdateCall) OnSearchByName(bParam string, cParam db.Pagination) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByName(bParam, cParam) +} + +func (_c *pluginStorerUpdateCall) OnUpdate(bParam string, cParam db.Plugin) *pluginStorerUpdateCall { + return _c.Parent.OnUpdate(bParam, cParam) +} + +func (_c *pluginStorerUpdateCall) OnCreateRaw(bParam interface{}) *pluginStorerCreateCall { + return _c.Parent.OnCreateRaw(bParam) +} + +func (_c *pluginStorerUpdateCall) OnCreateHashRaw(module interface{}, version interface{}, hash interface{}) *pluginStorerCreateHashCall { + return _c.Parent.OnCreateHashRaw(module, version, hash) +} + +func (_c *pluginStorerUpdateCall) OnDeleteRaw(id interface{}) *pluginStorerDeleteCall { + return _c.Parent.OnDeleteRaw(id) +} + +func (_c *pluginStorerUpdateCall) OnGetRaw(id interface{}) *pluginStorerGetCall { + return _c.Parent.OnGetRaw(id) +} + +func (_c *pluginStorerUpdateCall) OnGetByNameRaw(bParam interface{}, cParam interface{}, dParam interface{}) *pluginStorerGetByNameCall { + return _c.Parent.OnGetByNameRaw(bParam, cParam, dParam) +} + +func (_c *pluginStorerUpdateCall) OnGetHashByNameRaw(module interface{}, version interface{}) *pluginStorerGetHashByNameCall { + return _c.Parent.OnGetHashByNameRaw(module, version) +} + +func (_c *pluginStorerUpdateCall) OnListRaw(bParam interface{}) *pluginStorerListCall { + return _c.Parent.OnListRaw(bParam) +} + +func (_c *pluginStorerUpdateCall) OnSearchByNameRaw(bParam interface{}, cParam interface{}) *pluginStorerSearchByNameCall { + return _c.Parent.OnSearchByNameRaw(bParam, cParam) +} + +func (_c *pluginStorerUpdateCall) OnUpdateRaw(bParam interface{}, cParam interface{}) *pluginStorerUpdateCall { + return _c.Parent.OnUpdateRaw(bParam, cParam) +} + +// goproxyPluginClientMock mock of GoproxyPluginClient. +type goproxyPluginClientMock struct{ mock.Mock } + +// NewGoproxyPluginClientMock creates a new goproxyPluginClientMock. +func NewGoproxyPluginClientMock(tb testing.TB) *goproxyPluginClientMock { + tb.Helper() + + m := &goproxyPluginClientMock{} + m.Mock.Test(tb) + + tb.Cleanup(func() { m.AssertExpectations(tb) }) + + return m +} + +func (_m *goproxyPluginClientMock) DownloadSources(moduleName string, version string) (io.ReadCloser, error) { + _ret := _m.Called(moduleName, version) + + if _rf, ok := _ret.Get(0).(func(string, string) (io.ReadCloser, error)); ok { + return _rf(moduleName, version) + } + + _ra0, _ := _ret.Get(0).(io.ReadCloser) + _rb1 := _ret.Error(1) + + return _ra0, _rb1 +} + +func (_m *goproxyPluginClientMock) OnDownloadSources(moduleName string, version string) *goproxyPluginClientDownloadSourcesCall { + return &goproxyPluginClientDownloadSourcesCall{Call: _m.Mock.On("DownloadSources", moduleName, version), Parent: _m} +} + +func (_m *goproxyPluginClientMock) OnDownloadSourcesRaw(moduleName interface{}, version interface{}) *goproxyPluginClientDownloadSourcesCall { + return &goproxyPluginClientDownloadSourcesCall{Call: _m.Mock.On("DownloadSources", moduleName, version), Parent: _m} +} + +type goproxyPluginClientDownloadSourcesCall struct { + *mock.Call + Parent *goproxyPluginClientMock +} + +func (_c *goproxyPluginClientDownloadSourcesCall) Panic(msg string) *goproxyPluginClientDownloadSourcesCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *goproxyPluginClientDownloadSourcesCall) Once() *goproxyPluginClientDownloadSourcesCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *goproxyPluginClientDownloadSourcesCall) Twice() *goproxyPluginClientDownloadSourcesCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *goproxyPluginClientDownloadSourcesCall) Times(i int) *goproxyPluginClientDownloadSourcesCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *goproxyPluginClientDownloadSourcesCall) WaitUntil(w <-chan time.Time) *goproxyPluginClientDownloadSourcesCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *goproxyPluginClientDownloadSourcesCall) After(d time.Duration) *goproxyPluginClientDownloadSourcesCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *goproxyPluginClientDownloadSourcesCall) Run(fn func(args mock.Arguments)) *goproxyPluginClientDownloadSourcesCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *goproxyPluginClientDownloadSourcesCall) Maybe() *goproxyPluginClientDownloadSourcesCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *goproxyPluginClientDownloadSourcesCall) TypedReturns(a io.ReadCloser, b error) *goproxyPluginClientDownloadSourcesCall { + _c.Call = _c.Return(a, b) + return _c +} + +func (_c *goproxyPluginClientDownloadSourcesCall) ReturnsFn(fn func(string, string) (io.ReadCloser, error)) *goproxyPluginClientDownloadSourcesCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *goproxyPluginClientDownloadSourcesCall) TypedRun(fn func(string, string)) *goproxyPluginClientDownloadSourcesCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _moduleName := args.String(0) + _version := args.String(1) + fn(_moduleName, _version) + }) + return _c +} + +func (_c *goproxyPluginClientDownloadSourcesCall) OnDownloadSources(moduleName string, version string) *goproxyPluginClientDownloadSourcesCall { + return _c.Parent.OnDownloadSources(moduleName, version) +} + +func (_c *goproxyPluginClientDownloadSourcesCall) OnGetModFile(moduleName string, version string) *goproxyPluginClientGetModFileCall { + return _c.Parent.OnGetModFile(moduleName, version) +} + +func (_c *goproxyPluginClientDownloadSourcesCall) OnDownloadSourcesRaw(moduleName interface{}, version interface{}) *goproxyPluginClientDownloadSourcesCall { + return _c.Parent.OnDownloadSourcesRaw(moduleName, version) +} + +func (_c *goproxyPluginClientDownloadSourcesCall) OnGetModFileRaw(moduleName interface{}, version interface{}) *goproxyPluginClientGetModFileCall { + return _c.Parent.OnGetModFileRaw(moduleName, version) +} + +func (_m *goproxyPluginClientMock) GetModFile(moduleName string, version string) (*modfile.File, error) { + _ret := _m.Called(moduleName, version) + + if _rf, ok := _ret.Get(0).(func(string, string) (*modfile.File, error)); ok { + return _rf(moduleName, version) + } + + _ra0, _ := _ret.Get(0).(*modfile.File) + _rb1 := _ret.Error(1) + + return _ra0, _rb1 +} + +func (_m *goproxyPluginClientMock) OnGetModFile(moduleName string, version string) *goproxyPluginClientGetModFileCall { + return &goproxyPluginClientGetModFileCall{Call: _m.Mock.On("GetModFile", moduleName, version), Parent: _m} +} + +func (_m *goproxyPluginClientMock) OnGetModFileRaw(moduleName interface{}, version interface{}) *goproxyPluginClientGetModFileCall { + return &goproxyPluginClientGetModFileCall{Call: _m.Mock.On("GetModFile", moduleName, version), Parent: _m} +} + +type goproxyPluginClientGetModFileCall struct { + *mock.Call + Parent *goproxyPluginClientMock +} + +func (_c *goproxyPluginClientGetModFileCall) Panic(msg string) *goproxyPluginClientGetModFileCall { + _c.Call = _c.Call.Panic(msg) + return _c +} + +func (_c *goproxyPluginClientGetModFileCall) Once() *goproxyPluginClientGetModFileCall { + _c.Call = _c.Call.Once() + return _c +} + +func (_c *goproxyPluginClientGetModFileCall) Twice() *goproxyPluginClientGetModFileCall { + _c.Call = _c.Call.Twice() + return _c +} + +func (_c *goproxyPluginClientGetModFileCall) Times(i int) *goproxyPluginClientGetModFileCall { + _c.Call = _c.Call.Times(i) + return _c +} + +func (_c *goproxyPluginClientGetModFileCall) WaitUntil(w <-chan time.Time) *goproxyPluginClientGetModFileCall { + _c.Call = _c.Call.WaitUntil(w) + return _c +} + +func (_c *goproxyPluginClientGetModFileCall) After(d time.Duration) *goproxyPluginClientGetModFileCall { + _c.Call = _c.Call.After(d) + return _c +} + +func (_c *goproxyPluginClientGetModFileCall) Run(fn func(args mock.Arguments)) *goproxyPluginClientGetModFileCall { + _c.Call = _c.Call.Run(fn) + return _c +} + +func (_c *goproxyPluginClientGetModFileCall) Maybe() *goproxyPluginClientGetModFileCall { + _c.Call = _c.Call.Maybe() + return _c +} + +func (_c *goproxyPluginClientGetModFileCall) TypedReturns(a *modfile.File, b error) *goproxyPluginClientGetModFileCall { + _c.Call = _c.Return(a, b) + return _c +} + +func (_c *goproxyPluginClientGetModFileCall) ReturnsFn(fn func(string, string) (*modfile.File, error)) *goproxyPluginClientGetModFileCall { + _c.Call = _c.Return(fn) + return _c +} + +func (_c *goproxyPluginClientGetModFileCall) TypedRun(fn func(string, string)) *goproxyPluginClientGetModFileCall { + _c.Call = _c.Call.Run(func(args mock.Arguments) { + _moduleName := args.String(0) + _version := args.String(1) + fn(_moduleName, _version) + }) + return _c +} + +func (_c *goproxyPluginClientGetModFileCall) OnDownloadSources(moduleName string, version string) *goproxyPluginClientDownloadSourcesCall { + return _c.Parent.OnDownloadSources(moduleName, version) +} + +func (_c *goproxyPluginClientGetModFileCall) OnGetModFile(moduleName string, version string) *goproxyPluginClientGetModFileCall { + return _c.Parent.OnGetModFile(moduleName, version) +} + +func (_c *goproxyPluginClientGetModFileCall) OnDownloadSourcesRaw(moduleName interface{}, version interface{}) *goproxyPluginClientDownloadSourcesCall { + return _c.Parent.OnDownloadSourcesRaw(moduleName, version) +} + +func (_c *goproxyPluginClientGetModFileCall) OnGetModFileRaw(moduleName interface{}, version interface{}) *goproxyPluginClientGetModFileCall { + return _c.Parent.OnGetModFileRaw(moduleName, version) +} diff --git a/pkg/handlers/mock_test.go b/pkg/handlers/mock_test.go new file mode 100644 index 0000000..1193aff --- /dev/null +++ b/pkg/handlers/mock_test.go @@ -0,0 +1,5 @@ +package handlers + +// mocktail:GithubPluginClient +// mocktail:PluginStorer +// mocktail:GoproxyPluginClient diff --git a/pkg/handlers/module.go b/pkg/handlers/module.go index cc43eb0..f84f733 100644 --- a/pkg/handlers/module.go +++ b/pkg/handlers/module.go @@ -23,7 +23,11 @@ import ( ) const ( - hashHeader = "X-Plugin-Hash" + hashHeader = "X-Plugin-Hash" + cacheControlHeader = "Cache-Control" + cacheControlNoCache = "no-cache" + cacheControlMaxAge = "max-age" + cacheControlSMaxAge = "s-maxage" ) // Download a plugin archive. @@ -53,11 +57,13 @@ func (h Handlers) Download(rw http.ResponseWriter, req *http.Request) { span.RecordError(err) if errors.As(err, &db.NotFoundError{}) { logger.Warn().Err(err).Msg("Unknown plugin") + setCacheControl(rw, 0) JSONErrorf(rw, http.StatusNotFound, "Unknown plugin: %s@%s", pluginName, version) return } logger.Error().Err(err).Msg("Failed to get plugin") + setCacheControl(rw, 0) JSONErrorf(rw, http.StatusInternalServerError, "Failed to get plugin %s@%s", pluginName, version) return } @@ -72,16 +78,18 @@ func (h Handlers) Download(rw http.ResponseWriter, req *http.Request) { span.RecordError(errH) if !errors.As(errH, &db.NotFoundError{}) { logger.Error().Err(errH).Msg("Failed to get plugin hash") + setCacheControl(rw, 0) JSONErrorf(rw, http.StatusInternalServerError, "Failed to get plugin %s@%s", pluginName, version) return } } else if ph.Hash == sum { + setCacheControl(rw, h.ttl) rw.WriteHeader(http.StatusNotModified) return } span.AddEvent("module.download", trace.WithAttributes(attributes...)) - logger.Error().Msgf("Someone is trying to hack the archive: %v", sum) + logger.Error().Msgf("Someone is trying to hack the archive: %v != %v", ph.Hash, sum) } span.SetAttributes(attributes...) @@ -104,6 +112,7 @@ func (h Handlers) Download(rw http.ResponseWriter, req *http.Request) { if err != nil { span.RecordError(err) logger.Error().Err(err).Msg("Failed to get module file") + setCacheControl(rw, 0) JSONErrorf(rw, http.StatusInternalServerError, "Failed to get plugin %s@%s", pluginName, version) return } @@ -158,6 +167,7 @@ func (h Handlers) downloadGoProxy(ctx context.Context, moduleName, version strin } if err == nil { + setCacheControl(rw, h.ttl) _, err = io.Copy(rw, sources) if err != nil { span.RecordError(err) @@ -197,6 +207,7 @@ func (h Handlers) downloadGoProxy(ctx context.Context, moduleName, version strin return } + setCacheControl(rw, h.ttl) _, err = rw.Write(raw) if err != nil { span.RecordError(err) @@ -223,6 +234,7 @@ func (h Handlers) downloadGitHub(ctx context.Context, moduleName, version string request, err = h.getArchiveLinkRequest(ctx, moduleName, version) } if err != nil { + setCacheControl(rw, 0) span.RecordError(err) logger.Error().Err(err).Msg("Failed to get archive link") JSONErrorf(rw, http.StatusInternalServerError, "Failed to get plugin %s@%s", moduleName, version) @@ -231,6 +243,7 @@ func (h Handlers) downloadGitHub(ctx context.Context, moduleName, version string _, err = h.store.GetHashByName(ctx, moduleName, version) if err != nil && !errors.As(err, &db.NotFoundError{}) { + setCacheControl(rw, 0) span.RecordError(err) logger.Error().Err(err).Msg("Failed to get plugin hash") JSONErrorf(rw, http.StatusInternalServerError, "Failed to get plugin %s@%s", moduleName, version) @@ -238,8 +251,10 @@ func (h Handlers) downloadGitHub(ctx context.Context, moduleName, version string } if err == nil { + setCacheControl(rw, h.ttl) _, err = h.gh.Do(ctx, request, rw) if err != nil { + setCacheControl(rw, 0) span.RecordError(err) logger.Error().Err(err).Msg("Failed to write response body") JSONErrorf(rw, http.StatusInternalServerError, "Failed to get plugin %s@%s", moduleName, version) @@ -276,7 +291,6 @@ func (h Handlers) downloadGitHub(ctx context.Context, moduleName, version string JSONErrorf(rw, http.StatusInternalServerError, "Failed to get plugin %s@%s", moduleName, version) return } - sum := fmt.Sprintf("%x", hash.Sum(nil)) _, err = h.store.CreateHash(ctx, moduleName, version, sum) @@ -287,6 +301,7 @@ func (h Handlers) downloadGitHub(ctx context.Context, moduleName, version string return } + setCacheControl(rw, h.ttl) _, err = rw.Write(raw) if err != nil { span.RecordError(err) @@ -306,7 +321,7 @@ func (h Handlers) getArchiveLinkRequest(ctx context.Context, moduleName, version owner, repoName := path.Split(strings.TrimPrefix(moduleName, "github.com/")) owner = strings.TrimSuffix(owner, "/") - link, _, err := h.gh.Repositories.GetArchiveLink(ctx, owner, repoName, github.Zipball, opts, 3) + link, _, err := h.gh.GetArchiveLink(ctx, owner, repoName, github.Zipball, opts, 3) if err != nil { span.RecordError(err) return nil, fmt.Errorf("failed to get archive link: %w", err) @@ -322,7 +337,7 @@ func (h Handlers) getAssetLinkRequest(ctx context.Context, moduleName, version s owner, repoName := path.Split(strings.TrimPrefix(moduleName, "github.com/")) owner = strings.TrimSuffix(owner, "/") - release, _, err := h.gh.Repositories.GetReleaseByTag(ctx, owner, repoName, version) + release, _, err := h.gh.GetReleaseByTag(ctx, owner, repoName, version) if err != nil { span.RecordError(err) return nil, fmt.Errorf("failed to get release: %w", err) @@ -401,3 +416,19 @@ func extractPluginInfo(endpoint *url.URL, sep string) (string, string) { func cleanModuleName(moduleName string) string { return strings.TrimSuffix(strings.TrimPrefix(moduleName, "/"), "/") } + +// cf. https://www.rfc-editor.org/rfc/rfc7231#section-6.1 +// cf. https://www.rfc-editor.org/rfc/rfc7234#section-3 +// This method should only be used when 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, and 501 are returned but setting +// Cache-Control to no-cache is the only way this can't be cached. +func setCacheControl(rw http.ResponseWriter, t int) { + if t == 0 { + rw.Header().Set(cacheControlHeader, cacheControlNoCache) + return + } + + rw.Header().Set(cacheControlHeader, strings.Join([]string{ + fmt.Sprintf("%s=%d", cacheControlMaxAge, t), + fmt.Sprintf("%s=%d", cacheControlSMaxAge, t), + }, ",")) +} diff --git a/pkg/handlers/module_test.go b/pkg/handlers/module_test.go index 9551584..b3f2857 100644 --- a/pkg/handlers/module_test.go +++ b/pkg/handlers/module_test.go @@ -1,11 +1,22 @@ package handlers import ( + "errors" + "io" + "net/http" + "net/http/httptest" "net/url" + "strings" "testing" + "time" + "github.com/google/go-github/v57/github" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/traefik/plugin-service/pkg/db" + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) func Test_cleanModuleName(t *testing.T) { @@ -102,3 +113,482 @@ func Test_extractPluginInfo(t *testing.T) { }) } } + +func Test_Download(t *testing.T) { + data := db.Plugin{ + Author: "traefik", + Compatibility: "v2", + CreatedAt: time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC), + DisplayName: "Demo Plugin", + ID: "276809780784267776", + Import: "github.com/traefik/plugindemo", + LatestVersion: "v0.2.1", + Name: "github.com/traefik/plugindemo", + Readme: "README", + Snippet: map[string]interface{}{"toml": "toml", "yaml": "yaml"}, + Stars: 22, + Summary: "[Demo] Add Request Header", + Type: "middleware", + Versions: []string{"v0.2.1", "v0.2.0", "v0.1.0"}, + } + + testDB := NewPluginStorerMock(t).OnGetByName("github.com/traefik/plugindemo", false, false).Once().TypedReturns(data, nil). + OnGetHashByName("github.com/traefik/plugindemo", "v0.2.1").TypedReturns(db.PluginHash{}, nil).Once(). + Parent + + goproxyMock := NewGoproxyPluginClientMock(t). + OnGetModFile("github.com/traefik/plugindemo", "v0.2.1").TypedReturns(&modfile.File{}, nil). + OnDownloadSources("github.com/traefik/plugindemo", "v0.2.1").TypedReturns(io.NopCloser(strings.NewReader("test")), nil). + Parent + githubMock := NewGithubPluginClientMock(t) + + rw := httptest.NewRecorder() + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/traefik/plugindemo/v0.2.1", http.NoBody) + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusOK, rw.Code) + assert.Equal(t, "test", rw.Body.String()) + assert.Equal(t, "max-age=10,s-maxage=10", rw.Header().Get(cacheControlHeader)) +} + +func Test_Download_withDifferentHash(t *testing.T) { + data := db.Plugin{ + Author: "traefik", + Compatibility: "v2", + CreatedAt: time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC), + DisplayName: "Demo Plugin", + ID: "276809780784267776", + Import: "github.com/traefik/plugindemo", + LatestVersion: "v0.2.1", + Name: "github.com/traefik/plugindemo", + Readme: "README", + Snippet: map[string]interface{}{"toml": "toml", "yaml": "yaml"}, + Stars: 22, + Summary: "[Demo] Add Request Header", + Type: "middleware", + Versions: []string{"v0.2.1", "v0.2.0", "v0.1.0"}, + } + + testDB := NewPluginStorerMock(t).OnGetByName("github.com/traefik/plugindemo", false, false).Once().TypedReturns(data, nil). + OnGetHashByName("github.com/traefik/plugindemo", "v0.2.1").Once().TypedReturns(db.PluginHash{Hash: "yy"}, nil).Twice(). + Parent + + goproxyMock := NewGoproxyPluginClientMock(t).OnGetModFile("github.com/traefik/plugindemo", "v0.2.1").Once().TypedReturns(&modfile.File{}, nil). + OnDownloadSources("github.com/traefik/plugindemo", "v0.2.1").Once().TypedReturns(io.NopCloser(strings.NewReader("test")), nil). + Parent + githubMock := NewGithubPluginClientMock(t) + + rw := httptest.NewRecorder() + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/traefik/plugindemo/v0.2.1", http.NoBody) + req.Header.Set(hashHeader, "xx") + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusOK, rw.Code) + assert.Equal(t, "test", rw.Body.String()) + assert.Equal(t, "max-age=10,s-maxage=10", rw.Header().Get(cacheControlHeader)) +} + +func Test_Download_handle_GetByName_Error(t *testing.T) { + testDB := NewPluginStorerMock(t).OnGetByName("github.com/traefik/plugindemo", false, false).Once().TypedReturns(db.Plugin{}, errors.New("test")).Parent + + goproxyMock := NewGoproxyPluginClientMock(t) + githubMock := NewGithubPluginClientMock(t) + + rw := httptest.NewRecorder() + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/traefik/plugindemo/v0.2.1", http.NoBody) + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusInternalServerError, rw.Code) + assert.Equal(t, `{"error":"Failed to get plugin github.com/traefik/plugindemo@v0.2.1"}`+"\n", rw.Body.String()) + assert.Equal(t, "no-cache", rw.Header().Get(cacheControlHeader)) +} + +func Test_Download_handle_GetByName_Error_dbNotFoundError(t *testing.T) { + testDB := NewPluginStorerMock(t).OnGetByName("github.com/traefik/plugindemo", false, false).Once().TypedReturns(db.Plugin{}, db.NotFoundError{Err: errors.New("test")}).Parent + + goproxyMock := NewGoproxyPluginClientMock(t) + githubMock := NewGithubPluginClientMock(t) + + rw := httptest.NewRecorder() + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/traefik/plugindemo/v0.2.1", http.NoBody) + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusNotFound, rw.Code) + assert.Equal(t, `{"error":"Unknown plugin: github.com/traefik/plugindemo@v0.2.1"}`+"\n", rw.Body.String()) + assert.Equal(t, "no-cache", rw.Header().Get(cacheControlHeader)) +} + +func Test_Download_handle_GetHashByName_Error(t *testing.T) { + data := db.Plugin{ + Author: "traefik", + Compatibility: "v2", + CreatedAt: time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC), + DisplayName: "Demo Plugin", + ID: "276809780784267776", + Import: "github.com/traefik/plugindemo", + LatestVersion: "v0.2.1", + Name: "github.com/traefik/plugindemo", + Readme: "README", + Snippet: map[string]interface{}{"toml": "toml", "yaml": "yaml"}, + Stars: 22, + Summary: "[Demo] Add Request Header", + Type: "middleware", + Versions: []string{"v0.2.1", "v0.2.0", "v0.1.0"}, + } + + testDB := NewPluginStorerMock(t).OnGetByName("github.com/traefik/plugindemo", false, false).Once().TypedReturns(data, nil). + OnGetHashByName("github.com/traefik/plugindemo", "v0.2.1").TypedReturns(db.PluginHash{}, errors.New("error")).Once(). + Parent + + goproxyMock := NewGoproxyPluginClientMock(t) + githubMock := NewGithubPluginClientMock(t) + + rw := httptest.NewRecorder() + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/traefik/plugindemo/v0.2.1", http.NoBody) + req.Header.Set(hashHeader, "xx") + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusInternalServerError, rw.Code) + assert.Equal(t, `{"error":"Failed to get plugin github.com/traefik/plugindemo@v0.2.1"}`+"\n", rw.Body.String()) + assert.Equal(t, "no-cache", rw.Header().Get(cacheControlHeader)) +} + +func Test_Download_handle_GetModFile_Error(t *testing.T) { + data := db.Plugin{ + Author: "traefik", + Compatibility: "v2", + CreatedAt: time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC), + DisplayName: "Demo Plugin", + ID: "276809780784267776", + Import: "github.com/traefik/plugindemo", + LatestVersion: "v0.2.1", + Name: "github.com/traefik/plugindemo", + Readme: "README", + Snippet: map[string]interface{}{"toml": "toml", "yaml": "yaml"}, + Stars: 22, + Summary: "[Demo] Add Request Header", + Type: "middleware", + Versions: []string{"v0.2.1", "v0.2.0", "v0.1.0"}, + } + + testDB := NewPluginStorerMock(t).OnGetByName("github.com/traefik/plugindemo", false, false).Once().TypedReturns(data, nil).Parent + + goproxyMock := NewGoproxyPluginClientMock(t). + OnGetModFile("github.com/traefik/plugindemo", "v0.2.1").TypedReturns(&modfile.File{}, errors.New("error")).Parent + githubMock := NewGithubPluginClientMock(t) + + rw := httptest.NewRecorder() + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/traefik/plugindemo/v0.2.1", http.NoBody) + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusInternalServerError, rw.Code) + assert.Equal(t, `{"error":"Failed to get plugin github.com/traefik/plugindemo@v0.2.1"}`+"\n", rw.Body.String()) + assert.Equal(t, "no-cache", rw.Header().Get(cacheControlHeader)) +} + +func Test_Download_unhandledMethod(t *testing.T) { + testDB := NewPluginStorerMock(t) + + goproxyMock := NewGoproxyPluginClientMock(t) + githubMock := NewGithubPluginClientMock(t) + + rw := httptest.NewRecorder() + + req := httptest.NewRequest(http.MethodHead, "/public/download/github.com/traefik/plugindemo/v0.2.1", http.NoBody) + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusMethodNotAllowed, rw.Code) +} + +func Test_Download_wasm(t *testing.T) { + data := db.Plugin{ + Author: "traefik", + Compatibility: "v2", + CreatedAt: time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC), + DisplayName: "Demo Plugin", + ID: "276809780784267776", + Import: "github.com/traefik/plugindemowasm", + LatestVersion: "v0.0.1", + Name: "github.com/traefik/plugindemowasm", + Readme: "README", + Runtime: "wasm", + Snippet: map[string]interface{}{"toml": "toml", "yaml": "yaml"}, + Stars: 22, + Summary: "Demo Plugin WASM", + Type: "middleware", + Versions: []string{"v0.0.1"}, + } + + testDB := NewPluginStorerMock(t).OnGetByName("github.com/traefik/plugindemowasm", false, false).Once().TypedReturns(data, nil). + OnGetHashByName("github.com/traefik/plugindemowasm", "v0.0.1").TypedReturns(db.PluginHash{}, nil).Once(). + Parent + + goproxyMock := NewGoproxyPluginClientMock(t) + + rw := httptest.NewRecorder() + link := &url.URL{Scheme: "https", Host: "api.github.com", Path: "/repos/traefik/plugindemowasm/releases/assets/138238821"} + + githubMock := NewGithubPluginClientMock(t). + OnGetReleaseByTag("traefik", "plugindemowasm", "v0.0.1").TypedReturns(&github.RepositoryRelease{ + Assets: []*github.ReleaseAsset{ + {Name: github.String("plugindemowasm_0.0.1_checksums.txt"), URL: github.String("https://api.github.com/repos/traefik/plugindemowasm/releases/assets/138238820")}, + {Name: github.String("plugindemowasm_v0.0.1.zip"), URL: github.String("https://api.github.com/repos/traefik/plugindemowasm/releases/assets/138238821")}, + }}, nil, nil).Once(). + OnDoRaw(mock.MatchedBy(func(req *http.Request) bool { + if req.URL.String() != link.String() { + return false + } + rw.WriteHeader(http.StatusOK) + _, _ = rw.Write([]byte("test")) + + return true + }), rw).TypedReturns(nil, nil). + Parent + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/traefik/plugindemowasm/v0.0.1", http.NoBody) + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusOK, rw.Code) + assert.Equal(t, "test", rw.Body.String()) + assert.Equal(t, "max-age=10,s-maxage=10", rw.Header().Get(cacheControlHeader)) +} + +func Test_Download_withHash(t *testing.T) { + data := db.Plugin{ + Author: "traefik", + Compatibility: "v2", + CreatedAt: time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC), + DisplayName: "Demo Plugin", + ID: "276809780784267776", + Import: "github.com/traefik/plugindemo", + LatestVersion: "v0.2.1", + Name: "github.com/traefik/plugindemo", + Readme: "README", + Snippet: map[string]interface{}{"toml": "toml", "yaml": "yaml"}, + Stars: 22, + Summary: "[Demo] Add Request Header", + Type: "middleware", + Versions: []string{"v0.2.1", "v0.2.0", "v0.1.0"}, + } + + testDB := NewPluginStorerMock(t).OnGetByName("github.com/traefik/plugindemo", false, false).Once().TypedReturns(data, nil). + OnGetHashByName("github.com/traefik/plugindemo", "v0.2.1").TypedReturns(db.PluginHash{Hash: "xx"}, nil).Once(). + Parent + + goproxyMock := NewGoproxyPluginClientMock(t) + githubMock := NewGithubPluginClientMock(t) + + rw := httptest.NewRecorder() + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/traefik/plugindemo/v0.2.1", http.NoBody) + req.Header.Set(hashHeader, "xx") + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusNotModified, rw.Code) + assert.Equal(t, "", rw.Body.String()) + assert.Equal(t, "max-age=10,s-maxage=10", rw.Header().Get(cacheControlHeader)) +} + +func Test_Download_withRequirements(t *testing.T) { + data := db.Plugin{ + Author: "maxlerebourg", + Compatibility: "", + CreatedAt: time.Date(2020, 9, 29, 6, 0, 12, 517000, time.UTC), + DisplayName: "Crowdsec Bouncer Traefik Plugin", + ID: "6335346ca4caa9ddeffda116", + Import: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", + LatestVersion: "v1.3.5", + Name: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", + Readme: "![GitHub](https://img.shields.io/github/license/maxlerebourg/crowdsec-bouncer-traefik-plugin)\n...", + Snippet: map[string]interface{}{"toml": "toml", "yaml": "yaml"}, + Stars: 22, + Summary: "Middleware plugin which forwards the request IP to local Crowdsec agent, which can be used to allow/deny the request", + Type: "middleware", + Versions: []string{"v1.3.5", "v1.3.4"}, + } + + testDB := NewPluginStorerMock(t).OnGetByName("github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", false, false).Once().TypedReturns(data, nil). + OnGetHashByName("github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", "v1.3.5").TypedReturns(db.PluginHash{}, nil).Once(). + Parent + + goproxyMock := NewGoproxyPluginClientMock(t). + OnGetModFile("github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", "v1.3.5").TypedReturns( + &modfile.File{ + Require: []*modfile.Require{ + {Mod: module.Version{Path: "github.com/leprosus/golang-ttl-map", Version: "v1.1.7"}, Indirect: false}, + {Mod: module.Version{Path: "github.com/maxlerebourg/simpleredis", Version: "v1.0.11"}, Indirect: false}, + }, + }, nil). + Parent + + rw := httptest.NewRecorder() + link := &url.URL{Scheme: "https", Host: "codeload.github.com", Path: "/maxlerebourg/crowdsec-bouncer-traefik-plugin/legacy.zip/refs/tags/v1.3.5"} + githubMock := NewGithubPluginClientMock(t).OnGetArchiveLink("maxlerebourg", "crowdsec-bouncer-traefik-plugin", "zipball", &github.RepositoryContentGetOptions{Ref: "v1.3.5"}, 3).TypedReturns(link, &github.Response{Response: &http.Response{StatusCode: http.StatusFound, Header: map[string][]string{"location": {link.String()}}}}, nil).Once(). + OnDoRaw(mock.MatchedBy(func(req *http.Request) bool { + if req.URL.String() != link.String() { + return false + } + rw.WriteHeader(http.StatusOK) + _, _ = rw.Write([]byte("test")) + + return true + }), rw).TypedReturns(nil, nil).Parent + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/v1.3.5", http.NoBody) + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusOK, rw.Code) + assert.Equal(t, "test", rw.Body.String()) + assert.Equal(t, "max-age=10,s-maxage=10", rw.Header().Get(cacheControlHeader)) +} + +func Test_Download_withRequirements_handle_Do_Error(t *testing.T) { + data := db.Plugin{ + Author: "maxlerebourg", + Compatibility: "", + CreatedAt: time.Date(2020, 9, 29, 6, 0, 12, 517000, time.UTC), + DisplayName: "Crowdsec Bouncer Traefik Plugin", + ID: "6335346ca4caa9ddeffda116", + Import: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", + LatestVersion: "v1.3.5", + Name: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", + Readme: "![GitHub](https://img.shields.io/github/license/maxlerebourg/crowdsec-bouncer-traefik-plugin)\n...", + Snippet: map[string]interface{}{"toml": "toml", "yaml": "yaml"}, + Stars: 22, + Summary: "Middleware plugin which forwards the request IP to local Crowdsec agent, which can be used to allow/deny the request", + Type: "middleware", + Versions: []string{"v1.3.5", "v1.3.4"}, + } + + testDB := NewPluginStorerMock(t).OnGetByName("github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", false, false).Once().TypedReturns(data, nil). + OnGetHashByName("github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", "v1.3.5").TypedReturns(db.PluginHash{}, nil).Once(). + Parent + + goproxyMock := NewGoproxyPluginClientMock(t). + OnGetModFile("github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", "v1.3.5").TypedReturns( + &modfile.File{ + Require: []*modfile.Require{ + {Mod: module.Version{Path: "github.com/leprosus/golang-ttl-map", Version: "v1.1.7"}, Indirect: false}, + {Mod: module.Version{Path: "github.com/maxlerebourg/simpleredis", Version: "v1.0.11"}, Indirect: false}, + }, + }, nil). + Parent + + rw := httptest.NewRecorder() + link := &url.URL{Scheme: "https", Host: "codeload.github.com", Path: "/maxlerebourg/crowdsec-bouncer-traefik-plugin/legacy.zip/refs/tags/v1.3.5"} + githubMock := NewGithubPluginClientMock(t).OnGetArchiveLink("maxlerebourg", "crowdsec-bouncer-traefik-plugin", "zipball", &github.RepositoryContentGetOptions{Ref: "v1.3.5"}, 3).TypedReturns(link, &github.Response{Response: &http.Response{StatusCode: http.StatusFound, Header: map[string][]string{"location": {link.String()}}}}, nil).Once(). + OnDoRaw(mock.MatchedBy(func(req *http.Request) bool { + return req.URL.String() == link.String() + }), rw).TypedReturns(nil, errors.New("error")).Parent + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/v1.3.5", http.NoBody) + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusInternalServerError, rw.Code) + assert.Equal(t, `{"error":"Failed to get plugin github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin@v1.3.5"}`+"\n", rw.Body.String()) + assert.Equal(t, "no-cache", rw.Header().Get(cacheControlHeader)) +} + +func Test_Download_withRequirements_handle_GetArchiveLink_Error(t *testing.T) { + data := db.Plugin{ + Author: "maxlerebourg", + Compatibility: "", + CreatedAt: time.Date(2020, 9, 29, 6, 0, 12, 517000, time.UTC), + DisplayName: "Crowdsec Bouncer Traefik Plugin", + ID: "6335346ca4caa9ddeffda116", + Import: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", + LatestVersion: "v1.3.5", + Name: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", + Readme: "![GitHub](https://img.shields.io/github/license/maxlerebourg/crowdsec-bouncer-traefik-plugin)\n...", + Snippet: map[string]interface{}{"toml": "toml", "yaml": "yaml"}, + Stars: 22, + Summary: "Middleware plugin which forwards the request IP to local Crowdsec agent, which can be used to allow/deny the request", + Type: "middleware", + Versions: []string{"v1.3.5", "v1.3.4"}, + } + + testDB := NewPluginStorerMock(t).OnGetByName("github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", false, false).Once().TypedReturns(data, nil).Parent + + goproxyMock := NewGoproxyPluginClientMock(t). + OnGetModFile("github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", "v1.3.5").TypedReturns( + &modfile.File{ + Require: []*modfile.Require{ + {Mod: module.Version{Path: "github.com/leprosus/golang-ttl-map", Version: "v1.1.7"}, Indirect: false}, + {Mod: module.Version{Path: "github.com/maxlerebourg/simpleredis", Version: "v1.0.11"}, Indirect: false}, + }, + }, nil). + Parent + + rw := httptest.NewRecorder() + githubMock := NewGithubPluginClientMock(t).OnGetArchiveLink("maxlerebourg", "crowdsec-bouncer-traefik-plugin", "zipball", &github.RepositoryContentGetOptions{Ref: "v1.3.5"}, 3).TypedReturns(nil, nil, errors.New("error")).Once().Parent + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/v1.3.5", http.NoBody) + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusInternalServerError, rw.Code) + assert.Equal(t, `{"error":"Failed to get plugin github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin@v1.3.5"}`+"\n", rw.Body.String()) + assert.Equal(t, "no-cache", rw.Header().Get(cacheControlHeader)) +} + +func Test_Download_withRequirements_handle_GetHashByName_Error(t *testing.T) { + data := db.Plugin{ + Author: "maxlerebourg", + Compatibility: "", + CreatedAt: time.Date(2020, 9, 29, 6, 0, 12, 517000, time.UTC), + DisplayName: "Crowdsec Bouncer Traefik Plugin", + ID: "6335346ca4caa9ddeffda116", + Import: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", + LatestVersion: "v1.3.5", + Name: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", + Readme: "![GitHub](https://img.shields.io/github/license/maxlerebourg/crowdsec-bouncer-traefik-plugin)\n...", + Snippet: map[string]interface{}{"toml": "toml", "yaml": "yaml"}, + Stars: 22, + Summary: "Middleware plugin which forwards the request IP to local Crowdsec agent, which can be used to allow/deny the request", + Type: "middleware", + Versions: []string{"v1.3.5", "v1.3.4"}, + } + + testDB := NewPluginStorerMock(t).OnGetByName("github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", false, false).Once().TypedReturns(data, nil). + OnGetHashByName("github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", "v1.3.5").TypedReturns(db.PluginHash{}, errors.New("error")).Once(). + Parent + + goproxyMock := NewGoproxyPluginClientMock(t). + OnGetModFile("github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin", "v1.3.5").TypedReturns( + &modfile.File{ + Require: []*modfile.Require{ + {Mod: module.Version{Path: "github.com/leprosus/golang-ttl-map", Version: "v1.1.7"}, Indirect: false}, + {Mod: module.Version{Path: "github.com/maxlerebourg/simpleredis", Version: "v1.0.11"}, Indirect: false}, + }, + }, nil). + Parent + + rw := httptest.NewRecorder() + link := &url.URL{Scheme: "https", Host: "codeload.github.com", Path: "/maxlerebourg/crowdsec-bouncer-traefik-plugin/legacy.zip/refs/tags/v1.3.5"} + githubMock := NewGithubPluginClientMock(t).OnGetArchiveLink("maxlerebourg", "crowdsec-bouncer-traefik-plugin", "zipball", &github.RepositoryContentGetOptions{Ref: "v1.3.5"}, 3).TypedReturns(link, &github.Response{Response: &http.Response{StatusCode: http.StatusFound, Header: map[string][]string{"location": {link.String()}}}}, nil).Once().Parent + + req := httptest.NewRequest(http.MethodGet, "/public/download/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/v1.3.5", http.NoBody) + + New(testDB, goproxyMock, githubMock, 10*time.Second).Download(rw, req) + + assert.Equal(t, http.StatusInternalServerError, rw.Code) + assert.Equal(t, `{"error":"Failed to get plugin github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin@v1.3.5"}`+"\n", rw.Body.String()) + assert.Equal(t, "no-cache", rw.Header().Get(cacheControlHeader)) +}