diff --git a/makefile b/makefile index b70c54afc..3b57587fd 100644 --- a/makefile +++ b/makefile @@ -35,7 +35,7 @@ generate-swagger: # To install mockery, `brew install mockery` # (As a backup, use `go install github.com/vektra/mockery/v2@v2.32.4` but check https://github.com/vektra/mockery/releases for versions) generate-mocks: - cd sherlock && go generate ./... + cd sherlock && mockery # We use `go mod vendor` to package local dependencies in a way that the gcloud CLI can upload, but # we don't keep that directory around because it'll confuse GoLand (we want our source of truth to be diff --git a/sherlock/.mockery.yaml b/sherlock/.mockery.yaml index 5e0076a33..41a5c4485 100644 --- a/sherlock/.mockery.yaml +++ b/sherlock/.mockery.yaml @@ -5,6 +5,11 @@ mockname: "Mock{{ .InterfaceNameCamel }}" outpkg: "{{ .PackageName }}_mocks" packages: + github.com/gin-gonic/gin: + interfaces: + IRoutes: + config: + dir: ./internal/api/gin_mocks github.com/broadinstitute/sherlock/sherlock/internal/github: interfaces: mockableActionsClient: diff --git a/sherlock/internal/api/gin_mocks/mock_i_routes.go b/sherlock/internal/api/gin_mocks/mock_i_routes.go new file mode 100644 index 000000000..3ccb8cf60 --- /dev/null +++ b/sherlock/internal/api/gin_mocks/mock_i_routes.go @@ -0,0 +1,868 @@ +// Code generated by mockery v2.32.4. DO NOT EDIT. + +package gin_mocks + +import ( + http "net/http" + + gin "github.com/gin-gonic/gin" + + mock "github.com/stretchr/testify/mock" +) + +// MockIRoutes is an autogenerated mock type for the IRoutes type +type MockIRoutes struct { + mock.Mock +} + +type MockIRoutes_Expecter struct { + mock *mock.Mock +} + +func (_m *MockIRoutes) EXPECT() *MockIRoutes_Expecter { + return &MockIRoutes_Expecter{mock: &_m.Mock} +} + +// Any provides a mock function with given fields: _a0, _a1 +func (_m *MockIRoutes) Any(_a0 string, _a1 ...gin.HandlerFunc) gin.IRoutes { + _va := make([]interface{}, len(_a1)) + for _i := range _a1 { + _va[_i] = _a1[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, ...gin.HandlerFunc) gin.IRoutes); ok { + r0 = rf(_a0, _a1...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_Any_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Any' +type MockIRoutes_Any_Call struct { + *mock.Call +} + +// Any is a helper method to define mock.On call +// - _a0 string +// - _a1 ...gin.HandlerFunc +func (_e *MockIRoutes_Expecter) Any(_a0 interface{}, _a1 ...interface{}) *MockIRoutes_Any_Call { + return &MockIRoutes_Any_Call{Call: _e.mock.On("Any", + append([]interface{}{_a0}, _a1...)...)} +} + +func (_c *MockIRoutes_Any_Call) Run(run func(_a0 string, _a1 ...gin.HandlerFunc)) *MockIRoutes_Any_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]gin.HandlerFunc, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(gin.HandlerFunc) + } + } + run(args[0].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockIRoutes_Any_Call) Return(_a0 gin.IRoutes) *MockIRoutes_Any_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_Any_Call) RunAndReturn(run func(string, ...gin.HandlerFunc) gin.IRoutes) *MockIRoutes_Any_Call { + _c.Call.Return(run) + return _c +} + +// DELETE provides a mock function with given fields: _a0, _a1 +func (_m *MockIRoutes) DELETE(_a0 string, _a1 ...gin.HandlerFunc) gin.IRoutes { + _va := make([]interface{}, len(_a1)) + for _i := range _a1 { + _va[_i] = _a1[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, ...gin.HandlerFunc) gin.IRoutes); ok { + r0 = rf(_a0, _a1...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_DELETE_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DELETE' +type MockIRoutes_DELETE_Call struct { + *mock.Call +} + +// DELETE is a helper method to define mock.On call +// - _a0 string +// - _a1 ...gin.HandlerFunc +func (_e *MockIRoutes_Expecter) DELETE(_a0 interface{}, _a1 ...interface{}) *MockIRoutes_DELETE_Call { + return &MockIRoutes_DELETE_Call{Call: _e.mock.On("DELETE", + append([]interface{}{_a0}, _a1...)...)} +} + +func (_c *MockIRoutes_DELETE_Call) Run(run func(_a0 string, _a1 ...gin.HandlerFunc)) *MockIRoutes_DELETE_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]gin.HandlerFunc, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(gin.HandlerFunc) + } + } + run(args[0].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockIRoutes_DELETE_Call) Return(_a0 gin.IRoutes) *MockIRoutes_DELETE_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_DELETE_Call) RunAndReturn(run func(string, ...gin.HandlerFunc) gin.IRoutes) *MockIRoutes_DELETE_Call { + _c.Call.Return(run) + return _c +} + +// GET provides a mock function with given fields: _a0, _a1 +func (_m *MockIRoutes) GET(_a0 string, _a1 ...gin.HandlerFunc) gin.IRoutes { + _va := make([]interface{}, len(_a1)) + for _i := range _a1 { + _va[_i] = _a1[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, ...gin.HandlerFunc) gin.IRoutes); ok { + r0 = rf(_a0, _a1...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_GET_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GET' +type MockIRoutes_GET_Call struct { + *mock.Call +} + +// GET is a helper method to define mock.On call +// - _a0 string +// - _a1 ...gin.HandlerFunc +func (_e *MockIRoutes_Expecter) GET(_a0 interface{}, _a1 ...interface{}) *MockIRoutes_GET_Call { + return &MockIRoutes_GET_Call{Call: _e.mock.On("GET", + append([]interface{}{_a0}, _a1...)...)} +} + +func (_c *MockIRoutes_GET_Call) Run(run func(_a0 string, _a1 ...gin.HandlerFunc)) *MockIRoutes_GET_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]gin.HandlerFunc, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(gin.HandlerFunc) + } + } + run(args[0].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockIRoutes_GET_Call) Return(_a0 gin.IRoutes) *MockIRoutes_GET_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_GET_Call) RunAndReturn(run func(string, ...gin.HandlerFunc) gin.IRoutes) *MockIRoutes_GET_Call { + _c.Call.Return(run) + return _c +} + +// HEAD provides a mock function with given fields: _a0, _a1 +func (_m *MockIRoutes) HEAD(_a0 string, _a1 ...gin.HandlerFunc) gin.IRoutes { + _va := make([]interface{}, len(_a1)) + for _i := range _a1 { + _va[_i] = _a1[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, ...gin.HandlerFunc) gin.IRoutes); ok { + r0 = rf(_a0, _a1...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_HEAD_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HEAD' +type MockIRoutes_HEAD_Call struct { + *mock.Call +} + +// HEAD is a helper method to define mock.On call +// - _a0 string +// - _a1 ...gin.HandlerFunc +func (_e *MockIRoutes_Expecter) HEAD(_a0 interface{}, _a1 ...interface{}) *MockIRoutes_HEAD_Call { + return &MockIRoutes_HEAD_Call{Call: _e.mock.On("HEAD", + append([]interface{}{_a0}, _a1...)...)} +} + +func (_c *MockIRoutes_HEAD_Call) Run(run func(_a0 string, _a1 ...gin.HandlerFunc)) *MockIRoutes_HEAD_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]gin.HandlerFunc, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(gin.HandlerFunc) + } + } + run(args[0].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockIRoutes_HEAD_Call) Return(_a0 gin.IRoutes) *MockIRoutes_HEAD_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_HEAD_Call) RunAndReturn(run func(string, ...gin.HandlerFunc) gin.IRoutes) *MockIRoutes_HEAD_Call { + _c.Call.Return(run) + return _c +} + +// Handle provides a mock function with given fields: _a0, _a1, _a2 +func (_m *MockIRoutes) Handle(_a0 string, _a1 string, _a2 ...gin.HandlerFunc) gin.IRoutes { + _va := make([]interface{}, len(_a2)) + for _i := range _a2 { + _va[_i] = _a2[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0, _a1) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, string, ...gin.HandlerFunc) gin.IRoutes); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_Handle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Handle' +type MockIRoutes_Handle_Call struct { + *mock.Call +} + +// Handle is a helper method to define mock.On call +// - _a0 string +// - _a1 string +// - _a2 ...gin.HandlerFunc +func (_e *MockIRoutes_Expecter) Handle(_a0 interface{}, _a1 interface{}, _a2 ...interface{}) *MockIRoutes_Handle_Call { + return &MockIRoutes_Handle_Call{Call: _e.mock.On("Handle", + append([]interface{}{_a0, _a1}, _a2...)...)} +} + +func (_c *MockIRoutes_Handle_Call) Run(run func(_a0 string, _a1 string, _a2 ...gin.HandlerFunc)) *MockIRoutes_Handle_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]gin.HandlerFunc, len(args)-2) + for i, a := range args[2:] { + if a != nil { + variadicArgs[i] = a.(gin.HandlerFunc) + } + } + run(args[0].(string), args[1].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockIRoutes_Handle_Call) Return(_a0 gin.IRoutes) *MockIRoutes_Handle_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_Handle_Call) RunAndReturn(run func(string, string, ...gin.HandlerFunc) gin.IRoutes) *MockIRoutes_Handle_Call { + _c.Call.Return(run) + return _c +} + +// Match provides a mock function with given fields: _a0, _a1, _a2 +func (_m *MockIRoutes) Match(_a0 []string, _a1 string, _a2 ...gin.HandlerFunc) gin.IRoutes { + _va := make([]interface{}, len(_a2)) + for _i := range _a2 { + _va[_i] = _a2[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0, _a1) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func([]string, string, ...gin.HandlerFunc) gin.IRoutes); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_Match_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Match' +type MockIRoutes_Match_Call struct { + *mock.Call +} + +// Match is a helper method to define mock.On call +// - _a0 []string +// - _a1 string +// - _a2 ...gin.HandlerFunc +func (_e *MockIRoutes_Expecter) Match(_a0 interface{}, _a1 interface{}, _a2 ...interface{}) *MockIRoutes_Match_Call { + return &MockIRoutes_Match_Call{Call: _e.mock.On("Match", + append([]interface{}{_a0, _a1}, _a2...)...)} +} + +func (_c *MockIRoutes_Match_Call) Run(run func(_a0 []string, _a1 string, _a2 ...gin.HandlerFunc)) *MockIRoutes_Match_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]gin.HandlerFunc, len(args)-2) + for i, a := range args[2:] { + if a != nil { + variadicArgs[i] = a.(gin.HandlerFunc) + } + } + run(args[0].([]string), args[1].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockIRoutes_Match_Call) Return(_a0 gin.IRoutes) *MockIRoutes_Match_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_Match_Call) RunAndReturn(run func([]string, string, ...gin.HandlerFunc) gin.IRoutes) *MockIRoutes_Match_Call { + _c.Call.Return(run) + return _c +} + +// OPTIONS provides a mock function with given fields: _a0, _a1 +func (_m *MockIRoutes) OPTIONS(_a0 string, _a1 ...gin.HandlerFunc) gin.IRoutes { + _va := make([]interface{}, len(_a1)) + for _i := range _a1 { + _va[_i] = _a1[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, ...gin.HandlerFunc) gin.IRoutes); ok { + r0 = rf(_a0, _a1...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_OPTIONS_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OPTIONS' +type MockIRoutes_OPTIONS_Call struct { + *mock.Call +} + +// OPTIONS is a helper method to define mock.On call +// - _a0 string +// - _a1 ...gin.HandlerFunc +func (_e *MockIRoutes_Expecter) OPTIONS(_a0 interface{}, _a1 ...interface{}) *MockIRoutes_OPTIONS_Call { + return &MockIRoutes_OPTIONS_Call{Call: _e.mock.On("OPTIONS", + append([]interface{}{_a0}, _a1...)...)} +} + +func (_c *MockIRoutes_OPTIONS_Call) Run(run func(_a0 string, _a1 ...gin.HandlerFunc)) *MockIRoutes_OPTIONS_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]gin.HandlerFunc, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(gin.HandlerFunc) + } + } + run(args[0].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockIRoutes_OPTIONS_Call) Return(_a0 gin.IRoutes) *MockIRoutes_OPTIONS_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_OPTIONS_Call) RunAndReturn(run func(string, ...gin.HandlerFunc) gin.IRoutes) *MockIRoutes_OPTIONS_Call { + _c.Call.Return(run) + return _c +} + +// PATCH provides a mock function with given fields: _a0, _a1 +func (_m *MockIRoutes) PATCH(_a0 string, _a1 ...gin.HandlerFunc) gin.IRoutes { + _va := make([]interface{}, len(_a1)) + for _i := range _a1 { + _va[_i] = _a1[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, ...gin.HandlerFunc) gin.IRoutes); ok { + r0 = rf(_a0, _a1...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_PATCH_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PATCH' +type MockIRoutes_PATCH_Call struct { + *mock.Call +} + +// PATCH is a helper method to define mock.On call +// - _a0 string +// - _a1 ...gin.HandlerFunc +func (_e *MockIRoutes_Expecter) PATCH(_a0 interface{}, _a1 ...interface{}) *MockIRoutes_PATCH_Call { + return &MockIRoutes_PATCH_Call{Call: _e.mock.On("PATCH", + append([]interface{}{_a0}, _a1...)...)} +} + +func (_c *MockIRoutes_PATCH_Call) Run(run func(_a0 string, _a1 ...gin.HandlerFunc)) *MockIRoutes_PATCH_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]gin.HandlerFunc, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(gin.HandlerFunc) + } + } + run(args[0].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockIRoutes_PATCH_Call) Return(_a0 gin.IRoutes) *MockIRoutes_PATCH_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_PATCH_Call) RunAndReturn(run func(string, ...gin.HandlerFunc) gin.IRoutes) *MockIRoutes_PATCH_Call { + _c.Call.Return(run) + return _c +} + +// POST provides a mock function with given fields: _a0, _a1 +func (_m *MockIRoutes) POST(_a0 string, _a1 ...gin.HandlerFunc) gin.IRoutes { + _va := make([]interface{}, len(_a1)) + for _i := range _a1 { + _va[_i] = _a1[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, ...gin.HandlerFunc) gin.IRoutes); ok { + r0 = rf(_a0, _a1...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_POST_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'POST' +type MockIRoutes_POST_Call struct { + *mock.Call +} + +// POST is a helper method to define mock.On call +// - _a0 string +// - _a1 ...gin.HandlerFunc +func (_e *MockIRoutes_Expecter) POST(_a0 interface{}, _a1 ...interface{}) *MockIRoutes_POST_Call { + return &MockIRoutes_POST_Call{Call: _e.mock.On("POST", + append([]interface{}{_a0}, _a1...)...)} +} + +func (_c *MockIRoutes_POST_Call) Run(run func(_a0 string, _a1 ...gin.HandlerFunc)) *MockIRoutes_POST_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]gin.HandlerFunc, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(gin.HandlerFunc) + } + } + run(args[0].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockIRoutes_POST_Call) Return(_a0 gin.IRoutes) *MockIRoutes_POST_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_POST_Call) RunAndReturn(run func(string, ...gin.HandlerFunc) gin.IRoutes) *MockIRoutes_POST_Call { + _c.Call.Return(run) + return _c +} + +// PUT provides a mock function with given fields: _a0, _a1 +func (_m *MockIRoutes) PUT(_a0 string, _a1 ...gin.HandlerFunc) gin.IRoutes { + _va := make([]interface{}, len(_a1)) + for _i := range _a1 { + _va[_i] = _a1[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, ...gin.HandlerFunc) gin.IRoutes); ok { + r0 = rf(_a0, _a1...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_PUT_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PUT' +type MockIRoutes_PUT_Call struct { + *mock.Call +} + +// PUT is a helper method to define mock.On call +// - _a0 string +// - _a1 ...gin.HandlerFunc +func (_e *MockIRoutes_Expecter) PUT(_a0 interface{}, _a1 ...interface{}) *MockIRoutes_PUT_Call { + return &MockIRoutes_PUT_Call{Call: _e.mock.On("PUT", + append([]interface{}{_a0}, _a1...)...)} +} + +func (_c *MockIRoutes_PUT_Call) Run(run func(_a0 string, _a1 ...gin.HandlerFunc)) *MockIRoutes_PUT_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]gin.HandlerFunc, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(gin.HandlerFunc) + } + } + run(args[0].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockIRoutes_PUT_Call) Return(_a0 gin.IRoutes) *MockIRoutes_PUT_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_PUT_Call) RunAndReturn(run func(string, ...gin.HandlerFunc) gin.IRoutes) *MockIRoutes_PUT_Call { + _c.Call.Return(run) + return _c +} + +// Static provides a mock function with given fields: _a0, _a1 +func (_m *MockIRoutes) Static(_a0 string, _a1 string) gin.IRoutes { + ret := _m.Called(_a0, _a1) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, string) gin.IRoutes); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_Static_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Static' +type MockIRoutes_Static_Call struct { + *mock.Call +} + +// Static is a helper method to define mock.On call +// - _a0 string +// - _a1 string +func (_e *MockIRoutes_Expecter) Static(_a0 interface{}, _a1 interface{}) *MockIRoutes_Static_Call { + return &MockIRoutes_Static_Call{Call: _e.mock.On("Static", _a0, _a1)} +} + +func (_c *MockIRoutes_Static_Call) Run(run func(_a0 string, _a1 string)) *MockIRoutes_Static_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string)) + }) + return _c +} + +func (_c *MockIRoutes_Static_Call) Return(_a0 gin.IRoutes) *MockIRoutes_Static_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_Static_Call) RunAndReturn(run func(string, string) gin.IRoutes) *MockIRoutes_Static_Call { + _c.Call.Return(run) + return _c +} + +// StaticFS provides a mock function with given fields: _a0, _a1 +func (_m *MockIRoutes) StaticFS(_a0 string, _a1 http.FileSystem) gin.IRoutes { + ret := _m.Called(_a0, _a1) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, http.FileSystem) gin.IRoutes); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_StaticFS_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StaticFS' +type MockIRoutes_StaticFS_Call struct { + *mock.Call +} + +// StaticFS is a helper method to define mock.On call +// - _a0 string +// - _a1 http.FileSystem +func (_e *MockIRoutes_Expecter) StaticFS(_a0 interface{}, _a1 interface{}) *MockIRoutes_StaticFS_Call { + return &MockIRoutes_StaticFS_Call{Call: _e.mock.On("StaticFS", _a0, _a1)} +} + +func (_c *MockIRoutes_StaticFS_Call) Run(run func(_a0 string, _a1 http.FileSystem)) *MockIRoutes_StaticFS_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(http.FileSystem)) + }) + return _c +} + +func (_c *MockIRoutes_StaticFS_Call) Return(_a0 gin.IRoutes) *MockIRoutes_StaticFS_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_StaticFS_Call) RunAndReturn(run func(string, http.FileSystem) gin.IRoutes) *MockIRoutes_StaticFS_Call { + _c.Call.Return(run) + return _c +} + +// StaticFile provides a mock function with given fields: _a0, _a1 +func (_m *MockIRoutes) StaticFile(_a0 string, _a1 string) gin.IRoutes { + ret := _m.Called(_a0, _a1) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, string) gin.IRoutes); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_StaticFile_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StaticFile' +type MockIRoutes_StaticFile_Call struct { + *mock.Call +} + +// StaticFile is a helper method to define mock.On call +// - _a0 string +// - _a1 string +func (_e *MockIRoutes_Expecter) StaticFile(_a0 interface{}, _a1 interface{}) *MockIRoutes_StaticFile_Call { + return &MockIRoutes_StaticFile_Call{Call: _e.mock.On("StaticFile", _a0, _a1)} +} + +func (_c *MockIRoutes_StaticFile_Call) Run(run func(_a0 string, _a1 string)) *MockIRoutes_StaticFile_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string)) + }) + return _c +} + +func (_c *MockIRoutes_StaticFile_Call) Return(_a0 gin.IRoutes) *MockIRoutes_StaticFile_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_StaticFile_Call) RunAndReturn(run func(string, string) gin.IRoutes) *MockIRoutes_StaticFile_Call { + _c.Call.Return(run) + return _c +} + +// StaticFileFS provides a mock function with given fields: _a0, _a1, _a2 +func (_m *MockIRoutes) StaticFileFS(_a0 string, _a1 string, _a2 http.FileSystem) gin.IRoutes { + ret := _m.Called(_a0, _a1, _a2) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(string, string, http.FileSystem) gin.IRoutes); ok { + r0 = rf(_a0, _a1, _a2) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_StaticFileFS_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StaticFileFS' +type MockIRoutes_StaticFileFS_Call struct { + *mock.Call +} + +// StaticFileFS is a helper method to define mock.On call +// - _a0 string +// - _a1 string +// - _a2 http.FileSystem +func (_e *MockIRoutes_Expecter) StaticFileFS(_a0 interface{}, _a1 interface{}, _a2 interface{}) *MockIRoutes_StaticFileFS_Call { + return &MockIRoutes_StaticFileFS_Call{Call: _e.mock.On("StaticFileFS", _a0, _a1, _a2)} +} + +func (_c *MockIRoutes_StaticFileFS_Call) Run(run func(_a0 string, _a1 string, _a2 http.FileSystem)) *MockIRoutes_StaticFileFS_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string), args[2].(http.FileSystem)) + }) + return _c +} + +func (_c *MockIRoutes_StaticFileFS_Call) Return(_a0 gin.IRoutes) *MockIRoutes_StaticFileFS_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_StaticFileFS_Call) RunAndReturn(run func(string, string, http.FileSystem) gin.IRoutes) *MockIRoutes_StaticFileFS_Call { + _c.Call.Return(run) + return _c +} + +// Use provides a mock function with given fields: _a0 +func (_m *MockIRoutes) Use(_a0 ...gin.HandlerFunc) gin.IRoutes { + _va := make([]interface{}, len(_a0)) + for _i := range _a0 { + _va[_i] = _a0[_i] + } + var _ca []interface{} + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 gin.IRoutes + if rf, ok := ret.Get(0).(func(...gin.HandlerFunc) gin.IRoutes); ok { + r0 = rf(_a0...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(gin.IRoutes) + } + } + + return r0 +} + +// MockIRoutes_Use_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Use' +type MockIRoutes_Use_Call struct { + *mock.Call +} + +// Use is a helper method to define mock.On call +// - _a0 ...gin.HandlerFunc +func (_e *MockIRoutes_Expecter) Use(_a0 ...interface{}) *MockIRoutes_Use_Call { + return &MockIRoutes_Use_Call{Call: _e.mock.On("Use", + append([]interface{}{}, _a0...)...)} +} + +func (_c *MockIRoutes_Use_Call) Run(run func(_a0 ...gin.HandlerFunc)) *MockIRoutes_Use_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]gin.HandlerFunc, len(args)-0) + for i, a := range args[0:] { + if a != nil { + variadicArgs[i] = a.(gin.HandlerFunc) + } + } + run(variadicArgs...) + }) + return _c +} + +func (_c *MockIRoutes_Use_Call) Return(_a0 gin.IRoutes) *MockIRoutes_Use_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRoutes_Use_Call) RunAndReturn(run func(...gin.HandlerFunc) gin.IRoutes) *MockIRoutes_Use_Call { + _c.Call.Return(run) + return _c +} + +// NewMockIRoutes creates a new instance of MockIRoutes. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockIRoutes(t interface { + mock.TestingT + Cleanup(func()) +}) *MockIRoutes { + mock := &MockIRoutes{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/sherlock/internal/api/sherlock/app_version_v3_upsert.go b/sherlock/internal/api/sherlock/app_version_v3_upsert.go index c034a31a4..8003f9fdb 100644 --- a/sherlock/internal/api/sherlock/app_version_v3_upsert.go +++ b/sherlock/internal/api/sherlock/app_version_v3_upsert.go @@ -21,7 +21,7 @@ import ( // @param appVersion body AppVersionV3Create true "The AppVersion to upsert" // @success 201 {object} AppVersionV3 // @failure 400,403,404,407,409,500 {object} errors.ErrorResponse -// @router /api/app-versions/v3 [post] +// @router /api/app-versions/v3 [put] func appVersionsV3Upsert(ctx *gin.Context) { db, err := authentication.MustUseDB(ctx) if err != nil { diff --git a/sherlock/internal/api/sherlock/chart_version_v3_upsert.go b/sherlock/internal/api/sherlock/chart_version_v3_upsert.go index 741171cce..cea9fa67e 100644 --- a/sherlock/internal/api/sherlock/chart_version_v3_upsert.go +++ b/sherlock/internal/api/sherlock/chart_version_v3_upsert.go @@ -21,7 +21,7 @@ import ( // @param chartVersion body ChartVersionV3Create true "The ChartVersion to upsert" // @success 201 {object} ChartVersionV3 // @failure 400,403,404,407,409,500 {object} errors.ErrorResponse -// @router /api/chart-versions/v3 [post] +// @router /api/chart-versions/v3 [put] func chartVersionsV3Upsert(ctx *gin.Context) { db, err := authentication.MustUseDB(ctx) if err != nil { diff --git a/sherlock/internal/api/sherlock/routes.go b/sherlock/internal/api/sherlock/routes.go index a8fce4454..fd87a6848 100644 --- a/sherlock/internal/api/sherlock/routes.go +++ b/sherlock/internal/api/sherlock/routes.go @@ -41,7 +41,7 @@ import "github.com/gin-gonic/gin" // `//procedures//`. // // - If they do this, the endpoints should categorize themselves by their shared group, instead of their type. -func ConfigureRoutes(apiRouter *gin.RouterGroup) { +func ConfigureRoutes(apiRouter gin.IRoutes) { apiRouter.GET("app-versions/v3/*selector", appVersionsV3Get) apiRouter.GET("app-versions/v3", appVersionsV3List) apiRouter.PATCH("app-versions/v3/*selector", appVersionsV3Edit) diff --git a/sherlock/internal/api/sherlock/routes_test.go b/sherlock/internal/api/sherlock/routes_test.go new file mode 100644 index 000000000..6195784ee --- /dev/null +++ b/sherlock/internal/api/sherlock/routes_test.go @@ -0,0 +1,82 @@ +package sherlock + +import ( + "embed" + "fmt" + "github.com/broadinstitute/sherlock/sherlock/internal/api/gin_mocks" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "regexp" + "strings" + "testing" +) + +//go:embed *.go +var filesToLookForSwaggerCommentsIn embed.FS + +var regexToParseSwaggerRouteDeclarations = regexp.MustCompile(`//\s+@router\s+(.+)`) +var regexToHelpConvertGinRouteConfigurations = regexp.MustCompile(`[*:]([^/]+)`) + +func TestConfigureRoutes_swaggerComments(t *testing.T) { + // Map of route declarations and if they were found + expectedRouteDeclarations := make(map[string]bool) + + // Make a mock router to help us assemble the above map + mockRouter := gin_mocks.NewMockIRoutes(t) + for _, method := range []string{"GET", "POST", "DELETE", "PATCH", "PUT", "OPTIONS", "HEAD"} { + redeclaredMethodToAvoidPointerShenanigans := method + mockRouter. + On(redeclaredMethodToAvoidPointerShenanigans, mock.AnythingOfType("string"), mock.Anything). + Run(func(args mock.Arguments) { + routeDeclaration := fmt.Sprintf("%s [%s]", + transformPathToSwaggerFormat(args.Get(0).(string)), + strings.ToLower(redeclaredMethodToAvoidPointerShenanigans)) + if _, alreadyExists := expectedRouteDeclarations[routeDeclaration]; alreadyExists { + assert.Fail(t, fmt.Sprintf("routes.go's ConfigureRoutes seems to configure `%s` twice", routeDeclaration)) + } else { + expectedRouteDeclarations[routeDeclaration] = false + } + }). + Return(nil). + Maybe() + } + + // Run our mock through the configuration function + assert.NotPanics(t, func() { + ConfigureRoutes(mockRouter) + }) + + // Iterate through the source files, looking for declarations + sourceFiles, err := filesToLookForSwaggerCommentsIn.ReadDir(".") + assert.NoError(t, err) + for _, sourceFile := range sourceFiles { + assert.Falsef(t, sourceFile.IsDir(), "%s is a directory", sourceFile.Name()) + sourceFileContents, err := filesToLookForSwaggerCommentsIn.ReadFile(sourceFile.Name()) + assert.NoError(t, err) + for _, routeDeclarationMatch := range regexToParseSwaggerRouteDeclarations.FindAllSubmatch(sourceFileContents, -1) { + if assert.Lenf(t, routeDeclarationMatch, 2, "route declaration regex matches should only have two items in the array, the whole line and the declaration itself") { + routeDeclaration := string(routeDeclarationMatch[1]) + alreadyDeclared, shouldBeDeclared := expectedRouteDeclarations[routeDeclaration] + assert.Truef(t, shouldBeDeclared, "%s was declared in %s's Swagger comments but isn't configured in routes.go's ConfigureRoutes", routeDeclaration, sourceFile.Name()) + assert.Falsef(t, alreadyDeclared, "%s was declared twice in Swagger comments (duplicate detected in %s)", routeDeclaration, sourceFile.Name()) + expectedRouteDeclarations[routeDeclaration] = true + } + } + } + + // If there's any declarations that are still false, we didn't find them and should say so + for expectedRouteDeclaration, wasDeclared := range expectedRouteDeclarations { + assert.Truef(t, wasDeclared, "%s was configured in routes.go's ConfigureRoutes but wasn't declared in any Swagger comment", expectedRouteDeclaration) + } +} + +func transformPathToSwaggerFormat(path string) string { + return fmt.Sprintf("/api/%s", regexToHelpConvertGinRouteConfigurations.ReplaceAllString(path, "{$1}")) +} + +func Test_transformPathToSwaggerFormat(t *testing.T) { + assert.Equal(t, "/api/foo/bar", transformPathToSwaggerFormat("foo/bar")) + assert.Equal(t, "/api/foo/bar/{baz}", transformPathToSwaggerFormat("foo/bar/*baz")) + assert.Equal(t, "/api/foo/bar/{baz}", transformPathToSwaggerFormat("foo/bar/:baz")) + assert.Equal(t, "/api/foo/{bar}/{baz}", transformPathToSwaggerFormat("foo/:bar/*baz")) +} diff --git a/sherlock/internal/github/client.go b/sherlock/internal/github/client.go index ff8d61271..7c309c5c2 100644 --- a/sherlock/internal/github/client.go +++ b/sherlock/internal/github/client.go @@ -7,10 +7,7 @@ import ( "testing" ) -// If you're using GoLand you can use the gutter annotation to the left of the line below to regenerate the mocks. -// Otherwise, `make generate-mocks` from the root of the repo. In either case, you'll need to `brew install mockery`. -// -//go:generate mockery +// `make generate-mocks` from the root of the repo to regenerate (you'll need to `brew install mockery`) type mockableActionsClient interface { CreateWorkflowDispatchEventByFileName(ctx context.Context, owner, repo, workflowFileName string, event github.CreateWorkflowDispatchEventRequest) (*github.Response, error) } diff --git a/sherlock/internal/slack/client.go b/sherlock/internal/slack/client.go index 8bb26b59b..d1b15aa6a 100644 --- a/sherlock/internal/slack/client.go +++ b/sherlock/internal/slack/client.go @@ -8,10 +8,7 @@ import ( "testing" ) -// If you're using GoLand you can use the gutter annotation to the left of the line below to regenerate the mock. -// Otherwise, `make generate-mocks` from the root of the repo. In either case, you'll need to `brew install mockery`. -// -//go:generate mockery +// `make generate-mocks` from the root of the repo to regenerate (you'll need to `brew install mockery`) type mockableClient interface { SendMessageContext(ctx context.Context, channelID string, options ...slack.MsgOption) (_channel string, _timestamp string, _text string, err error) AddReaction(name string, item slack.ItemRef) error