From 8e68afb20db40296f983053660014f4aa18105e8 Mon Sep 17 00:00:00 2001 From: Sunioatm <104454675+Sunioatm@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:08:51 +0700 Subject: [PATCH 1/5] feat: adopt gateway - adopt handler - adopt service - unit test pass but didn't test with manual test yet --- go.mod | 4 +- go.sum | 8 +-- src/app/dto/adopt.dto.go | 12 ++--- src/app/handler/pet/pet.handler.go | 49 +++++++++++++++++ src/app/handler/pet/pet.handler_test.go | 57 ++++++++++++++++++++ src/app/service/pet/pet.service.go | 47 +++++++++++++++++ src/app/service/pet/pet.service_test.go | 70 +++++++++++++++++++++++++ src/main.go | 1 + src/mocks/client/pet/pet.mock.go | 10 ++++ src/mocks/service/pet/pet.mock.go | 13 +++++ 10 files changed, 259 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 17065c7..2b09d6a 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/gofiber/fiber/v2 v2.51.0 github.com/golang/mock v1.6.0 github.com/google/uuid v1.5.0 - github.com/isd-sgcu/johnjud-go-proto v0.0.8 + github.com/isd-sgcu/johnjud-go-proto v0.0.9 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.31.0 github.com/spf13/viper v1.18.2 @@ -66,7 +66,7 @@ require ( golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.16.1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 499d0ee..5bdc034 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/isd-sgcu/johnjud-go-proto v0.0.8 h1:nIQBZgK2OFVrLjVtpeDgwows8poA7LhsIVE4hlbBC1o= -github.com/isd-sgcu/johnjud-go-proto v0.0.8/go.mod h1:HP0w9gC30b5WNnqeFBM9JJZud+pvyikz0+pGFSI/Wjw= +github.com/isd-sgcu/johnjud-go-proto v0.0.9 h1:cFfZ2JSpW0jg94Iv5zHQJGnoekj0eCQe42SJaTpnp3c= +github.com/isd-sgcu/johnjud-go-proto v0.0.9/go.mod h1:1OK6aiCgtXQiLhxp0r6iLEejYIRpckWQZDrCZ9Trbo4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -234,8 +234,8 @@ google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/src/app/dto/adopt.dto.go b/src/app/dto/adopt.dto.go index 82a453d..fd42a51 100644 --- a/src/app/dto/adopt.dto.go +++ b/src/app/dto/adopt.dto.go @@ -1,10 +1,10 @@ package dto -import ( - "github.com/google/uuid" -) - type AdoptDto struct { - UserID uuid.UUID `json:"user_id" validate:"required"` - PetID uuid.UUID `json:"pet_id" validate:"required"` + UserID string `json:"user_id" validate:"required"` + PetID string `json:"pet_id" validate:"required"` +} + +type AdoptByRequest struct { + Adopt AdoptDto `json:"adopt" validate:"required"` } diff --git a/src/app/handler/pet/pet.handler.go b/src/app/handler/pet/pet.handler.go index 95af61e..afbb469 100644 --- a/src/app/handler/pet/pet.handler.go +++ b/src/app/handler/pet/pet.handler.go @@ -25,6 +25,7 @@ type Service interface { Update(string, *dto.UpdatePetRequest) (*pet_proto.Pet, *dto.ResponseErr) ChangeView(string, *dto.ChangeViewPetRequest) (bool, *dto.ResponseErr) Delete(string) (bool, *dto.ResponseErr) + Adopt(string, *dto.AdoptByRequest) (bool, *dto.ResponseErr) } func NewHandler(service Service, imageService imageSrv.Service, validate validator.IDtoValidator) *Handler { @@ -216,3 +217,51 @@ func (h *Handler) Delete(c router.IContext) { c.JSON(http.StatusOK, res) return } + +func (h *Handler) Adopt(c router.IContext) { + petId, err := c.Param("id") + if err != nil { + c.JSON(http.StatusInternalServerError, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: "Invalid ID", + Data: nil, + }) + return + } + + request := &dto.AdoptByRequest{ + Adopt: dto.AdoptDto{}, + } + + err = c.Bind(request) + if err != nil { + c.JSON(http.StatusBadRequest, dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.BindingRequestErrorMessage + err.Error(), + Data: nil, + }) + return + } + + if err := h.validate.Validate(request); err != nil { + var errorMessage []string + for _, reqErr := range err { + errorMessage = append(errorMessage, reqErr.Message) + } + c.JSON(http.StatusBadRequest, dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidRequestBodyMessage + strings.Join(errorMessage, ", "), + Data: nil, + }) + return + } + + pet, errRes := h.service.Adopt(petId, request) + if errRes != nil { + c.JSON(errRes.StatusCode, errRes) + return + } + + c.JSON(http.StatusOK, pet) + return +} diff --git a/src/app/handler/pet/pet.handler_test.go b/src/app/handler/pet/pet.handler_test.go index 1b544a4..c85c816 100644 --- a/src/app/handler/pet/pet.handler_test.go +++ b/src/app/handler/pet/pet.handler_test.go @@ -26,6 +26,7 @@ type PetHandlerTest struct { CreatePetRequest *dto.CreatePetRequest ChangeViewPetRequest *dto.ChangeViewPetRequest UpdatePetRequest *dto.UpdatePetRequest + AdoptByRequest *dto.AdoptByRequest BindErr *dto.ResponseErr NotFoundErr *dto.ResponseErr ServiceDownErr *dto.ResponseErr @@ -94,6 +95,8 @@ func (t *PetHandlerTest) SetupTest() { t.ChangeViewPetRequest = &dto.ChangeViewPetRequest{} + t.AdoptByRequest = &dto.AdoptByRequest{} + t.ServiceDownErr = &dto.ResponseErr{ StatusCode: http.StatusServiceUnavailable, Message: "Service is down", @@ -393,3 +396,57 @@ func (t *PetHandlerTest) TestChangeViewGrpcErr() { handler := NewHandler(petSvc, imageSvc, validator) handler.Delete(context) } + +func (t *PetHandlerTest) TestAdoptSuccess() { + adoptResponse := true + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().Delete(t.Pet.Id).Return(adoptResponse, nil) + context.EXPECT().JSON(http.StatusOK, adoptResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Delete(context) +} + +func (t *PetHandlerTest) TestAdoptNotFound() { + adoptResponse := false + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().Delete(t.Pet.Id).Return(adoptResponse, t.NotFoundErr) + context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Delete(context) +} + +func (t *PetHandlerTest) TestAdoptGrpcErr() { + adoptResponse := false + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().Delete(t.Pet.Id).Return(adoptResponse, t.ServiceDownErr) + context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Delete(context) +} diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index 0667893..ebb6928 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -235,6 +235,53 @@ func (s *Service) ChangeView(id string, in *dto.ChangeViewPetRequest) (result bo return res.Success, nil } +func (s *Service) Adopt(petId string, in *dto.AdoptByRequest) (result bool, err *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + request := &proto.AdoptPetRequest{ + PetId: petId, + UserId: in.Adopt.UserID, + } + + res, errRes := s.petClient.AdoptPet(ctx, request) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Err(errRes). + Str("service", "pet"). + Str("module", "adopt pet"). + Msg(st.Message()) + switch st.Code() { + case codes.NotFound: + return false, &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.PetNotFoundMessage, + Data: nil, + } + case codes.InvalidArgument: + return false, &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidArgument, + Data: nil, + } + case codes.Unavailable: + return false, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + default: + return false, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + } + return res.Success, nil +} + func DtoToRaw(in *dto.PetDto) *proto.Pet { return &proto.Pet{ Id: in.Id, diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 61b3559..a36b2a1 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -33,6 +33,8 @@ type PetServiceTest struct { InvalidArgumentErr *dto.ResponseErr InternalErr *dto.ResponseErr ChangeViewedPetDto *dto.ChangeViewPetRequest + AdoptPetReq *petProto.AdoptPetRequest + AdoptPetDto *dto.AdoptByRequest Images []*imageProto.Image ImageUrls []string @@ -135,6 +137,18 @@ func (t *PetServiceTest) SetupTest() { Visible: false, } + t.AdoptPetDto = &dto.AdoptByRequest{ + Adopt: dto.AdoptDto{ + PetID: t.Pet.Id, + UserID: faker.UUIDDigit(), + }, + } + + t.AdoptPetReq = &petProto.AdoptPetRequest{ + PetId: t.Pet.Id, + UserId: t.AdoptPetDto.Adopt.UserID, + } + t.UnavailableServiceErr = &dto.ResponseErr{ StatusCode: http.StatusServiceUnavailable, Message: constant.UnavailableServiceMessage, @@ -497,3 +511,59 @@ func (t *PetServiceTest) TestChangeViewUnavailableServiceError() { assert.False(t.T(), actual) assert.Equal(t.T(), expected, err) } + +func (t *PetServiceTest) TestAdoptSuccess() { + protoReq := t.AdoptPetReq + protoResp := &petProto.AdoptPetResponse{ + Success: true, + } + + client := &petMock.PetClientMock{} + client.On("AdoptPet", protoReq).Return(protoResp, nil) + + svc := NewService(client) + actual, err := svc.Adopt(t.Pet.Id, t.AdoptPetDto) + + assert.Nil(t.T(), err) + assert.True(t.T(), actual) +} + +func (t *PetServiceTest) TestAdoptNotFoundError() { + protoReq := t.AdoptPetReq + protoResp := &petProto.AdoptPetResponse{ + Success: false, + } + + clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) + + expected := t.NotFoundErr + + client := &petMock.PetClientMock{} + client.On("AdoptPet", protoReq).Return(protoResp, clientErr) + + svc := NewService(client) + actual, err := svc.Adopt(t.Pet.Id, t.AdoptPetDto) + + assert.False(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestAdoptUnavailableServiceError() { + protoReq := t.AdoptPetReq + protoResp := &petProto.AdoptPetResponse{ + Success: false, + } + + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + + expected := t.UnavailableServiceErr + + client := &petMock.PetClientMock{} + client.On("AdoptPet", protoReq).Return(protoResp, clientErr) + + svc := NewService(client) + actual, err := svc.Adopt(t.Pet.Id, t.AdoptPetDto) + + assert.False(t.T(), actual) + assert.Equal(t.T(), expected, err) +} diff --git a/src/main.go b/src/main.go index ebda5be..9578a2d 100644 --- a/src/main.go +++ b/src/main.go @@ -127,6 +127,7 @@ func main() { r.PostPet("/create", petHandler.Create) r.PutPet("/:id", petHandler.Update) r.PutPet("/:id/visible", petHandler.Update) + r.PutPet("/:id/adopt", petHandler.Adopt) r.DeletePet("/:id", petHandler.Delete) v1 := router.NewAPIv1(r, conf.App) diff --git a/src/mocks/client/pet/pet.mock.go b/src/mocks/client/pet/pet.mock.go index 8627e7f..ebd3b18 100644 --- a/src/mocks/client/pet/pet.mock.go +++ b/src/mocks/client/pet/pet.mock.go @@ -69,3 +69,13 @@ func (c *PetClientMock) Delete(ctx context.Context, in *petProto.DeletePetReques return res, args.Error(1) } + +func (c *PetClientMock) AdoptPet(ctx context.Context, in *petProto.AdoptPetRequest, opts ...grpc.CallOption) (res *petProto.AdoptPetResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*petProto.AdoptPetResponse) + } + + return res, args.Error(1) +} diff --git a/src/mocks/service/pet/pet.mock.go b/src/mocks/service/pet/pet.mock.go index 690ed24..d61b428 100644 --- a/src/mocks/service/pet/pet.mock.go +++ b/src/mocks/service/pet/pet.mock.go @@ -124,3 +124,16 @@ func (mr *MockServiceMockRecorder) Update(id, in interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockService)(nil).Update), id, in) } + +func (m *MockService) Adopt(petId string, in *dto.AdoptByRequest) (bool, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Adopt", petId, in) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +func (mr *MockServiceMockRecorder) Adopt(petId, in interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Adopt", reflect.TypeOf((*MockService)(nil).Adopt), petId, in) +} From 3ac9be0999d06de79553bafb3f1029fc8ab31b84 Mon Sep 17 00:00:00 2001 From: Sunioatm <104454675+Sunioatm@users.noreply.github.com> Date: Thu, 4 Jan 2024 22:52:43 +0700 Subject: [PATCH 2/5] Merge dev --- src/app/service/pet/pet.service_test.go | 15 +++++++-------- src/mocks/client/pet/pet.mock.go | 10 ---------- src/mocks/service/pet/pet.mock.go | 17 ++--------------- 3 files changed, 9 insertions(+), 33 deletions(-) diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 03bc07d..c1ad487 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -34,8 +34,7 @@ type PetServiceTest struct { InvalidArgumentErr *dto.ResponseErr InternalErr *dto.ResponseErr ChangeViewedPetDto *dto.ChangeViewPetRequest - AdoptPetReq *petProto.AdoptPetRequest - AdoptPetDto *dto.AdoptByRequest + AdoptDto *dto.AdoptByRequest Images []*imageProto.Image ImageUrls []string @@ -517,7 +516,7 @@ func (t *PetServiceTest) TestChangeViewUnavailableServiceError() { } func (t *PetServiceTest) TestAdoptSuccess() { - protoReq := t.AdoptPetReq + protoReq := t.AdoptReq protoResp := &petProto.AdoptPetResponse{ Success: true, } @@ -526,14 +525,14 @@ func (t *PetServiceTest) TestAdoptSuccess() { client.On("AdoptPet", protoReq).Return(protoResp, nil) svc := NewService(client) - actual, err := svc.Adopt(t.Pet.Id, t.AdoptPetDto) + actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) assert.Nil(t.T(), err) assert.True(t.T(), actual) } func (t *PetServiceTest) TestAdoptNotFoundError() { - protoReq := t.AdoptPetReq + protoReq := t.AdoptReq protoResp := &petProto.AdoptPetResponse{ Success: false, } @@ -546,14 +545,14 @@ func (t *PetServiceTest) TestAdoptNotFoundError() { client.On("AdoptPet", protoReq).Return(protoResp, clientErr) svc := NewService(client) - actual, err := svc.Adopt(t.Pet.Id, t.AdoptPetDto) + actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) assert.False(t.T(), actual) assert.Equal(t.T(), expected, err) } func (t *PetServiceTest) TestAdoptUnavailableServiceError() { - protoReq := t.AdoptPetReq + protoReq := t.AdoptReq protoResp := &petProto.AdoptPetResponse{ Success: false, } @@ -566,7 +565,7 @@ func (t *PetServiceTest) TestAdoptUnavailableServiceError() { client.On("AdoptPet", protoReq).Return(protoResp, clientErr) svc := NewService(client) - actual, err := svc.Adopt(t.Pet.Id, t.AdoptPetDto) + actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) assert.False(t.T(), actual) assert.Equal(t.T(), expected, err) diff --git a/src/mocks/client/pet/pet.mock.go b/src/mocks/client/pet/pet.mock.go index 6428b0f..5148750 100644 --- a/src/mocks/client/pet/pet.mock.go +++ b/src/mocks/client/pet/pet.mock.go @@ -78,13 +78,3 @@ func (c *PetClientMock) Delete(ctx context.Context, in *petProto.DeletePetReques return res, args.Error(1) } - -func (c *PetClientMock) AdoptPet(ctx context.Context, in *petProto.AdoptPetRequest, opts ...grpc.CallOption) (res *petProto.AdoptPetResponse, err error) { - args := c.Called(in) - - if args.Get(0) != nil { - res = args.Get(0).(*petProto.AdoptPetResponse) - } - - return res, args.Error(1) -} diff --git a/src/mocks/service/pet/pet.mock.go b/src/mocks/service/pet/pet.mock.go index 90a639f..2e235bc 100644 --- a/src/mocks/service/pet/pet.mock.go +++ b/src/mocks/service/pet/pet.mock.go @@ -36,9 +36,9 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { } // Adopt mocks base method. -func (m *MockService) Adopt(arg0 *dto.AdoptDto) (bool, *dto.ResponseErr) { +func (m *MockService) Adopt(arg0 string, arg1 *dto.AdoptByRequest) (bool, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Adopt", arg0) + ret := m.ctrl.Call(m, "Adopt", arg0, arg1) ret0, _ := ret[0].(bool) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 @@ -139,16 +139,3 @@ func (mr *MockServiceMockRecorder) Update(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockService)(nil).Update), arg0, arg1) } - -func (m *MockService) Adopt(petId string, in *dto.AdoptByRequest) (bool, *dto.ResponseErr) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Adopt", petId, in) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(*dto.ResponseErr) - return ret0, ret1 -} - -func (mr *MockServiceMockRecorder) Adopt(petId, in interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Adopt", reflect.TypeOf((*MockService)(nil).Adopt), petId, in) -} From 6ab09337c7319e185f1b27b469d8dfe022774bd1 Mon Sep 17 00:00:00 2001 From: Sunioatm <104454675+Sunioatm@users.noreply.github.com> Date: Fri, 5 Jan 2024 23:22:59 +0700 Subject: [PATCH 3/5] fix: handler --- src/app/dto/adopt.dto.go | 3 ++- src/app/handler/pet/pet.handler.go | 19 +++++++++++++++---- src/app/service/pet/pet.service.go | 2 +- src/app/service/pet/pet.service_test.go | 6 ++---- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/app/dto/adopt.dto.go b/src/app/dto/adopt.dto.go index fd42a51..e42302d 100644 --- a/src/app/dto/adopt.dto.go +++ b/src/app/dto/adopt.dto.go @@ -6,5 +6,6 @@ type AdoptDto struct { } type AdoptByRequest struct { - Adopt AdoptDto `json:"adopt" validate:"required"` + UserID string `json:"user_id" validate:"required"` + PetID string `json:"pet_id" validate:"required"` } diff --git a/src/app/handler/pet/pet.handler.go b/src/app/handler/pet/pet.handler.go index d43414c..560be0b 100644 --- a/src/app/handler/pet/pet.handler.go +++ b/src/app/handler/pet/pet.handler.go @@ -288,6 +288,20 @@ func (h *Handler) Delete(c router.IContext) { return } +// Adopt is a function that handles the adoption of a pet in the database +// @Summary Adopt a pet +// @Description Return true if the pet is successfully adopted +// @Param id path string true "Pet ID" +// @Param user_id body string true "User ID" +// @Param pet_id body string true "Pet ID" +// @Tags pet +// @Accept json +// @Produce json +// @Success 201 {object} bool +// @Failure 400 {object} dto.ResponseBadRequestErr "Invalid request body" +// @Failure 500 {object} dto.ResponseInternalErr "Internal service error" +// @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" +// @Router /v1/pets/{id}/adopt [put] func (h *Handler) Adopt(c router.IContext) { petId, err := c.Param("id") if err != nil { @@ -299,10 +313,7 @@ func (h *Handler) Adopt(c router.IContext) { return } - request := &dto.AdoptByRequest{ - Adopt: dto.AdoptDto{}, - } - + request := &dto.AdoptByRequest{} err = c.Bind(request) if err != nil { c.JSON(http.StatusBadRequest, dto.ResponseErr{ diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index 03eb118..4d2904f 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -277,7 +277,7 @@ func (s *Service) Adopt(petId string, in *dto.AdoptByRequest) (result bool, err request := &proto.AdoptPetRequest{ PetId: petId, - UserId: in.Adopt.UserID, + UserId: in.UserID, } res, errRes := s.petClient.AdoptPet(ctx, request) diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index c1ad487..4191741 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -141,10 +141,8 @@ func (t *PetServiceTest) SetupTest() { } t.AdoptDto = &dto.AdoptByRequest{ - Adopt: dto.AdoptDto{ - PetID: t.Pet.Id, - UserID: t.Pet.AdoptBy, - }, + PetID: t.Pet.Id, + UserID: t.Pet.AdoptBy, } t.AdoptReq = &petProto.AdoptPetRequest{ From 495bc8e39652b27d6dcfc237f21f58650a0bd226 Mon Sep 17 00:00:00 2001 From: Sunioatm <104454675+Sunioatm@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:44:12 +0700 Subject: [PATCH 4/5] fix: change variable name - change to make variable name consistency with dev branch --- src/app/handler/pet/pet.handler_test.go | 26 ++++++++++++------------- src/app/service/pet/pet.service.go | 5 ----- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/app/handler/pet/pet.handler_test.go b/src/app/handler/pet/pet.handler_test.go index ad5e326..659e221 100644 --- a/src/app/handler/pet/pet.handler_test.go +++ b/src/app/handler/pet/pet.handler_test.go @@ -459,16 +459,16 @@ func (t *PetHandlerTest) TestAdoptSuccess() { } expectedResponse := dto.ResponseSuccess{ StatusCode: http.StatusOK, - Message: petconst.AdoptPetSuccessMessage, + Message: petConst.AdoptPetSuccessMessage, Data: adoptByResponse, } controller := gomock.NewController(t.T()) - petSvc := mock_pet.NewMockService(controller) - imageSvc := mock_image.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + petSvc := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) context.EXPECT().Bind(t.AdoptByRequest).Return(nil) @@ -487,10 +487,10 @@ func (t *PetHandlerTest) TestAdoptNotFound() { controller := gomock.NewController(t.T()) - petSvc := mock_pet.NewMockService(controller) - imageSvc := mock_image.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + petSvc := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) context.EXPECT().Bind(t.AdoptByRequest).Return(nil) @@ -509,10 +509,10 @@ func (t *PetHandlerTest) TestAdoptGrpcErr() { controller := gomock.NewController(t.T()) - petSvc := mock_pet.NewMockService(controller) - imageSvc := mock_image.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + petSvc := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) context.EXPECT().Bind(t.AdoptByRequest).Return(nil) diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index d8e8cf1..8cc0401 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -18,11 +18,6 @@ type Service struct { petClient petproto.PetServiceClient } -// Adopt implements pet.Service. -func (*Service) Adopt(*dto.AdoptDto) (bool, *dto.ResponseErr) { - panic("unimplemented") -} - func NewService(petClient petproto.PetServiceClient) *Service { return &Service{ petClient: petClient, From 3caba53c2f01267f913287c1271971599018a57b Mon Sep 17 00:00:00 2001 From: Sunioatm <104454675+Sunioatm@users.noreply.github.com> Date: Sun, 7 Jan 2024 00:28:55 +0700 Subject: [PATCH 5/5] fix: changes requested - remove response validate required - adopt service error return nil - fix test --- src/app/dto/adopt.dto.go | 2 +- src/app/service/pet/pet.service.go | 16 ++++++---------- src/app/service/pet/pet.service_test.go | 14 ++++---------- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/app/dto/adopt.dto.go b/src/app/dto/adopt.dto.go index 5cf4ad2..56ecaef 100644 --- a/src/app/dto/adopt.dto.go +++ b/src/app/dto/adopt.dto.go @@ -11,5 +11,5 @@ type AdoptByRequest struct { } type AdoptByResponse struct { - Success bool `json:"success" validate:"required"` + Success bool `json:"success"` } diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index 8cc0401..4362e19 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -280,7 +280,6 @@ func (s *Service) Adopt(petId string, in *dto.AdoptByRequest) (result *dto.Adopt UserId: in.UserID, PetId: in.PetID, }) - if errRes != nil { st, _ := status.FromError(errRes) log.Error(). @@ -290,25 +289,22 @@ func (s *Service) Adopt(petId string, in *dto.AdoptByRequest) (result *dto.Adopt Msg(st.Message()) switch st.Code() { case codes.NotFound: - return &dto.AdoptByResponse{ - Success: false, - }, &dto.ResponseErr{ + return nil, + &dto.ResponseErr{ StatusCode: http.StatusNotFound, Message: constant.PetNotFoundMessage, Data: nil, } case codes.Unavailable: - return &dto.AdoptByResponse{ - Success: false, - }, &dto.ResponseErr{ + return nil, + &dto.ResponseErr{ StatusCode: http.StatusServiceUnavailable, Message: constant.UnavailableServiceMessage, Data: nil, } default: - return &dto.AdoptByResponse{ - Success: false, - }, &dto.ResponseErr{ + return nil, + &dto.ResponseErr{ StatusCode: http.StatusServiceUnavailable, Message: constant.InternalErrorMessage, Data: nil, diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 797af40..5705c12 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -539,40 +539,34 @@ func (t *PetServiceTest) TestAdoptSuccess() { func (t *PetServiceTest) TestAdoptNotFoundError() { protoReq := t.AdoptReq - protoResp := &petproto.AdoptPetResponse{ - Success: false, - } clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) expected := t.NotFoundErr client := &petmock.PetClientMock{} - client.On("AdoptPet", protoReq).Return(protoResp, clientErr) + client.On("AdoptPet", protoReq).Return(nil, clientErr) svc := NewService(client) actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) - assert.Equal(t.T(), &dto.AdoptByResponse{Success: false}, actual) + assert.Nil(t.T(), actual) assert.Equal(t.T(), expected, err) } func (t *PetServiceTest) TestAdoptUnavailableServiceError() { protoReq := t.AdoptReq - protoResp := &petproto.AdoptPetResponse{ - Success: false, - } clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) expected := t.UnavailableServiceErr client := &petmock.PetClientMock{} - client.On("AdoptPet", protoReq).Return(protoResp, clientErr) + client.On("AdoptPet", protoReq).Return(nil, clientErr) svc := NewService(client) actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) - assert.Equal(t.T(), &dto.AdoptByResponse{Success: false}, actual) + assert.Nil(t.T(), actual) assert.Equal(t.T(), expected, err) }