From 03eb69588b219073459742a6df25fc4195b38ec6 Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:29:02 +0700 Subject: [PATCH 1/6] feat: checkin core --- internal/checkin/checkin.handler.go | 127 ++++++++++++++++++++++++++++ internal/checkin/checkin.service.go | 122 ++++++++++++++++++++++++++ internal/checkin/checkin.utils.go | 40 +++++++++ internal/dto/checkin.dto.go | 34 ++++++++ 4 files changed, 323 insertions(+) create mode 100644 internal/checkin/checkin.handler.go create mode 100644 internal/checkin/checkin.service.go create mode 100644 internal/checkin/checkin.utils.go create mode 100644 internal/dto/checkin.dto.go diff --git a/internal/checkin/checkin.handler.go b/internal/checkin/checkin.handler.go new file mode 100644 index 0000000..f56a16f --- /dev/null +++ b/internal/checkin/checkin.handler.go @@ -0,0 +1,127 @@ +package checkin + +import ( + "net/http" + "strings" + + "github.com/isd-sgcu/rpkm67-gateway/internal/dto" + "github.com/isd-sgcu/rpkm67-gateway/internal/router" + "github.com/isd-sgcu/rpkm67-gateway/internal/validator" + "go.uber.org/zap" +) + +type Handler interface { + Create(c router.Context) + FindByEmail(c router.Context) + FindByUserID(c router.Context) +} + +func NewHandler(svc Service, validate validator.DtoValidator, log *zap.Logger) Handler { + return &handlerImpl{ + svc: svc, + validate: validate, + log: log, + } +} + +type handlerImpl struct { + svc Service + validate validator.DtoValidator + log *zap.Logger +} + +func (h *handlerImpl) Create(c router.Context) { + body := &dto.CreateCheckInRequest{} + if err := c.Bind(body); err != nil { + h.log.Named("Create").Error("Bind: failed to bind request body", zap.Error(err)) + c.BadRequestError(err.Error()) + return + } + + if errorList := h.validate.Validate(body); errorList != nil { + h.log.Named("Create").Error("Validate: ", zap.Strings("errorList", errorList)) + c.BadRequestError(strings.Join(errorList, ", ")) + return + } + + req := &dto.CreateCheckInRequest{ + Email: body.Email, + UserID: body.UserID, + Event: body.Event, + } + + res, appErr := h.svc.Create(req) + if appErr != nil { + h.log.Named("Create").Error("Create: ", zap.Error(appErr)) + c.ResponseError(appErr) + return + } + + c.JSON(http.StatusCreated, &dto.CreateCheckInResponse{ + CheckIn: &dto.CheckIn{ + ID: res.CheckIn.ID, + UserID: res.CheckIn.UserID, + Event: res.CheckIn.Event, + }, + }) +} + +func (h *handlerImpl) FindByEmail(c router.Context) { + body := &dto.FindByEmailCheckInRequest{} + if err := c.Bind(body); err != nil { + h.log.Named("FindByEmail").Error("Bind: failed to bind request body", zap.Error(err)) + c.BadRequestError(err.Error()) + return + } + + if errorList := h.validate.Validate(body); errorList != nil { + h.log.Named("FindByEmail").Error("Validate: ", zap.Strings("errorList", errorList)) + c.BadRequestError(strings.Join(errorList, ", ")) + return + } + + req := &dto.FindByEmailCheckInRequest{ + Email: body.Email, + } + + res, appErr := h.svc.FindByEmail(req) + if appErr != nil { + h.log.Named("FindByEmail").Error("FindByEmail: ", zap.Error(appErr)) + c.ResponseError(appErr) + return + } + + c.JSON(http.StatusOK, &dto.FindByEmailCheckInResponse{ + CheckIns: res.CheckIns, + }) +} + +func (h *handlerImpl) FindByUserID(c router.Context) { + body := &dto.FindByUserIdCheckInRequest{} + if err := c.Bind(body); err != nil { + h.log.Named("FindByUserID").Error("Bind: failed to bind request body", zap.Error(err)) + c.BadRequestError(err.Error()) + return + } + + if errorList := h.validate.Validate(body); errorList != nil { + h.log.Named("FindByUserID").Error("Validate: ", zap.Strings("errorList", errorList)) + c.BadRequestError(strings.Join(errorList, ", ")) + return + } + + req := &dto.FindByUserIdCheckInRequest{ + UserID: body.UserID, + } + + res, appErr := h.svc.FindByUserID(req) + if appErr != nil { + h.log.Named("FindByUserID").Error("FindByUserID: ", zap.Error(appErr)) + c.ResponseError(appErr) + return + } + + c.JSON(http.StatusOK, &dto.FindByUserIdCheckInResponse{ + CheckIns: res.CheckIns, + }) +} diff --git a/internal/checkin/checkin.service.go b/internal/checkin/checkin.service.go new file mode 100644 index 0000000..e62a623 --- /dev/null +++ b/internal/checkin/checkin.service.go @@ -0,0 +1,122 @@ +package checkin + +import ( + "context" + "time" + + "github.com/isd-sgcu/rpkm67-gateway/apperror" + "github.com/isd-sgcu/rpkm67-gateway/internal/dto" + checkinProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/checkin/checkin/v1" + "go.uber.org/zap" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type Service interface { + Create(req *dto.CreateCheckInRequest) (*dto.CreateCheckInResponse, *apperror.AppError) + FindByUserID(req *dto.FindByUserIdCheckInRequest) (*dto.FindByUserIdCheckInResponse, *apperror.AppError) + FindByEmail(req *dto.FindByEmailCheckInRequest) (*dto.FindByEmailCheckInResponse, *apperror.AppError) +} + +type serviceImpl struct { + client checkinProto.CheckInServiceClient + log *zap.Logger +} + +func NewService(client checkinProto.CheckInServiceClient, log *zap.Logger) Service { + return &serviceImpl{ + client: client, + log: log, + } +} + +func (s *serviceImpl) Create(req *dto.CreateCheckInRequest) (*dto.CreateCheckInResponse, *apperror.AppError) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + res, err := s.client.Create(ctx, &checkinProto.CreateCheckInRequest{ + Email: req.Email, + UserId: req.UserID, + Event: req.Event, + }) + if err != nil { + s.log.Named("Create").Error("Create: ", zap.Error(err)) + st, ok := status.FromError(err) + if !ok { + return nil, apperror.InternalServer + } + switch st.Code() { + case codes.InvalidArgument: + return nil, apperror.BadRequest + case codes.Internal: + return nil, apperror.InternalServerError(err.Error()) + default: + return nil, apperror.ServiceUnavailable + } + } + + return &dto.CreateCheckInResponse{ + CheckIn: &dto.CheckIn{ + ID: res.CheckIn.Id, + UserID: res.CheckIn.UserId, + Email: res.CheckIn.Email, + Event: res.CheckIn.Event, + }, + }, nil +} + +func (s *serviceImpl) FindByEmail(req *dto.FindByEmailCheckInRequest) (*dto.FindByEmailCheckInResponse, *apperror.AppError) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + res, err := s.client.FindByEmail(ctx, &checkinProto.FindByEmailCheckInRequest{ + Email: req.Email, + }) + if err != nil { + s.log.Named("FindByEmail").Error("FindByEmail: ", zap.Error(err)) + st, ok := status.FromError(err) + if !ok { + return nil, apperror.InternalServer + } + switch st.Code() { + case codes.InvalidArgument: + return nil, apperror.BadRequest + case codes.Internal: + return nil, apperror.InternalServerError(err.Error()) + default: + return nil, apperror.ServiceUnavailable + } + } + + return &dto.FindByEmailCheckInResponse{ + CheckIns: ProtoToDtos(res.CheckIns), + }, nil +} + +func (s *serviceImpl) FindByUserID(req *dto.FindByUserIdCheckInRequest) (*dto.FindByUserIdCheckInResponse, *apperror.AppError) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + res, err := s.client.FindByUserId(ctx, &checkinProto.FindByUserIdCheckInRequest{ + UserId: req.UserID, + }) + if err != nil { + s.log.Named("FindByUserID").Error("FindByUserID: ", zap.Error(err)) + st, ok := status.FromError(err) + if !ok { + return nil, apperror.InternalServer + } + switch st.Code() { + case codes.InvalidArgument: + return nil, apperror.BadRequest + case codes.Internal: + return nil, apperror.InternalServerError(err.Error()) + default: + return nil, apperror.ServiceUnavailable + } + } + + return &dto.FindByUserIdCheckInResponse{ + CheckIns: ProtoToDtos(res.CheckIns), + }, nil +} diff --git a/internal/checkin/checkin.utils.go b/internal/checkin/checkin.utils.go new file mode 100644 index 0000000..0434a47 --- /dev/null +++ b/internal/checkin/checkin.utils.go @@ -0,0 +1,40 @@ +package checkin + +import ( + "github.com/isd-sgcu/rpkm67-gateway/internal/dto" + checkinProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/checkin/checkin/v1" +) + +func ProtoToDto(in *checkinProto.CheckIn) *dto.CheckIn { + return &dto.CheckIn{ + ID: in.Id, + UserID: in.UserId, + Email: in.Email, + Event: in.Event, + } +} + +func ProtoToDtos(in []*checkinProto.CheckIn) []*dto.CheckIn { + var out []*dto.CheckIn + for _, v := range in { + out = append(out, ProtoToDto(v)) + } + return out +} + +// func DtoToProto(in *dto.CheckIn) *checkinProto.CheckIn { +// return &checkinProto.CheckIn{ +// Id: in.ID, +// UserId: in.UserID, +// Email: in.Email, +// Event: in.Event, +// } +// } + +// func DtoToProtos(in []*dto.CheckIn) []*checkinProto.CheckIn { +// var out []*checkinProto.CheckIn +// for _, v := range in { +// out = append(out, DtoToProto(v)) +// } +// return out +// } diff --git a/internal/dto/checkin.dto.go b/internal/dto/checkin.dto.go new file mode 100644 index 0000000..16342d2 --- /dev/null +++ b/internal/dto/checkin.dto.go @@ -0,0 +1,34 @@ +package dto + +type CheckIn struct { + ID string `json:"id"` + UserID string `json:"user_id"` + Email string `json:"email"` + Event string `json:"event"` +} + +type CreateCheckInRequest struct { + UserID string `json:"user_id"` + Email string `json:"email"` + Event string `json:"event"` +} + +type CreateCheckInResponse struct { + CheckIn *CheckIn `json:"checkin"` +} + +type FindByUserIdCheckInRequest struct { + UserID string `json:"user_id"` +} + +type FindByUserIdCheckInResponse struct { + CheckIns []*CheckIn `json:"checkins"` +} + +type FindByEmailCheckInRequest struct { + Email string `json:"email"` +} + +type FindByEmailCheckInResponse struct { + CheckIns []*CheckIn `json:"checkins"` +} From 8ee0752b8ddf2d0c76858117455a658145008dc3 Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 28 Jun 2024 22:11:56 +0700 Subject: [PATCH 2/6] feat: mock --- Makefile | 5 +- go.mod | 4 +- go.sum | 17 +----- mocks/checkin/checkin.client.go | 97 ++++++++++++++++++++++++++++++++ mocks/checkin/checkin.handler.go | 71 +++++++++++++++++++++++ mocks/checkin/checkin.service.go | 81 ++++++++++++++++++++++++++ 6 files changed, 255 insertions(+), 20 deletions(-) create mode 100644 mocks/checkin/checkin.client.go create mode 100644 mocks/checkin/checkin.handler.go create mode 100644 mocks/checkin/checkin.service.go diff --git a/Makefile b/Makefile index 931a616..82295af 100644 --- a/Makefile +++ b/Makefile @@ -9,11 +9,12 @@ watch: mock-gen: mockgen -source ./internal/auth/auth.handler.go -destination ./mocks/auth/auth.handler.go mockgen -source ./internal/auth/auth.service.go -destination ./mocks/auth/auth.service.go - mockgen -source ./internal/baan/baan.handler.go -destination ./mocks/baan/baan.handler.go - mockgen -source ./internal/baan/baan.service.go -destination ./mocks/baan/baan.service.go mockgen -source ./internal/selection/selection.handler.go -destination ./mocks/selection/selection.handler.go mockgen -source ./internal/selection/selection.service.go -destination ./mocks/selection/selection.service.go mockgen -source ./internal/selection/selection.client.go -destination ./mocks/selection/selection.client.go + mockgen -source ./internal/checkin/checkin.handler.go -destination ./mocks/checkin/checkin.handler.go + mockgen -source ./internal/checkin/checkin.service.go -destination ./mocks/checkin/checkin.service.go + mockgen -source ./internal/checkin/checkin.client.go -destination ./mocks/checkin/checkin.client.go mockgen -source ./internal/router/context.go -destination ./mocks/router/context.mock.go mockgen -source ./internal/validator/validator.go -destination ./mocks/validator/validator.mock.go diff --git a/go.mod b/go.mod index 9a00260..c6914eb 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/go-playground/validator/v10 v10.20.0 github.com/golang/mock v1.6.0 github.com/google/uuid v1.6.0 - github.com/isd-sgcu/rpkm67-go-proto v0.1.5 + github.com/isd-sgcu/rpkm67-go-proto v0.1.6 github.com/joho/godotenv v1.5.1 github.com/stretchr/testify v1.9.0 github.com/swaggo/files v1.0.1 @@ -21,8 +21,6 @@ require ( google.golang.org/grpc v1.64.0 ) -require github.com/stretchr/objx v0.5.2 // indirect - require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect diff --git a/go.sum b/go.sum index b51ac47..a43b43e 100644 --- a/go.sum +++ b/go.sum @@ -55,20 +55,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/isd-sgcu/rpkm67-go-proto v0.0.4 h1:ZO1m0EfTtjQ2IcRy6mUHj+mAb4loM3ckeisKefKqKmY= -github.com/isd-sgcu/rpkm67-go-proto v0.0.4/go.mod h1:Z5SYz5kEe4W+MdqPouF0zEOiaqvg+s9I1S5d0q6e+Jw= -github.com/isd-sgcu/rpkm67-go-proto v0.0.5 h1:8zTvNQ0NPokoVRK/NQJYxWjcBFMZNK0avotPs9RSPh0= -github.com/isd-sgcu/rpkm67-go-proto v0.0.5/go.mod h1:Z5SYz5kEe4W+MdqPouF0zEOiaqvg+s9I1S5d0q6e+Jw= -github.com/isd-sgcu/rpkm67-go-proto v0.0.6 h1:alECc0pLyJmbJ2cLBukNDplka+ucWutR6yLXqAn0lJM= -github.com/isd-sgcu/rpkm67-go-proto v0.0.6/go.mod h1:Z5SYz5kEe4W+MdqPouF0zEOiaqvg+s9I1S5d0q6e+Jw= -github.com/isd-sgcu/rpkm67-go-proto v0.0.7 h1:BrHjp7hDFmXTMuMKuA4mK3bjtHTvzozO0vYC1hV1a+w= -github.com/isd-sgcu/rpkm67-go-proto v0.0.7/go.mod h1:Z5SYz5kEe4W+MdqPouF0zEOiaqvg+s9I1S5d0q6e+Jw= -github.com/isd-sgcu/rpkm67-go-proto v0.1.2 h1:sLq8HWYaqnv0VO7cD5o4pLu+Mzf2fnIJuAT7DGqRaB8= -github.com/isd-sgcu/rpkm67-go-proto v0.1.2/go.mod h1:Z5SYz5kEe4W+MdqPouF0zEOiaqvg+s9I1S5d0q6e+Jw= -github.com/isd-sgcu/rpkm67-go-proto v0.1.3 h1:9+wrvKUUY5GDot1SmU9HtUgf8JzhPLHWKtCfmBQU+Yw= -github.com/isd-sgcu/rpkm67-go-proto v0.1.3/go.mod h1:Z5SYz5kEe4W+MdqPouF0zEOiaqvg+s9I1S5d0q6e+Jw= -github.com/isd-sgcu/rpkm67-go-proto v0.1.5 h1:WShrm8DeVqIY1ZelgM88vW8LMnLxF6dTt650A0YkC8U= -github.com/isd-sgcu/rpkm67-go-proto v0.1.5/go.mod h1:Z5SYz5kEe4W+MdqPouF0zEOiaqvg+s9I1S5d0q6e+Jw= +github.com/isd-sgcu/rpkm67-go-proto v0.1.6 h1:6mubghe7HuGJYv+hgpIxJBBrmVk5UdjHjdvzykLLhQ0= +github.com/isd-sgcu/rpkm67-go-proto v0.1.6/go.mod h1:Z5SYz5kEe4W+MdqPouF0zEOiaqvg+s9I1S5d0q6e+Jw= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -109,7 +97,6 @@ github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6po github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= diff --git a/mocks/checkin/checkin.client.go b/mocks/checkin/checkin.client.go new file mode 100644 index 0000000..dbfac0b --- /dev/null +++ b/mocks/checkin/checkin.client.go @@ -0,0 +1,97 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./internal/checkin/checkin.client.go + +// Package mock_checkin is a generated GoMock package. +package mock_checkin + +import ( + context "context" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + v1 "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/checkin/checkin/v1" + grpc "google.golang.org/grpc" +) + +// MockClient is a mock of Client interface. +type MockClient struct { + ctrl *gomock.Controller + recorder *MockClientMockRecorder +} + +// MockClientMockRecorder is the mock recorder for MockClient. +type MockClientMockRecorder struct { + mock *MockClient +} + +// NewMockClient creates a new mock instance. +func NewMockClient(ctrl *gomock.Controller) *MockClient { + mock := &MockClient{ctrl: ctrl} + mock.recorder = &MockClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClient) EXPECT() *MockClientMockRecorder { + return m.recorder +} + +// Create mocks base method. +func (m *MockClient) Create(ctx context.Context, in *v1.CreateCheckInRequest, opts ...grpc.CallOption) (*v1.CreateCheckInResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Create", varargs...) + ret0, _ := ret[0].(*v1.CreateCheckInResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Create indicates an expected call of Create. +func (mr *MockClientMockRecorder) Create(ctx, in interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockClient)(nil).Create), varargs...) +} + +// FindByEmail mocks base method. +func (m *MockClient) FindByEmail(ctx context.Context, in *v1.FindByEmailCheckInRequest, opts ...grpc.CallOption) (*v1.FindByEmailCheckInResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "FindByEmail", varargs...) + ret0, _ := ret[0].(*v1.FindByEmailCheckInResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FindByEmail indicates an expected call of FindByEmail. +func (mr *MockClientMockRecorder) FindByEmail(ctx, in interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByEmail", reflect.TypeOf((*MockClient)(nil).FindByEmail), varargs...) +} + +// FindByUserId mocks base method. +func (m *MockClient) FindByUserId(ctx context.Context, in *v1.FindByUserIdCheckInRequest, opts ...grpc.CallOption) (*v1.FindByUserIdCheckInResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "FindByUserId", varargs...) + ret0, _ := ret[0].(*v1.FindByUserIdCheckInResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FindByUserId indicates an expected call of FindByUserId. +func (mr *MockClientMockRecorder) FindByUserId(ctx, in interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByUserId", reflect.TypeOf((*MockClient)(nil).FindByUserId), varargs...) +} diff --git a/mocks/checkin/checkin.handler.go b/mocks/checkin/checkin.handler.go new file mode 100644 index 0000000..ba553af --- /dev/null +++ b/mocks/checkin/checkin.handler.go @@ -0,0 +1,71 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./internal/checkin/checkin.handler.go + +// Package mock_checkin is a generated GoMock package. +package mock_checkin + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + router "github.com/isd-sgcu/rpkm67-gateway/internal/router" +) + +// MockHandler is a mock of Handler interface. +type MockHandler struct { + ctrl *gomock.Controller + recorder *MockHandlerMockRecorder +} + +// MockHandlerMockRecorder is the mock recorder for MockHandler. +type MockHandlerMockRecorder struct { + mock *MockHandler +} + +// NewMockHandler creates a new mock instance. +func NewMockHandler(ctrl *gomock.Controller) *MockHandler { + mock := &MockHandler{ctrl: ctrl} + mock.recorder = &MockHandlerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockHandler) EXPECT() *MockHandlerMockRecorder { + return m.recorder +} + +// Create mocks base method. +func (m *MockHandler) Create(c router.Context) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Create", c) +} + +// Create indicates an expected call of Create. +func (mr *MockHandlerMockRecorder) Create(c interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockHandler)(nil).Create), c) +} + +// FindByEmail mocks base method. +func (m *MockHandler) FindByEmail(c router.Context) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "FindByEmail", c) +} + +// FindByEmail indicates an expected call of FindByEmail. +func (mr *MockHandlerMockRecorder) FindByEmail(c interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByEmail", reflect.TypeOf((*MockHandler)(nil).FindByEmail), c) +} + +// FindByUserID mocks base method. +func (m *MockHandler) FindByUserID(c router.Context) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "FindByUserID", c) +} + +// FindByUserID indicates an expected call of FindByUserID. +func (mr *MockHandlerMockRecorder) FindByUserID(c interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByUserID", reflect.TypeOf((*MockHandler)(nil).FindByUserID), c) +} diff --git a/mocks/checkin/checkin.service.go b/mocks/checkin/checkin.service.go new file mode 100644 index 0000000..b2b2ea6 --- /dev/null +++ b/mocks/checkin/checkin.service.go @@ -0,0 +1,81 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./internal/checkin/checkin.service.go + +// Package mock_checkin is a generated GoMock package. +package mock_checkin + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + apperror "github.com/isd-sgcu/rpkm67-gateway/apperror" + dto "github.com/isd-sgcu/rpkm67-gateway/internal/dto" +) + +// MockService is a mock of Service interface. +type MockService struct { + ctrl *gomock.Controller + recorder *MockServiceMockRecorder +} + +// 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 +} + +// Create mocks base method. +func (m *MockService) Create(req *dto.CreateCheckInRequest) (*dto.CreateCheckInResponse, *apperror.AppError) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", req) + ret0, _ := ret[0].(*dto.CreateCheckInResponse) + ret1, _ := ret[1].(*apperror.AppError) + return ret0, ret1 +} + +// Create indicates an expected call of Create. +func (mr *MockServiceMockRecorder) Create(req interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockService)(nil).Create), req) +} + +// FindByEmail mocks base method. +func (m *MockService) FindByEmail(req *dto.FindByEmailCheckInRequest) (*dto.FindByEmailCheckInResponse, *apperror.AppError) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindByEmail", req) + ret0, _ := ret[0].(*dto.FindByEmailCheckInResponse) + ret1, _ := ret[1].(*apperror.AppError) + return ret0, ret1 +} + +// FindByEmail indicates an expected call of FindByEmail. +func (mr *MockServiceMockRecorder) FindByEmail(req interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByEmail", reflect.TypeOf((*MockService)(nil).FindByEmail), req) +} + +// FindByUserID mocks base method. +func (m *MockService) FindByUserID(req *dto.FindByUserIdCheckInRequest) (*dto.FindByUserIdCheckInResponse, *apperror.AppError) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindByUserID", req) + ret0, _ := ret[0].(*dto.FindByUserIdCheckInResponse) + ret1, _ := ret[1].(*apperror.AppError) + return ret0, ret1 +} + +// FindByUserID indicates an expected call of FindByUserID. +func (mr *MockServiceMockRecorder) FindByUserID(req interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByUserID", reflect.TypeOf((*MockService)(nil).FindByUserID), req) +} From 86a926d7b553e906cb79b596eee90908e4bd485b Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 28 Jun 2024 22:12:17 +0700 Subject: [PATCH 3/6] fix: remove baan gateway --- internal/baan/baan.handler.go | 68 -------------- internal/baan/baan.service.go | 84 ----------------- internal/baan/baan.utils.go | 32 ------- internal/baan/test/baan.handler_test.go | 88 ------------------ internal/baan/test/baan.service_test.go | 93 ------------------- internal/baan/test/baan.service_test.utils.go | 31 ------- mocks/baan/baan.handler.go | 59 ------------ mocks/baan/baan.service.go | 66 ------------- mocks/client/baan/baan.mock.go | 33 ------- 9 files changed, 554 deletions(-) delete mode 100644 internal/baan/baan.handler.go delete mode 100644 internal/baan/baan.service.go delete mode 100644 internal/baan/baan.utils.go delete mode 100644 internal/baan/test/baan.handler_test.go delete mode 100644 internal/baan/test/baan.service_test.go delete mode 100644 internal/baan/test/baan.service_test.utils.go delete mode 100644 mocks/baan/baan.handler.go delete mode 100644 mocks/baan/baan.service.go delete mode 100644 mocks/client/baan/baan.mock.go diff --git a/internal/baan/baan.handler.go b/internal/baan/baan.handler.go deleted file mode 100644 index 04ec941..0000000 --- a/internal/baan/baan.handler.go +++ /dev/null @@ -1,68 +0,0 @@ -package baan - -import ( - "net/http" - "strings" - - "github.com/isd-sgcu/rpkm67-gateway/internal/dto" - "github.com/isd-sgcu/rpkm67-gateway/internal/router" - "github.com/isd-sgcu/rpkm67-gateway/internal/validator" - "go.uber.org/zap" -) - -type Handler interface { - FindAllBaan(c router.Context) - FindOneBaan(c router.Context) -} - -func NewHandler(svc Service, validate validator.DtoValidator, log *zap.Logger) Handler { - return &handlerImpl{ - svc: svc, - validate: validate, - log: log, - } -} - -type handlerImpl struct { - svc Service - validate validator.DtoValidator - log *zap.Logger -} - -func (h *handlerImpl) FindAllBaan(c router.Context) { - req := &dto.FindAllBaanRequest{} - res, appErr := h.svc.FindAllBaan(req) - if appErr != nil { - h.log.Named("FindAllBaan").Error("FindAllBaan: ", zap.Error(appErr)) - c.ResponseError(appErr) - return - } - - c.JSON(http.StatusOK, &dto.FindAllBaanResponse{Baans: res.Baans}) -} - -func (h *handlerImpl) FindOneBaan(c router.Context) { - baanId := c.Param("id") - if baanId == "" { - c.BadRequestError("url parameter 'id' not found") - } - - req := &dto.FindOneBaanRequest{ - Id: baanId, - } - - if errorList := h.validate.Validate(req); errorList != nil { - h.log.Named("FineOneBaan").Error("Validate: ", zap.Strings("errorList", errorList)) - c.BadRequestError(strings.Join(errorList, ", ")) - return - } - - res, appErr := h.svc.FindOneBaan(req) - if appErr != nil { - h.log.Named("FindOneBaan").Error("FindOneBaan: ", zap.Error(appErr)) - c.ResponseError(appErr) - return - } - - c.JSON(http.StatusOK, &dto.FindOneBaanResponse{Baan: res.Baan}) -} diff --git a/internal/baan/baan.service.go b/internal/baan/baan.service.go deleted file mode 100644 index 9a0e361..0000000 --- a/internal/baan/baan.service.go +++ /dev/null @@ -1,84 +0,0 @@ -package baan - -import ( - "context" - "time" - - "github.com/isd-sgcu/rpkm67-gateway/apperror" - "github.com/isd-sgcu/rpkm67-gateway/internal/dto" - baanProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/backend/baan/v1" - "go.uber.org/zap" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -type Service interface { - FindAllBaan(req *dto.FindAllBaanRequest) (*dto.FindAllBaanResponse, *apperror.AppError) - FindOneBaan(req *dto.FindOneBaanRequest) (*dto.FindOneBaanResponse, *apperror.AppError) -} - -type serviceImpl struct { - client baanProto.BaanServiceClient - log *zap.Logger -} - -func NewService(client baanProto.BaanServiceClient, log *zap.Logger) Service { - return &serviceImpl{ - client: client, - log: log, - } -} - -func (s *serviceImpl) FindAllBaan(req *dto.FindAllBaanRequest) (*dto.FindAllBaanResponse, *apperror.AppError) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - res, err := s.client.FindAllBaan(ctx, &baanProto.FindAllBaanRequest{}) - if err != nil { - s.log.Named("FindAllBaan").Error("FindAllBaan: ", zap.Error(err)) - st, ok := status.FromError(err) - if !ok { - return nil, apperror.InternalServer - } - switch st.Code() { - case codes.InvalidArgument: - return nil, apperror.BadRequestError("Invalid argument") - case codes.Internal: - return nil, apperror.InternalServerError(err.Error()) - default: - return nil, apperror.ServiceUnavailable - } - } - - return &dto.FindAllBaanResponse{ - Baans: ProtoToDtoList(res.Baans), - }, nil -} - -func (s *serviceImpl) FindOneBaan(req *dto.FindOneBaanRequest) (*dto.FindOneBaanResponse, *apperror.AppError) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - res, err := s.client.FindOneBaan(ctx, &baanProto.FindOneBaanRequest{ - Id: req.Id, - }) - if err != nil { - s.log.Named("FindOneBaan").Error("FindOneBaan: ", zap.Error(err)) - st, ok := status.FromError(err) - if !ok { - return nil, apperror.InternalServer - } - switch st.Code() { - case codes.NotFound: - return nil, apperror.NotFoundError("Baan not found") - case codes.Internal: - return nil, apperror.InternalServerError(err.Error()) - default: - return nil, apperror.ServiceUnavailable - } - } - - return &dto.FindOneBaanResponse{ - Baan: ProtoToDto(res.Baan), - }, nil -} diff --git a/internal/baan/baan.utils.go b/internal/baan/baan.utils.go deleted file mode 100644 index afa1f4d..0000000 --- a/internal/baan/baan.utils.go +++ /dev/null @@ -1,32 +0,0 @@ -package baan - -import ( - "github.com/isd-sgcu/rpkm67-gateway/internal/dto" - baanProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/backend/baan/v1" -) - -func ProtoToDto(in *baanProto.Baan) *dto.Baan { - return &dto.Baan{ - Id: in.Id, - NameTH: in.NameTH, - DescriptionTH: in.DescriptionTH, - NameEN: in.NameEN, - DescriptionEN: in.DescriptionEN, - Size: dto.BaanSize(in.Size), - Facebook: in.Facebook, - FacebookUrl: in.FacebookUrl, - Instagram: in.Instagram, - InstagramUrl: in.InstagramUrl, - Line: in.Line, - LineUrl: in.LineUrl, - ImageUrl: in.ImageUrl, - } -} - -func ProtoToDtoList(in []*baanProto.Baan) []*dto.Baan { - var out []*dto.Baan - for _, b := range in { - out = append(out, ProtoToDto(b)) - } - return out -} diff --git a/internal/baan/test/baan.handler_test.go b/internal/baan/test/baan.handler_test.go deleted file mode 100644 index c31e283..0000000 --- a/internal/baan/test/baan.handler_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package test - -import ( - "net/http" - "testing" - - "github.com/golang/mock/gomock" - "github.com/isd-sgcu/rpkm67-gateway/apperror" - "github.com/isd-sgcu/rpkm67-gateway/internal/baan" - "github.com/isd-sgcu/rpkm67-gateway/internal/dto" - baanMock "github.com/isd-sgcu/rpkm67-gateway/mocks/baan" - routerMock "github.com/isd-sgcu/rpkm67-gateway/mocks/router" - validatorMock "github.com/isd-sgcu/rpkm67-gateway/mocks/validator" - "github.com/stretchr/testify/suite" - "go.uber.org/zap" -) - -type BaanHandlerTest struct { - suite.Suite - controller *gomock.Controller - logger *zap.Logger - Baans []*dto.Baan - Baan *dto.Baan - FindAllBaanReq *dto.FindAllBaanRequest - FindOneBaanReq *dto.FindOneBaanRequest - Err *apperror.AppError - ParamMock string -} - -func TestBaanHandler(t *testing.T) { - suite.Run(t, new(BaanHandlerTest)) -} - -func (t *BaanHandlerTest) SetupTest() { - t.controller = gomock.NewController(t.T()) - t.logger = zap.NewNop() - - baansProto := MockBaansProto() - baanProto := baansProto[0] - - t.Baans = baan.ProtoToDtoList(baansProto) - t.Baan = baan.ProtoToDto(baanProto) - - t.FindAllBaanReq = &dto.FindAllBaanRequest{} - t.FindOneBaanReq = &dto.FindOneBaanRequest{ - Id: t.Baan.Id, - } - - t.ParamMock = t.Baan.Id -} - -func (t *BaanHandlerTest) TestFindAllBaanSuccess() { - baanSvc := baanMock.NewMockService(t.controller) - validator := validatorMock.NewMockDtoValidator(t.controller) - context := routerMock.NewMockContext(t.controller) - handler := baan.NewHandler(baanSvc, validator, t.logger) - - expectedResp := &dto.FindAllBaanResponse{ - Baans: t.Baans, - } - - baanSvc.EXPECT().FindAllBaan(t.FindAllBaanReq).Return(expectedResp, t.Err) - context.EXPECT().JSON(http.StatusOK, expectedResp) - - handler.FindAllBaan(context) -} - -func (t *BaanHandlerTest) TestFindOneBaanSuccess() { - baanSvc := baanMock.NewMockService(t.controller) - validator := validatorMock.NewMockDtoValidator(t.controller) - context := routerMock.NewMockContext(t.controller) - handler := baan.NewHandler(baanSvc, validator, t.logger) - - expectedResp := &dto.FindOneBaanResponse{ - Baan: t.Baan, - } - - context.EXPECT().Param("id").Return(t.ParamMock) - validator.EXPECT().Validate(t.FindOneBaanReq).Return(nil) - baanSvc.EXPECT().FindOneBaan(t.FindOneBaanReq).Return(expectedResp, t.Err) - context.EXPECT().JSON(http.StatusOK, expectedResp) - - handler.FindOneBaan(context) -} - -func (t *BaanHandlerTest) TearDownTest() { - t.controller.Finish() -} diff --git a/internal/baan/test/baan.service_test.go b/internal/baan/test/baan.service_test.go deleted file mode 100644 index e7d783d..0000000 --- a/internal/baan/test/baan.service_test.go +++ /dev/null @@ -1,93 +0,0 @@ -package test - -import ( - "testing" - - "github.com/golang/mock/gomock" - "github.com/isd-sgcu/rpkm67-gateway/apperror" - "github.com/isd-sgcu/rpkm67-gateway/internal/baan" - "github.com/isd-sgcu/rpkm67-gateway/internal/dto" - baanMock "github.com/isd-sgcu/rpkm67-gateway/mocks/client/baan" - baanProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/backend/baan/v1" - "github.com/stretchr/testify/suite" - "go.uber.org/zap" -) - -type BaanServiceTest struct { - suite.Suite - controller *gomock.Controller - logger *zap.Logger - BaansProto []*baanProto.Baan - BaanProto *baanProto.Baan - BaansDto []*dto.Baan - BaanDto *dto.Baan - FindAllBaanProtoReq *baanProto.FindAllBaanRequest - FindAllBaanDtoReq *dto.FindAllBaanRequest - FindOneBaanProtoReq *baanProto.FindOneBaanRequest - FindOneBaanDtoReq *dto.FindOneBaanRequest - Err apperror.AppError -} - -func TestBaanService(t *testing.T) { - suite.Run(t, new(BaanServiceTest)) -} - -func (t *BaanServiceTest) SetupTest() { - t.controller = gomock.NewController(t.T()) - t.logger = zap.NewNop() - - t.BaansProto = MockBaansProto() - t.BaanProto = t.BaansProto[0] - t.BaansDto = baan.ProtoToDtoList(t.BaansProto) - t.BaanDto = baan.ProtoToDto(t.BaanProto) - - t.FindAllBaanProtoReq = &baanProto.FindAllBaanRequest{} - t.FindOneBaanProtoReq = &baanProto.FindOneBaanRequest{ - Id: t.BaanProto.Id, - } - t.FindAllBaanDtoReq = &dto.FindAllBaanRequest{} - t.FindOneBaanDtoReq = &dto.FindOneBaanRequest{ - Id: t.BaanDto.Id, - } -} - -func (t *BaanServiceTest) TestFindAllBaanSuccess() { - client := baanMock.BaanClientMock{} - svc := baan.NewService(&client, t.logger) - - protoResp := &baanProto.FindAllBaanResponse{ - Baans: t.BaansProto, - } - findAllBaansDto := baan.ProtoToDtoList(protoResp.Baans) - expected := &dto.FindAllBaanResponse{ - Baans: findAllBaansDto, - } - - client.On("FindAllBaan", t.FindAllBaanProtoReq).Return(protoResp, nil) - actual, err := svc.FindAllBaan(t.FindAllBaanDtoReq) - - t.Nil(err) - t.Equal(expected, actual) -} - -func (t *BaanServiceTest) TestFindOneBaanSuccess() { - client := baanMock.BaanClientMock{} - svc := baan.NewService(&client, t.logger) - - protoResp := &baanProto.FindOneBaanResponse{ - Baan: t.BaanProto, - } - expected := &dto.FindOneBaanResponse{ - Baan: t.BaanDto, - } - - client.On("FindOneBaan", t.FindOneBaanProtoReq).Return(protoResp, nil) - actual, err := svc.FindOneBaan(t.FindOneBaanDtoReq) - - t.Nil(err) - t.Equal(expected, actual) -} - -func (t *BaanServiceTest) TearDownTest() { - t.controller.Finish() -} diff --git a/internal/baan/test/baan.service_test.utils.go b/internal/baan/test/baan.service_test.utils.go deleted file mode 100644 index cd6ad16..0000000 --- a/internal/baan/test/baan.service_test.utils.go +++ /dev/null @@ -1,31 +0,0 @@ -package test - -import ( - "math/rand" - - "github.com/bxcodec/faker/v4" - baanProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/backend/baan/v1" -) - -func MockBaansProto() []*baanProto.Baan { - var baans []*baanProto.Baan - for i := 0; i < 10; i++ { - baan := &baanProto.Baan{ - Id: faker.UUIDHyphenated(), - NameTH: faker.Name(), - DescriptionTH: faker.Sentence(), - NameEN: faker.Name(), - DescriptionEN: faker.Sentence(), - Size: baanProto.BaanSize(rand.Intn(6)), - Facebook: faker.URL(), - FacebookUrl: faker.URL(), - Instagram: faker.URL(), - InstagramUrl: faker.URL(), - Line: faker.URL(), - LineUrl: faker.URL(), - ImageUrl: faker.URL(), - } - baans = append(baans, baan) - } - return baans -} diff --git a/mocks/baan/baan.handler.go b/mocks/baan/baan.handler.go deleted file mode 100644 index 84da72d..0000000 --- a/mocks/baan/baan.handler.go +++ /dev/null @@ -1,59 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: ./internal/baan/baan.handler.go - -// Package mock_baan is a generated GoMock package. -package mock_baan - -import ( - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - router "github.com/isd-sgcu/rpkm67-gateway/internal/router" -) - -// MockHandler is a mock of Handler interface. -type MockHandler struct { - ctrl *gomock.Controller - recorder *MockHandlerMockRecorder -} - -// MockHandlerMockRecorder is the mock recorder for MockHandler. -type MockHandlerMockRecorder struct { - mock *MockHandler -} - -// NewMockHandler creates a new mock instance. -func NewMockHandler(ctrl *gomock.Controller) *MockHandler { - mock := &MockHandler{ctrl: ctrl} - mock.recorder = &MockHandlerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockHandler) EXPECT() *MockHandlerMockRecorder { - return m.recorder -} - -// FindAllBaan mocks base method. -func (m *MockHandler) FindAllBaan(c router.Context) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "FindAllBaan", c) -} - -// FindAllBaan indicates an expected call of FindAllBaan. -func (mr *MockHandlerMockRecorder) FindAllBaan(c interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAllBaan", reflect.TypeOf((*MockHandler)(nil).FindAllBaan), c) -} - -// FindOneBaan mocks base method. -func (m *MockHandler) FindOneBaan(c router.Context) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "FindOneBaan", c) -} - -// FindOneBaan indicates an expected call of FindOneBaan. -func (mr *MockHandlerMockRecorder) FindOneBaan(c interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOneBaan", reflect.TypeOf((*MockHandler)(nil).FindOneBaan), c) -} diff --git a/mocks/baan/baan.service.go b/mocks/baan/baan.service.go deleted file mode 100644 index 5404f84..0000000 --- a/mocks/baan/baan.service.go +++ /dev/null @@ -1,66 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: ./internal/baan/baan.service.go - -// Package mock_baan is a generated GoMock package. -package mock_baan - -import ( - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - apperror "github.com/isd-sgcu/rpkm67-gateway/apperror" - dto "github.com/isd-sgcu/rpkm67-gateway/internal/dto" -) - -// MockService is a mock of Service interface. -type MockService struct { - ctrl *gomock.Controller - recorder *MockServiceMockRecorder -} - -// 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 -} - -// FindAllBaan mocks base method. -func (m *MockService) FindAllBaan(req *dto.FindAllBaanRequest) (*dto.FindAllBaanResponse, *apperror.AppError) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindAllBaan", req) - ret0, _ := ret[0].(*dto.FindAllBaanResponse) - ret1, _ := ret[1].(*apperror.AppError) - return ret0, ret1 -} - -// FindAllBaan indicates an expected call of FindAllBaan. -func (mr *MockServiceMockRecorder) FindAllBaan(req interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAllBaan", reflect.TypeOf((*MockService)(nil).FindAllBaan), req) -} - -// FindOneBaan mocks base method. -func (m *MockService) FindOneBaan(req *dto.FindOneBaanRequest) (*dto.FindOneBaanResponse, *apperror.AppError) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindOneBaan", req) - ret0, _ := ret[0].(*dto.FindOneBaanResponse) - ret1, _ := ret[1].(*apperror.AppError) - return ret0, ret1 -} - -// FindOneBaan indicates an expected call of FindOneBaan. -func (mr *MockServiceMockRecorder) FindOneBaan(req interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOneBaan", reflect.TypeOf((*MockService)(nil).FindOneBaan), req) -} diff --git a/mocks/client/baan/baan.mock.go b/mocks/client/baan/baan.mock.go deleted file mode 100644 index 2fec9ec..0000000 --- a/mocks/client/baan/baan.mock.go +++ /dev/null @@ -1,33 +0,0 @@ -package baan - -import ( - "context" - - baanProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/backend/baan/v1" - "github.com/stretchr/testify/mock" - "google.golang.org/grpc" -) - -type BaanClientMock struct { - mock.Mock -} - -func (c *BaanClientMock) FindAllBaan(_ context.Context, req *baanProto.FindAllBaanRequest, _ ...grpc.CallOption) (res *baanProto.FindAllBaanResponse, err error) { - args := c.Called(req) - - if args.Get(0) != nil { - res = args.Get(0).(*baanProto.FindAllBaanResponse) - } - - return res, args.Error(1) -} - -func (c *BaanClientMock) FindOneBaan(_ context.Context, req *baanProto.FindOneBaanRequest, _ ...grpc.CallOption) (res *baanProto.FindOneBaanResponse, err error) { - args := c.Called(req) - - if args.Get(0) != nil { - res = args.Get(0).(*baanProto.FindOneBaanResponse) - } - - return res, args.Error(1) -} From 678a90fa80056119f14caf99dee25707f1e1b27a Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 28 Jun 2024 22:13:08 +0700 Subject: [PATCH 4/6] fix: selection test, dto --- internal/dto/selection.dto.go | 16 ++++++++++++++-- internal/selection/selection.handler.go | 4 +++- internal/selection/selection.service.go | 4 ++-- internal/selection/selection.utils.go | 2 +- .../selection/test/selection.handler_test.go | 6 +++--- .../selection/test/selection.service_test.go | 11 +++++------ 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/internal/dto/selection.dto.go b/internal/dto/selection.dto.go index f8696c8..d30414d 100644 --- a/internal/dto/selection.dto.go +++ b/internal/dto/selection.dto.go @@ -7,6 +7,11 @@ type Selection struct { Order int `json:"order"` } +type BaanCount struct { + BaanId string `json:"baan_id"` + Count int32 `json:"count"` +} + type CreateSelectionRequest struct { GroupId string `json:"group_id" validate:"required"` BaanId string `json:"baan_ids" validate:"required"` @@ -22,13 +27,20 @@ type FindByGroupIdSelectionRequest struct { } type FindByGroupIdSelectionResponse struct { - Selection *Selection `json:"selection"` + Selections []*Selection `json:"selections"` } type DeleteSelectionRequest struct { - Id string `json:"id" validate:"required"` + GroupId string `json:"id" validate:"required"` } type DeleteSelectionResponse struct { Success bool `json:"success"` } + +type CountByBaanIdSelectionRequest struct { +} + +type CountByBaanIdSelectionResponse struct { + BaanCounts []*BaanCount `json:"baan_counts"` +} diff --git a/internal/selection/selection.handler.go b/internal/selection/selection.handler.go index 8abc01a..99c9232 100644 --- a/internal/selection/selection.handler.go +++ b/internal/selection/selection.handler.go @@ -79,7 +79,9 @@ func (h *handlerImpl) FindByGroupIdSelection(c router.Context) { return } - c.JSON(http.StatusOK, &dto.FindByGroupIdSelectionResponse{Selection: res.Selection}) + c.JSON(http.StatusOK, &dto.FindByGroupIdSelectionResponse{ + Selections: res.Selections, + }) } func (h *handlerImpl) DeleteSelection(c router.Context) { diff --git a/internal/selection/selection.service.go b/internal/selection/selection.service.go index da7b384..45eba0e 100644 --- a/internal/selection/selection.service.go +++ b/internal/selection/selection.service.go @@ -83,7 +83,7 @@ func (s *serviceImpl) FindByGroupIdSelection(req *dto.FindByGroupIdSelectionRequ } return &dto.FindByGroupIdSelectionResponse{ - Selection: ProtoToDto(res.Selection), + Selections: ProtoToDtos(res.Selections), }, nil } @@ -92,7 +92,7 @@ func (s *serviceImpl) DeleteSelection(req *dto.DeleteSelectionRequest) (*dto.Del defer cancel() res, err := s.client.Delete(ctx, &selectionProto.DeleteSelectionRequest{ - Id: req.Id, + GroupId: req.GroupId, }) if err != nil { s.log.Named("UpdateSelection").Error("Update: ", zap.Error(err)) diff --git a/internal/selection/selection.utils.go b/internal/selection/selection.utils.go index 8476e74..5557489 100644 --- a/internal/selection/selection.utils.go +++ b/internal/selection/selection.utils.go @@ -21,7 +21,7 @@ func DtoToProto(selection *dto.Selection) *selectionProto.Selection { } } -func ProtoToDtoList(selections []*selectionProto.Selection) []*dto.Selection { +func ProtoToDtos(selections []*selectionProto.Selection) []*dto.Selection { var out []*dto.Selection for _, selection := range selections { out = append(out, ProtoToDto(selection)) diff --git a/internal/selection/test/selection.handler_test.go b/internal/selection/test/selection.handler_test.go index 07e2d97..ce8bfad 100644 --- a/internal/selection/test/selection.handler_test.go +++ b/internal/selection/test/selection.handler_test.go @@ -37,7 +37,7 @@ func (t *SelectionHandlerTest) SetupTest() { selectionsProto := MockSelectionsProto() selectionProto := selectionsProto[0] - t.Selections = selection.ProtoToDtoList(selectionsProto) + t.Selections = selection.ProtoToDtos(selectionsProto) t.Selection = selection.ProtoToDto(selectionProto) t.CreateSelectionReq = &dto.CreateSelectionRequest{ @@ -48,7 +48,7 @@ func (t *SelectionHandlerTest) SetupTest() { GroupId: t.Selection.GroupId, } t.DeleteSelectionReq = &dto.DeleteSelectionRequest{ - Id: t.Selection.Id, + GroupId: t.Selection.GroupId, } } @@ -101,7 +101,7 @@ func (t *SelectionHandlerTest) TestFindByStudentIdSelectionSuccess() { handler := selection.NewHandler(selectionSvc, validator, t.logger) expectedResp := &dto.FindByGroupIdSelectionResponse{ - Selection: t.Selection, + Selections: t.Selections, } context.EXPECT().Param("id").Return(t.Selection.GroupId) diff --git a/internal/selection/test/selection.service_test.go b/internal/selection/test/selection.service_test.go index 762f929..cfccb86 100644 --- a/internal/selection/test/selection.service_test.go +++ b/internal/selection/test/selection.service_test.go @@ -29,7 +29,6 @@ type SelectionServiceTest struct { FindByGroupIdSelectionDtoRequest *dto.FindByGroupIdSelectionRequest DeleteSelectionProtoRequest *selectionProto.DeleteSelectionRequest DeleteSelectionDtoRequest *dto.DeleteSelectionRequest - Err apperror.AppError } func TestSelectionService(t *testing.T) { @@ -42,7 +41,7 @@ func (t *SelectionServiceTest) SetupTest() { t.SelectionsProto = MockSelectionsProto() t.SelectionProto = t.SelectionsProto[0] - t.SelectionsDto = selection.ProtoToDtoList(t.SelectionsProto) + t.SelectionsDto = selection.ProtoToDtos(t.SelectionsProto) t.SelectionDto = selection.ProtoToDto(t.SelectionProto) t.CreateSelectionProtoRequest = &selectionProto.CreateSelectionRequest{ @@ -60,10 +59,10 @@ func (t *SelectionServiceTest) SetupTest() { GroupId: t.SelectionDto.GroupId, } t.DeleteSelectionProtoRequest = &selectionProto.DeleteSelectionRequest{ - Id: t.SelectionProto.Id, + GroupId: t.SelectionProto.GroupId, } t.DeleteSelectionDtoRequest = &dto.DeleteSelectionRequest{ - Id: t.SelectionDto.Id, + GroupId: t.SelectionDto.GroupId, } } @@ -122,10 +121,10 @@ func (t *SelectionServiceTest) TestFindByGroupIdSelectionSuccess() { svc := selection.NewService(client, t.logger) protoResp := &selectionProto.FindByGroupIdSelectionResponse{ - Selection: t.SelectionProto, + Selections: t.SelectionsProto, } expected := &dto.FindByGroupIdSelectionResponse{ - Selection: t.SelectionDto, + Selections: t.SelectionsDto, } client.EXPECT().FindByGroupId(gomock.Any(), t.FindByGroupIdSelectionProtoRequest).Return(protoResp, nil) From 7c1e22fb199710b9169473e9144d216fde10a788 Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 28 Jun 2024 22:13:29 +0700 Subject: [PATCH 5/6] feat: checkin gateway w/ test --- internal/checkin/checkin.client.go | 36 +++ internal/checkin/checkin.handler.go | 1 + internal/checkin/checkin.service.go | 6 +- internal/checkin/test/checkin.handler_test.go | 229 ++++++++++++++++++ internal/checkin/test/checkin.service_test.go | 202 +++++++++++++++ internal/checkin/test/checkin.utils_test.go | 27 +++ 6 files changed, 498 insertions(+), 3 deletions(-) create mode 100644 internal/checkin/checkin.client.go create mode 100644 internal/checkin/test/checkin.handler_test.go create mode 100644 internal/checkin/test/checkin.service_test.go create mode 100644 internal/checkin/test/checkin.utils_test.go diff --git a/internal/checkin/checkin.client.go b/internal/checkin/checkin.client.go new file mode 100644 index 0000000..60d036d --- /dev/null +++ b/internal/checkin/checkin.client.go @@ -0,0 +1,36 @@ +package checkin + +import ( + "context" + + checkinProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/checkin/checkin/v1" + "google.golang.org/grpc" +) + +type clientImpl struct { + client checkinProto.CheckInServiceClient +} + +type Client interface { + Create(ctx context.Context, in *checkinProto.CreateCheckInRequest, opts ...grpc.CallOption) (*checkinProto.CreateCheckInResponse, error) + FindByUserId(ctx context.Context, in *checkinProto.FindByUserIdCheckInRequest, opts ...grpc.CallOption) (*checkinProto.FindByUserIdCheckInResponse, error) + FindByEmail(ctx context.Context, in *checkinProto.FindByEmailCheckInRequest, opts ...grpc.CallOption) (*checkinProto.FindByEmailCheckInResponse, error) +} + +func NewClient(client checkinProto.CheckInServiceClient) Client { + return &clientImpl{ + client: client, + } +} + +func (c *clientImpl) Create(ctx context.Context, in *checkinProto.CreateCheckInRequest, opts ...grpc.CallOption) (*checkinProto.CreateCheckInResponse, error) { + return c.client.Create(ctx, in, opts...) +} + +func (c *clientImpl) FindByUserId(ctx context.Context, in *checkinProto.FindByUserIdCheckInRequest, opts ...grpc.CallOption) (*checkinProto.FindByUserIdCheckInResponse, error) { + return c.client.FindByUserId(ctx, in, opts...) +} + +func (c *clientImpl) FindByEmail(ctx context.Context, in *checkinProto.FindByEmailCheckInRequest, opts ...grpc.CallOption) (*checkinProto.FindByEmailCheckInResponse, error) { + return c.client.FindByEmail(ctx, in, opts...) +} diff --git a/internal/checkin/checkin.handler.go b/internal/checkin/checkin.handler.go index f56a16f..65eb928 100644 --- a/internal/checkin/checkin.handler.go +++ b/internal/checkin/checkin.handler.go @@ -61,6 +61,7 @@ func (h *handlerImpl) Create(c router.Context) { CheckIn: &dto.CheckIn{ ID: res.CheckIn.ID, UserID: res.CheckIn.UserID, + Email: res.CheckIn.Email, Event: res.CheckIn.Event, }, }) diff --git a/internal/checkin/checkin.service.go b/internal/checkin/checkin.service.go index e62a623..cc9cd9c 100644 --- a/internal/checkin/checkin.service.go +++ b/internal/checkin/checkin.service.go @@ -49,7 +49,7 @@ func (s *serviceImpl) Create(req *dto.CreateCheckInRequest) (*dto.CreateCheckInR case codes.InvalidArgument: return nil, apperror.BadRequest case codes.Internal: - return nil, apperror.InternalServerError(err.Error()) + return nil, apperror.InternalServer default: return nil, apperror.ServiceUnavailable } @@ -82,7 +82,7 @@ func (s *serviceImpl) FindByEmail(req *dto.FindByEmailCheckInRequest) (*dto.Find case codes.InvalidArgument: return nil, apperror.BadRequest case codes.Internal: - return nil, apperror.InternalServerError(err.Error()) + return nil, apperror.InternalServer default: return nil, apperror.ServiceUnavailable } @@ -110,7 +110,7 @@ func (s *serviceImpl) FindByUserID(req *dto.FindByUserIdCheckInRequest) (*dto.Fi case codes.InvalidArgument: return nil, apperror.BadRequest case codes.Internal: - return nil, apperror.InternalServerError(err.Error()) + return nil, apperror.InternalServer default: return nil, apperror.ServiceUnavailable } diff --git a/internal/checkin/test/checkin.handler_test.go b/internal/checkin/test/checkin.handler_test.go new file mode 100644 index 0000000..82322ee --- /dev/null +++ b/internal/checkin/test/checkin.handler_test.go @@ -0,0 +1,229 @@ +package test + +import ( + "net/http" + "testing" + + "github.com/golang/mock/gomock" + "github.com/isd-sgcu/rpkm67-gateway/apperror" + "github.com/isd-sgcu/rpkm67-gateway/internal/checkin" + "github.com/isd-sgcu/rpkm67-gateway/internal/dto" + "github.com/stretchr/testify/suite" + "go.uber.org/zap" + + checkinMock "github.com/isd-sgcu/rpkm67-gateway/mocks/checkin" + routerMock "github.com/isd-sgcu/rpkm67-gateway/mocks/router" + validatorMock "github.com/isd-sgcu/rpkm67-gateway/mocks/validator" +) + +type CheckInHandlerTest struct { + suite.Suite + controller *gomock.Controller + logger *zap.Logger + checkins []*dto.CheckIn + checkin *dto.CheckIn + createCheckinReq *dto.CreateCheckInRequest + findByUserIdCheckinReq *dto.FindByUserIdCheckInRequest + findByEmailCheckinReq *dto.FindByEmailCheckInRequest +} + +func TestCheckinHandler(t *testing.T) { + suite.Run(t, new(CheckInHandlerTest)) +} + +func (t *CheckInHandlerTest) SetupTest() { + t.controller = gomock.NewController(t.T()) + t.logger = zap.NewNop() + + checkinsProto := MockCheckInsProto() + t.checkins = checkin.ProtoToDtos(checkinsProto) + t.checkin = t.checkins[0] + + t.createCheckinReq = &dto.CreateCheckInRequest{ + Email: t.checkin.Email, + UserID: t.checkin.UserID, + Event: t.checkin.Event, + } + t.findByUserIdCheckinReq = &dto.FindByUserIdCheckInRequest{ + UserID: t.checkin.UserID, + } + t.findByEmailCheckinReq = &dto.FindByEmailCheckInRequest{ + Email: t.checkin.Email, + } +} + +func (t *CheckInHandlerTest) TestCreateCheckinSuccess() { + checkinSvc := checkinMock.NewMockService(t.controller) + validator := validatorMock.NewMockDtoValidator(t.controller) + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(checkinSvc, validator, t.logger) + + expectedResp := &dto.CreateCheckInResponse{ + CheckIn: &dto.CheckIn{ + Email: t.checkin.Email, + UserID: t.checkin.UserID, + Event: t.checkin.Event, + }, + } + + context.EXPECT().Bind(&dto.CreateCheckInRequest{}).SetArg(0, *t.createCheckinReq) + validator.EXPECT().Validate(t.createCheckinReq).Return(nil) + checkinSvc.EXPECT().Create(t.createCheckinReq).Return(expectedResp, nil) + context.EXPECT().JSON(http.StatusCreated, expectedResp) + + handler.Create(context) +} + +func (t *CheckInHandlerTest) TestCreateCheckinBindError() { + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(nil, nil, t.logger) + + context.EXPECT().Bind(&dto.CreateCheckInRequest{}).Return(apperror.BadRequest) + context.EXPECT().BadRequestError(apperror.BadRequest.Error()) + + handler.Create(context) +} + +func (t *CheckInHandlerTest) TestCreateCheckinValidationError() { + checkinSvc := checkinMock.NewMockService(t.controller) + validator := validatorMock.NewMockDtoValidator(t.controller) + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(checkinSvc, validator, t.logger) + + expectedError := []string{"error1", "error2"} + + context.EXPECT().Bind(&dto.CreateCheckInRequest{}).SetArg(0, *t.createCheckinReq) + validator.EXPECT().Validate(t.createCheckinReq).Return(expectedError) + context.EXPECT().BadRequestError("error1, error2") + + handler.Create(context) +} + +func (t *CheckInHandlerTest) TestCreateCheckinServiceError() { + checkinSvc := checkinMock.NewMockService(t.controller) + validator := validatorMock.NewMockDtoValidator(t.controller) + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(checkinSvc, validator, t.logger) + + context.EXPECT().Bind(&dto.CreateCheckInRequest{}).SetArg(0, *t.createCheckinReq) + validator.EXPECT().Validate(t.createCheckinReq).Return(nil) + checkinSvc.EXPECT().Create(t.createCheckinReq).Return(nil, apperror.InternalServer) + context.EXPECT().ResponseError(apperror.InternalServer) + + handler.Create(context) + +} + +func (t *CheckInHandlerTest) TestFindByEmailCheckinSuccess() { + checkinSvc := checkinMock.NewMockService(t.controller) + validator := validatorMock.NewMockDtoValidator(t.controller) + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(checkinSvc, validator, t.logger) + + expectedResp := &dto.FindByEmailCheckInResponse{ + CheckIns: t.checkins, + } + + context.EXPECT().Bind(&dto.FindByEmailCheckInRequest{}).SetArg(0, *t.findByEmailCheckinReq) + validator.EXPECT().Validate(t.findByEmailCheckinReq).Return(nil) + checkinSvc.EXPECT().FindByEmail(t.findByEmailCheckinReq).Return(expectedResp, nil) + context.EXPECT().JSON(http.StatusOK, expectedResp) + + handler.FindByEmail(context) +} + +func (t *CheckInHandlerTest) TestFindByEmailCheckinBindError() { + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(nil, nil, t.logger) + + context.EXPECT().Bind(&dto.FindByEmailCheckInRequest{}).Return(apperror.BadRequest) + context.EXPECT().BadRequestError(apperror.BadRequest.Error()) + + handler.FindByEmail(context) +} + +func (t *CheckInHandlerTest) TestFindByEmailCheckinValidationError() { + checkinSvc := checkinMock.NewMockService(t.controller) + validator := validatorMock.NewMockDtoValidator(t.controller) + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(checkinSvc, validator, t.logger) + + expectedError := []string{"error1", "error2"} + + context.EXPECT().Bind(&dto.FindByEmailCheckInRequest{}).SetArg(0, *t.findByEmailCheckinReq) + validator.EXPECT().Validate(t.findByEmailCheckinReq).Return(expectedError) + context.EXPECT().BadRequestError("error1, error2") + + handler.FindByEmail(context) +} + +func (t *CheckInHandlerTest) TestFindByEmailCheckinServiceError() { + checkinSvc := checkinMock.NewMockService(t.controller) + validator := validatorMock.NewMockDtoValidator(t.controller) + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(checkinSvc, validator, t.logger) + + context.EXPECT().Bind(&dto.FindByEmailCheckInRequest{}).SetArg(0, *t.findByEmailCheckinReq) + validator.EXPECT().Validate(t.findByEmailCheckinReq).Return(nil) + checkinSvc.EXPECT().FindByEmail(t.findByEmailCheckinReq).Return(nil, apperror.InternalServer) + context.EXPECT().ResponseError(apperror.InternalServer) + + handler.FindByEmail(context) +} + +func (t *CheckInHandlerTest) TestFindByUserIdCheckinSuccess() { + checkinSvc := checkinMock.NewMockService(t.controller) + validator := validatorMock.NewMockDtoValidator(t.controller) + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(checkinSvc, validator, t.logger) + + expectedResp := &dto.FindByUserIdCheckInResponse{ + CheckIns: t.checkins, + } + + context.EXPECT().Bind(&dto.FindByUserIdCheckInRequest{}).SetArg(0, *t.findByUserIdCheckinReq) + validator.EXPECT().Validate(t.findByUserIdCheckinReq).Return(nil) + checkinSvc.EXPECT().FindByUserID(t.findByUserIdCheckinReq).Return(expectedResp, nil) + context.EXPECT().JSON(http.StatusOK, expectedResp) + + handler.FindByUserID(context) +} + +func (t *CheckInHandlerTest) TestFindByUserIdCheckinBindError() { + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(nil, nil, t.logger) + + context.EXPECT().Bind(&dto.FindByUserIdCheckInRequest{}).Return(apperror.BadRequest) + context.EXPECT().BadRequestError(apperror.BadRequest.Error()) + + handler.FindByUserID(context) +} + +func (t *CheckInHandlerTest) TestFindByUserIdCheckinValidationError() { + checkinSvc := checkinMock.NewMockService(t.controller) + validator := validatorMock.NewMockDtoValidator(t.controller) + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(checkinSvc, validator, t.logger) + + expectedError := []string{"error1", "error2"} + + context.EXPECT().Bind(&dto.FindByUserIdCheckInRequest{}).SetArg(0, *t.findByUserIdCheckinReq) + validator.EXPECT().Validate(t.findByUserIdCheckinReq).Return(expectedError) + context.EXPECT().BadRequestError("error1, error2") + + handler.FindByUserID(context) +} + +func (t *CheckInHandlerTest) TestFindByUserIdCheckinServiceError() { + checkinSvc := checkinMock.NewMockService(t.controller) + validator := validatorMock.NewMockDtoValidator(t.controller) + context := routerMock.NewMockContext(t.controller) + handler := checkin.NewHandler(checkinSvc, validator, t.logger) + + context.EXPECT().Bind(&dto.FindByUserIdCheckInRequest{}).SetArg(0, *t.findByUserIdCheckinReq) + validator.EXPECT().Validate(t.findByUserIdCheckinReq).Return(nil) + checkinSvc.EXPECT().FindByUserID(t.findByUserIdCheckinReq).Return(nil, apperror.InternalServer) + context.EXPECT().ResponseError(apperror.InternalServer) + + handler.FindByUserID(context) +} diff --git a/internal/checkin/test/checkin.service_test.go b/internal/checkin/test/checkin.service_test.go new file mode 100644 index 0000000..005133c --- /dev/null +++ b/internal/checkin/test/checkin.service_test.go @@ -0,0 +1,202 @@ +package test + +import ( + "testing" + + "github.com/golang/mock/gomock" + "github.com/isd-sgcu/rpkm67-gateway/apperror" + "github.com/isd-sgcu/rpkm67-gateway/internal/checkin" + "github.com/isd-sgcu/rpkm67-gateway/internal/dto" + checkinMock "github.com/isd-sgcu/rpkm67-gateway/mocks/checkin" + checkinProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/checkin/checkin/v1" + "github.com/stretchr/testify/suite" + "go.uber.org/zap" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type CheckInServiceTest struct { + suite.Suite + controller *gomock.Controller + logger *zap.Logger + checkinsProto []*checkinProto.CheckIn + checkinProto *checkinProto.CheckIn + checkinsDto []*dto.CheckIn + checkinDto *dto.CheckIn + createCheckInProtoRequest *checkinProto.CreateCheckInRequest + createCheckInDtoRequest *dto.CreateCheckInRequest + findByUserIdCheckInProtoRequest *checkinProto.FindByUserIdCheckInRequest + findByUserIdCheckInDtoRequest *dto.FindByUserIdCheckInRequest + findByEmailCheckInProtoRequest *checkinProto.FindByEmailCheckInRequest + findByEmailCheckInDtoRequest *dto.FindByEmailCheckInRequest +} + +func TestCheckInService(t *testing.T) { + suite.Run(t, new(CheckInServiceTest)) +} + +func (t *CheckInServiceTest) SetupTest() { + t.controller = gomock.NewController(t.T()) + t.logger = zap.NewNop() + + t.checkinsProto = MockCheckInsProto() + t.checkinProto = t.checkinsProto[0] + t.checkinsDto = checkin.ProtoToDtos(t.checkinsProto) + t.checkinDto = t.checkinsDto[0] + t.createCheckInProtoRequest = &checkinProto.CreateCheckInRequest{ + Email: t.checkinProto.Email, + UserId: t.checkinProto.UserId, + Event: t.checkinProto.Event, + } + t.createCheckInDtoRequest = &dto.CreateCheckInRequest{ + Email: t.checkinDto.Email, + UserID: t.checkinDto.UserID, + Event: t.checkinDto.Event, + } + t.findByUserIdCheckInProtoRequest = &checkinProto.FindByUserIdCheckInRequest{ + UserId: t.checkinProto.UserId, + } + t.findByUserIdCheckInDtoRequest = &dto.FindByUserIdCheckInRequest{ + UserID: t.checkinDto.UserID, + } + t.findByEmailCheckInProtoRequest = &checkinProto.FindByEmailCheckInRequest{ + Email: t.checkinProto.Email, + } + t.findByEmailCheckInDtoRequest = &dto.FindByEmailCheckInRequest{ + Email: t.checkinDto.Email, + } +} + +func (t *CheckInServiceTest) TestCreateCheckInSuccess() { + client := checkinMock.NewMockClient(t.controller) + svc := checkin.NewService(client, t.logger) + + protoResp := &checkinProto.CreateCheckInResponse{ + CheckIn: t.checkinProto, + } + + createCheckinDto := checkin.ProtoToDto(t.checkinProto) + expected := &dto.CreateCheckInResponse{ + CheckIn: createCheckinDto, + } + + client.EXPECT().Create(gomock.Any(), t.createCheckInProtoRequest).Return(protoResp, nil) + actual, err := svc.Create(t.createCheckInDtoRequest) + + t.Nil(err) + t.Equal(expected, actual) +} + +func (t *CheckInServiceTest) TestCreateCheckInInvalidArgument() { + client := checkinMock.NewMockClient(t.controller) + svc := checkin.NewService(client, t.logger) + + clientErr := status.Error(codes.InvalidArgument, apperror.BadRequest.Error()) + + client.EXPECT().Create(gomock.Any(), t.createCheckInProtoRequest).Return(nil, clientErr) + actual, err := svc.Create(t.createCheckInDtoRequest) + + t.Nil(actual) + t.Equal(apperror.BadRequest, err) +} + +func (t *CheckInServiceTest) TestCreateCheckInInternalError() { + client := checkinMock.NewMockClient(t.controller) + svc := checkin.NewService(client, t.logger) + + clientErr := status.Error(codes.Internal, apperror.InternalServer.Error()) + + client.EXPECT().Create(gomock.Any(), t.createCheckInProtoRequest).Return(nil, clientErr) + actual, err := svc.Create(t.createCheckInDtoRequest) + + t.Nil(actual) + t.Equal(apperror.InternalServer, err) +} + +func (t *CheckInServiceTest) TestFindByUserIdCheckInSuccess() { + client := checkinMock.NewMockClient(t.controller) + svc := checkin.NewService(client, t.logger) + + protoResp := &checkinProto.FindByUserIdCheckInResponse{ + CheckIns: t.checkinsProto, + } + expected := &dto.FindByUserIdCheckInResponse{ + CheckIns: t.checkinsDto, + } + + client.EXPECT().FindByUserId(gomock.Any(), t.findByUserIdCheckInProtoRequest).Return(protoResp, nil) + actual, err := svc.FindByUserID(t.findByUserIdCheckInDtoRequest) + + t.Nil(err) + t.Equal(expected, actual) +} + +func (t *CheckInServiceTest) TestFindByUserIdCheckInInvalidArgument() { + client := checkinMock.NewMockClient(t.controller) + svc := checkin.NewService(client, t.logger) + + clientErr := status.Error(codes.InvalidArgument, apperror.BadRequest.Error()) + + client.EXPECT().FindByUserId(gomock.Any(), t.findByUserIdCheckInProtoRequest).Return(nil, clientErr) + actual, err := svc.FindByUserID(t.findByUserIdCheckInDtoRequest) + + t.Nil(actual) + t.Equal(apperror.BadRequest, err) +} + +func (t *CheckInServiceTest) TestFindByUserIdCheckInInternalError() { + client := checkinMock.NewMockClient(t.controller) + svc := checkin.NewService(client, t.logger) + + clientErr := status.Error(codes.Internal, apperror.InternalServer.Error()) + + client.EXPECT().FindByUserId(gomock.Any(), t.findByUserIdCheckInProtoRequest).Return(nil, clientErr) + actual, err := svc.FindByUserID(t.findByUserIdCheckInDtoRequest) + + t.Nil(actual) + t.Equal(apperror.InternalServer, err) +} + +func (t *CheckInServiceTest) TestFindByEmailCheckInSuccess() { + client := checkinMock.NewMockClient(t.controller) + svc := checkin.NewService(client, t.logger) + + protoResp := &checkinProto.FindByEmailCheckInResponse{ + CheckIns: t.checkinsProto, + } + expected := &dto.FindByEmailCheckInResponse{ + CheckIns: t.checkinsDto, + } + + client.EXPECT().FindByEmail(gomock.Any(), t.findByEmailCheckInProtoRequest).Return(protoResp, nil) + actual, err := svc.FindByEmail(t.findByEmailCheckInDtoRequest) + + t.Nil(err) + t.Equal(expected, actual) +} + +func (t *CheckInServiceTest) TestFindByEmailCheckInInvalidArgument() { + client := checkinMock.NewMockClient(t.controller) + svc := checkin.NewService(client, t.logger) + + clientErr := status.Error(codes.InvalidArgument, apperror.BadRequest.Error()) + + client.EXPECT().FindByEmail(gomock.Any(), t.findByEmailCheckInProtoRequest).Return(nil, clientErr) + actual, err := svc.FindByEmail(t.findByEmailCheckInDtoRequest) + + t.Nil(actual) + t.Equal(apperror.BadRequest, err) +} + +func (t *CheckInServiceTest) TestFindByEmailCheckInInternalError() { + client := checkinMock.NewMockClient(t.controller) + svc := checkin.NewService(client, t.logger) + + clientErr := status.Error(codes.Internal, apperror.InternalServer.Error()) + + client.EXPECT().FindByEmail(gomock.Any(), t.findByEmailCheckInProtoRequest).Return(nil, clientErr) + actual, err := svc.FindByEmail(t.findByEmailCheckInDtoRequest) + + t.Nil(actual) + t.Equal(apperror.InternalServer, err) +} diff --git a/internal/checkin/test/checkin.utils_test.go b/internal/checkin/test/checkin.utils_test.go new file mode 100644 index 0000000..738998b --- /dev/null +++ b/internal/checkin/test/checkin.utils_test.go @@ -0,0 +1,27 @@ +package test + +import ( + "github.com/bxcodec/faker/v4" + checkinProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/checkin/checkin/v1" +) + +func MockCheckInProto() *checkinProto.CheckIn { + return &checkinProto.CheckIn{ + Id: faker.UUIDDigit(), + UserId: faker.UUIDDigit(), + Email: faker.Email(), + } +} + +func MockCheckInsProto() []*checkinProto.CheckIn { + var checkIns []*checkinProto.CheckIn + for i := 0; i < 10; i++ { + checkIn := &checkinProto.CheckIn{ + Id: faker.UUIDDigit(), + UserId: faker.UUIDDigit(), + Email: faker.Email(), + } + checkIns = append(checkIns, checkIn) + } + return checkIns +} From 30ac69930017d4a6036eb7ec75af22114137fbea Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 28 Jun 2024 22:13:39 +0700 Subject: [PATCH 6/6] fix: app, config --- cmd/main.go | 15 +++++++++++++++ config/config.go | 8 ++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 6b09744..4872ed1 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -5,11 +5,13 @@ import ( "github.com/isd-sgcu/rpkm67-gateway/config" auth "github.com/isd-sgcu/rpkm67-gateway/internal/auth" + "github.com/isd-sgcu/rpkm67-gateway/internal/checkin" "github.com/isd-sgcu/rpkm67-gateway/internal/router" "github.com/isd-sgcu/rpkm67-gateway/internal/validator" "github.com/isd-sgcu/rpkm67-gateway/logger" "github.com/isd-sgcu/rpkm67-gateway/middleware" authProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/auth/auth/v1" + checkinProto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/checkin/checkin/v1" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) @@ -34,16 +36,29 @@ func main() { logger.Sugar().Fatalf("cannot connect to auth service", err) } + checkinConn, err := grpc.NewClient(conf.Svc.CheckIn, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + logger.Sugar().Fatalf("cannot connect to checkin service", err) + } + authClient := authProto.NewAuthServiceClient(authConn) authSvc := auth.NewService(authClient, logger) authHdr := auth.NewHandler(authSvc, validate, logger) + checkinClient := checkinProto.NewCheckInServiceClient(checkinConn) + checkinSvc := checkin.NewService(checkinClient, logger) + checkinHdr := checkin.NewHandler(checkinSvc, validate, logger) + r := router.New(conf, corsHandler, authMiddleware) r.V1Get("/auth/google-url", authHdr.GetGoogleLoginUrl) r.V1Post("/auth/verify-google", authHdr.VerifyGoogleLogin) r.V1Post("/auth/test", authHdr.Test) + r.V1Post("/checkin", checkinHdr.Create) + r.V1Post("/checkin/userId", checkinHdr.FindByUserID) + r.V1Post("/checkin/email", checkinHdr.FindByEmail) + if err := r.Run(fmt.Sprintf(":%v", conf.App.Port)); err != nil { logger.Fatal("unable to start server") } diff --git a/config/config.go b/config/config.go index e6f2ca3..41066a0 100644 --- a/config/config.go +++ b/config/config.go @@ -12,7 +12,9 @@ type AppConfig struct { } type ServiceConfig struct { - Auth string + Auth string + CheckIn string + Store string } type CorsConfig struct { @@ -39,7 +41,9 @@ func LoadConfig() (*Config, error) { } serviceConfig := ServiceConfig{ - Auth: os.Getenv("SERVICE_AUTH"), + Auth: os.Getenv("SERVICE_AUTH"), + CheckIn: os.Getenv("SERVICE_CHECKIN"), + Store: os.Getenv("SERVICE_STORE"), } corsConfig := CorsConfig{