diff --git a/Makefile b/Makefile index af5143d..d9dda90 100644 --- a/Makefile +++ b/Makefile @@ -122,6 +122,10 @@ mock: -destination=internal/app/auth/mock/auth.go \ github.com/ozontech/seq-ui/internal/app/auth \ OIDCProvider,JWTProvider + PATH="$(LOCAL_BIN):$(PATH)" mockgen \ + -destination=internal/pkg/service/dashboards/mock/service.go \ + github.com/ozontech/seq-ui/internal/pkg/service/dashboards \ + Service .PHONY: protoc protoc: diff --git a/internal/api/dashboards/v1/grpc/api.go b/internal/api/dashboards/v1/grpc/api.go index 7e59b4e..dfc6457 100644 --- a/internal/api/dashboards/v1/grpc/api.go +++ b/internal/api/dashboards/v1/grpc/api.go @@ -2,18 +2,18 @@ package grpc import ( "github.com/ozontech/seq-ui/internal/api/profiles" - "github.com/ozontech/seq-ui/internal/pkg/service" + dashboardsservice "github.com/ozontech/seq-ui/internal/pkg/service/dashboards" "github.com/ozontech/seq-ui/pkg/dashboards/v1" ) type API struct { dashboards.UnimplementedDashboardsServiceServer - service service.Service + service dashboardsservice.Service profiles *profiles.Profiles } -func New(svc service.Service, p *profiles.Profiles) *API { +func New(svc dashboardsservice.Service, p *profiles.Profiles) *API { return &API{ service: svc, profiles: p, diff --git a/internal/api/dashboards/v1/http/api.go b/internal/api/dashboards/v1/http/api.go index b192e69..02e67f2 100644 --- a/internal/api/dashboards/v1/http/api.go +++ b/internal/api/dashboards/v1/http/api.go @@ -5,15 +5,15 @@ import ( "github.com/ozontech/seq-ui/internal/api/profiles" "github.com/ozontech/seq-ui/internal/app/types" - "github.com/ozontech/seq-ui/internal/pkg/service" + dashboardsservice "github.com/ozontech/seq-ui/internal/pkg/service/dashboards" ) type API struct { - service service.Service + service dashboardsservice.Service profiles *profiles.Profiles } -func New(svc service.Service, p *profiles.Profiles) *API { +func New(svc dashboardsservice.Service, p *profiles.Profiles) *API { return &API{ service: svc, profiles: p, diff --git a/internal/api/dashboards/v1/http/create_test.go b/internal/api/dashboards/v1/http/create_test.go index 1582042..0d4c34f 100644 --- a/internal/api/dashboards/v1/http/create_test.go +++ b/internal/api/dashboards/v1/http/create_test.go @@ -2,8 +2,6 @@ package http import ( "context" - "errors" - "fmt" "net/http" "net/http/httptest" "strings" @@ -12,9 +10,18 @@ import ( "go.uber.org/mock/gomock" "github.com/ozontech/seq-ui/internal/api/httputil" + "github.com/ozontech/seq-ui/internal/api/profiles" "github.com/ozontech/seq-ui/internal/app/types" + mock "github.com/ozontech/seq-ui/internal/pkg/service/dashboards/mock" ) +func setupAPI(t *testing.T) (*API, *mock.MockService) { + ctrl := gomock.NewController(t) + mockedSvc := mock.NewMockService(ctrl) + p := profiles.New(mockedSvc) + return New(mockedSvc, p), mockedSvc +} + func TestServeCreate(t *testing.T) { userName := "unnamed" var profileID int64 = 1 @@ -22,10 +29,6 @@ func TestServeCreate(t *testing.T) { dashboardName := "my_dashboard" dashboardMeta := "my_meta" - formatReqBody := func(name, meta string) string { - return fmt.Sprintf(`{"name":%q,"meta":%q}`, name, meta) - } - type mockArgs struct { req types.CreateDashboardRequest resp string @@ -35,18 +38,16 @@ func TestServeCreate(t *testing.T) { tests := []struct { name string - reqBody string - wantRespBody string - wantStatus int + req createRequest + want createResponse + wantErr bool mockArgs *mockArgs - noUser bool }{ { - name: "success", - reqBody: formatReqBody(dashboardName, dashboardMeta), - wantRespBody: fmt.Sprintf(`{"uuid":%q}`, dashboardUUID), - wantStatus: http.StatusOK, + name: "ok", + req: createRequest{Name: dashboardName, Meta: dashboardMeta}, + want: createResponse{UUID: dashboardUUID}, mockArgs: &mockArgs{ req: types.CreateDashboardRequest{ ProfileID: profileID, @@ -57,43 +58,21 @@ func TestServeCreate(t *testing.T) { }, }, { - name: "err_invalid_request", - reqBody: "invalid-request", - wantStatus: http.StatusBadRequest, - noUser: true, - }, - { - name: "err_no_user", - reqBody: formatReqBody(dashboardName, dashboardMeta), - wantStatus: http.StatusUnauthorized, - noUser: true, - }, - { - name: "err_svc_empty_name", - reqBody: formatReqBody("", dashboardMeta), - wantStatus: http.StatusBadRequest, - }, - { - name: "err_svc_empty_meta", - reqBody: formatReqBody(dashboardName, ""), - wantStatus: http.StatusBadRequest, - }, - { - name: "err_repo_random", - reqBody: formatReqBody(dashboardName, dashboardMeta), - wantStatus: http.StatusInternalServerError, + name: "err_svc", + req: createRequest{Name: dashboardName, Meta: dashboardMeta}, + wantErr: true, mockArgs: &mockArgs{ req: types.CreateDashboardRequest{ ProfileID: profileID, Name: dashboardName, Meta: dashboardMeta, }, - err: errors.New("random repo err"), + err: errSomethingWrong, }, }, } + for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() diff --git a/internal/api/dashboards/v1/http/test_data.go b/internal/api/dashboards/v1/http/test_data.go index 4c1df04..e65a669 100644 --- a/internal/api/dashboards/v1/http/test_data.go +++ b/internal/api/dashboards/v1/http/test_data.go @@ -1,12 +1,17 @@ package http import ( + "errors" "testing" "github.com/ozontech/seq-ui/internal/api/dashboards/v1/test" repo_mock "github.com/ozontech/seq-ui/internal/pkg/repository/mock" ) +var ( + errSomethingWrong = errors.New("something happened wrong") +) + func newTestData(t *testing.T) (*API, *repo_mock.MockDashboards) { mock, s, p := test.NewTestData(t) return New(s, p), mock diff --git a/internal/pkg/service/dashboards/mock/service.go b/internal/pkg/service/dashboards/mock/service.go new file mode 100644 index 0000000..31e43b8 --- /dev/null +++ b/internal/pkg/service/dashboards/mock/service.go @@ -0,0 +1,145 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ozontech/seq-ui/internal/pkg/service/dashboards (interfaces: Service) +// +// Generated by this command: +// +// mockgen -destination=internal/pkg/service/dashboards/mock/service.go github.com/ozontech/seq-ui/internal/pkg/service/dashboards Service +// + +// Package mock_dashboards is a generated GoMock package. +package mock_dashboards + +import ( + context "context" + reflect "reflect" + + types "github.com/ozontech/seq-ui/internal/app/types" + gomock "go.uber.org/mock/gomock" +) + +// MockService is a mock of Service interface. +type MockService struct { + ctrl *gomock.Controller + recorder *MockServiceMockRecorder + isgomock struct{} +} + +// MockServiceMockRecorder is the mock recorder for MockService. +type MockServiceMockRecorder struct { + mock *MockService +} + +// NewMockService creates a new mock instance. +func NewMockService(ctrl *gomock.Controller) *MockService { + mock := &MockService{ctrl: ctrl} + mock.recorder = &MockServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockService) EXPECT() *MockServiceMockRecorder { + return m.recorder +} + +// CreateDashboard mocks base method. +func (m *MockService) CreateDashboard(arg0 context.Context, arg1 types.CreateDashboardRequest) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateDashboard", arg0, arg1) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateDashboard indicates an expected call of CreateDashboard. +func (mr *MockServiceMockRecorder) CreateDashboard(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDashboard", reflect.TypeOf((*MockService)(nil).CreateDashboard), arg0, arg1) +} + +// DeleteDashboard mocks base method. +func (m *MockService) DeleteDashboard(arg0 context.Context, arg1 types.DeleteDashboardRequest) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDashboard", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteDashboard indicates an expected call of DeleteDashboard. +func (mr *MockServiceMockRecorder) DeleteDashboard(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDashboard", reflect.TypeOf((*MockService)(nil).DeleteDashboard), arg0, arg1) +} + +// GetAllDashboards mocks base method. +func (m *MockService) GetAllDashboards(arg0 context.Context, arg1 types.GetAllDashboardsRequest) (types.DashboardInfosWithOwner, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAllDashboards", arg0, arg1) + ret0, _ := ret[0].(types.DashboardInfosWithOwner) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAllDashboards indicates an expected call of GetAllDashboards. +func (mr *MockServiceMockRecorder) GetAllDashboards(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllDashboards", reflect.TypeOf((*MockService)(nil).GetAllDashboards), arg0, arg1) +} + +// GetDashboardByUUID mocks base method. +func (m *MockService) GetDashboardByUUID(arg0 context.Context, arg1 string) (types.Dashboard, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDashboardByUUID", arg0, arg1) + ret0, _ := ret[0].(types.Dashboard) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDashboardByUUID indicates an expected call of GetDashboardByUUID. +func (mr *MockServiceMockRecorder) GetDashboardByUUID(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDashboardByUUID", reflect.TypeOf((*MockService)(nil).GetDashboardByUUID), arg0, arg1) +} + +// GetMyDashboards mocks base method. +func (m *MockService) GetMyDashboards(arg0 context.Context, arg1 types.GetUserDashboardsRequest) (types.DashboardInfos, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMyDashboards", arg0, arg1) + ret0, _ := ret[0].(types.DashboardInfos) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMyDashboards indicates an expected call of GetMyDashboards. +func (mr *MockServiceMockRecorder) GetMyDashboards(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMyDashboards", reflect.TypeOf((*MockService)(nil).GetMyDashboards), arg0, arg1) +} + +// SearchDashboards mocks base method. +func (m *MockService) SearchDashboards(arg0 context.Context, arg1 types.SearchDashboardsRequest) (types.DashboardInfosWithOwner, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SearchDashboards", arg0, arg1) + ret0, _ := ret[0].(types.DashboardInfosWithOwner) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SearchDashboards indicates an expected call of SearchDashboards. +func (mr *MockServiceMockRecorder) SearchDashboards(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchDashboards", reflect.TypeOf((*MockService)(nil).SearchDashboards), arg0, arg1) +} + +// UpdateDashboard mocks base method. +func (m *MockService) UpdateDashboard(arg0 context.Context, arg1 types.UpdateDashboardRequest) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateDashboard", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateDashboard indicates an expected call of UpdateDashboard. +func (mr *MockServiceMockRecorder) UpdateDashboard(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDashboard", reflect.TypeOf((*MockService)(nil).UpdateDashboard), arg0, arg1) +} diff --git a/internal/pkg/service/dashboards.go b/internal/pkg/service/dashboards/service.go similarity index 67% rename from internal/pkg/service/dashboards.go rename to internal/pkg/service/dashboards/service.go index e87b391..1d68c10 100644 --- a/internal/pkg/service/dashboards.go +++ b/internal/pkg/service/dashboards/service.go @@ -1,41 +1,51 @@ -package service +package dashboards import ( "context" "github.com/gofrs/uuid" - "github.com/ozontech/seq-ui/internal/app/types" + "github.com/ozontech/seq-ui/internal/pkg/repository" ) -// GetAllDashboards from underlying repository. +type Service interface { + GetAllDashboards(context.Context, types.GetAllDashboardsRequest) (types.DashboardInfosWithOwner, error) + GetMyDashboards(context.Context, types.GetUserDashboardsRequest) (types.DashboardInfos, error) + GetDashboardByUUID(context.Context, string) (types.Dashboard, error) + CreateDashboard(context.Context, types.CreateDashboardRequest) (string, error) + UpdateDashboard(context.Context, types.UpdateDashboardRequest) error + DeleteDashboard(context.Context, types.DeleteDashboardRequest) error + SearchDashboards(context.Context, types.SearchDashboardsRequest) (types.DashboardInfosWithOwner, error) +} + +type service struct { + repo repository.Dashboards +} + func (s *service) GetAllDashboards(ctx context.Context, req types.GetAllDashboardsRequest) (types.DashboardInfosWithOwner, error) { if err := checkLimitOffset(req.Limit, req.Offset); err != nil { return nil, err } - return s.repo.Dashboards.GetAll(ctx, req) + return s.repo.GetAll(ctx, req) } -// GetMyDashboards from underlying repository. func (s *service) GetMyDashboards(ctx context.Context, req types.GetUserDashboardsRequest) (types.DashboardInfos, error) { if err := checkLimitOffset(req.Limit, req.Offset); err != nil { return nil, err } - return s.repo.Dashboards.GetMy(ctx, req) + return s.repo.GetMy(ctx, req) } -// GetDashboardByUUID from underlying repository. func (s *service) GetDashboardByUUID(ctx context.Context, id string) (types.Dashboard, error) { if err := checkUUID(id); err != nil { return types.Dashboard{}, err } - return s.repo.Dashboards.GetByUUID(ctx, id) + return s.repo.GetByUUID(ctx, id) } -// CreateDashboard in underlying repository. func (s *service) CreateDashboard(ctx context.Context, req types.CreateDashboardRequest) (string, error) { if req.Name == "" { return "", types.NewErrInvalidRequestField("empty 'name'") @@ -44,10 +54,9 @@ func (s *service) CreateDashboard(ctx context.Context, req types.CreateDashboard return "", types.NewErrInvalidRequestField("empty 'meta'") } - return s.repo.Dashboards.Create(ctx, req) + return s.repo.Create(ctx, req) } -// UpdateDashboard in underlying repository. func (s *service) UpdateDashboard(ctx context.Context, req types.UpdateDashboardRequest) error { if err := checkUUID(req.UUID); err != nil { return err @@ -56,24 +65,22 @@ func (s *service) UpdateDashboard(ctx context.Context, req types.UpdateDashboard return types.ErrEmptyUpdateRequest } - return s.repo.Dashboards.Update(ctx, req) + return s.repo.Update(ctx, req) } -// DeleteDashboard in underlying repository. func (s *service) DeleteDashboard(ctx context.Context, req types.DeleteDashboardRequest) error { if err := checkUUID(req.UUID); err != nil { return err } - return s.repo.Dashboards.Delete(ctx, req) + return s.repo.Delete(ctx, req) } -// SearchDashboards in underlying repository. func (s *service) SearchDashboards(ctx context.Context, req types.SearchDashboardsRequest) (types.DashboardInfosWithOwner, error) { if err := checkLimitOffset(req.Limit, req.Offset); err != nil { return nil, err } - return s.repo.Dashboards.Search(ctx, req) + return s.repo.Search(ctx, req) } func checkUUID(v string) error { diff --git a/internal/pkg/service/service.go b/internal/pkg/service/service.go index 4a34733..e8e2140 100644 --- a/internal/pkg/service/service.go +++ b/internal/pkg/service/service.go @@ -14,14 +14,6 @@ type Service interface { GetFavoriteQueries(context.Context, types.GetFavoriteQueriesRequest) (types.FavoriteQueries, error) GetOrCreateFavoriteQuery(context.Context, types.GetOrCreateFavoriteQueryRequest) (int64, error) DeleteFavoriteQuery(context.Context, types.DeleteFavoriteQueryRequest) error - - GetAllDashboards(context.Context, types.GetAllDashboardsRequest) (types.DashboardInfosWithOwner, error) - GetMyDashboards(context.Context, types.GetUserDashboardsRequest) (types.DashboardInfos, error) - GetDashboardByUUID(context.Context, string) (types.Dashboard, error) - CreateDashboard(context.Context, types.CreateDashboardRequest) (string, error) - UpdateDashboard(context.Context, types.UpdateDashboardRequest) error - DeleteDashboard(context.Context, types.DeleteDashboardRequest) error - SearchDashboards(context.Context, types.SearchDashboardsRequest) (types.DashboardInfosWithOwner, error) } type service struct {