From 5d00cdbabf10fa5406d9b2ebf9a6c0b47bcfc3c0 Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 08:53:25 +0700 Subject: [PATCH 001/104] feat: implement forgot password service --- src/app/dto/auth.dto.go | 8 ++ src/app/service/auth/auth.service.go | 53 ++++++++++ src/app/service/auth/auth.service_test.go | 122 +++++++++++++++++++++- src/pkg/service/auth/auth.service.go | 1 + 4 files changed, 180 insertions(+), 4 deletions(-) diff --git a/src/app/dto/auth.dto.go b/src/app/dto/auth.dto.go index fe33c9b..4a68f91 100644 --- a/src/app/dto/auth.dto.go +++ b/src/app/dto/auth.dto.go @@ -31,3 +31,11 @@ type SignOutResponse struct { type RefreshTokenRequest struct { RefreshToken string `json:"refresh_token" validate:"required"` } + +type ForgotPasswordRequest struct { + Email string `json:"email" validate:"required,email"` +} + +type ForgotPasswordResponse struct { + IsSuccess bool `json:"is_success"` +} diff --git a/src/app/service/auth/auth.service.go b/src/app/service/auth/auth.service.go index 2f33c62..b42452f 100644 --- a/src/app/service/auth/auth.service.go +++ b/src/app/service/auth/auth.service.go @@ -288,3 +288,56 @@ func (s *Service) RefreshToken(request *dto.RefreshTokenRequest) (*dto.Credentia ExpiresIn: int(response.Credential.ExpiresIn), }, nil } + +func (s *Service) ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + _, err := s.client.ForgotPassword(ctx, &authProto.ForgotPasswordRequest{ + Email: request.Email, + }) + if err != nil { + st, ok := status.FromError(err) + log.Error(). + Str("service", "auth"). + Str("action", "ForgotPassword"). + Str("email", request.Email). + Msg(st.Message()) + if !ok { + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + switch st.Code() { + case codes.NotFound: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.UserNotFoundMessage, + Data: nil, + } + case codes.Internal: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + default: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + } + } + + log.Info(). + Str("service", "auth"). + Str("action", "ForgotPassword"). + Str("email", request.Email). + Msg("Forgot password successfully") + return &dto.ForgotPasswordResponse{ + IsSuccess: true, + }, nil +} diff --git a/src/app/service/auth/auth.service_test.go b/src/app/service/auth/auth.service_test.go index c041928..25b1f0c 100644 --- a/src/app/service/auth/auth.service_test.go +++ b/src/app/service/auth/auth.service_test.go @@ -18,10 +18,11 @@ import ( type AuthServiceTest struct { suite.Suite - signupRequestDto *dto.SignupRequest - signInDto *dto.SignInRequest - token string - refreshTokenRequest *dto.RefreshTokenRequest + signupRequestDto *dto.SignupRequest + signInDto *dto.SignInRequest + token string + refreshTokenRequest *dto.RefreshTokenRequest + forgotPasswordRequest *dto.ForgotPasswordRequest } func TestAuthService(t *testing.T) { @@ -43,11 +44,15 @@ func (t *AuthServiceTest) SetupTest() { refreshTokenRequest := &dto.RefreshTokenRequest{ RefreshToken: faker.UUIDDigit(), } + forgotPasswordRequest := &dto.ForgotPasswordRequest{ + Email: faker.Email(), + } t.signupRequestDto = signupRequestDto t.signInDto = signInDto t.token = token t.refreshTokenRequest = refreshTokenRequest + t.forgotPasswordRequest = forgotPasswordRequest } func (t *AuthServiceTest) TestSignupSuccess() { @@ -601,3 +606,112 @@ func (t *AuthServiceTest) TestRefreshTokenUnknownError() { assert.Nil(t.T(), actual) assert.Equal(t.T(), expected, err) } + +func (t *AuthServiceTest) TestForgotPasswordSuccess() { + protoReq := &authProto.ForgotPasswordRequest{ + Email: t.forgotPasswordRequest.Email, + } + protoResp := &authProto.ForgotPasswordResponse{ + Url: faker.URL(), + } + expected := &dto.ForgotPasswordResponse{ + IsSuccess: true, + } + + client := auth.AuthClientMock{} + client.On("ForgotPassword", protoReq).Return(protoResp, nil) + + svc := NewService(&client) + actual, err := svc.ForgotPassword(t.forgotPasswordRequest) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *AuthServiceTest) TestForgotPasswordNotFound() { + protoReq := &authProto.ForgotPasswordRequest{ + Email: t.forgotPasswordRequest.Email, + } + protoErr := status.Error(codes.NotFound, "Not found") + + expected := &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.UserNotFoundMessage, + Data: nil, + } + + client := auth.AuthClientMock{} + client.On("ForgotPassword", protoReq).Return(nil, protoErr) + + svc := NewService(&client) + actual, err := svc.ForgotPassword(t.forgotPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) TestForgotPasswordInternalErr() { + protoReq := &authProto.ForgotPasswordRequest{ + Email: t.forgotPasswordRequest.Email, + } + protoErr := status.Error(codes.Internal, "Internal error") + + expected := &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + + client := auth.AuthClientMock{} + client.On("ForgotPassword", protoReq).Return(nil, protoErr) + + svc := NewService(&client) + actual, err := svc.ForgotPassword(t.forgotPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) TestForgotPasswordUnavailableService() { + protoReq := &authProto.ForgotPasswordRequest{ + Email: t.forgotPasswordRequest.Email, + } + protoErr := status.Error(codes.Unavailable, "Connection lost") + + expected := &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + + client := auth.AuthClientMock{} + client.On("ForgotPassword", protoReq).Return(nil, protoErr) + + svc := NewService(&client) + actual, err := svc.ForgotPassword(t.forgotPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) TestForgotPasswordUnknownErr() { + protoReq := &authProto.ForgotPasswordRequest{ + Email: t.forgotPasswordRequest.Email, + } + protoErr := errors.New("Unknown Error") + + expected := &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + + client := auth.AuthClientMock{} + client.On("ForgotPassword", protoReq).Return(nil, protoErr) + + svc := NewService(&client) + actual, err := svc.ForgotPassword(t.forgotPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} diff --git a/src/pkg/service/auth/auth.service.go b/src/pkg/service/auth/auth.service.go index cc003a1..c527153 100644 --- a/src/pkg/service/auth/auth.service.go +++ b/src/pkg/service/auth/auth.service.go @@ -10,4 +10,5 @@ type Service interface { SignOut(string) (*dto.SignOutResponse, *dto.ResponseErr) Validate(string) (*dto.TokenPayloadAuth, *dto.ResponseErr) RefreshToken(*dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) + ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) } From b9cca296c8338ee4d0feb2158ae97a89637bc313 Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 08:53:39 +0700 Subject: [PATCH 002/104] feat: generate mock --- src/mocks/router/context.mock.go | 17 ++++++----------- src/mocks/service/auth/auth.mock.go | 15 +++++++++++++++ src/mocks/service/image/image.mock.go | 15 +++++---------- src/mocks/service/pet/pet.mock.go | 21 ++++++++------------- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/mocks/router/context.mock.go b/src/mocks/router/context.mock.go index 9db2501..729beeb 100644 --- a/src/mocks/router/context.mock.go +++ b/src/mocks/router/context.mock.go @@ -1,10 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. // Source: ./src/app/router/context.go -// -// Generated by this command: -// -// mockgen -source ./src/app/router/context.go -destination ./src/mocks/router/context.mock.go -// // Package mock_router is a generated GoMock package. package mock_router @@ -39,7 +34,7 @@ func (m *MockIContext) EXPECT() *MockIContextMockRecorder { } // Bind mocks base method. -func (m *MockIContext) Bind(arg0 any) error { +func (m *MockIContext) Bind(arg0 interface{}) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Bind", arg0) ret0, _ := ret[0].(error) @@ -47,7 +42,7 @@ func (m *MockIContext) Bind(arg0 any) error { } // Bind indicates an expected call of Bind. -func (mr *MockIContextMockRecorder) Bind(arg0 any) *gomock.Call { +func (mr *MockIContextMockRecorder) Bind(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Bind", reflect.TypeOf((*MockIContext)(nil).Bind), arg0) } @@ -68,13 +63,13 @@ func (mr *MockIContextMockRecorder) ID() *gomock.Call { } // JSON mocks base method. -func (m *MockIContext) JSON(arg0 int, arg1 any) { +func (m *MockIContext) JSON(arg0 int, arg1 interface{}) { m.ctrl.T.Helper() m.ctrl.Call(m, "JSON", arg0, arg1) } // JSON indicates an expected call of JSON. -func (mr *MockIContextMockRecorder) JSON(arg0, arg1 any) *gomock.Call { +func (mr *MockIContextMockRecorder) JSON(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "JSON", reflect.TypeOf((*MockIContext)(nil).JSON), arg0, arg1) } @@ -117,7 +112,7 @@ func (m *MockIContext) Param(arg0 string) (string, error) { } // Param indicates an expected call of Param. -func (mr *MockIContextMockRecorder) Param(arg0 any) *gomock.Call { +func (mr *MockIContextMockRecorder) Param(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Param", reflect.TypeOf((*MockIContext)(nil).Param), arg0) } @@ -171,7 +166,7 @@ func (m *MockIContext) StoreValue(arg0, arg1 string) { } // StoreValue indicates an expected call of StoreValue. -func (mr *MockIContextMockRecorder) StoreValue(arg0, arg1 any) *gomock.Call { +func (mr *MockIContextMockRecorder) StoreValue(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoreValue", reflect.TypeOf((*MockIContext)(nil).StoreValue), arg0, arg1) } diff --git a/src/mocks/service/auth/auth.mock.go b/src/mocks/service/auth/auth.mock.go index df1d4ad..5115774 100644 --- a/src/mocks/service/auth/auth.mock.go +++ b/src/mocks/service/auth/auth.mock.go @@ -34,6 +34,21 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { return m.recorder } +// ForgotPassword mocks base method. +func (m *MockService) ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ForgotPassword", request) + ret0, _ := ret[0].(*dto.ForgotPasswordResponse) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// ForgotPassword indicates an expected call of ForgotPassword. +func (mr *MockServiceMockRecorder) ForgotPassword(request interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForgotPassword", reflect.TypeOf((*MockService)(nil).ForgotPassword), request) +} + // RefreshToken mocks base method. func (m *MockService) RefreshToken(arg0 *dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) { m.ctrl.T.Helper() diff --git a/src/mocks/service/image/image.mock.go b/src/mocks/service/image/image.mock.go index 6e7fb6b..48da035 100644 --- a/src/mocks/service/image/image.mock.go +++ b/src/mocks/service/image/image.mock.go @@ -1,10 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. // Source: ./src/pkg/service/image/image.service.go -// -// Generated by this command: -// -// mockgen -source ./src/pkg/service/image/image.service.go -destination ./src/mocks/service/image/image.mock.go -// // Package mock_image is a generated GoMock package. package mock_image @@ -12,8 +7,8 @@ package mock_image import ( reflect "reflect" - dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" gomock "github.com/golang/mock/gomock" + dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" ) // MockService is a mock of Service interface. @@ -49,7 +44,7 @@ func (m *MockService) AssignPet(arg0 *dto.AssignPetRequest) (*dto.AssignPetRespo } // AssignPet indicates an expected call of AssignPet. -func (mr *MockServiceMockRecorder) AssignPet(arg0 any) *gomock.Call { +func (mr *MockServiceMockRecorder) AssignPet(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssignPet", reflect.TypeOf((*MockService)(nil).AssignPet), arg0) } @@ -64,7 +59,7 @@ func (m *MockService) Delete(arg0 string) (*dto.DeleteImageResponse, *dto.Respon } // Delete indicates an expected call of Delete. -func (mr *MockServiceMockRecorder) Delete(arg0 any) *gomock.Call { +func (mr *MockServiceMockRecorder) Delete(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), arg0) } @@ -79,7 +74,7 @@ func (m *MockService) FindByPetId(arg0 string) ([]*dto.ImageResponse, *dto.Respo } // FindByPetId indicates an expected call of FindByPetId. -func (mr *MockServiceMockRecorder) FindByPetId(arg0 any) *gomock.Call { +func (mr *MockServiceMockRecorder) FindByPetId(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByPetId", reflect.TypeOf((*MockService)(nil).FindByPetId), arg0) } @@ -94,7 +89,7 @@ func (m *MockService) Upload(arg0 *dto.UploadImageRequest) (*dto.ImageResponse, } // Upload indicates an expected call of Upload. -func (mr *MockServiceMockRecorder) Upload(arg0 any) *gomock.Call { +func (mr *MockServiceMockRecorder) Upload(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upload", reflect.TypeOf((*MockService)(nil).Upload), arg0) } diff --git a/src/mocks/service/pet/pet.mock.go b/src/mocks/service/pet/pet.mock.go index 35b82b0..eba3652 100644 --- a/src/mocks/service/pet/pet.mock.go +++ b/src/mocks/service/pet/pet.mock.go @@ -1,10 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. // Source: ./src/pkg/service/pet/pet.service.go -// -// Generated by this command: -// -// mockgen -source ./src/pkg/service/pet/pet.service.go -destination ./src/mocks/service/pet/pet.mock.go -// // Package mock_pet is a generated GoMock package. package mock_pet @@ -12,8 +7,8 @@ package mock_pet import ( reflect "reflect" - dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" gomock "github.com/golang/mock/gomock" + dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" ) // MockService is a mock of Service interface. @@ -49,7 +44,7 @@ func (m *MockService) Adopt(arg0 string, arg1 *dto.AdoptByRequest) (*dto.AdoptBy } // Adopt indicates an expected call of Adopt. -func (mr *MockServiceMockRecorder) Adopt(arg0, arg1 any) *gomock.Call { +func (mr *MockServiceMockRecorder) Adopt(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Adopt", reflect.TypeOf((*MockService)(nil).Adopt), arg0, arg1) } @@ -64,7 +59,7 @@ func (m *MockService) ChangeView(arg0 string, arg1 *dto.ChangeViewPetRequest) (* } // ChangeView indicates an expected call of ChangeView. -func (mr *MockServiceMockRecorder) ChangeView(arg0, arg1 any) *gomock.Call { +func (mr *MockServiceMockRecorder) ChangeView(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangeView", reflect.TypeOf((*MockService)(nil).ChangeView), arg0, arg1) } @@ -79,7 +74,7 @@ func (m *MockService) Create(arg0 *dto.CreatePetRequest) (*dto.PetResponse, *dto } // Create indicates an expected call of Create. -func (mr *MockServiceMockRecorder) Create(arg0 any) *gomock.Call { +func (mr *MockServiceMockRecorder) Create(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockService)(nil).Create), arg0) } @@ -94,7 +89,7 @@ func (m *MockService) Delete(arg0 string) (*dto.DeleteResponse, *dto.ResponseErr } // Delete indicates an expected call of Delete. -func (mr *MockServiceMockRecorder) Delete(arg0 any) *gomock.Call { +func (mr *MockServiceMockRecorder) Delete(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), arg0) } @@ -109,7 +104,7 @@ func (m *MockService) FindAll(arg0 *dto.FindAllPetRequest) (*dto.FindAllPetRespo } // FindAll indicates an expected call of FindAll. -func (mr *MockServiceMockRecorder) FindAll(arg0 any) *gomock.Call { +func (mr *MockServiceMockRecorder) FindAll(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAll", reflect.TypeOf((*MockService)(nil).FindAll), arg0) } @@ -124,7 +119,7 @@ func (m *MockService) FindOne(arg0 string) (*dto.PetResponse, *dto.ResponseErr) } // FindOne indicates an expected call of FindOne. -func (mr *MockServiceMockRecorder) FindOne(arg0 any) *gomock.Call { +func (mr *MockServiceMockRecorder) FindOne(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockService)(nil).FindOne), arg0) } @@ -139,7 +134,7 @@ func (m *MockService) Update(arg0 string, arg1 *dto.UpdatePetRequest) (*dto.PetR } // Update indicates an expected call of Update. -func (mr *MockServiceMockRecorder) Update(arg0, arg1 any) *gomock.Call { +func (mr *MockServiceMockRecorder) Update(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockService)(nil).Update), arg0, arg1) } From 1ce9fe81f4a24c8c00894c449677fe91cf034519 Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 09:57:19 +0700 Subject: [PATCH 003/104] feat: implement forgot password handler --- src/app/handler/auth/auth.handler.go | 46 ++++++++++ src/app/handler/auth/auth.handler_test.go | 103 ++++++++++++++++++++-- 2 files changed, 144 insertions(+), 5 deletions(-) diff --git a/src/app/handler/auth/auth.handler.go b/src/app/handler/auth/auth.handler.go index 9eade02..249b05d 100644 --- a/src/app/handler/auth/auth.handler.go +++ b/src/app/handler/auth/auth.handler.go @@ -184,3 +184,49 @@ func (h *Handler) RefreshToken(c router.IContext) { c.JSON(http.StatusOK, response) } + +// ForgotPassword is a function to send email to reset password when you forgot password +// @Summary Forgot Password +// @Description Return isSuccess +// @Param request body dto.ForgotPasswordRequest true "forgotPassword request dto" +// @Tags auth +// @Accept json +// @Produce json +// @Success 200 {object} dto.ForgotPasswordResponse +// @Failure 400 {object} dto.ResponseBadRequestErr "Invalid email" +// @Failure 500 {object} dto.ResponseInternalErr "Internal service error" +// @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" +// @Router /v1/auth/forgot-password [post] +func (h *Handler) ForgotPassword(c router.IContext) { + request := &dto.ForgotPasswordRequest{} + 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 + } + + response, respErr := h.service.ForgotPassword(request) + if respErr != nil { + c.JSON(respErr.StatusCode, respErr) + return + } + + c.JSON(http.StatusOK, response) +} diff --git a/src/app/handler/auth/auth.handler_test.go b/src/app/handler/auth/auth.handler_test.go index 3a73e40..b4555a3 100644 --- a/src/app/handler/auth/auth.handler_test.go +++ b/src/app/handler/auth/auth.handler_test.go @@ -18,11 +18,12 @@ import ( type AuthHandlerTest struct { suite.Suite - signupRequest *dto.SignupRequest - signInRequest *dto.SignInRequest - refreshTokenRequest *dto.RefreshTokenRequest - bindErr error - validateErr []*dto.BadReqErrResponse + signupRequest *dto.SignupRequest + signInRequest *dto.SignInRequest + refreshTokenRequest *dto.RefreshTokenRequest + forgotPasswordRequest *dto.ForgotPasswordRequest + bindErr error + validateErr []*dto.BadReqErrResponse } func TestAuthHandler(t *testing.T) { @@ -33,6 +34,7 @@ func (t *AuthHandlerTest) SetupTest() { signupRequest := &dto.SignupRequest{} signInRequest := &dto.SignInRequest{} refreshTokenRequest := &dto.RefreshTokenRequest{} + forgotPasswordRequest := &dto.ForgotPasswordRequest{} bindErr := errors.New("Binding request failed") validateErr := []*dto.BadReqErrResponse{ { @@ -50,6 +52,7 @@ func (t *AuthHandlerTest) SetupTest() { t.signupRequest = signupRequest t.signInRequest = signInRequest t.refreshTokenRequest = refreshTokenRequest + t.forgotPasswordRequest = forgotPasswordRequest t.bindErr = bindErr t.validateErr = validateErr } @@ -378,3 +381,93 @@ func (t *AuthHandlerTest) TestRefreshTokenServiceError() { handler.RefreshToken(context) } + +func (t *AuthHandlerTest) TestForgotPasswordSuccess() { + forgotPasswordResponse := &dto.ForgotPasswordResponse{ + IsSuccess: true, + } + + controller := gomock.NewController(t.T()) + + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + handler := NewHandler(authSvc, userSvc, validator) + + context.EXPECT().Bind(t.forgotPasswordRequest).Return(nil) + validator.EXPECT().Validate(t.forgotPasswordRequest).Return(nil) + authSvc.EXPECT().ForgotPassword(t.forgotPasswordRequest).Return(forgotPasswordResponse, nil) + context.EXPECT().JSON(http.StatusOK, forgotPasswordResponse) + + handler.ForgotPassword(context) +} + +func (t *AuthHandlerTest) TestForgotPasswordBindFailed() { + errResponse := dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.BindingRequestErrorMessage + t.bindErr.Error(), + Data: nil, + } + + controller := gomock.NewController(t.T()) + + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + handler := NewHandler(authSvc, userSvc, validator) + + context.EXPECT().Bind(t.forgotPasswordRequest).Return(t.bindErr) + context.EXPECT().JSON(http.StatusBadRequest, errResponse) + handler.ForgotPassword(context) +} + +func (t *AuthHandlerTest) TestForgotPasswordValidateFailed() { + errResponse := dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidRequestBodyMessage + "BadRequestError1, BadRequestError2", + Data: nil, + } + + controller := gomock.NewController(t.T()) + + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + handler := NewHandler(authSvc, userSvc, validator) + + context.EXPECT().Bind(t.forgotPasswordRequest).Return(nil) + validator.EXPECT().Validate(t.forgotPasswordRequest).Return(t.validateErr) + context.EXPECT().JSON(http.StatusBadRequest, errResponse) + + handler.ForgotPassword(context) +} + +func (t *AuthHandlerTest) TestForgotPasswordServiceError() { + forgotPasswordErr := &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + + controller := gomock.NewController(t.T()) + + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + handler := NewHandler(authSvc, userSvc, validator) + + context.EXPECT().Bind(t.forgotPasswordRequest).Return(nil) + validator.EXPECT().Validate(t.forgotPasswordRequest).Return(nil) + authSvc.EXPECT().ForgotPassword(t.forgotPasswordRequest).Return(nil, forgotPasswordErr) + context.EXPECT().JSON(http.StatusInternalServerError, forgotPasswordErr) + + handler.ForgotPassword(context) +} From bfd48bf40d87fcfbad7509c049df8c3ed7600935 Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 09:58:01 +0700 Subject: [PATCH 004/104] feat: add forgot password route --- src/main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.go b/src/main.go index 8e785da..484d196 100644 --- a/src/main.go +++ b/src/main.go @@ -11,7 +11,7 @@ import ( "time" authHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/auth" - healthcheck "github.com/isd-sgcu/johnjud-gateway/src/app/handler/healthcheck" + "github.com/isd-sgcu/johnjud-gateway/src/app/handler/healthcheck" imageHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/image" likeHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/like" petHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/pet" @@ -129,6 +129,7 @@ func main() { r.PostAuth("/signout", authHandler.SignOut) //r.PostAuth("/me", authHandler.Validate) r.PostAuth("/refreshToken", authHandler.RefreshToken) + r.PostAuth("/forgot-password", authHandler.ForgotPassword) r.GetHealthCheck("", hc.HealthCheck) From 5a3ad467a70dc078a38afaaf94e41091de68e7ba Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 09:58:15 +0700 Subject: [PATCH 005/104] chore: update docs --- src/docs/docs.go | 371 ++++++++++++++++++++++++++++++++++++++---- src/docs/swagger.json | 371 ++++++++++++++++++++++++++++++++++++++---- src/docs/swagger.yaml | 252 ++++++++++++++++++++++++---- 3 files changed, 894 insertions(+), 100 deletions(-) diff --git a/src/docs/docs.go b/src/docs/docs.go index ee19d5a..14841e5 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -18,6 +18,58 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/v1/auth/forgot-password": { + "post": { + "description": "Return isSuccess", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Forgot Password", + "parameters": [ + { + "description": "forgotPassword request dto", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.ForgotPasswordRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.ForgotPasswordResponse" + } + }, + "400": { + "description": "Invalid email", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, "/v1/auth/refreshToken": { "post": { "description": "Return the credential", @@ -595,6 +647,156 @@ const docTemplate = `{ } } } + }, + "/v1/users": { + "put": { + "description": "Returns the data of user if successfully", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "updates user", + "parameters": [ + { + "description": "update user dto", + "name": "update", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateUserRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.User" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, + "/v1/users/{id}": { + "get": { + "description": "Returns the data of user if successful", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "finds one user", + "parameters": [ + { + "type": "string", + "description": "user id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.User" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + }, + "delete": { + "description": "Returns successful status if user is successfully deleted", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "deletes user", + "parameters": [ + { + "type": "string", + "description": "user id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.DeleteUserResponse" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } } }, "definitions": { @@ -646,9 +848,6 @@ const docTemplate = `{ }, "dto.ChangeViewPetResponse": { "type": "object", - "required": [ - "success" - ], "properties": { "success": { "type": "boolean" @@ -659,14 +858,15 @@ const docTemplate = `{ "type": "object", "required": [ "birthdate", + "color", "gender", "habit", - "is_club_pet", "is_sterile", "is_vaccinated", "is_visible", "name", - "species", + "origin", + "pattern", "status", "type" ], @@ -677,21 +877,25 @@ const docTemplate = `{ "adopt_by": { "type": "string" }, - "background": { - "type": "string" - }, "birthdate": { "type": "string" }, "caption": { "type": "string" }, + "color": { + "type": "string" + }, "contact": { "type": "string" }, "gender": { - "type": "integer", - "example": 1 + "allOf": [ + { + "$ref": "#/definitions/pet.Gender" + } + ], + "example": "male" }, "habit": { "type": "string" @@ -702,9 +906,6 @@ const docTemplate = `{ "type": "string" } }, - "is_club_pet": { - "type": "boolean" - }, "is_sterile": { "type": "boolean" }, @@ -717,12 +918,19 @@ const docTemplate = `{ "name": { "type": "string" }, - "species": { + "origin": { + "type": "string" + }, + "pattern": { "type": "string" }, "status": { - "type": "integer", - "example": 1 + "allOf": [ + { + "$ref": "#/definitions/pet.Status" + } + ], + "example": "findhome" }, "type": { "type": "string" @@ -747,12 +955,36 @@ const docTemplate = `{ } }, "dto.DeleteResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + }, + "dto.DeleteUserResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + }, + "dto.ForgotPasswordRequest": { "type": "object", "required": [ - "success" + "email" ], "properties": { - "success": { + "email": { + "type": "string" + } + } + }, + "dto.ForgotPasswordResponse": { + "type": "object", + "properties": { + "is_success": { "type": "boolean" } } @@ -763,6 +995,9 @@ const docTemplate = `{ "id": { "type": "string" }, + "object_key": { + "type": "string" + }, "url": { "type": "string" } @@ -777,20 +1012,20 @@ const docTemplate = `{ "adopt_by": { "type": "string" }, - "background": { - "type": "string" - }, "birthdate": { "type": "string" }, "caption": { "type": "string" }, + "color": { + "type": "string" + }, "contact": { "type": "string" }, "gender": { - "type": "integer" + "$ref": "#/definitions/pet.Gender" }, "habit": { "type": "string" @@ -804,9 +1039,6 @@ const docTemplate = `{ "$ref": "#/definitions/dto.ImageResponse" } }, - "is_club_pet": { - "type": "boolean" - }, "is_sterile": { "type": "boolean" }, @@ -819,11 +1051,14 @@ const docTemplate = `{ "name": { "type": "string" }, - "species": { + "origin": { + "type": "string" + }, + "pattern": { "type": "string" }, "status": { - "type": "integer" + "$ref": "#/definitions/pet.Status" }, "type": { "type": "string" @@ -1006,20 +1241,20 @@ const docTemplate = `{ "adopt_by": { "type": "string" }, - "background": { - "type": "string" - }, "birthdate": { "type": "string" }, "caption": { "type": "string" }, + "color": { + "type": "string" + }, "contact": { "type": "string" }, "gender": { - "type": "integer" + "$ref": "#/definitions/pet.Gender" }, "habit": { "type": "string" @@ -1030,9 +1265,6 @@ const docTemplate = `{ "type": "string" } }, - "is_club_pet": { - "type": "boolean" - }, "is_sterile": { "type": "boolean" }, @@ -1045,16 +1277,83 @@ const docTemplate = `{ "name": { "type": "string" }, - "species": { + "origin": { + "type": "string" + }, + "pattern": { "type": "string" }, "status": { - "type": "integer" + "$ref": "#/definitions/pet.Status" }, "type": { "type": "string" } } + }, + "dto.UpdateUserRequest": { + "type": "object", + "required": [ + "email", + "firstname", + "lastname", + "password" + ], + "properties": { + "email": { + "type": "string" + }, + "firstname": { + "type": "string" + }, + "lastname": { + "type": "string" + }, + "password": { + "type": "string", + "maxLength": 30, + "minLength": 6 + } + } + }, + "dto.User": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "firstname": { + "type": "string" + }, + "id": { + "type": "string" + }, + "lastname": { + "type": "string" + } + } + }, + "pet.Gender": { + "type": "string", + "enum": [ + "male", + "female" + ], + "x-enum-varnames": [ + "MALE", + "FEMALE" + ] + }, + "pet.Status": { + "type": "string", + "enum": [ + "adopted", + "findhome" + ], + "x-enum-varnames": [ + "ADOPTED", + "FINDHOME" + ] } }, "securityDefinitions": { diff --git a/src/docs/swagger.json b/src/docs/swagger.json index deaf951..bffd226 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -14,6 +14,58 @@ "version": "1.0" }, "paths": { + "/v1/auth/forgot-password": { + "post": { + "description": "Return isSuccess", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Forgot Password", + "parameters": [ + { + "description": "forgotPassword request dto", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.ForgotPasswordRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.ForgotPasswordResponse" + } + }, + "400": { + "description": "Invalid email", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, "/v1/auth/refreshToken": { "post": { "description": "Return the credential", @@ -591,6 +643,156 @@ } } } + }, + "/v1/users": { + "put": { + "description": "Returns the data of user if successfully", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "updates user", + "parameters": [ + { + "description": "update user dto", + "name": "update", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateUserRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.User" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, + "/v1/users/{id}": { + "get": { + "description": "Returns the data of user if successful", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "finds one user", + "parameters": [ + { + "type": "string", + "description": "user id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.User" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + }, + "delete": { + "description": "Returns successful status if user is successfully deleted", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "deletes user", + "parameters": [ + { + "type": "string", + "description": "user id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.DeleteUserResponse" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } } }, "definitions": { @@ -642,9 +844,6 @@ }, "dto.ChangeViewPetResponse": { "type": "object", - "required": [ - "success" - ], "properties": { "success": { "type": "boolean" @@ -655,14 +854,15 @@ "type": "object", "required": [ "birthdate", + "color", "gender", "habit", - "is_club_pet", "is_sterile", "is_vaccinated", "is_visible", "name", - "species", + "origin", + "pattern", "status", "type" ], @@ -673,21 +873,25 @@ "adopt_by": { "type": "string" }, - "background": { - "type": "string" - }, "birthdate": { "type": "string" }, "caption": { "type": "string" }, + "color": { + "type": "string" + }, "contact": { "type": "string" }, "gender": { - "type": "integer", - "example": 1 + "allOf": [ + { + "$ref": "#/definitions/pet.Gender" + } + ], + "example": "male" }, "habit": { "type": "string" @@ -698,9 +902,6 @@ "type": "string" } }, - "is_club_pet": { - "type": "boolean" - }, "is_sterile": { "type": "boolean" }, @@ -713,12 +914,19 @@ "name": { "type": "string" }, - "species": { + "origin": { + "type": "string" + }, + "pattern": { "type": "string" }, "status": { - "type": "integer", - "example": 1 + "allOf": [ + { + "$ref": "#/definitions/pet.Status" + } + ], + "example": "findhome" }, "type": { "type": "string" @@ -743,12 +951,36 @@ } }, "dto.DeleteResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + }, + "dto.DeleteUserResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + }, + "dto.ForgotPasswordRequest": { "type": "object", "required": [ - "success" + "email" ], "properties": { - "success": { + "email": { + "type": "string" + } + } + }, + "dto.ForgotPasswordResponse": { + "type": "object", + "properties": { + "is_success": { "type": "boolean" } } @@ -759,6 +991,9 @@ "id": { "type": "string" }, + "object_key": { + "type": "string" + }, "url": { "type": "string" } @@ -773,20 +1008,20 @@ "adopt_by": { "type": "string" }, - "background": { - "type": "string" - }, "birthdate": { "type": "string" }, "caption": { "type": "string" }, + "color": { + "type": "string" + }, "contact": { "type": "string" }, "gender": { - "type": "integer" + "$ref": "#/definitions/pet.Gender" }, "habit": { "type": "string" @@ -800,9 +1035,6 @@ "$ref": "#/definitions/dto.ImageResponse" } }, - "is_club_pet": { - "type": "boolean" - }, "is_sterile": { "type": "boolean" }, @@ -815,11 +1047,14 @@ "name": { "type": "string" }, - "species": { + "origin": { + "type": "string" + }, + "pattern": { "type": "string" }, "status": { - "type": "integer" + "$ref": "#/definitions/pet.Status" }, "type": { "type": "string" @@ -1002,20 +1237,20 @@ "adopt_by": { "type": "string" }, - "background": { - "type": "string" - }, "birthdate": { "type": "string" }, "caption": { "type": "string" }, + "color": { + "type": "string" + }, "contact": { "type": "string" }, "gender": { - "type": "integer" + "$ref": "#/definitions/pet.Gender" }, "habit": { "type": "string" @@ -1026,9 +1261,6 @@ "type": "string" } }, - "is_club_pet": { - "type": "boolean" - }, "is_sterile": { "type": "boolean" }, @@ -1041,16 +1273,83 @@ "name": { "type": "string" }, - "species": { + "origin": { + "type": "string" + }, + "pattern": { "type": "string" }, "status": { - "type": "integer" + "$ref": "#/definitions/pet.Status" }, "type": { "type": "string" } } + }, + "dto.UpdateUserRequest": { + "type": "object", + "required": [ + "email", + "firstname", + "lastname", + "password" + ], + "properties": { + "email": { + "type": "string" + }, + "firstname": { + "type": "string" + }, + "lastname": { + "type": "string" + }, + "password": { + "type": "string", + "maxLength": 30, + "minLength": 6 + } + } + }, + "dto.User": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "firstname": { + "type": "string" + }, + "id": { + "type": "string" + }, + "lastname": { + "type": "string" + } + } + }, + "pet.Gender": { + "type": "string", + "enum": [ + "male", + "female" + ], + "x-enum-varnames": [ + "MALE", + "FEMALE" + ] + }, + "pet.Status": { + "type": "string", + "enum": [ + "adopted", + "findhome" + ], + "x-enum-varnames": [ + "ADOPTED", + "FINDHOME" + ] } }, "securityDefinitions": { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index e585f99..363cd54 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -33,8 +33,6 @@ definitions: properties: success: type: boolean - required: - - success type: object dto.CreatePetRequest: properties: @@ -42,25 +40,24 @@ definitions: type: string adopt_by: type: string - background: - type: string birthdate: type: string caption: type: string + color: + type: string contact: type: string gender: - example: 1 - type: integer + allOf: + - $ref: '#/definitions/pet.Gender' + example: male habit: type: string images: items: type: string type: array - is_club_pet: - type: boolean is_sterile: type: boolean is_vaccinated: @@ -69,23 +66,27 @@ definitions: type: boolean name: type: string - species: + origin: + type: string + pattern: type: string status: - example: 1 - type: integer + allOf: + - $ref: '#/definitions/pet.Status' + example: findhome type: type: string required: - birthdate + - color - gender - habit - - is_club_pet - is_sterile - is_vaccinated - is_visible - name - - species + - origin + - pattern - status - type type: object @@ -105,13 +106,30 @@ definitions: properties: success: type: boolean + type: object + dto.DeleteUserResponse: + properties: + success: + type: boolean + type: object + dto.ForgotPasswordRequest: + properties: + email: + type: string required: - - success + - email + type: object + dto.ForgotPasswordResponse: + properties: + is_success: + type: boolean type: object dto.ImageResponse: properties: id: type: string + object_key: + type: string url: type: string type: object @@ -121,16 +139,16 @@ definitions: type: string adopt_by: type: string - background: - type: string birthdate: type: string caption: type: string + color: + type: string contact: type: string gender: - type: integer + $ref: '#/definitions/pet.Gender' habit: type: string id: @@ -139,8 +157,6 @@ definitions: items: $ref: '#/definitions/dto.ImageResponse' type: array - is_club_pet: - type: boolean is_sterile: type: boolean is_vaccinated: @@ -149,10 +165,12 @@ definitions: type: boolean name: type: string - species: + origin: + type: string + pattern: type: string status: - type: integer + $ref: '#/definitions/pet.Status' type: type: string type: object @@ -278,24 +296,22 @@ definitions: type: string adopt_by: type: string - background: - type: string birthdate: type: string caption: type: string + color: + type: string contact: type: string gender: - type: integer + $ref: '#/definitions/pet.Gender' habit: type: string images: items: type: string type: array - is_club_pet: - type: boolean is_sterile: type: boolean is_vaccinated: @@ -304,13 +320,60 @@ definitions: type: boolean name: type: string - species: + origin: + type: string + pattern: type: string status: - type: integer + $ref: '#/definitions/pet.Status' type: type: string type: object + dto.UpdateUserRequest: + properties: + email: + type: string + firstname: + type: string + lastname: + type: string + password: + maxLength: 30 + minLength: 6 + type: string + required: + - email + - firstname + - lastname + - password + type: object + dto.User: + properties: + email: + type: string + firstname: + type: string + id: + type: string + lastname: + type: string + type: object + pet.Gender: + enum: + - male + - female + type: string + x-enum-varnames: + - MALE + - FEMALE + pet.Status: + enum: + - adopted + - findhome + type: string + x-enum-varnames: + - ADOPTED + - FINDHOME info: contact: email: sd.team.sgcu@gmail.com @@ -319,6 +382,40 @@ info: title: JohnJud API version: "1.0" paths: + /v1/auth/forgot-password: + post: + consumes: + - application/json + description: Return isSuccess + parameters: + - description: forgotPassword request dto + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.ForgotPasswordRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.ForgotPasswordResponse' + "400": + description: Invalid email + schema: + $ref: '#/definitions/dto.ResponseBadRequestErr' + "500": + description: Internal service error + schema: + $ref: '#/definitions/dto.ResponseInternalErr' + "503": + description: Service is down + schema: + $ref: '#/definitions/dto.ResponseServiceDownErr' + summary: Forgot Password + tags: + - auth /v1/auth/refreshToken: post: consumes: @@ -701,6 +798,105 @@ paths: summary: creates pet tags: - pet + /v1/users: + put: + consumes: + - application/json + description: Returns the data of user if successfully + parameters: + - description: update user dto + in: body + name: update + required: true + schema: + $ref: '#/definitions/dto.UpdateUserRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/dto.User' + "400": + description: Invalid request body + schema: + $ref: '#/definitions/dto.ResponseBadRequestErr' + "500": + description: Internal service error + schema: + $ref: '#/definitions/dto.ResponseInternalErr' + "503": + description: Service is down + schema: + $ref: '#/definitions/dto.ResponseServiceDownErr' + summary: updates user + tags: + - auth + /v1/users/{id}: + delete: + consumes: + - application/json + description: Returns successful status if user is successfully deleted + parameters: + - description: user id + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/dto.DeleteUserResponse' + "400": + description: Invalid request body + schema: + $ref: '#/definitions/dto.ResponseBadRequestErr' + "500": + description: Internal service error + schema: + $ref: '#/definitions/dto.ResponseInternalErr' + "503": + description: Service is down + schema: + $ref: '#/definitions/dto.ResponseServiceDownErr' + summary: deletes user + tags: + - user + get: + consumes: + - application/json + description: Returns the data of user if successful + parameters: + - description: user id + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.User' + "400": + description: Invalid request body + schema: + $ref: '#/definitions/dto.ResponseBadRequestErr' + "500": + description: Internal service error + schema: + $ref: '#/definitions/dto.ResponseInternalErr' + "503": + description: Service is down + schema: + $ref: '#/definitions/dto.ResponseServiceDownErr' + summary: finds one user + tags: + - user schemes: - https - http From 13320ac550406fe53de30b84095c3f8bffdc163b Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 10:00:16 +0700 Subject: [PATCH 006/104] fix: exclude forgot-password path from middleware --- src/constant/auth/auth.constant.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/constant/auth/auth.constant.go b/src/constant/auth/auth.constant.go index 281fc8c..3394890 100644 --- a/src/constant/auth/auth.constant.go +++ b/src/constant/auth/auth.constant.go @@ -1,12 +1,13 @@ package auth var ExcludePath = map[string]struct{}{ - "POST /auth/signup": {}, - "POST /auth/signin": {}, - "POST /auth/verify": {}, - "GET /user/:id": {}, - "GET /pets": {}, - "GET /adopt": {}, + "POST /auth/signup": {}, + "POST /auth/signin": {}, + "POST /auth/verify": {}, + "POST /auth/forgot-password": {}, + "GET /user/:id": {}, + "GET /pets": {}, + "GET /adopt": {}, } var AdminPath = map[string]struct{}{ From 55baee8c8285e66d88dd4b687bfb101024c4db39 Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 15:39:07 +0700 Subject: [PATCH 007/104] feat: implement reset password service --- src/app/constant/error.constant.go | 1 + src/app/dto/auth.dto.go | 9 ++ src/app/service/auth/auth.service.go | 54 ++++++++++ src/app/service/auth/auth.service_test.go | 121 ++++++++++++++++++++++ src/pkg/service/auth/auth.service.go | 1 + 5 files changed, 186 insertions(+) diff --git a/src/app/constant/error.constant.go b/src/app/constant/error.constant.go index 5e378d3..a56c6b6 100644 --- a/src/app/constant/error.constant.go +++ b/src/app/constant/error.constant.go @@ -3,6 +3,7 @@ package constant const BindingRequestErrorMessage = "Binding Request Error due to:" const InvalidRequestBodyMessage = "Invalid Request Body due to:" const InvalidTokenMessage = "Invalid token" +const ForbiddenSamePasswordMessage = "The same password is forbidden " const IncorrectEmailPasswordMessage = "Incorrect Email or Password" const UnauthorizedMessage = "Unauthorized" const DuplicateEmailMessage = "Duplicate Email" diff --git a/src/app/dto/auth.dto.go b/src/app/dto/auth.dto.go index 4a68f91..e60a30b 100644 --- a/src/app/dto/auth.dto.go +++ b/src/app/dto/auth.dto.go @@ -39,3 +39,12 @@ type ForgotPasswordRequest struct { type ForgotPasswordResponse struct { IsSuccess bool `json:"is_success"` } + +type ResetPasswordRequest struct { + Token string `json:"token" validate:"required"` + Password string `json:"password" validate:"required"` +} + +type ResetPasswordResponse struct { + IsSuccess bool `json:"is_success"` +} diff --git a/src/app/service/auth/auth.service.go b/src/app/service/auth/auth.service.go index b42452f..dd60984 100644 --- a/src/app/service/auth/auth.service.go +++ b/src/app/service/auth/auth.service.go @@ -341,3 +341,57 @@ func (s *Service) ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.Forgo IsSuccess: true, }, nil } + +func (s *Service) ResetPassword(request *dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + response, err := s.client.ResetPassword(ctx, &authProto.ResetPasswordRequest{ + Token: request.Token, + Password: request.Password, + }) + if err != nil { + st, ok := status.FromError(err) + log.Error(). + Str("service", "auth"). + Str("action", "ResetPassword"). + Str("token", request.Token). + Msg(st.Message()) + if !ok { + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + switch st.Code() { + case codes.InvalidArgument: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.ForbiddenSamePasswordMessage, + Data: nil, + } + case codes.Internal: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + default: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + } + } + + log.Info(). + Str("service", "auth"). + Str("action", "ResetPassword"). + Str("token", request.Token). + Msg("Reset password successfully") + return &dto.ResetPasswordResponse{ + IsSuccess: response.IsSuccess, + }, nil +} diff --git a/src/app/service/auth/auth.service_test.go b/src/app/service/auth/auth.service_test.go index 25b1f0c..b545ed7 100644 --- a/src/app/service/auth/auth.service_test.go +++ b/src/app/service/auth/auth.service_test.go @@ -23,6 +23,7 @@ type AuthServiceTest struct { token string refreshTokenRequest *dto.RefreshTokenRequest forgotPasswordRequest *dto.ForgotPasswordRequest + resetPasswordRequest *dto.ResetPasswordRequest } func TestAuthService(t *testing.T) { @@ -47,12 +48,17 @@ func (t *AuthServiceTest) SetupTest() { forgotPasswordRequest := &dto.ForgotPasswordRequest{ Email: faker.Email(), } + resetPasswordRequest := &dto.ResetPasswordRequest{ + Token: faker.Word(), + Password: faker.Password(), + } t.signupRequestDto = signupRequestDto t.signInDto = signInDto t.token = token t.refreshTokenRequest = refreshTokenRequest t.forgotPasswordRequest = forgotPasswordRequest + t.resetPasswordRequest = resetPasswordRequest } func (t *AuthServiceTest) TestSignupSuccess() { @@ -715,3 +721,118 @@ func (t *AuthServiceTest) TestForgotPasswordUnknownErr() { assert.Nil(t.T(), actual) assert.Equal(t.T(), expected, err) } + +func (t *AuthServiceTest) TestResetPasswordSuccess() { + protoReq := &authProto.ResetPasswordRequest{ + Token: t.resetPasswordRequest.Token, + Password: t.resetPasswordRequest.Password, + } + protoResp := &authProto.ResetPasswordResponse{ + IsSuccess: true, + } + + expected := &dto.ResetPasswordResponse{ + IsSuccess: true, + } + + client := auth.AuthClientMock{} + client.On("ResetPassword", protoReq).Return(protoResp, nil) + + svc := NewService(&client) + actual, err := svc.ResetPassword(t.resetPasswordRequest) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *AuthServiceTest) TestResetPasswordInvalid() { + protoReq := &authProto.ResetPasswordRequest{ + Token: t.resetPasswordRequest.Token, + Password: t.resetPasswordRequest.Password, + } + protoErr := status.Error(codes.InvalidArgument, "Same password") + + expected := &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.ForbiddenSamePasswordMessage, + Data: nil, + } + + client := auth.AuthClientMock{} + client.On("ResetPassword", protoReq).Return(nil, protoErr) + + svc := NewService(&client) + actual, err := svc.ResetPassword(t.resetPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) TestResetPasswordInternalErr() { + protoReq := &authProto.ResetPasswordRequest{ + Token: t.resetPasswordRequest.Token, + Password: t.resetPasswordRequest.Password, + } + protoErr := status.Error(codes.Internal, "Internal error") + + expected := &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + + client := auth.AuthClientMock{} + client.On("ResetPassword", protoReq).Return(nil, protoErr) + + svc := NewService(&client) + actual, err := svc.ResetPassword(t.resetPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) TestResetPasswordUnavailableService() { + protoReq := &authProto.ResetPasswordRequest{ + Token: t.resetPasswordRequest.Token, + Password: t.resetPasswordRequest.Password, + } + protoErr := status.Error(codes.Unavailable, "Connection lost") + + expected := &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + + client := auth.AuthClientMock{} + client.On("ResetPassword", protoReq).Return(nil, protoErr) + + svc := NewService(&client) + actual, err := svc.ResetPassword(t.resetPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) TestResetPasswordUnknownErr() { + protoReq := &authProto.ResetPasswordRequest{ + Token: t.resetPasswordRequest.Token, + Password: t.resetPasswordRequest.Password, + } + protoErr := errors.New("Unknown Error") + + expected := &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + + client := auth.AuthClientMock{} + client.On("ResetPassword", protoReq).Return(nil, protoErr) + + svc := NewService(&client) + actual, err := svc.ResetPassword(t.resetPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} diff --git a/src/pkg/service/auth/auth.service.go b/src/pkg/service/auth/auth.service.go index c527153..11f3375 100644 --- a/src/pkg/service/auth/auth.service.go +++ b/src/pkg/service/auth/auth.service.go @@ -11,4 +11,5 @@ type Service interface { Validate(string) (*dto.TokenPayloadAuth, *dto.ResponseErr) RefreshToken(*dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) + ResetPassword(*dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) } From 1e153afe4a84a6def1e6ba9924505e44d1ccf9b2 Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 15:59:21 +0700 Subject: [PATCH 008/104] feat: generate mock --- src/mocks/service/auth/auth.mock.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/mocks/service/auth/auth.mock.go b/src/mocks/service/auth/auth.mock.go index 5115774..76fa349 100644 --- a/src/mocks/service/auth/auth.mock.go +++ b/src/mocks/service/auth/auth.mock.go @@ -64,6 +64,21 @@ func (mr *MockServiceMockRecorder) RefreshToken(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RefreshToken", reflect.TypeOf((*MockService)(nil).RefreshToken), arg0) } +// ResetPassword mocks base method. +func (m *MockService) ResetPassword(arg0 *dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ResetPassword", arg0) + ret0, _ := ret[0].(*dto.ResetPasswordResponse) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// ResetPassword indicates an expected call of ResetPassword. +func (mr *MockServiceMockRecorder) ResetPassword(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetPassword", reflect.TypeOf((*MockService)(nil).ResetPassword), arg0) +} + // SignIn mocks base method. func (m *MockService) SignIn(arg0 *dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) { m.ctrl.T.Helper() From c12d12dffb8d6141c4fd842327ffbdee8f913681 Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 16:59:51 +0700 Subject: [PATCH 009/104] feat: implement reset password handler --- src/app/handler/auth/auth.handler.go | 34 ++++++++ src/app/handler/auth/auth.handler_test.go | 94 +++++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/src/app/handler/auth/auth.handler.go b/src/app/handler/auth/auth.handler.go index 249b05d..94e0251 100644 --- a/src/app/handler/auth/auth.handler.go +++ b/src/app/handler/auth/auth.handler.go @@ -230,3 +230,37 @@ func (h *Handler) ForgotPassword(c router.IContext) { c.JSON(http.StatusOK, response) } + +func (h *Handler) ResetPassword(c router.IContext) { + request := &dto.ResetPasswordRequest{} + 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 + } + + response, errResp := h.service.ResetPassword(request) + if errResp != nil { + c.JSON(errResp.StatusCode, errResp) + return + } + + c.JSON(http.StatusOK, response) +} diff --git a/src/app/handler/auth/auth.handler_test.go b/src/app/handler/auth/auth.handler_test.go index b4555a3..f653c11 100644 --- a/src/app/handler/auth/auth.handler_test.go +++ b/src/app/handler/auth/auth.handler_test.go @@ -22,6 +22,7 @@ type AuthHandlerTest struct { signInRequest *dto.SignInRequest refreshTokenRequest *dto.RefreshTokenRequest forgotPasswordRequest *dto.ForgotPasswordRequest + resetPasswordRequest *dto.ResetPasswordRequest bindErr error validateErr []*dto.BadReqErrResponse } @@ -35,6 +36,7 @@ func (t *AuthHandlerTest) SetupTest() { signInRequest := &dto.SignInRequest{} refreshTokenRequest := &dto.RefreshTokenRequest{} forgotPasswordRequest := &dto.ForgotPasswordRequest{} + resetPasswordRequest := &dto.ResetPasswordRequest{} bindErr := errors.New("Binding request failed") validateErr := []*dto.BadReqErrResponse{ { @@ -53,6 +55,7 @@ func (t *AuthHandlerTest) SetupTest() { t.signInRequest = signInRequest t.refreshTokenRequest = refreshTokenRequest t.forgotPasswordRequest = forgotPasswordRequest + t.resetPasswordRequest = resetPasswordRequest t.bindErr = bindErr t.validateErr = validateErr } @@ -471,3 +474,94 @@ func (t *AuthHandlerTest) TestForgotPasswordServiceError() { handler.ForgotPassword(context) } + +func (t *AuthHandlerTest) TestResetPasswordSuccess() { + resetPasswordResponse := &dto.ResetPasswordResponse{ + IsSuccess: true, + } + + controller := gomock.NewController(t.T()) + + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + handler := NewHandler(authSvc, userSvc, validator) + + context.EXPECT().Bind(t.resetPasswordRequest).Return(nil) + validator.EXPECT().Validate(t.resetPasswordRequest).Return(nil) + authSvc.EXPECT().ResetPassword(t.resetPasswordRequest).Return(resetPasswordResponse, nil) + context.EXPECT().JSON(http.StatusOK, resetPasswordResponse) + + handler.ResetPassword(context) +} + +func (t *AuthHandlerTest) TestResetPasswordBindFailed() { + errResponse := dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.BindingRequestErrorMessage + t.bindErr.Error(), + Data: nil, + } + + controller := gomock.NewController(t.T()) + + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + handler := NewHandler(authSvc, userSvc, validator) + + context.EXPECT().Bind(t.resetPasswordRequest).Return(t.bindErr) + context.EXPECT().JSON(http.StatusBadRequest, errResponse) + + handler.ResetPassword(context) +} + +func (t *AuthHandlerTest) TestResetPasswordValidateFailed() { + errResponse := dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidRequestBodyMessage + "BadRequestError1, BadRequestError2", + Data: nil, + } + + controller := gomock.NewController(t.T()) + + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + handler := NewHandler(authSvc, userSvc, validator) + + context.EXPECT().Bind(t.resetPasswordRequest).Return(nil) + validator.EXPECT().Validate(t.resetPasswordRequest).Return(t.validateErr) + context.EXPECT().JSON(http.StatusBadRequest, errResponse) + + handler.ResetPassword(context) +} + +func (t *AuthHandlerTest) TestResetPasswordServiceError() { + resetPasswordErr := &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + + controller := gomock.NewController(t.T()) + + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + handler := NewHandler(authSvc, userSvc, validator) + + context.EXPECT().Bind(t.resetPasswordRequest).Return(nil) + validator.EXPECT().Validate(t.resetPasswordRequest).Return(nil) + authSvc.EXPECT().ResetPassword(t.resetPasswordRequest).Return(nil, resetPasswordErr) + context.EXPECT().JSON(http.StatusInternalServerError, resetPasswordErr) + + handler.ResetPassword(context) +} From 9d0efb5e6106656c245740391d338d86170ccb65 Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 17:02:57 +0700 Subject: [PATCH 010/104] feat: add reset-password route --- src/app/router/auth.router.go | 7 +++++++ src/constant/auth/auth.constant.go | 1 + src/main.go | 1 + 3 files changed, 9 insertions(+) diff --git a/src/app/router/auth.router.go b/src/app/router/auth.router.go index 0bed6e0..30802a5 100644 --- a/src/app/router/auth.router.go +++ b/src/app/router/auth.router.go @@ -8,3 +8,10 @@ func (r *FiberRouter) PostAuth(path string, h func(ctx IContext)) { return nil }) } + +func (r *FiberRouter) PutAuth(path string, h func(ctx IContext)) { + r.auth.Put(path, func(c *fiber.Ctx) error { + h(NewFiberCtx(c)) + return nil + }) +} diff --git a/src/constant/auth/auth.constant.go b/src/constant/auth/auth.constant.go index 3394890..88746e5 100644 --- a/src/constant/auth/auth.constant.go +++ b/src/constant/auth/auth.constant.go @@ -5,6 +5,7 @@ var ExcludePath = map[string]struct{}{ "POST /auth/signin": {}, "POST /auth/verify": {}, "POST /auth/forgot-password": {}, + "PUT /auth/reset-password": {}, "GET /user/:id": {}, "GET /pets": {}, "GET /adopt": {}, diff --git a/src/main.go b/src/main.go index 484d196..9f06285 100644 --- a/src/main.go +++ b/src/main.go @@ -130,6 +130,7 @@ func main() { //r.PostAuth("/me", authHandler.Validate) r.PostAuth("/refreshToken", authHandler.RefreshToken) r.PostAuth("/forgot-password", authHandler.ForgotPassword) + r.PutAuth("/reset-password", authHandler.ResetPassword) r.GetHealthCheck("", hc.HealthCheck) From bcf3a1593f7e9f91b9373ac743b9a9fed47bb6e4 Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 17:06:36 +0700 Subject: [PATCH 011/104] chore --- src/app/constant/error.constant.go | 2 +- src/app/dto/auth.dto.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/constant/error.constant.go b/src/app/constant/error.constant.go index a56c6b6..a9544cc 100644 --- a/src/app/constant/error.constant.go +++ b/src/app/constant/error.constant.go @@ -3,7 +3,7 @@ package constant const BindingRequestErrorMessage = "Binding Request Error due to:" const InvalidRequestBodyMessage = "Invalid Request Body due to:" const InvalidTokenMessage = "Invalid token" -const ForbiddenSamePasswordMessage = "The same password is forbidden " +const ForbiddenSamePasswordMessage = "The same password is forbidden" const IncorrectEmailPasswordMessage = "Incorrect Email or Password" const UnauthorizedMessage = "Unauthorized" const DuplicateEmailMessage = "Duplicate Email" diff --git a/src/app/dto/auth.dto.go b/src/app/dto/auth.dto.go index e60a30b..c13c8a0 100644 --- a/src/app/dto/auth.dto.go +++ b/src/app/dto/auth.dto.go @@ -42,7 +42,7 @@ type ForgotPasswordResponse struct { type ResetPasswordRequest struct { Token string `json:"token" validate:"required"` - Password string `json:"password" validate:"required"` + Password string `json:"password" validate:"required,gte=6,lte=30"` } type ResetPasswordResponse struct { From 999267535220c79e15e48b21caf9f565a409855d Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Mon, 15 Jan 2024 17:15:04 +0700 Subject: [PATCH 012/104] chore: update docs --- src/app/handler/auth/auth.handler.go | 12 +++++ src/docs/docs.go | 77 ++++++++++++++++++++++++++++ src/docs/swagger.json | 77 ++++++++++++++++++++++++++++ src/docs/swagger.yaml | 51 ++++++++++++++++++ 4 files changed, 217 insertions(+) diff --git a/src/app/handler/auth/auth.handler.go b/src/app/handler/auth/auth.handler.go index 94e0251..1db143d 100644 --- a/src/app/handler/auth/auth.handler.go +++ b/src/app/handler/auth/auth.handler.go @@ -231,6 +231,18 @@ func (h *Handler) ForgotPassword(c router.IContext) { c.JSON(http.StatusOK, response) } +// ResetPassword is a function to reset password +// @Summary Reset Password +// @Description Return isSuccess +// @Param request body dto.ResetPasswordRequest true "resetPassword request dto" +// @Tags auth +// @Accept json +// @Produce json +// @Success 200 {object} dto.ResetPasswordResponse +// @Failure 400 {object} dto.ResponseBadRequestErr "Forbidden the same password" +// @Failure 500 {object} dto.ResponseInternalErr "Internal service error" +// @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" +// @Router /v1/auth/reset-password [put] func (h *Handler) ResetPassword(c router.IContext) { request := &dto.ResetPasswordRequest{} err := c.Bind(request) diff --git a/src/docs/docs.go b/src/docs/docs.go index 14841e5..34f864a 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -128,6 +128,58 @@ const docTemplate = `{ } } }, + "/v1/auth/reset-password": { + "put": { + "description": "Return isSuccess", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Reset Password", + "parameters": [ + { + "description": "resetPassword request dto", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.ResetPasswordRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.ResetPasswordResponse" + } + }, + "400": { + "description": "Forbidden the same password", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, "/v1/auth/signin": { "post": { "description": "Return the credential of user including access token and refresh token", @@ -1076,6 +1128,31 @@ const docTemplate = `{ } } }, + "dto.ResetPasswordRequest": { + "type": "object", + "required": [ + "password", + "token" + ], + "properties": { + "password": { + "type": "string", + "maxLength": 30, + "minLength": 6 + }, + "token": { + "type": "string" + } + } + }, + "dto.ResetPasswordResponse": { + "type": "object", + "properties": { + "is_success": { + "type": "boolean" + } + } + }, "dto.ResponseBadRequestErr": { "type": "object", "properties": { diff --git a/src/docs/swagger.json b/src/docs/swagger.json index bffd226..a061495 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -124,6 +124,58 @@ } } }, + "/v1/auth/reset-password": { + "put": { + "description": "Return isSuccess", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Reset Password", + "parameters": [ + { + "description": "resetPassword request dto", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.ResetPasswordRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.ResetPasswordResponse" + } + }, + "400": { + "description": "Forbidden the same password", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, "/v1/auth/signin": { "post": { "description": "Return the credential of user including access token and refresh token", @@ -1072,6 +1124,31 @@ } } }, + "dto.ResetPasswordRequest": { + "type": "object", + "required": [ + "password", + "token" + ], + "properties": { + "password": { + "type": "string", + "maxLength": 30, + "minLength": 6 + }, + "token": { + "type": "string" + } + } + }, + "dto.ResetPasswordResponse": { + "type": "object", + "properties": { + "is_success": { + "type": "boolean" + } + } + }, "dto.ResponseBadRequestErr": { "type": "object", "properties": { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 363cd54..7d44ec7 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -181,6 +181,23 @@ definitions: required: - refresh_token type: object + dto.ResetPasswordRequest: + properties: + password: + maxLength: 30 + minLength: 6 + type: string + token: + type: string + required: + - password + - token + type: object + dto.ResetPasswordResponse: + properties: + is_success: + type: boolean + type: object dto.ResponseBadRequestErr: properties: data: @@ -454,6 +471,40 @@ paths: summary: Refresh token tags: - auth + /v1/auth/reset-password: + put: + consumes: + - application/json + description: Return isSuccess + parameters: + - description: resetPassword request dto + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.ResetPasswordRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.ResetPasswordResponse' + "400": + description: Forbidden the same password + schema: + $ref: '#/definitions/dto.ResponseBadRequestErr' + "500": + description: Internal service error + schema: + $ref: '#/definitions/dto.ResponseInternalErr' + "503": + description: Service is down + schema: + $ref: '#/definitions/dto.ResponseServiceDownErr' + summary: Reset Password + tags: + - auth /v1/auth/signin: post: consumes: From 3d502df135db297a9e939f303bb3f785115a3c5d Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 17 Jan 2024 00:26:32 +0700 Subject: [PATCH 013/104] feat: env config --- .env.template | 8 +++++++ src/app/router/router.go | 4 ++-- src/config/config.go | 51 +++++++++++++++++++++++----------------- 3 files changed, 40 insertions(+), 23 deletions(-) create mode 100644 .env.template diff --git a/.env.template b/.env.template new file mode 100644 index 0000000..6008f0d --- /dev/null +++ b/.env.template @@ -0,0 +1,8 @@ +APP_PORT=3001 +APP_ENV=development + +DB_URL=postgres://root:root@localhost:5432/johnjud_db + +SERVICE_AUTH=localhost:3002 +SERVICE_BACKEND=localhost:3003 +SERVICE_FILE=localhost:3004 diff --git a/src/app/router/router.go b/src/app/router/router.go index 0f55c33..9b5e92c 100644 --- a/src/app/router/router.go +++ b/src/app/router/router.go @@ -22,7 +22,7 @@ type IGuard interface { } func NewAPIv1(r *FiberRouter, conf config.App) *fiber.App { - if conf.Debug { + if conf.IsDevelopment() { r.Use(logger.New(logger.Config{Next: func(c *fiber.Ctx) bool { return c.Path() == "/v1/" }})) @@ -32,7 +32,7 @@ func NewAPIv1(r *FiberRouter, conf config.App) *fiber.App { app := fiber.New(fiber.Config{ StrictRouting: true, AppName: "JohnJud API", - EnablePrintRoutes: conf.Debug, + EnablePrintRoutes: conf.IsDevelopment(), }) app.Mount("/v1", r.App) diff --git a/src/config/config.go b/src/config/config.go index 292a849..bb7e40a 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -1,42 +1,51 @@ package config import ( - "github.com/pkg/errors" "github.com/spf13/viper" ) type App struct { - Port int `mapstructure:"port"` - Debug bool `mapstructure:"debug"` + Port int `mapstructure:"PORT"` + Env string `mapstructure:"ENV"` } type Service struct { - Auth string `mapstructure:"auth"` - Backend string `mapstructure:"backend"` - File string `mapstructure:"file"` + Auth string `mapstructure:"AUTH"` + Backend string `mapstructure:"BACKEND"` + File string `mapstructure:"FILE"` } type Config struct { - App App `mapstructure:"app"` - Service Service `mapstructure:"service"` + App App + Service Service } -func LoadConfig() (config *Config, err error) { - viper.AddConfigPath("./config") - viper.SetConfigName("config") - viper.SetConfigType("yaml") +func LoadConfig() (*Config, error) { + appConfig := App{} + LoadEnvGroup(&appConfig, "APP") - viper.AutomaticEnv() + serviceConfig := Service{} + LoadEnvGroup(&serviceConfig, "SERVICE") - err = viper.ReadInConfig() - if err != nil { - return nil, errors.Wrap(err, "error occurs while reading the config") + config := &Config{ + App: appConfig, + Service: serviceConfig, } - err = viper.Unmarshal(&config) - if err != nil { - return nil, errors.Wrap(err, "error occurs while unmarshal the config") - } + return config, nil +} - return +func (ac *App) IsDevelopment() bool { + return ac.Env == "development" +} + +func LoadEnvGroup(config interface{}, prefix string) (err error) { + cfgLdr := viper.New() + cfgLdr.SetEnvPrefix(prefix) + cfgLdr.AutomaticEnv() + cfgLdr.AllowEmptyEnv(false) + if err := cfgLdr.Unmarshal(&config); err != nil { + return err + } + return nil } From 4834b709777c9ba2340c69369aef33b57b8efcdf Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 17 Jan 2024 00:37:09 +0700 Subject: [PATCH 014/104] fix: docker compose --- .env.template | 2 - docker-compose-prod.yaml | 119 +++++++++++++++++++++++++++++++++++++++ docker-compose.yaml | 37 ++++++++++-- 3 files changed, 150 insertions(+), 8 deletions(-) create mode 100644 docker-compose-prod.yaml diff --git a/.env.template b/.env.template index 6008f0d..5e36a24 100644 --- a/.env.template +++ b/.env.template @@ -1,8 +1,6 @@ APP_PORT=3001 APP_ENV=development -DB_URL=postgres://root:root@localhost:5432/johnjud_db - SERVICE_AUTH=localhost:3002 SERVICE_BACKEND=localhost:3003 SERVICE_FILE=localhost:3004 diff --git a/docker-compose-prod.yaml b/docker-compose-prod.yaml new file mode 100644 index 0000000..2af75a7 --- /dev/null +++ b/docker-compose-prod.yaml @@ -0,0 +1,119 @@ +version: "3.9" + +services: + gateway: + container_name: johnjud-gateway + restart: unless-stopped + build: . + ports: + - 3001:3001 + environment: + - APP_PORT=3001 + - APP_ENV=development + - SERVICE_AUTH=auth:3002 + - SERVICE_BACKEND=backend:3003 + - SERVICE_FILE=file:3004 + networks: + - johnjud + local-auth: + image: ghcr.io/isd-sgcu/johnjud-auth + container_name: auth + depends_on: + - local-db + - local-cache + restart: unless-stopped + environment: + - APP_PORT=3004 + - APP_ENV=production + - APP_SECRET=secret + - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - JWT_SECRET=secret + - JWT_EXPIRES_IN=3600 + - JWT_REFRESH_TOKEN_TTL=604800 + - JWT_ISSUER=issuer + - JWT_RESET_TOKEN_TTL=900 + - REDIS_HOST=localhost + - REDIS_PORT=6379 + - REDIS_PASSWORD= + - AUTH_CLIENT_URL=http://localhost:3000 + - SENDGRID_API_KEY=api_key + - SENDGRID_NAME=johnjud + - SENDGRID_ADDRESS=johnjud@gmail.com + networks: + - johnjud-local + - database + ports: + - "3002:3002" + + local-backend: + image: ghcr.io/isd-sgcu/johnjud-backend + container_name: backend + depends_on: + - local-db + - local-cache + restart: unless-stopped + environment: + - APP_PORT=3003 + - APP_ENV=production + - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - SERVICE_FILE=file:3004 + networks: + - johnjud-local + - database + ports: + - "3003:3003" + + local-file: + image: ghcr.io/isd-sgcu/johnjud-file + container_name: file + depends_on: + - local-db + - local-cache + restart: unless-stopped + environment: + - APP_PORT=3004 + - APP_ENV=production + - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - BUCKET_ENDPOINT=BUCKET_ENDPOINT + - BUCKET_ACCESS_KEY=BUCKET_ACCESS_KEY + - BUCKET_SECRET_KEY=BUCKET_SECRET_KEY + - BUCKET_NAME=johnjud-pet-images + - BUCKET_USE_SSL=false + networks: + - johnjud-local + - database + ports: + - "3004:3004" + + local-db: + image: postgres:15.1-alpine3.17 + container_name: local-db + restart: unless-stopped + environment: + POSTGRES_USER: root + POSTGRES_PASSWORD: root + POSTGRES_DB: johnjud_db + networks: + - database + volumes: + - ./volumes/postgres:/var/lib/postgresql/data + ports: + - "5432:5432" + + local-cache: + image: redis:7.2.3-alpine + container_name: local-cache + restart: unless-stopped + environment: + REDIS_HOST: localhost + ALLOW_EMPTY_PASSWORD: "yes" + networks: + - database + ports: + - "6379:6379" + +networks: + johnjud-local: + name: johnjud-local + database: + name: database diff --git a/docker-compose.yaml b/docker-compose.yaml index d911259..8f046c7 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -8,11 +8,26 @@ services: - local-db - local-cache restart: unless-stopped + environment: + - APP_PORT=3004 + - APP_ENV=development + - APP_SECRET=secret + - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - JWT_SECRET=secret + - JWT_EXPIRES_IN=3600 + - JWT_REFRESH_TOKEN_TTL=604800 + - JWT_ISSUER=issuer + - JWT_RESET_TOKEN_TTL=900 + - REDIS_HOST=localhost + - REDIS_PORT=6379 + - REDIS_PASSWORD= + - AUTH_CLIENT_URL=http://localhost:3000 + - SENDGRID_API_KEY=api_key + - SENDGRID_NAME=johnjud + - SENDGRID_ADDRESS=johnjud@gmail.com networks: - johnjud-local - database - volumes: - - ./config/auth:/app/config ports: - "3002:3002" @@ -23,11 +38,14 @@ services: - local-db - local-cache restart: unless-stopped + environment: + - APP_PORT=3003 + - APP_ENV=development + - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - SERVICE_FILE=file:3004 networks: - johnjud-local - database - volumes: - - ./config/backend:/app/config ports: - "3003:3003" @@ -38,11 +56,18 @@ services: - local-db - local-cache restart: unless-stopped + environment: + - APP_PORT=3004 + - APP_ENV=production + - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - BUCKET_ENDPOINT=BUCKET_ENDPOINT + - BUCKET_ACCESS_KEY=BUCKET_ACCESS_KEY + - BUCKET_SECRET_KEY=BUCKET_SECRET_KEY + - BUCKET_NAME=johnjud-pet-images + - BUCKET_USE_SSL=false networks: - johnjud-local - database - volumes: - - ./config/file:/app/config ports: - "3004:3004" From 1025784060a711d787a289d683456bc879494270 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 17 Jan 2024 01:06:01 +0700 Subject: [PATCH 015/104] feat: load env bash --- Makefile | 2 +- go.mod | 3 +-- go.sum | 9 ++------- tools/export-env.sh | 16 ++++++++++++++++ 4 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 tools/export-env.sh diff --git a/Makefile b/Makefile index e54dade..9225211 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ test: go tool cover -html=coverage.out -o coverage.html server: - go run ./src/. + . ./tools/export-env.sh ; go run ./src/. mock-gen: mockgen -source ./src/pkg/service/auth/auth.service.go -destination ./src/mocks/service/auth/auth.mock.go diff --git a/go.mod b/go.mod index c57ecda..806be65 100644 --- a/go.mod +++ b/go.mod @@ -13,9 +13,8 @@ require ( github.com/golang/mock v1.6.0 github.com/google/uuid v1.5.0 github.com/isd-sgcu/johnjud-go-proto v0.5.0 - github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.31.0 - github.com/spf13/viper v1.18.2 + github.com/spf13/viper v1.18.1 github.com/stretchr/testify v1.8.4 github.com/swaggo/swag v1.16.2 google.golang.org/grpc v1.60.1 diff --git a/go.sum b/go.sum index 67bd7d5..8f1963c 100644 --- a/go.sum +++ b/go.sum @@ -66,10 +66,6 @@ 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.2.2 h1:TOAmbwy/I+8/J5LPZH0ZN7lSLczBiZe1fs88gH8XrhY= -github.com/isd-sgcu/johnjud-go-proto v0.2.2/go.mod h1:1OK6aiCgtXQiLhxp0r6iLEejYIRpckWQZDrCZ9Trbo4= -github.com/isd-sgcu/johnjud-go-proto v0.3.1 h1:WyWfzl+5nWOw3AmINtcTfojg4CJh8ZRNbZC6qA//OXU= -github.com/isd-sgcu/johnjud-go-proto v0.3.1/go.mod h1:1OK6aiCgtXQiLhxp0r6iLEejYIRpckWQZDrCZ9Trbo4= github.com/isd-sgcu/johnjud-go-proto v0.5.0 h1:GgqRzWjya5p1yhfU/kpX8i4WL42+qT2TkyXZmssH6B4= github.com/isd-sgcu/johnjud-go-proto v0.5.0/go.mod h1:1OK6aiCgtXQiLhxp0r6iLEejYIRpckWQZDrCZ9Trbo4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -112,7 +108,6 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9 github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= @@ -141,8 +136,8 @@ github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.18.1 h1:rmuU42rScKWlhhJDyXZRKJQHXFX02chSVW1IvkPGiVM= +github.com/spf13/viper v1.18.1/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= 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 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= diff --git a/tools/export-env.sh b/tools/export-env.sh new file mode 100644 index 0000000..39688ee --- /dev/null +++ b/tools/export-env.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +## Usage: +## . ./export-env.sh ; $COMMAND +## . ./export-env.sh ; echo ${MINIENTREGA_FECHALIMITE} + +unamestr=$(uname) +if [ "$unamestr" = 'Linux' ]; then + + export $(grep -v '^#' .env | xargs -d '\n') + +elif [ "$unamestr" = 'FreeBSD' ] || [ "$unamestr" = 'Darwin' ]; then + + export $(grep -v '^#' .env | xargs -0) + +fi \ No newline at end of file From 239c92edd2bbbf5a626deb8ab59f052f51f8bae4 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 17 Jan 2024 01:06:29 +0700 Subject: [PATCH 016/104] fix: compose --- docker-compose.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 8f046c7..f106f8a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -12,7 +12,7 @@ services: - APP_PORT=3004 - APP_ENV=development - APP_SECRET=secret - - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - DB_URL=postgres://root:root@local-db:5432/johnjud_db - JWT_SECRET=secret - JWT_EXPIRES_IN=3600 - JWT_REFRESH_TOKEN_TTL=604800 @@ -41,7 +41,7 @@ services: environment: - APP_PORT=3003 - APP_ENV=development - - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - DB_URL=postgres://root:root@local-db:5432/johnjud_db - SERVICE_FILE=file:3004 networks: - johnjud-local @@ -59,7 +59,7 @@ services: environment: - APP_PORT=3004 - APP_ENV=production - - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - DB_URL=postgres://root:root@local-db:5432/johnjud_db - BUCKET_ENDPOINT=BUCKET_ENDPOINT - BUCKET_ACCESS_KEY=BUCKET_ACCESS_KEY - BUCKET_SECRET_KEY=BUCKET_SECRET_KEY From ca32b8486832da9f9d2062db8e692ce881030d14 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 17 Jan 2024 01:06:47 +0700 Subject: [PATCH 017/104] fix: config loader --- src/config/config.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/config/config.go b/src/config/config.go index bb7e40a..b7903ff 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -21,11 +21,23 @@ type Config struct { } func LoadConfig() (*Config, error) { + appCfgLdr := viper.New() + appCfgLdr.SetEnvPrefix("APP") + appCfgLdr.AutomaticEnv() + appCfgLdr.AllowEmptyEnv(false) appConfig := App{} - LoadEnvGroup(&appConfig, "APP") + if err := appCfgLdr.Unmarshal(&appConfig); err != nil { + return nil, err + } + serviceCfgLdr := viper.New() + serviceCfgLdr.SetEnvPrefix("SERVICE") + serviceCfgLdr.AutomaticEnv() + serviceCfgLdr.AllowEmptyEnv(false) serviceConfig := Service{} - LoadEnvGroup(&serviceConfig, "SERVICE") + if err := serviceCfgLdr.Unmarshal(&serviceConfig); err != nil { + return nil, err + } config := &Config{ App: appConfig, @@ -38,14 +50,3 @@ func LoadConfig() (*Config, error) { func (ac *App) IsDevelopment() bool { return ac.Env == "development" } - -func LoadEnvGroup(config interface{}, prefix string) (err error) { - cfgLdr := viper.New() - cfgLdr.SetEnvPrefix(prefix) - cfgLdr.AutomaticEnv() - cfgLdr.AllowEmptyEnv(false) - if err := cfgLdr.Unmarshal(&config); err != nil { - return err - } - return nil -} From c3af07bc2e2c41a94ed01d2c82fcc6c08f36153d Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 17 Jan 2024 01:07:46 +0700 Subject: [PATCH 018/104] fix: prod compose --- docker-compose-prod.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose-prod.yaml b/docker-compose-prod.yaml index 2af75a7..1d28060 100644 --- a/docker-compose-prod.yaml +++ b/docker-compose-prod.yaml @@ -14,7 +14,7 @@ services: - SERVICE_BACKEND=backend:3003 - SERVICE_FILE=file:3004 networks: - - johnjud + - johnjud-local local-auth: image: ghcr.io/isd-sgcu/johnjud-auth container_name: auth @@ -26,7 +26,7 @@ services: - APP_PORT=3004 - APP_ENV=production - APP_SECRET=secret - - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - DB_URL=postgres://root:root@local-db:5432/johnjud_db - JWT_SECRET=secret - JWT_EXPIRES_IN=3600 - JWT_REFRESH_TOKEN_TTL=604800 @@ -55,7 +55,7 @@ services: environment: - APP_PORT=3003 - APP_ENV=production - - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - DB_URL=postgres://root:root@local-db:5432/johnjud_db - SERVICE_FILE=file:3004 networks: - johnjud-local @@ -73,7 +73,7 @@ services: environment: - APP_PORT=3004 - APP_ENV=production - - DB_URL=postgres://root:root@johnjud-local-db:5432/johnjud_db + - DB_URL=postgres://root:root@local-db:5432/johnjud_db - BUCKET_ENDPOINT=BUCKET_ENDPOINT - BUCKET_ACCESS_KEY=BUCKET_ACCESS_KEY - BUCKET_SECRET_KEY=BUCKET_SECRET_KEY From 794fe39a4d5a6599a11c874ffbd62c9c8b91289c Mon Sep 17 00:00:00 2001 From: Nitiwat-owen <77772598+Nitiwat-owen@users.noreply.github.com> Date: Wed, 17 Jan 2024 09:29:05 +0700 Subject: [PATCH 019/104] fix: remove unused code --- src/pkg/service/auth/auth.service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkg/service/auth/auth.service.go b/src/pkg/service/auth/auth.service.go index 11f3375..0bd4875 100644 --- a/src/pkg/service/auth/auth.service.go +++ b/src/pkg/service/auth/auth.service.go @@ -10,6 +10,6 @@ type Service interface { SignOut(string) (*dto.SignOutResponse, *dto.ResponseErr) Validate(string) (*dto.TokenPayloadAuth, *dto.ResponseErr) RefreshToken(*dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) - ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) + ForgotPassword(*dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) ResetPassword(*dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) } From d27bc4758406e55c83e2237cc240f4c3a3068d28 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 17 Jan 2024 19:54:52 +0700 Subject: [PATCH 020/104] chore: remove config.yaml --- config/auth/config.example.yaml | 23 ----------------------- config/backend/config.example.yaml | 13 ------------- config/config.example.yaml | 12 ------------ config/file/config.example.yaml | 14 -------------- 4 files changed, 62 deletions(-) delete mode 100644 config/auth/config.example.yaml delete mode 100644 config/backend/config.example.yaml delete mode 100644 config/config.example.yaml delete mode 100644 config/file/config.example.yaml diff --git a/config/auth/config.example.yaml b/config/auth/config.example.yaml deleted file mode 100644 index 50d989a..0000000 --- a/config/auth/config.example.yaml +++ /dev/null @@ -1,23 +0,0 @@ -app: - port: 3002 - debug: true - secret: - -database: - host: local-db - port: 5432 - name: johnjud_db - username: root - password: root - -jwt: - secret: - expires_in: 3600 - refresh_token_ttl: 604800 - issuer: - -redis: - host: local-cache - port: 6379 - password: "" - dbnum: 0 \ No newline at end of file diff --git a/config/backend/config.example.yaml b/config/backend/config.example.yaml deleted file mode 100644 index e39ad3a..0000000 --- a/config/backend/config.example.yaml +++ /dev/null @@ -1,13 +0,0 @@ -app: - port: 3003 - debug: true - -database: - host: local-db - port: 5432 - name: johnjud_db - username: root - password: root - -service: - file: file:3004 \ No newline at end of file diff --git a/config/config.example.yaml b/config/config.example.yaml deleted file mode 100644 index 1a12b6b..0000000 --- a/config/config.example.yaml +++ /dev/null @@ -1,12 +0,0 @@ -app: - port: 3001 - debug: true - -service: - auth: localhost:3002 - backend: localhost:3003 - file: localhost:3004 - # Production, when gateway in a container in same network - # auth: auth:3002 - # backend: backend:3003 - # file: file:3004 \ No newline at end of file diff --git a/config/file/config.example.yaml b/config/file/config.example.yaml deleted file mode 100644 index f1ecd10..0000000 --- a/config/file/config.example.yaml +++ /dev/null @@ -1,14 +0,0 @@ -app: - port: 3004 - debug: true - -database: - host: local-db - port: 5432 - name: johnjud_db - username: root - password: root - -s3: - bucket_name: - region: \ No newline at end of file From e454e212a38615a7d1fbcf3355458605b46b5a91 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sun, 21 Jan 2024 14:51:45 +0700 Subject: [PATCH 021/104] fix: swagger docs --- src/app/router/router.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/router/router.go b/src/app/router/router.go index 9b5e92c..a89ef8e 100644 --- a/src/app/router/router.go +++ b/src/app/router/router.go @@ -6,6 +6,7 @@ import ( "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/isd-sgcu/johnjud-gateway/src/config" + _ "github.com/isd-sgcu/johnjud-gateway/src/docs" ) type FiberRouter struct { From d780a0a8e5346a76dca71cbe23c474be3a17b583 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sun, 21 Jan 2024 15:29:01 +0700 Subject: [PATCH 022/104] feat: image docs --- src/app/handler/image/image.handler.go | 79 ++++++++------------------ src/app/handler/pet/pet.handler.go | 2 +- src/docs/markdown/image.md | 2 + src/docs/markdown/pet.md | 2 + src/docs/markdown/user.md | 2 + src/main.go | 1 - 6 files changed, 30 insertions(+), 58 deletions(-) create mode 100644 src/docs/markdown/image.md create mode 100644 src/docs/markdown/pet.md create mode 100644 src/docs/markdown/user.md diff --git a/src/app/handler/image/image.handler.go b/src/app/handler/image/image.handler.go index 143fc9e..483451b 100644 --- a/src/app/handler/image/image.handler.go +++ b/src/app/handler/image/image.handler.go @@ -20,27 +20,18 @@ func NewHandler(service imageSvc.Service, validate validator.IDtoValidator) *Han return &Handler{service, validate} } -func (h *Handler) FindByPetId(c *router.FiberCtx) { - id, err := c.ID() - if err != nil { - c.JSON(http.StatusBadRequest, dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InvalidIDMessage, - Data: nil, - }) - return - } - - response, respErr := h.service.FindByPetId(id) - if respErr != nil { - c.JSON(respErr.StatusCode, respErr) - return - } - - c.JSON(http.StatusOK, response) - return -} - +// Upload is a function for uploading image to bucket +// @Summary Upload image +// @Description Returns the data of image. If updating pet, add petId. If creating pet, petId is not specified, but keep the imageId. +// @Param image body dto.UploadImageRequest true "upload image request dto" +// @Tags image +// @Accept json +// @Produce json +// @Success 201 {object} dto.ImageResponse +// @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/images/ [post] func (h *Handler) Upload(c *router.FiberCtx) { request := &dto.UploadImageRequest{} err := c.Bind(request) @@ -76,6 +67,17 @@ func (h *Handler) Upload(c *router.FiberCtx) { return } +// Delete is a function for deleting image from bucket +// @Summary Delete image +// @Description Returns status of deleting image +// @Param id path string true "image id" +// @Tags image +// @Accept json +// @Produce json +// @Success 200 {object} dto.DeleteResponse +// @Failure 500 {object} dto.ResponseInternalErr "Internal service error" +// @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" +// @Router /v1/images/{id} [delete] func (h *Handler) Delete(c *router.FiberCtx) { id, err := c.ID() if err != nil { @@ -96,38 +98,3 @@ func (h *Handler) Delete(c *router.FiberCtx) { c.JSON(http.StatusOK, res.Success) return } - -func (h *Handler) AssignPet(c *router.FiberCtx) { - request := &dto.AssignPetRequest{} - 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 - } - - response, respErr := h.service.AssignPet(request) - if respErr != nil { - c.JSON(respErr.StatusCode, respErr) - return - } - - c.JSON(http.StatusOK, response) - return -} diff --git a/src/app/handler/pet/pet.handler.go b/src/app/handler/pet/pet.handler.go index b9689c8..dfce616 100644 --- a/src/app/handler/pet/pet.handler.go +++ b/src/app/handler/pet/pet.handler.go @@ -259,7 +259,7 @@ func (h *Handler) ChangeView(c router.IContext) { // @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/ [delete] +// @Router /v1/pets/{id} [delete] func (h *Handler) Delete(c router.IContext) { id, err := c.Param("id") if err != nil { diff --git a/src/docs/markdown/image.md b/src/docs/markdown/image.md new file mode 100644 index 0000000..33ecf3c --- /dev/null +++ b/src/docs/markdown/image.md @@ -0,0 +1,2 @@ +# Image Tag API Documentation +**Image** functions goes here \ No newline at end of file diff --git a/src/docs/markdown/pet.md b/src/docs/markdown/pet.md new file mode 100644 index 0000000..a3348c3 --- /dev/null +++ b/src/docs/markdown/pet.md @@ -0,0 +1,2 @@ +# Pet Tag API Documentation +**Pet** functions goes here \ No newline at end of file diff --git a/src/docs/markdown/user.md b/src/docs/markdown/user.md new file mode 100644 index 0000000..18f1710 --- /dev/null +++ b/src/docs/markdown/user.md @@ -0,0 +1,2 @@ +# User Tag API Documentation +**User** functions goes here \ No newline at end of file diff --git a/src/main.go b/src/main.go index 9f06285..8c8fcb4 100644 --- a/src/main.go +++ b/src/main.go @@ -148,7 +148,6 @@ func main() { r.PostImage("/", imageHandler.Upload) r.DeleteImage("/:id", imageHandler.Delete) - r.PostImage("/assign", imageHandler.AssignPet) v1 := router.NewAPIv1(r, conf.App) From 01aa36d0417e09f8d12686c2dd93bc4135da5faa Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sun, 21 Jan 2024 15:50:06 +0700 Subject: [PATCH 023/104] chore: gen docs --- src/docs/docs.go | 160 ++++++++++++++++++++++++++++++++++++------ src/docs/swagger.json | 160 ++++++++++++++++++++++++++++++++++++------ src/docs/swagger.yaml | 99 +++++++++++++++++++++++--- 3 files changed, 367 insertions(+), 52 deletions(-) diff --git a/src/docs/docs.go b/src/docs/docs.go index 34f864a..2c61c78 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -337,9 +337,9 @@ const docTemplate = `{ } } }, - "/v1/pets/": { - "get": { - "description": "Returns the data of pets if successful", + "/v1/images/": { + "post": { + "description": "Returns the data of image. If updating pet, add petId. If creating pet, petId is not specified, but keep the imageId.", "consumes": [ "application/json" ], @@ -347,17 +347,31 @@ const docTemplate = `{ "application/json" ], "tags": [ - "pet" + "image" + ], + "summary": "Upload image", + "parameters": [ + { + "description": "upload image request dto", + "name": "image", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UploadImageRequest" + } + } ], - "summary": "finds all pets", "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/dto.PetResponse" - } + "$ref": "#/definitions/dto.ImageResponse" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" } }, "500": { @@ -373,9 +387,11 @@ const docTemplate = `{ } } } - }, + } + }, + "/v1/images/{id}": { "delete": { - "description": "Returns successful status if pet is successfully deleted", + "description": "Returns status of deleting image", "consumes": [ "application/json" ], @@ -383,29 +399,61 @@ const docTemplate = `{ "application/json" ], "tags": [ - "pet" + "image" ], - "summary": "deletes pet", + "summary": "Delete image", "parameters": [ { "type": "string", - "description": "pet id", + "description": "image id", "name": "id", "in": "path", "required": true } ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "schema": { "$ref": "#/definitions/dto.DeleteResponse" } }, - "400": { - "description": "Invalid request body", + "500": { + "description": "Internal service error", "schema": { - "$ref": "#/definitions/dto.ResponseBadRequestErr" + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, + "/v1/pets/": { + "get": { + "description": "Returns the data of pets if successful", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pet" + ], + "summary": "finds all pets", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.PetResponse" + } } }, "500": { @@ -580,6 +628,54 @@ const docTemplate = `{ } } } + }, + "delete": { + "description": "Returns successful status if pet is successfully deleted", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pet" + ], + "summary": "deletes pet", + "parameters": [ + { + "type": "string", + "description": "pet id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.DeleteResponse" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } } }, "/v1/pets/{id}/adopt": { @@ -1393,6 +1489,28 @@ const docTemplate = `{ } } }, + "dto.UploadImageRequest": { + "type": "object", + "required": [ + "data", + "filename", + "pet_id" + ], + "properties": { + "data": { + "type": "array", + "items": { + "type": "integer" + } + }, + "filename": { + "type": "string" + }, + "pet_id": { + "type": "string" + } + } + }, "dto.User": { "type": "object", "properties": { diff --git a/src/docs/swagger.json b/src/docs/swagger.json index a061495..f310e8a 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -333,9 +333,9 @@ } } }, - "/v1/pets/": { - "get": { - "description": "Returns the data of pets if successful", + "/v1/images/": { + "post": { + "description": "Returns the data of image. If updating pet, add petId. If creating pet, petId is not specified, but keep the imageId.", "consumes": [ "application/json" ], @@ -343,17 +343,31 @@ "application/json" ], "tags": [ - "pet" + "image" + ], + "summary": "Upload image", + "parameters": [ + { + "description": "upload image request dto", + "name": "image", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UploadImageRequest" + } + } ], - "summary": "finds all pets", "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/dto.PetResponse" - } + "$ref": "#/definitions/dto.ImageResponse" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" } }, "500": { @@ -369,9 +383,11 @@ } } } - }, + } + }, + "/v1/images/{id}": { "delete": { - "description": "Returns successful status if pet is successfully deleted", + "description": "Returns status of deleting image", "consumes": [ "application/json" ], @@ -379,29 +395,61 @@ "application/json" ], "tags": [ - "pet" + "image" ], - "summary": "deletes pet", + "summary": "Delete image", "parameters": [ { "type": "string", - "description": "pet id", + "description": "image id", "name": "id", "in": "path", "required": true } ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "schema": { "$ref": "#/definitions/dto.DeleteResponse" } }, - "400": { - "description": "Invalid request body", + "500": { + "description": "Internal service error", "schema": { - "$ref": "#/definitions/dto.ResponseBadRequestErr" + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, + "/v1/pets/": { + "get": { + "description": "Returns the data of pets if successful", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pet" + ], + "summary": "finds all pets", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.PetResponse" + } } }, "500": { @@ -576,6 +624,54 @@ } } } + }, + "delete": { + "description": "Returns successful status if pet is successfully deleted", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pet" + ], + "summary": "deletes pet", + "parameters": [ + { + "type": "string", + "description": "pet id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.DeleteResponse" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } } }, "/v1/pets/{id}/adopt": { @@ -1389,6 +1485,28 @@ } } }, + "dto.UploadImageRequest": { + "type": "object", + "required": [ + "data", + "filename", + "pet_id" + ], + "properties": { + "data": { + "type": "array", + "items": { + "type": "integer" + } + }, + "filename": { + "type": "string" + }, + "pet_id": { + "type": "string" + } + } + }, "dto.User": { "type": "object", "properties": { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 7d44ec7..19702bb 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -364,6 +364,21 @@ definitions: - lastname - password type: object + dto.UploadImageRequest: + properties: + data: + items: + type: integer + type: array + filename: + type: string + pet_id: + type: string + required: + - data + - filename + - pet_id + type: object dto.User: properties: email: @@ -609,24 +624,26 @@ paths: summary: Signup user tags: - auth - /v1/pets/: - delete: + /v1/images/: + post: consumes: - application/json - description: Returns successful status if pet is successfully deleted + description: Returns the data of image. If updating pet, add petId. If creating + pet, petId is not specified, but keep the imageId. parameters: - - description: pet id - in: path - name: id + - description: upload image request dto + in: body + name: image required: true - type: string + schema: + $ref: '#/definitions/dto.UploadImageRequest' produces: - application/json responses: "201": description: Created schema: - $ref: '#/definitions/dto.DeleteResponse' + $ref: '#/definitions/dto.ImageResponse' "400": description: Invalid request body schema: @@ -639,9 +656,39 @@ paths: description: Service is down schema: $ref: '#/definitions/dto.ResponseServiceDownErr' - summary: deletes pet + summary: Upload image tags: - - pet + - image + /v1/images/{id}: + delete: + consumes: + - application/json + description: Returns status of deleting image + parameters: + - description: image id + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.DeleteResponse' + "500": + description: Internal service error + schema: + $ref: '#/definitions/dto.ResponseInternalErr' + "503": + description: Service is down + schema: + $ref: '#/definitions/dto.ResponseServiceDownErr' + summary: Delete image + tags: + - image + /v1/pets/: get: consumes: - application/json @@ -667,6 +714,38 @@ paths: tags: - pet /v1/pets/{id}: + delete: + consumes: + - application/json + description: Returns successful status if pet is successfully deleted + parameters: + - description: pet id + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/dto.DeleteResponse' + "400": + description: Invalid request body + schema: + $ref: '#/definitions/dto.ResponseBadRequestErr' + "500": + description: Internal service error + schema: + $ref: '#/definitions/dto.ResponseInternalErr' + "503": + description: Service is down + schema: + $ref: '#/definitions/dto.ResponseServiceDownErr' + summary: deletes pet + tags: + - pet get: consumes: - application/json From 720712e123f4644d7095e16e949ce5ff00a7b601 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sun, 21 Jan 2024 16:00:56 +0700 Subject: [PATCH 024/104] feat: docs add tags --- src/main.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main.go b/src/main.go index 8c8fcb4..2db9238 100644 --- a/src/main.go +++ b/src/main.go @@ -53,6 +53,15 @@ import ( // @tag.name auth // @tag.description.markdown +// @tag.name image +// @tag.description.markdown + +// @tag.name pet +// @tag.description.markdown + +// @tag.name user +// @tag.description.markdown + func main() { conf, err := config.LoadConfig() if err != nil { From 65e030c96dfb5f7c10070a6f3f00cdc43e570a74 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sun, 21 Jan 2024 16:02:42 +0700 Subject: [PATCH 025/104] chore: gen docs --- src/docs/docs.go | 12 ++++++++++++ src/docs/swagger.json | 12 ++++++++++++ src/docs/swagger.yaml | 12 ++++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/docs/docs.go b/src/docs/docs.go index 2c61c78..a5c6c94 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -1563,6 +1563,18 @@ const docTemplate = `{ { "description": "# Auth Tag API Documentation\n**Auth** functions goes here", "name": "auth" + }, + { + "description": "# Image Tag API Documentation\n**Image** functions goes here", + "name": "image" + }, + { + "description": "# Pet Tag API Documentation\n**Pet** functions goes here", + "name": "pet" + }, + { + "description": "# User Tag API Documentation\n**User** functions goes here", + "name": "user" } ] }` diff --git a/src/docs/swagger.json b/src/docs/swagger.json index f310e8a..f8bedf5 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -1559,6 +1559,18 @@ { "description": "# Auth Tag API Documentation\n**Auth** functions goes here", "name": "auth" + }, + { + "description": "# Image Tag API Documentation\n**Image** functions goes here", + "name": "image" + }, + { + "description": "# Pet Tag API Documentation\n**Pet** functions goes here", + "name": "pet" + }, + { + "description": "# User Tag API Documentation\n**User** functions goes here", + "name": "user" } ] } \ No newline at end of file diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 19702bb..844a452 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -1042,3 +1042,15 @@ tags: # Auth Tag API Documentation **Auth** functions goes here name: auth +- description: |- + # Image Tag API Documentation + **Image** functions goes here + name: image +- description: |- + # Pet Tag API Documentation + **Pet** functions goes here + name: pet +- description: |- + # User Tag API Documentation + **User** functions goes here + name: user From 9263ab8b43283ad27ba0cda1e5dfea93803e1157 Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:21:45 +0700 Subject: [PATCH 026/104] chore: update proto --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 806be65..27865cd 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/gofiber/fiber/v2 v2.52.0 github.com/golang/mock v1.6.0 github.com/google/uuid v1.5.0 - github.com/isd-sgcu/johnjud-go-proto v0.5.0 + github.com/isd-sgcu/johnjud-go-proto v0.5.2 github.com/rs/zerolog v1.31.0 github.com/spf13/viper v1.18.1 github.com/stretchr/testify v1.8.4 diff --git a/go.sum b/go.sum index 8f1963c..62603e0 100644 --- a/go.sum +++ b/go.sum @@ -68,6 +68,8 @@ 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.5.0 h1:GgqRzWjya5p1yhfU/kpX8i4WL42+qT2TkyXZmssH6B4= github.com/isd-sgcu/johnjud-go-proto v0.5.0/go.mod h1:1OK6aiCgtXQiLhxp0r6iLEejYIRpckWQZDrCZ9Trbo4= +github.com/isd-sgcu/johnjud-go-proto v0.5.2 h1:LWhi7zaEeEOJ60nyCxxMeAr7Bvl9stWvQbaw0RWz/Cs= +github.com/isd-sgcu/johnjud-go-proto v0.5.2/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= From 18d52eb15635de8191e6daf4d5c84d8c6731ce33 Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:21:51 +0700 Subject: [PATCH 027/104] fix: pet dto --- src/app/dto/pet.dto.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/dto/pet.dto.go b/src/app/dto/pet.dto.go index 6455129..970b38a 100644 --- a/src/app/dto/pet.dto.go +++ b/src/app/dto/pet.dto.go @@ -32,6 +32,8 @@ type FindAllPetRequest struct { Color string `json:"color"` Pattern string `json:"pattern"` Age string `json:"age"` + MinAge int `json:"min_age"` + MaxAge int `json:"max_age"` Origin string `json:"origin"` PageSize int `json:"page_size"` Page int `json:"page"` From 77e122536f0b06afd275b008e53361c7749d2689 Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:32:48 +0700 Subject: [PATCH 028/104] fix: pet utils --- src/app/utils/pet/pet.utils.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/app/utils/pet/pet.utils.go b/src/app/utils/pet/pet.utils.go index c768f29..55c0ff1 100644 --- a/src/app/utils/pet/pet.utils.go +++ b/src/app/utils/pet/pet.utils.go @@ -147,10 +147,11 @@ func FindAllDtoToProto(in *dto.FindAllPetRequest) *petproto.FindAllPetRequest { Gender: in.Gender, Color: in.Color, Pattern: in.Pattern, - Age: in.Age, Origin: in.Origin, PageSize: int32(in.PageSize), Page: int32(in.Page), + MaxAge: int32(in.MaxAge), + MinAge: int32(in.MinAge), } } @@ -170,7 +171,8 @@ func QueriesToFindAllDto(queries map[string]string) (*dto.FindAllPetRequest, err Gender: "", Color: "", Pattern: "", - Age: "", + MinAge: 0, + MaxAge: 0, Origin: "", PageSize: 0, Page: 0, @@ -188,8 +190,18 @@ func QueriesToFindAllDto(queries map[string]string) (*dto.FindAllPetRequest, err request.Color = v case "pattern": request.Pattern = v - case "age": - request.Age = v + case "minAge": + minAge, err := strconv.Atoi(v) + if err != nil { + return nil, errors.New("error parsing minAge") + } + request.MinAge = minAge + case "maxAge": + maxAge, err := strconv.Atoi(v) + if err != nil { + return nil, errors.New("error parsing maxAge") + } + request.MaxAge = maxAge case "origin": request.Origin = v case "pageSize": From e7e85522c2076fcb23b01fd34000ee45b0efc5b5 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 24 Jan 2024 22:00:37 +0700 Subject: [PATCH 029/104] temp: disable admin paths --- src/constant/auth/auth.constant.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/constant/auth/auth.constant.go b/src/constant/auth/auth.constant.go index 88746e5..733f5ae 100644 --- a/src/constant/auth/auth.constant.go +++ b/src/constant/auth/auth.constant.go @@ -12,15 +12,15 @@ var ExcludePath = map[string]struct{}{ } var AdminPath = map[string]struct{}{ - "DELETE /user/:id": {}, - "POST /pets": {}, - "PUT /pets/:id": {}, - "PUT /pets/:id/visible": {}, - "DELETE /pets/:id": {}, - "POST /images/assign/:pet_id": {}, - "DELETE /images/:id": {}, - "POST /images/": {}, - "GET /images/:id": {}, + // "DELETE /user/:id": {}, + // "POST /pets": {}, + // "PUT /pets/:id": {}, + // "PUT /pets/:id/visible": {}, + // "DELETE /pets/:id": {}, + // "POST /images/assign/:pet_id": {}, + // "DELETE /images/:id": {}, + // "POST /images/": {}, + // "GET /images/:id": {}, } var VersionList = map[string]struct{}{ From 4a72dbf0c169e4b9e38469b5fa0eaca9407eaac8 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 24 Jan 2024 22:41:07 +0700 Subject: [PATCH 030/104] fix: docker compose redis/auth --- docker-compose-prod.yaml | 4 ++-- docker-compose.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose-prod.yaml b/docker-compose-prod.yaml index 1d28060..a913564 100644 --- a/docker-compose-prod.yaml +++ b/docker-compose-prod.yaml @@ -23,7 +23,7 @@ services: - local-cache restart: unless-stopped environment: - - APP_PORT=3004 + - APP_PORT=3002 - APP_ENV=production - APP_SECRET=secret - DB_URL=postgres://root:root@local-db:5432/johnjud_db @@ -32,7 +32,7 @@ services: - JWT_REFRESH_TOKEN_TTL=604800 - JWT_ISSUER=issuer - JWT_RESET_TOKEN_TTL=900 - - REDIS_HOST=localhost + - REDIS_HOST=local-cache - REDIS_PORT=6379 - REDIS_PASSWORD= - AUTH_CLIENT_URL=http://localhost:3000 diff --git a/docker-compose.yaml b/docker-compose.yaml index f106f8a..07eaa40 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -9,7 +9,7 @@ services: - local-cache restart: unless-stopped environment: - - APP_PORT=3004 + - APP_PORT=3002 - APP_ENV=development - APP_SECRET=secret - DB_URL=postgres://root:root@local-db:5432/johnjud_db @@ -18,7 +18,7 @@ services: - JWT_REFRESH_TOKEN_TTL=604800 - JWT_ISSUER=issuer - JWT_RESET_TOKEN_TTL=900 - - REDIS_HOST=localhost + - REDIS_HOST=local-cache - REDIS_PORT=6379 - REDIS_PASSWORD= - AUTH_CLIENT_URL=http://localhost:3000 From 9cad6c2d3f4e7803f418ea82e94e40bac9f2e9f4 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Mon, 29 Jan 2024 22:44:10 +0700 Subject: [PATCH 031/104] fix: docker file --- docker-compose-prod.yaml | 4 ++-- docker-compose.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose-prod.yaml b/docker-compose-prod.yaml index a913564..6c2c196 100644 --- a/docker-compose-prod.yaml +++ b/docker-compose-prod.yaml @@ -74,11 +74,11 @@ services: - APP_PORT=3004 - APP_ENV=production - DB_URL=postgres://root:root@local-db:5432/johnjud_db - - BUCKET_ENDPOINT=BUCKET_ENDPOINT + - BUCKET_ENDPOINT=minio-api.isd.sgcu.in.th - BUCKET_ACCESS_KEY=BUCKET_ACCESS_KEY - BUCKET_SECRET_KEY=BUCKET_SECRET_KEY - BUCKET_NAME=johnjud-pet-images - - BUCKET_USE_SSL=false + - BUCKET_USE_SSL=true networks: - johnjud-local - database diff --git a/docker-compose.yaml b/docker-compose.yaml index 07eaa40..54d0f68 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -60,11 +60,11 @@ services: - APP_PORT=3004 - APP_ENV=production - DB_URL=postgres://root:root@local-db:5432/johnjud_db - - BUCKET_ENDPOINT=BUCKET_ENDPOINT + - BUCKET_ENDPOINT=minio-api.isd.sgcu.in.th - BUCKET_ACCESS_KEY=BUCKET_ACCESS_KEY - BUCKET_SECRET_KEY=BUCKET_SECRET_KEY - BUCKET_NAME=johnjud-pet-images - - BUCKET_USE_SSL=false + - BUCKET_USE_SSL=true networks: - johnjud-local - database From aee0830a6328f086300f8b32707e3082ab800eb0 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Mon, 29 Jan 2024 22:52:10 +0700 Subject: [PATCH 032/104] fix: image upload remove / --- src/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.go b/src/main.go index 2db9238..b2517d4 100644 --- a/src/main.go +++ b/src/main.go @@ -155,7 +155,7 @@ func main() { r.PostLike("", likeHandler.Create) r.DeleteLike("/:id", likeHandler.Delete) - r.PostImage("/", imageHandler.Upload) + r.PostImage("", imageHandler.Upload) r.DeleteImage("/:id", imageHandler.Delete) v1 := router.NewAPIv1(r, conf.App) From 750b722c4711bab0b1ca9817e4db0e79595a0927 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Mon, 29 Jan 2024 22:52:51 +0700 Subject: [PATCH 033/104] fix: image upload swagger --- src/app/handler/image/image.handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/handler/image/image.handler.go b/src/app/handler/image/image.handler.go index 483451b..4cf8c99 100644 --- a/src/app/handler/image/image.handler.go +++ b/src/app/handler/image/image.handler.go @@ -31,7 +31,7 @@ func NewHandler(service imageSvc.Service, validate validator.IDtoValidator) *Han // @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/images/ [post] +// @Router /v1/images [post] func (h *Handler) Upload(c *router.FiberCtx) { request := &dto.UploadImageRequest{} err := c.Bind(request) From ff4f68a390fb01d6a593c73333719150e12281b3 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Mon, 29 Jan 2024 22:57:39 +0700 Subject: [PATCH 034/104] fix: image upload petId not required --- src/app/dto/image.dto.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/dto/image.dto.go b/src/app/dto/image.dto.go index 98414f1..d8aca38 100644 --- a/src/app/dto/image.dto.go +++ b/src/app/dto/image.dto.go @@ -9,7 +9,7 @@ type ImageResponse struct { type UploadImageRequest struct { Filename string `json:"filename" validate:"required"` Data []byte `json:"data" validate:"required"` - PetId string `json:"pet_id" validate:"required"` + PetId string `json:"pet_id"` } type DeleteImageResponse struct { From c4daf1c2720891c0e94cab366733006c0b4f32ee Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Mon, 29 Jan 2024 23:06:41 +0700 Subject: [PATCH 035/104] fix: update swagger --- src/docs/docs.go | 5 ++--- src/docs/swagger.json | 5 ++--- src/docs/swagger.yaml | 3 +-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/docs/docs.go b/src/docs/docs.go index a5c6c94..505e88b 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -337,7 +337,7 @@ const docTemplate = `{ } } }, - "/v1/images/": { + "/v1/images": { "post": { "description": "Returns the data of image. If updating pet, add petId. If creating pet, petId is not specified, but keep the imageId.", "consumes": [ @@ -1493,8 +1493,7 @@ const docTemplate = `{ "type": "object", "required": [ "data", - "filename", - "pet_id" + "filename" ], "properties": { "data": { diff --git a/src/docs/swagger.json b/src/docs/swagger.json index f8bedf5..3c1927f 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -333,7 +333,7 @@ } } }, - "/v1/images/": { + "/v1/images": { "post": { "description": "Returns the data of image. If updating pet, add petId. If creating pet, petId is not specified, but keep the imageId.", "consumes": [ @@ -1489,8 +1489,7 @@ "type": "object", "required": [ "data", - "filename", - "pet_id" + "filename" ], "properties": { "data": { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 844a452..0a6164f 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -377,7 +377,6 @@ definitions: required: - data - filename - - pet_id type: object dto.User: properties: @@ -624,7 +623,7 @@ paths: summary: Signup user tags: - auth - /v1/images/: + /v1/images: post: consumes: - application/json From a171fd15d6f9cbdbef21b4152770577fbcf3e1b8 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Mon, 29 Jan 2024 23:31:37 +0700 Subject: [PATCH 036/104] feat: context file, formdata --- src/app/dto/image.dto.go | 5 ++++ src/app/router/context.go | 43 +++++++++++++++++++++++++++++ src/mocks/router/context.mock.go | 30 ++++++++++++++++++++ src/mocks/service/auth/auth.mock.go | 8 +++--- 4 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src/app/dto/image.dto.go b/src/app/dto/image.dto.go index d8aca38..5ecaf4d 100644 --- a/src/app/dto/image.dto.go +++ b/src/app/dto/image.dto.go @@ -1,5 +1,10 @@ package dto +type DecomposedFile struct { + Filename string + Data []byte +} + type ImageResponse struct { Id string `json:"id"` Url string `json:"url"` diff --git a/src/app/router/context.go b/src/app/router/context.go index 55e4b1d..50afddb 100644 --- a/src/app/router/context.go +++ b/src/app/router/context.go @@ -1,10 +1,16 @@ package router import ( + "bytes" + "errors" + "fmt" + "io" "strings" "github.com/gofiber/fiber/v2" "github.com/google/uuid" + "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + "github.com/isd-sgcu/johnjud-gateway/src/app/utils" ) type IContext interface { @@ -20,6 +26,8 @@ type IContext interface { StoreValue(string, string) Next() error Queries() map[string]string + File(string, map[string]struct{}, int64) (*dto.DecomposedFile, error) + GetFormData(string) string } type FiberCtx struct { @@ -96,6 +104,41 @@ func (c *FiberCtx) Queries() map[string]string { return c.Ctx.Queries() } +func (c *FiberCtx) File(key string, allowContent map[string]struct{}, maxSize int64) (*dto.DecomposedFile, error) { + file, err := c.Ctx.FormFile(key) + if err != nil { + return nil, err + } + + if !utils.IsExisted(allowContent, file.Header["Content-Type"][0]) { + return nil, errors.New("Not allow content") + } + + if file.Size > maxSize { + return nil, errors.New(fmt.Sprintf("Max file size is %v", maxSize)) + } + content, err := file.Open() + if err != nil { + return nil, errors.New("Cannot read file") + } + + defer content.Close() + + buf := bytes.NewBuffer(nil) + if _, err := io.Copy(buf, content); err != nil { + return nil, err + } + + return &dto.DecomposedFile{ + Filename: file.Filename, + Data: buf.Bytes(), + }, nil +} + +func (c *FiberCtx) GetFormData(key string) string { + return c.Ctx.FormValue(key) +} + //func (c *FiberCtx) Next() { // err := c.Ctx.Next() // fmt.Println(c.Route().Path) diff --git a/src/mocks/router/context.mock.go b/src/mocks/router/context.mock.go index 729beeb..7a371c7 100644 --- a/src/mocks/router/context.mock.go +++ b/src/mocks/router/context.mock.go @@ -8,6 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" + dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" ) // MockIContext is a mock of IContext interface. @@ -47,6 +48,35 @@ func (mr *MockIContextMockRecorder) Bind(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Bind", reflect.TypeOf((*MockIContext)(nil).Bind), arg0) } +// File mocks base method. +func (m *MockIContext) File(arg0 string, arg1 map[string]struct{}, arg2 int64) (*dto.DecomposedFile, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "File", arg0, arg1, arg2) + ret0, _ := ret[0].(*dto.DecomposedFile) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// File indicates an expected call of File. +func (mr *MockIContextMockRecorder) File(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "File", reflect.TypeOf((*MockIContext)(nil).File), arg0, arg1, arg2) +} + +// GetFormData mocks base method. +func (m *MockIContext) GetFormData(arg0 string) string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFormData", arg0) + ret0, _ := ret[0].(string) + return ret0 +} + +// GetFormData indicates an expected call of GetFormData. +func (mr *MockIContextMockRecorder) GetFormData(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFormData", reflect.TypeOf((*MockIContext)(nil).GetFormData), arg0) +} + // ID mocks base method. func (m *MockIContext) ID() (string, error) { m.ctrl.T.Helper() diff --git a/src/mocks/service/auth/auth.mock.go b/src/mocks/service/auth/auth.mock.go index 76fa349..52e1c8d 100644 --- a/src/mocks/service/auth/auth.mock.go +++ b/src/mocks/service/auth/auth.mock.go @@ -35,18 +35,18 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { } // ForgotPassword mocks base method. -func (m *MockService) ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) { +func (m *MockService) ForgotPassword(arg0 *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ForgotPassword", request) + ret := m.ctrl.Call(m, "ForgotPassword", arg0) ret0, _ := ret[0].(*dto.ForgotPasswordResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // ForgotPassword indicates an expected call of ForgotPassword. -func (mr *MockServiceMockRecorder) ForgotPassword(request interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) ForgotPassword(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForgotPassword", reflect.TypeOf((*MockService)(nil).ForgotPassword), request) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForgotPassword", reflect.TypeOf((*MockService)(nil).ForgotPassword), arg0) } // RefreshToken mocks base method. From 069ba3cbb494431ac3872a9dd401615a44d14ebf Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Mon, 29 Jan 2024 23:47:06 +0700 Subject: [PATCH 037/104] feat: add maxfilesize --- .env.template | 1 + src/config/config.go | 5 +++-- src/main.go | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.env.template b/.env.template index 5e36a24..afa9ce5 100644 --- a/.env.template +++ b/.env.template @@ -1,5 +1,6 @@ APP_PORT=3001 APP_ENV=development +APP_MAX_FILE_SIZE=10 SERVICE_AUTH=localhost:3002 SERVICE_BACKEND=localhost:3003 diff --git a/src/config/config.go b/src/config/config.go index b7903ff..10e1db2 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -5,8 +5,9 @@ import ( ) type App struct { - Port int `mapstructure:"PORT"` - Env string `mapstructure:"ENV"` + Port int `mapstructure:"PORT"` + Env string `mapstructure:"ENV"` + MaxFileSize int64 `mapstructure:"MAX_FILE_SIZE"` } type Service struct { diff --git a/src/main.go b/src/main.go index b2517d4..30308be 100644 --- a/src/main.go +++ b/src/main.go @@ -117,7 +117,7 @@ func main() { imageClient := imageProto.NewImageServiceClient(fileConn) imageService := imageSvc.NewService(imageClient) - imageHandler := imageHdr.NewHandler(imageService, v) + imageHandler := imageHdr.NewHandler(imageService, v, conf.App.MaxFileSize) petClient := petProto.NewPetServiceClient(backendConn) petService := petSvc.NewService(petClient) From 7968b175147f7524b974c4e0543043ca59a927d9 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Mon, 29 Jan 2024 23:47:20 +0700 Subject: [PATCH 038/104] feat: file const --- src/constant/file/file.constant.go | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/constant/file/file.constant.go diff --git a/src/constant/file/file.constant.go b/src/constant/file/file.constant.go new file mode 100644 index 0000000..0b6ffcd --- /dev/null +++ b/src/constant/file/file.constant.go @@ -0,0 +1,8 @@ +package file + +var AllowContentType = map[string]struct{}{ + "image/jpeg": {}, + "image/jpg": {}, + "image/png": {}, + "image/gif": {}, +} From 00d5a8ec9a4f44fe40f30f4b444cf5632dd7d902 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Mon, 29 Jan 2024 23:50:14 +0700 Subject: [PATCH 039/104] feat: image upload use form --- src/app/constant/error.constant.go | 2 ++ src/app/handler/image/image.handler.go | 39 +++++++++++++------------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/app/constant/error.constant.go b/src/app/constant/error.constant.go index a9544cc..ac7036e 100644 --- a/src/app/constant/error.constant.go +++ b/src/app/constant/error.constant.go @@ -15,3 +15,5 @@ const InvalidArgumentMessage = "Invalid Argument" const PetNotFoundMessage = "Pet not found" const UserNotFoundMessage = "User not found" const ImageNotFoundMessage = "Image not found" + +const InvalidContentMessage = "Invalid content" diff --git a/src/app/handler/image/image.handler.go b/src/app/handler/image/image.handler.go index 4cf8c99..9d34b6c 100644 --- a/src/app/handler/image/image.handler.go +++ b/src/app/handler/image/image.handler.go @@ -2,22 +2,24 @@ package image import ( "net/http" - "strings" "github.com/isd-sgcu/johnjud-gateway/src/app/constant" "github.com/isd-sgcu/johnjud-gateway/src/app/dto" "github.com/isd-sgcu/johnjud-gateway/src/app/router" "github.com/isd-sgcu/johnjud-gateway/src/app/validator" + "github.com/isd-sgcu/johnjud-gateway/src/constant/file" imageSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/image" + "github.com/rs/zerolog/log" ) type Handler struct { - service imageSvc.Service - validate validator.IDtoValidator + service imageSvc.Service + validate validator.IDtoValidator + maxFileSize int64 } -func NewHandler(service imageSvc.Service, validate validator.IDtoValidator) *Handler { - return &Handler{service, validate} +func NewHandler(service imageSvc.Service, validate validator.IDtoValidator, maxFileSize int64) *Handler { + return &Handler{service, validate, maxFileSize} } // Upload is a function for uploading image to bucket @@ -33,28 +35,27 @@ func NewHandler(service imageSvc.Service, validate validator.IDtoValidator) *Han // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/images [post] func (h *Handler) Upload(c *router.FiberCtx) { - request := &dto.UploadImageRequest{} - err := c.Bind(request) + filename := c.GetFormData("filename") + petId := c.GetFormData("petId") + file, err := c.File("file", file.AllowContentType, h.maxFileSize) if err != nil { + log.Error(). + Err(err). + Str("service", "image"). + Str("module", "upload"). + Msg("Invalid content") c.JSON(http.StatusBadRequest, dto.ResponseErr{ StatusCode: http.StatusBadRequest, - Message: constant.BindingRequestErrorMessage + err.Error(), + Message: constant.InvalidContentMessage, 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 + request := &dto.UploadImageRequest{ + Filename: filename, + Data: file.Data, + PetId: petId, } response, respErr := h.service.Upload(request) From 32a8dcd1e575edb472610fa711d821c3df651eed Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Mon, 29 Jan 2024 23:55:30 +0700 Subject: [PATCH 040/104] fix: maxfilesize * MB --- src/app/handler/image/image.handler.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/app/handler/image/image.handler.go b/src/app/handler/image/image.handler.go index 9d34b6c..ec7f163 100644 --- a/src/app/handler/image/image.handler.go +++ b/src/app/handler/image/image.handler.go @@ -19,7 +19,11 @@ type Handler struct { } func NewHandler(service imageSvc.Service, validate validator.IDtoValidator, maxFileSize int64) *Handler { - return &Handler{service, validate, maxFileSize} + return &Handler{ + service: service, + validate: validate, + maxFileSize: int64(maxFileSize * 1024 * 1024), + } } // Upload is a function for uploading image to bucket From b458a5f434d58568ed70a4df9c5c23e820a2f596 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Mon, 29 Jan 2024 23:57:15 +0700 Subject: [PATCH 041/104] feat: router add bodylimit --- src/app/router/router.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/router/router.go b/src/app/router/router.go index a89ef8e..33b132e 100644 --- a/src/app/router/router.go +++ b/src/app/router/router.go @@ -42,7 +42,10 @@ func NewAPIv1(r *FiberRouter, conf config.App) *fiber.App { } func NewFiberRouter(authGuard IGuard, conf config.App) *FiberRouter { - r := fiber.New(fiber.Config{}) + r := fiber.New(fiber.Config{ + AppName: "JohnJud API", + BodyLimit: int(conf.MaxFileSize * 1024 * 1024), + }) r.Use(cors.New(cors.Config{ AllowOrigins: "*", From 2f63ddb62d2aab0492f461c5e616184d443c1888 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Tue, 30 Jan 2024 00:05:07 +0700 Subject: [PATCH 042/104] fix: docker prod --- docker-compose-prod.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose-prod.yaml b/docker-compose-prod.yaml index 6c2c196..9d7d772 100644 --- a/docker-compose-prod.yaml +++ b/docker-compose-prod.yaml @@ -10,6 +10,7 @@ services: environment: - APP_PORT=3001 - APP_ENV=development + - APP_MAX_FILE_SIZE=10 - SERVICE_AUTH=auth:3002 - SERVICE_BACKEND=backend:3003 - SERVICE_FILE=file:3004 From ee9c4e651ca9aa32904df34f69ae65655c0bf054 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Tue, 30 Jan 2024 00:09:29 +0700 Subject: [PATCH 043/104] feat: swagger + data -> file --- src/app/dto/image.dto.go | 2 +- src/app/handler/image/image.handler.go | 4 ++-- src/app/utils/image/image.utils.go | 2 +- src/docs/docs.go | 6 +++--- src/docs/swagger.json | 6 +++--- src/docs/swagger.yaml | 6 +++--- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/app/dto/image.dto.go b/src/app/dto/image.dto.go index 5ecaf4d..d07bdbe 100644 --- a/src/app/dto/image.dto.go +++ b/src/app/dto/image.dto.go @@ -13,7 +13,7 @@ type ImageResponse struct { type UploadImageRequest struct { Filename string `json:"filename" validate:"required"` - Data []byte `json:"data" validate:"required"` + File []byte `json:"file" validate:"required"` PetId string `json:"pet_id"` } diff --git a/src/app/handler/image/image.handler.go b/src/app/handler/image/image.handler.go index ec7f163..e904405 100644 --- a/src/app/handler/image/image.handler.go +++ b/src/app/handler/image/image.handler.go @@ -31,7 +31,7 @@ func NewHandler(service imageSvc.Service, validate validator.IDtoValidator, maxF // @Description Returns the data of image. If updating pet, add petId. If creating pet, petId is not specified, but keep the imageId. // @Param image body dto.UploadImageRequest true "upload image request dto" // @Tags image -// @Accept json +// @Accept multipart/form-data // @Produce json // @Success 201 {object} dto.ImageResponse // @Failure 400 {object} dto.ResponseBadRequestErr "Invalid request body" @@ -58,7 +58,7 @@ func (h *Handler) Upload(c *router.FiberCtx) { request := &dto.UploadImageRequest{ Filename: filename, - Data: file.Data, + File: file.Data, PetId: petId, } diff --git a/src/app/utils/image/image.utils.go b/src/app/utils/image/image.utils.go index 705c34f..620a830 100644 --- a/src/app/utils/image/image.utils.go +++ b/src/app/utils/image/image.utils.go @@ -30,7 +30,7 @@ func ProtoToDtoList(in []*imageProto.Image) []*dto.ImageResponse { func CreateDtoToProto(in *dto.UploadImageRequest) *imageProto.UploadImageRequest { return &imageProto.UploadImageRequest{ Filename: in.Filename, - Data: in.Data, + Data: in.File, PetId: in.PetId, } } diff --git a/src/docs/docs.go b/src/docs/docs.go index 505e88b..8e9ba2f 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -341,7 +341,7 @@ const docTemplate = `{ "post": { "description": "Returns the data of image. If updating pet, add petId. If creating pet, petId is not specified, but keep the imageId.", "consumes": [ - "application/json" + "multipart/form-data" ], "produces": [ "application/json" @@ -1492,11 +1492,11 @@ const docTemplate = `{ "dto.UploadImageRequest": { "type": "object", "required": [ - "data", + "file", "filename" ], "properties": { - "data": { + "file": { "type": "array", "items": { "type": "integer" diff --git a/src/docs/swagger.json b/src/docs/swagger.json index 3c1927f..1350d3d 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -337,7 +337,7 @@ "post": { "description": "Returns the data of image. If updating pet, add petId. If creating pet, petId is not specified, but keep the imageId.", "consumes": [ - "application/json" + "multipart/form-data" ], "produces": [ "application/json" @@ -1488,11 +1488,11 @@ "dto.UploadImageRequest": { "type": "object", "required": [ - "data", + "file", "filename" ], "properties": { - "data": { + "file": { "type": "array", "items": { "type": "integer" diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 0a6164f..8c9baca 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -366,7 +366,7 @@ definitions: type: object dto.UploadImageRequest: properties: - data: + file: items: type: integer type: array @@ -375,7 +375,7 @@ definitions: pet_id: type: string required: - - data + - file - filename type: object dto.User: @@ -626,7 +626,7 @@ paths: /v1/images: post: consumes: - - application/json + - multipart/form-data description: Returns the data of image. If updating pet, add petId. If creating pet, petId is not specified, but keep the imageId. parameters: From e14e0fe14b700b1b35115366a05fbcc2c1b51df7 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Tue, 30 Jan 2024 22:20:10 +0700 Subject: [PATCH 044/104] fix: image upload use filename from file --- src/app/handler/image/image.handler.go | 5 ++--- src/app/router/router.go | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/app/handler/image/image.handler.go b/src/app/handler/image/image.handler.go index e904405..c16f3d2 100644 --- a/src/app/handler/image/image.handler.go +++ b/src/app/handler/image/image.handler.go @@ -39,8 +39,7 @@ func NewHandler(service imageSvc.Service, validate validator.IDtoValidator, maxF // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/images [post] func (h *Handler) Upload(c *router.FiberCtx) { - filename := c.GetFormData("filename") - petId := c.GetFormData("petId") + petId := c.GetFormData("pet_id") file, err := c.File("file", file.AllowContentType, h.maxFileSize) if err != nil { log.Error(). @@ -57,7 +56,7 @@ func (h *Handler) Upload(c *router.FiberCtx) { } request := &dto.UploadImageRequest{ - Filename: filename, + Filename: file.Filename, File: file.Data, PetId: petId, } diff --git a/src/app/router/router.go b/src/app/router/router.go index 33b132e..f24910d 100644 --- a/src/app/router/router.go +++ b/src/app/router/router.go @@ -43,7 +43,6 @@ func NewAPIv1(r *FiberRouter, conf config.App) *fiber.App { func NewFiberRouter(authGuard IGuard, conf config.App) *FiberRouter { r := fiber.New(fiber.Config{ - AppName: "JohnJud API", BodyLimit: int(conf.MaxFileSize * 1024 * 1024), }) From d79b66990952e984ee48fee4ee4f16a69284856b Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:15:34 +0700 Subject: [PATCH 045/104] feat: image client mock --- src/mocks/client/image/image.mock.go | 49 ++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/mocks/client/image/image.mock.go diff --git a/src/mocks/client/image/image.mock.go b/src/mocks/client/image/image.mock.go new file mode 100644 index 0000000..66efa34 --- /dev/null +++ b/src/mocks/client/image/image.mock.go @@ -0,0 +1,49 @@ +package image + +import ( + "context" + + imageProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" + "github.com/stretchr/testify/mock" + "google.golang.org/grpc" +) + +type ImageClientMock struct { + mock.Mock +} + +func (c *ImageClientMock) Upload(_ context.Context, in *imageProto.UploadImageRequest, _ ...grpc.CallOption) (res *imageProto.UploadImageResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*imageProto.UploadImageResponse) + } + return res, args.Error(1) +} + +func (c *ImageClientMock) FindByPetId(_ context.Context, in *imageProto.FindImageByPetIdRequest, _ ...grpc.CallOption) (res *imageProto.FindImageByPetIdResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*imageProto.FindImageByPetIdResponse) + } + return res, args.Error(1) +} + +func (c *ImageClientMock) AssignPet(_ context.Context, in *imageProto.AssignPetRequest, _ ...grpc.CallOption) (res *imageProto.AssignPetResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*imageProto.AssignPetResponse) + } + return res, args.Error(1) +} + +func (c *ImageClientMock) Delete(_ context.Context, in *imageProto.DeleteImageRequest, _ ...grpc.CallOption) (res *imageProto.DeleteImageResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*imageProto.DeleteImageResponse) + } + return res, args.Error(1) +} From a47734b9940ac6fd2e55ea38ed0ad19fc6cb8ee9 Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:15:43 +0700 Subject: [PATCH 046/104] chore: fix petService --- src/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.go b/src/main.go index 30308be..0538fa1 100644 --- a/src/main.go +++ b/src/main.go @@ -120,7 +120,7 @@ func main() { imageHandler := imageHdr.NewHandler(imageService, v, conf.App.MaxFileSize) petClient := petProto.NewPetServiceClient(backendConn) - petService := petSvc.NewService(petClient) + petService := petSvc.NewService(petClient, imageService) petHandler := petHdr.NewHandler(petService, imageService, v) likeClient := likeProto.NewLikeServiceClient(backendConn) From 42a2ef86caf62ed68bca8483d4e864679ae9cece Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:16:16 +0700 Subject: [PATCH 047/104] feat: image utils --- src/app/utils/pet/pet.utils.go | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/app/utils/pet/pet.utils.go b/src/app/utils/pet/pet.utils.go index 55c0ff1..4741024 100644 --- a/src/app/utils/pet/pet.utils.go +++ b/src/app/utils/pet/pet.utils.go @@ -29,7 +29,35 @@ func MockImageList(n int) [][]*imgproto.Image { return imagesList } -func ProtoToDto(in *petproto.Pet, images []*imgproto.Image) *dto.PetResponse { +func ImageProtoToDto(images []*imgproto.Image) []*dto.ImageResponse { + var imageDto []*dto.ImageResponse + for _, image := range images { + imageDto = append(imageDto, &dto.ImageResponse{ + Id: image.Id, + Url: image.ImageUrl, + ObjectKey: image.ObjectKey, + }) + } + return imageDto +} + +func ImageListProtoToDto(imagesList [][]*imgproto.Image) [][]*dto.ImageResponse { + var imageListDto [][]*dto.ImageResponse + for _, images := range imagesList { + var imageDto []*dto.ImageResponse + for _, image := range images { + imageDto = append(imageDto, &dto.ImageResponse{ + Id: image.Id, + Url: image.ImageUrl, + ObjectKey: image.ObjectKey, + }) + } + imageListDto = append(imageListDto, imageDto) + } + return imageListDto +} + +func ProtoToDto(in *petproto.Pet, images []*dto.ImageResponse) *dto.PetResponse { pet := &dto.PetResponse{ Id: in.Id, Type: in.Type, @@ -48,7 +76,7 @@ func ProtoToDto(in *petproto.Pet, images []*imgproto.Image) *dto.PetResponse { Address: in.Address, Contact: in.Contact, AdoptBy: in.AdoptBy, - Images: extractImages(images), + Images: images, } return pet } @@ -122,7 +150,7 @@ func ProtoToDtoList(in []*petproto.Pet, imagesList [][]*imgproto.Image) []*dto.P Address: p.Address, Contact: p.Contact, AdoptBy: p.AdoptBy, - Images: extractImages(imagesList[i]), + Images: ImageProtoToDto(imagesList[i]), } resp = append(resp, pet) } From fd98be2c2ca68e77a205f29d61908af0e7d07f6a Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:16:22 +0700 Subject: [PATCH 048/104] fix: pet service test --- src/app/service/pet/pet.service_test.go | 153 ++++++++++++++++++++---- 1 file changed, 128 insertions(+), 25 deletions(-) diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 909b39d..4822b46 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -8,8 +8,10 @@ import ( "github.com/go-faker/faker/v4" "github.com/isd-sgcu/johnjud-gateway/src/app/constant" "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + imageSvc "github.com/isd-sgcu/johnjud-gateway/src/app/service/image" utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/pet" "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" + imagemock "github.com/isd-sgcu/johnjud-gateway/src/mocks/client/image" petmock "github.com/isd-sgcu/johnjud-gateway/src/mocks/client/pet" petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" imgproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" @@ -45,6 +47,11 @@ type PetServiceTest struct { Images []*imgproto.Image ImagesList [][]*imgproto.Image + + AssignPetReq *imgproto.AssignPetRequest + AssignPetDto *dto.AssignPetRequest + + FindByPetIdReq *imgproto.FindImageByPetIdRequest } func TestPetService(t *testing.T) { @@ -122,7 +129,7 @@ func (t *PetServiceTest) SetupTest() { AdoptBy: t.Pet.AdoptBy, } - t.PetDto = utils.ProtoToDto(t.Pet, t.Pet.Images) + t.PetDto = utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Pet.Images)) t.FindAllPetDto = &dto.FindAllPetRequest{ Search: "", @@ -199,6 +206,20 @@ func (t *PetServiceTest) SetupTest() { PetID: t.Pet.Id, } + t.AssignPetReq = &imgproto.AssignPetRequest{ + Ids: []string{}, + PetId: t.Pet.Id, + } + + t.AssignPetDto = &dto.AssignPetRequest{ + Ids: []string{}, + PetId: t.Pet.Id, + } + + t.FindByPetIdReq = &imgproto.FindImageByPetIdRequest{ + PetId: t.Pet.Id, + } + t.UnavailableServiceErr = &dto.ResponseErr{ StatusCode: http.StatusServiceUnavailable, Message: constant.UnavailableServiceMessage, @@ -241,7 +262,10 @@ func (t *PetServiceTest) TestFindAllSuccess() { client := petmock.PetClientMock{} client.On("FindAll", t.FindAllPetReq).Return(protoResp, nil) - svc := NewService(&client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(&client, imageSvc) actual, err := svc.FindAll(t.FindAllPetDto) assert.Nil(t.T(), err) @@ -256,7 +280,10 @@ func (t *PetServiceTest) TestFindAllUnavailableServiceError() { client := petmock.PetClientMock{} client.On("FindAll", t.FindAllPetReq).Return(nil, clientErr) - svc := NewService(&client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(&client, imageSvc) actual, err := svc.FindAll(t.FindAllPetDto) assert.Nil(t.T(), actual) @@ -271,12 +298,21 @@ func (t *PetServiceTest) TestFindOneSuccess() { Pet: t.Pet, } - expected := utils.ProtoToDto(t.Pet, t.Pet.Images) + findByPetIdReq := t.FindByPetIdReq + findByPetIdResp := &imgproto.FindImageByPetIdResponse{ + Images: t.Images, + } + + expected := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Pet.Images)) client := petmock.PetClientMock{} client.On("FindOne", protoReq).Return(protoResp, nil) - svc := NewService(&client) + imageClient := imagemock.ImageClientMock{} + imageClient.On("FindByPetId", findByPetIdReq).Return(findByPetIdResp, nil) + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(&client, imageSvc) actual, err := svc.FindOne(t.Pet.Id) assert.Nil(t.T(), err) @@ -295,7 +331,10 @@ func (t *PetServiceTest) TestFindOneNotFoundError() { client := petmock.PetClientMock{} client.On("FindOne", protoReq).Return(nil, clientErr) - svc := NewService(&client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(&client, imageSvc) actual, err := svc.FindOne(t.Pet.Id) assert.Nil(t.T(), actual) @@ -314,7 +353,11 @@ func (t *PetServiceTest) TestFindOneUnavailableServiceError() { client := petmock.PetClientMock{} client.On("FindOne", protoReq).Return(nil, clientErr) - svc := NewService(&client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + + svc := NewService(&client, imageSvc) actual, err := svc.FindOne(t.Pet.Id) assert.Nil(t.T(), actual) @@ -327,12 +370,27 @@ func (t *PetServiceTest) TestCreateSuccess() { Pet: t.Pet, } - expected := utils.ProtoToDto(t.Pet, t.Pet.Images) + assignPetReq := t.AssignPetReq + assignPetResp := &imgproto.AssignPetResponse{ + Success: true, + } + + findByPetIdReq := t.FindByPetIdReq + findByPetIdResp := &imgproto.FindImageByPetIdResponse{ + Images: t.Images, + } + + expected := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Pet.Images)) client := &petmock.PetClientMock{} client.On("Create", protoReq).Return(protoResp, nil) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + imageClient.On("AssignPet", assignPetReq).Return(assignPetResp, nil) + imageClient.On("FindByPetId", findByPetIdReq).Return(findByPetIdResp, nil) + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Create(t.CreatePetDto) assert.Nil(t.T(), err) @@ -349,7 +407,10 @@ func (t *PetServiceTest) TestCreateInvalidArgumentError() { client := &petmock.PetClientMock{} client.On("Create", protoReq).Return(nil, clientErr) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Create(t.CreatePetDto) assert.Nil(t.T(), actual) @@ -366,7 +427,10 @@ func (t *PetServiceTest) TestCreateInternalError() { client := &petmock.PetClientMock{} client.On("Create", protoReq).Return(nil, clientErr) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Create(t.CreatePetDto) assert.Nil(t.T(), actual) @@ -383,7 +447,10 @@ func (t *PetServiceTest) TestCreateUnavailableServiceError() { client := &petmock.PetClientMock{} client.On("Create", protoReq).Return(nil, clientErr) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Create(t.CreatePetDto) assert.Nil(t.T(), actual) @@ -396,12 +463,15 @@ func (t *PetServiceTest) TestUpdateSuccess() { Pet: t.Pet, } - expected := utils.ProtoToDto(t.Pet, t.Pet.Images) + expected := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Pet.Images)) client := &petmock.PetClientMock{} client.On("Update", protoReq).Return(protoResp, nil) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) assert.Nil(t.T(), err) @@ -417,7 +487,10 @@ func (t *PetServiceTest) TestUpdateNotFound() { client := &petmock.PetClientMock{} client.On("Update", protoReq).Return(nil, clientErr) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) assert.Nil(t.T(), actual) @@ -433,7 +506,10 @@ func (t *PetServiceTest) TestUpdateUnavailableServiceError() { client := &petmock.PetClientMock{} client.On("Update", protoReq).Return(nil, clientErr) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) assert.Nil(t.T(), actual) @@ -453,7 +529,10 @@ func (t *PetServiceTest) TestDeleteSuccess() { client := &petmock.PetClientMock{} client.On("Delete", protoReq).Return(protoResp, nil) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Delete(t.Pet.Id) assert.Nil(t.T(), err) @@ -474,7 +553,10 @@ func (t *PetServiceTest) TestDeleteNotFound() { client := &petmock.PetClientMock{} client.On("Delete", protoReq).Return(protoResp, clientErr) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Delete(t.Pet.Id) assert.Nil(t.T(), actual) @@ -495,7 +577,10 @@ func (t *PetServiceTest) TestDeleteServiceUnavailableError() { client := &petmock.PetClientMock{} client.On("Delete", protoReq).Return(protoResp, clientErr) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Delete(t.Pet.Id) assert.Nil(t.T(), actual) @@ -511,7 +596,10 @@ func (t *PetServiceTest) TestChangeViewSuccess() { client := &petmock.PetClientMock{} client.On("ChangeView", protoReq).Return(protoResp, nil) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) assert.Nil(t.T(), err) @@ -531,7 +619,10 @@ func (t *PetServiceTest) TestChangeViewNotFoundError() { client := &petmock.PetClientMock{} client.On("ChangeView", protoReq).Return(protoResp, clientErr) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) assert.Equal(t.T(), &dto.ChangeViewPetResponse{Success: false}, actual) @@ -551,7 +642,10 @@ func (t *PetServiceTest) TestChangeViewUnavailableServiceError() { client := &petmock.PetClientMock{} client.On("ChangeView", protoReq).Return(protoResp, clientErr) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) assert.Equal(t.T(), &dto.ChangeViewPetResponse{Success: false}, actual) @@ -567,7 +661,10 @@ func (t *PetServiceTest) TestAdoptSuccess() { client := &petmock.PetClientMock{} client.On("AdoptPet", protoReq).Return(protoResp, nil) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) assert.Nil(t.T(), err) @@ -584,7 +681,10 @@ func (t *PetServiceTest) TestAdoptNotFoundError() { client := &petmock.PetClientMock{} client.On("AdoptPet", protoReq).Return(nil, clientErr) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) assert.Nil(t.T(), actual) @@ -601,7 +701,10 @@ func (t *PetServiceTest) TestAdoptUnavailableServiceError() { client := &petmock.PetClientMock{} client.On("AdoptPet", protoReq).Return(nil, clientErr) - svc := NewService(client) + imageClient := imagemock.ImageClientMock{} + + imageSvc := imageSvc.NewService(&imageClient) + svc := NewService(client, imageSvc) actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) assert.Nil(t.T(), actual) From 9fced93a39ebaeee853edb2bdca3397dfaf7b28c Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:17:00 +0700 Subject: [PATCH 049/104] feat: use imageService instead `mock` image --- src/app/service/pet/pet.service.go | 44 ++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index a18a682..f22b51f 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -7,7 +7,9 @@ import ( "github.com/isd-sgcu/johnjud-gateway/src/app/constant" "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/pet" + imageSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/image" petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" @@ -15,12 +17,14 @@ import ( ) type Service struct { - petClient petproto.PetServiceClient + petClient petproto.PetServiceClient + imageService imageSvc.Service } -func NewService(petClient petproto.PetServiceClient) *Service { +func NewService(petClient petproto.PetServiceClient, imageService imageSvc.Service) *Service { return &Service{ - petClient: petClient, + petClient: petClient, + imageService: imageService, } } @@ -94,8 +98,13 @@ func (s *Service) FindOne(id string) (result *dto.PetResponse, err *dto.Response } } } - images := utils.MockImageList(1)[0] - findOneResponse := utils.ProtoToDto(res.Pet, images) + + imgRes, imgErrRes := s.imageService.FindByPetId(res.Pet.Id) + if imgErrRes != nil { + return nil, imgErrRes + } + + findOneResponse := utils.ProtoToDto(res.Pet, imgRes) return findOneResponse, nil } @@ -134,8 +143,27 @@ func (s *Service) Create(in *dto.CreatePetRequest) (result *dto.PetResponse, err } } } - images := utils.MockImageList(1)[0] - createPetResponse := utils.ProtoToDto(res.Pet, images) + + assignRes, assignErr := s.imageService.AssignPet(&dto.AssignPetRequest{ + Ids: in.Images, + PetId: res.Pet.Id, + }) + if assignErr != nil { + return nil, assignErr + } + if assignRes.Success == false { + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + + imgRes, imgErrRes := s.imageService.FindByPetId(res.Pet.Id) + if imgErrRes != nil { + return nil, imgErrRes + } + createPetResponse := utils.ProtoToDto(res.Pet, imgRes) return createPetResponse, nil } @@ -181,7 +209,7 @@ func (s *Service) Update(id string, in *dto.UpdatePetRequest) (result *dto.PetRe } } images := utils.MockImageList(1)[0] - updatePetResponse := utils.ProtoToDto(res.Pet, images) + updatePetResponse := utils.ProtoToDto(res.Pet, utils.ImageProtoToDto(images)) return updatePetResponse, nil } From 1cdf4fce83d737dbd9093e90630ac88da2a849f0 Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:17:15 +0700 Subject: [PATCH 050/104] fix: pet handler test --- src/app/handler/pet/pet.handler_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/handler/pet/pet.handler_test.go b/src/app/handler/pet/pet.handler_test.go index e42dfbb..0abf7f1 100644 --- a/src/app/handler/pet/pet.handler_test.go +++ b/src/app/handler/pet/pet.handler_test.go @@ -180,7 +180,7 @@ func (t *PetHandlerTest) TestFindAllSuccess() { } func (t *PetHandlerTest) TestFindOneSuccess() { - findOneResponse := utils.ProtoToDto(t.Pet, t.Images) + findOneResponse := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Images)) expectedResponse := findOneResponse controller := gomock.NewController(t.T()) @@ -235,7 +235,7 @@ func (t *PetHandlerTest) TestFindOneGrpcErr() { } func (t *PetHandlerTest) TestCreateSuccess() { - createResponse := utils.ProtoToDto(t.Pet, t.Images) + createResponse := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Images)) expectedResponse := createResponse controller := gomock.NewController(t.T()) @@ -274,7 +274,7 @@ func (t *PetHandlerTest) TestCreateGrpcErr() { } func (t *PetHandlerTest) TestUpdateSuccess() { - updateResponse := utils.ProtoToDto(t.Pet, t.Images) + updateResponse := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Images)) expectedResponse := updateResponse controller := gomock.NewController(t.T()) From 1ced6eb27e63f7293db95b5d1d8cbf7a5c7fee6d Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:17:45 +0700 Subject: [PATCH 051/104] chore: use `[]*ImageResponse` instead `[]ImageResponse` --- src/app/dto/pet.dto.go | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/app/dto/pet.dto.go b/src/app/dto/pet.dto.go index 970b38a..cece7bf 100644 --- a/src/app/dto/pet.dto.go +++ b/src/app/dto/pet.dto.go @@ -5,24 +5,24 @@ import ( ) type PetResponse struct { - Id string `json:"id"` - Type string `json:"type"` - Name string `json:"name"` - Birthdate string `json:"birthdate"` - Gender pet.Gender `json:"gender"` - Color string `json:"color"` - Pattern string `json:"pattern"` - Habit string `json:"habit"` - Caption string `json:"caption"` - Status pet.Status `json:"status"` - IsSterile *bool `json:"is_sterile"` - IsVaccinated *bool `json:"is_vaccinated"` - IsVisible *bool `json:"is_visible"` - Origin string `json:"origin"` - Address string `json:"address"` - Contact string `json:"contact"` - AdoptBy string `json:"adopt_by"` - Images []ImageResponse `json:"images"` + Id string `json:"id"` + Type string `json:"type"` + Name string `json:"name"` + Birthdate string `json:"birthdate"` + Gender pet.Gender `json:"gender"` + Color string `json:"color"` + Pattern string `json:"pattern"` + Habit string `json:"habit"` + Caption string `json:"caption"` + Status pet.Status `json:"status"` + IsSterile *bool `json:"is_sterile"` + IsVaccinated *bool `json:"is_vaccinated"` + IsVisible *bool `json:"is_visible"` + Origin string `json:"origin"` + Address string `json:"address"` + Contact string `json:"contact"` + AdoptBy string `json:"adopt_by"` + Images []*ImageResponse `json:"images"` } type FindAllPetRequest struct { From 7d4b1393eab92a4a2837b1495ccc2ed8f372502e Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Sat, 3 Feb 2024 12:47:12 +0700 Subject: [PATCH 052/104] chore --- src/app/service/pet/pet.service.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index f22b51f..3d1e750 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -144,20 +144,13 @@ func (s *Service) Create(in *dto.CreatePetRequest) (result *dto.PetResponse, err } } - assignRes, assignErr := s.imageService.AssignPet(&dto.AssignPetRequest{ + _, assignErr := s.imageService.AssignPet(&dto.AssignPetRequest{ Ids: in.Images, PetId: res.Pet.Id, }) if assignErr != nil { return nil, assignErr } - if assignRes.Success == false { - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } imgRes, imgErrRes := s.imageService.FindByPetId(res.Pet.Id) if imgErrRes != nil { From d21e7acaed32a86fa664fcec0e92a1dc89ab0cc5 Mon Sep 17 00:00:00 2001 From: Gear <84141000+macgeargear@users.noreply.github.com> Date: Sat, 3 Feb 2024 12:47:38 +0700 Subject: [PATCH 053/104] chore --- src/app/service/pet/pet.service.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index 3d1e750..1810451 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -156,6 +156,7 @@ func (s *Service) Create(in *dto.CreatePetRequest) (result *dto.PetResponse, err if imgErrRes != nil { return nil, imgErrRes } + createPetResponse := utils.ProtoToDto(res.Pet, imgRes) return createPetResponse, nil } From ef488d65710ef141cd605f19f65a1574d530037a Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 16 Feb 2024 16:06:29 +0700 Subject: [PATCH 054/104] feat: update proto --- go.mod | 4 ++-- go.sum | 14 ++++++-------- src/app/service/auth/auth.service_test.go | 2 +- src/mocks/client/image/image.mock.go | 18 ++++++++++++++++++ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 27865cd..b9fcea2 100644 --- a/go.mod +++ b/go.mod @@ -12,12 +12,12 @@ require ( github.com/gofiber/fiber/v2 v2.52.0 github.com/golang/mock v1.6.0 github.com/google/uuid v1.5.0 - github.com/isd-sgcu/johnjud-go-proto v0.5.2 + github.com/isd-sgcu/johnjud-go-proto v0.6.0 github.com/rs/zerolog v1.31.0 github.com/spf13/viper v1.18.1 github.com/stretchr/testify v1.8.4 github.com/swaggo/swag v1.16.2 - google.golang.org/grpc v1.60.1 + google.golang.org/grpc v1.61.0 ) require ( diff --git a/go.sum b/go.sum index 62603e0..df32434 100644 --- a/go.sum +++ b/go.sum @@ -59,17 +59,15 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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.5.0 h1:GgqRzWjya5p1yhfU/kpX8i4WL42+qT2TkyXZmssH6B4= -github.com/isd-sgcu/johnjud-go-proto v0.5.0/go.mod h1:1OK6aiCgtXQiLhxp0r6iLEejYIRpckWQZDrCZ9Trbo4= -github.com/isd-sgcu/johnjud-go-proto v0.5.2 h1:LWhi7zaEeEOJ60nyCxxMeAr7Bvl9stWvQbaw0RWz/Cs= -github.com/isd-sgcu/johnjud-go-proto v0.5.2/go.mod h1:1OK6aiCgtXQiLhxp0r6iLEejYIRpckWQZDrCZ9Trbo4= +github.com/isd-sgcu/johnjud-go-proto v0.6.0 h1:sOWGjsqXwzpSaweSlNqPlttExZryp8mV76ob95LppjM= +github.com/isd-sgcu/johnjud-go-proto v0.6.0/go.mod h1:Yfajs+jSTcuVAKK9xLcVbZkUvCBO3exZV8bOGdelvW0= 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= @@ -246,8 +244,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= -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/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= +google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= 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.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= diff --git a/src/app/service/auth/auth.service_test.go b/src/app/service/auth/auth.service_test.go index b545ed7..9379fd3 100644 --- a/src/app/service/auth/auth.service_test.go +++ b/src/app/service/auth/auth.service_test.go @@ -23,7 +23,7 @@ type AuthServiceTest struct { token string refreshTokenRequest *dto.RefreshTokenRequest forgotPasswordRequest *dto.ForgotPasswordRequest - resetPasswordRequest *dto.ResetPasswordRequest + resetPasswordRequest *dto.ResetPasswordRequest } func TestAuthService(t *testing.T) { diff --git a/src/mocks/client/image/image.mock.go b/src/mocks/client/image/image.mock.go index 66efa34..9036637 100644 --- a/src/mocks/client/image/image.mock.go +++ b/src/mocks/client/image/image.mock.go @@ -21,6 +21,15 @@ func (c *ImageClientMock) Upload(_ context.Context, in *imageProto.UploadImageRe return res, args.Error(1) } +func (c *ImageClientMock) FindAll(_ context.Context, in *imageProto.FindAllImageRequest, _ ...grpc.CallOption) (res *imageProto.FindAllImageResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*imageProto.FindAllImageResponse) + } + return res, args.Error(1) +} + func (c *ImageClientMock) FindByPetId(_ context.Context, in *imageProto.FindImageByPetIdRequest, _ ...grpc.CallOption) (res *imageProto.FindImageByPetIdResponse, err error) { args := c.Called(in) @@ -47,3 +56,12 @@ func (c *ImageClientMock) Delete(_ context.Context, in *imageProto.DeleteImageRe } return res, args.Error(1) } + +func (c *ImageClientMock) DeleteByPetId(_ context.Context, in *imageProto.DeleteByPetIdRequest, _ ...grpc.CallOption) (res *imageProto.DeleteByPetIdResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*imageProto.DeleteByPetIdResponse) + } + return res, args.Error(1) +} From 892249d0a7bb7a9218f0959724ca6db1020074bc Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 16 Feb 2024 17:09:42 +0700 Subject: [PATCH 055/104] feat: image svc add findall, add petid --- src/app/dto/image.dto.go | 1 + src/app/service/image/image.service.go | 29 ++++++++++++++++++++++++++ src/app/utils/image/image.utils.go | 25 ++++++++++------------ src/mocks/service/image/image.mock.go | 15 +++++++++++++ src/pkg/service/image/image.service.go | 1 + 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/app/dto/image.dto.go b/src/app/dto/image.dto.go index d07bdbe..5439b81 100644 --- a/src/app/dto/image.dto.go +++ b/src/app/dto/image.dto.go @@ -7,6 +7,7 @@ type DecomposedFile struct { type ImageResponse struct { Id string `json:"id"` + PetId string `json:"pet_id"` Url string `json:"url"` ObjectKey string `json:"object_key"` } diff --git a/src/app/service/image/image.service.go b/src/app/service/image/image.service.go index ec00042..4a08c46 100644 --- a/src/app/service/image/image.service.go +++ b/src/app/service/image/image.service.go @@ -24,6 +24,35 @@ func NewService(client proto.ImageServiceClient) *Service { } } +func (s *Service) FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + res, errRes := s.client.FindAll(ctx, &proto.FindAllImageRequest{}) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Str("service", "image"). + Str("module", "find all"). + Msg(st.Message()) + switch st.Code() { + case codes.Unavailable: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + default: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + } + return utils.ProtoToDtoList(res.Images), nil +} + func (s *Service) FindByPetId(petId string) ([]*dto.ImageResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() diff --git a/src/app/utils/image/image.utils.go b/src/app/utils/image/image.utils.go index 620a830..c30c346 100644 --- a/src/app/utils/image/image.utils.go +++ b/src/app/utils/image/image.utils.go @@ -1,8 +1,6 @@ package image import ( - "fmt" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" imageProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" ) @@ -10,6 +8,7 @@ import ( func ProtoToDto(in *imageProto.Image) *dto.ImageResponse { return &dto.ImageResponse{ Id: in.Id, + PetId: in.PetId, Url: in.ImageUrl, ObjectKey: in.ObjectKey, } @@ -20,6 +19,7 @@ func ProtoToDtoList(in []*imageProto.Image) []*dto.ImageResponse { for _, i := range in { res = append(res, &dto.ImageResponse{ Id: i.Id, + PetId: i.PetId, Url: i.ImageUrl, ObjectKey: i.ObjectKey, }) @@ -35,19 +35,16 @@ func CreateDtoToProto(in *dto.UploadImageRequest) *imageProto.UploadImageRequest } } -func MockImageList(n int) [][]*imageProto.Image { - var imagesList [][]*imageProto.Image - for i := 0; i <= n; i++ { - var images []*imageProto.Image - for j := 0; j <= 3; j++ { - images = append(images, &imageProto.Image{ - Id: fmt.Sprintf("%v%v", i, j), - PetId: fmt.Sprintf("%v%v", i, j), - ImageUrl: fmt.Sprintf("%v%v", i, j), - ObjectKey: fmt.Sprintf("%v%v", i, j), - }) +func ImageList(in []*dto.ImageResponse) map[string][]*imageProto.Image { + imagesList := make(map[string][]*imageProto.Image) + for _, image := range in { + img := &imageProto.Image{ + Id: image.Id, + PetId: image.PetId, + ImageUrl: image.Url, + ObjectKey: image.ObjectKey, } - imagesList = append(imagesList, images) + imagesList[image.PetId] = append(imagesList[image.PetId], img) } return imagesList diff --git a/src/mocks/service/image/image.mock.go b/src/mocks/service/image/image.mock.go index 48da035..37bcdae 100644 --- a/src/mocks/service/image/image.mock.go +++ b/src/mocks/service/image/image.mock.go @@ -64,6 +64,21 @@ func (mr *MockServiceMockRecorder) Delete(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), arg0) } +// FindAll mocks base method. +func (m *MockService) FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindAll") + ret0, _ := ret[0].([]*dto.ImageResponse) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// FindAll indicates an expected call of FindAll. +func (mr *MockServiceMockRecorder) FindAll() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAll", reflect.TypeOf((*MockService)(nil).FindAll)) +} + // FindByPetId mocks base method. func (m *MockService) FindByPetId(arg0 string) ([]*dto.ImageResponse, *dto.ResponseErr) { m.ctrl.T.Helper() diff --git a/src/pkg/service/image/image.service.go b/src/pkg/service/image/image.service.go index e7ff7a1..bb9b976 100644 --- a/src/pkg/service/image/image.service.go +++ b/src/pkg/service/image/image.service.go @@ -5,6 +5,7 @@ import ( ) type Service interface { + FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) FindByPetId(string) ([]*dto.ImageResponse, *dto.ResponseErr) Upload(*dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) Delete(string) (*dto.DeleteImageResponse, *dto.ResponseErr) From 78318316888e8ea8c42744b52d93985e9dbecc2b Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 16 Feb 2024 17:10:02 +0700 Subject: [PATCH 056/104] feat: pet findall, update add real image --- src/app/handler/pet/pet.handler_test.go | 18 ++++++++++--- src/app/service/pet/pet.service.go | 17 +++++++++--- src/app/service/pet/pet.service_test.go | 36 +++++++++++++++++++++---- src/app/utils/pet/pet.utils.go | 30 ++++++++++----------- 4 files changed, 74 insertions(+), 27 deletions(-) diff --git a/src/app/handler/pet/pet.handler_test.go b/src/app/handler/pet/pet.handler_test.go index 0abf7f1..96cc980 100644 --- a/src/app/handler/pet/pet.handler_test.go +++ b/src/app/handler/pet/pet.handler_test.go @@ -40,7 +40,7 @@ type PetHandlerTest struct { ServiceDownErr *dto.ResponseErr InternalErr *dto.ResponseErr Images []*imgProto.Image - ImagesList [][]*imgProto.Image + ImagesList map[string][]*imgProto.Image } func TestPetHandler(t *testing.T) { @@ -48,9 +48,21 @@ func TestPetHandler(t *testing.T) { } func (t *PetHandlerTest) SetupTest() { - imagesList := utils.MockImageList(3) + petIds := []string{faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit()} + imagesList := make(map[string][]*imgProto.Image) + for i := 0; i <= 3; i++ { + for j := 0; j <= 3; j++ { + img := &imgProto.Image{ + Id: faker.UUIDDigit(), + PetId: petIds[i], + ImageUrl: faker.URL(), + ObjectKey: faker.Word(), + } + imagesList[petIds[i]] = append(imagesList[petIds[i]], img) + } + } t.ImagesList = imagesList - t.Images = imagesList[0] + t.Images = imagesList[petIds[0]] var pets []*petProto.Pet genders := []petConst.Gender{petConst.MALE, petConst.FEMALE} statuses := []petConst.Status{petConst.ADOPTED, petConst.FINDHOME} diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index 1810451..41a6aad 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -54,7 +54,13 @@ func (s *Service) FindAll(in *dto.FindAllPetRequest) (result *dto.FindAllPetResp Data: nil, } } - imagesList := utils.MockImageList(len(res.Pets)) + + images, errSvc := s.imageService.FindAll() + if errSvc != nil { + return nil, errSvc + } + + imagesList := utils.ImageList(images) findAllDto := utils.ProtoToDtoList(res.Pets, imagesList) metaData := utils.MetadataProtoToDto(res.Metadata) @@ -202,8 +208,13 @@ func (s *Service) Update(id string, in *dto.UpdatePetRequest) (result *dto.PetRe } } } - images := utils.MockImageList(1)[0] - updatePetResponse := utils.ProtoToDto(res.Pet, utils.ImageProtoToDto(images)) + + images, errSvc := s.imageService.FindByPetId(res.Pet.Id) + if errSvc != nil { + return nil, errSvc + } + + updatePetResponse := utils.ProtoToDto(res.Pet, images) return updatePetResponse, nil } diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 4822b46..84f92e6 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -29,6 +29,7 @@ type PetServiceTest struct { MetadataProto *petproto.FindAllPetMetaData PetNotVisible *petproto.Pet FindAllPetReq *petproto.FindAllPetRequest + FindAllImageReq *imgproto.FindAllImageRequest UpdatePetReq *petproto.UpdatePetRequest CreatePetReq *petproto.CreatePetRequest ChangeViewPetReq *petproto.ChangeViewPetRequest @@ -46,7 +47,8 @@ type PetServiceTest struct { AdoptDto *dto.AdoptByRequest Images []*imgproto.Image - ImagesList [][]*imgproto.Image + AllImages []*imgproto.Image + ImagesList map[string][]*imgproto.Image AssignPetReq *imgproto.AssignPetRequest AssignPetDto *dto.AssignPetRequest @@ -59,16 +61,30 @@ func TestPetService(t *testing.T) { } func (t *PetServiceTest) SetupTest() { - imagesList := utils.MockImageList(3) + petIds := []string{faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit()} + t.AllImages = []*imgproto.Image{} + imagesList := make(map[string][]*imgproto.Image) + for i := 0; i <= 3; i++ { + for j := 0; j <= 3; j++ { + img := &imgproto.Image{ + Id: faker.UUIDDigit(), + PetId: petIds[i], + ImageUrl: faker.URL(), + ObjectKey: faker.Word(), + } + imagesList[petIds[i]] = append(imagesList[petIds[i]], img) + t.AllImages = append(t.AllImages, img) + } + } t.ImagesList = imagesList - t.Images = imagesList[0] + t.Images = imagesList[petIds[0]] genders := []pet.Gender{pet.MALE, pet.FEMALE} statuses := []pet.Status{pet.ADOPTED, pet.FINDHOME} var pets []*petproto.Pet for i := 0; i <= 3; i++ { pet := &petproto.Pet{ - Id: faker.UUIDDigit(), + Id: petIds[i], Type: faker.Word(), Name: faker.Name(), Birthdate: faker.Word(), @@ -77,7 +93,7 @@ func (t *PetServiceTest) SetupTest() { Pattern: faker.Word(), Habit: faker.Paragraph(), Caption: faker.Paragraph(), - Images: imagesList[i], + Images: imagesList[petIds[i]], Status: string(statuses[rand.Intn(2)]), IsSterile: true, IsVaccinated: true, @@ -206,6 +222,8 @@ func (t *PetServiceTest) SetupTest() { PetID: t.Pet.Id, } + t.FindAllImageReq = &imgproto.FindAllImageRequest{} + t.AssignPetReq = &imgproto.AssignPetRequest{ Ids: []string{}, PetId: t.Pet.Id, @@ -262,7 +280,11 @@ func (t *PetServiceTest) TestFindAllSuccess() { client := petmock.PetClientMock{} client.On("FindAll", t.FindAllPetReq).Return(protoResp, nil) + findAllImageResp := &imgproto.FindAllImageResponse{ + Images: t.AllImages, + } imageClient := imagemock.ImageClientMock{} + imageClient.On("FindAll", t.FindAllImageReq).Return(findAllImageResp, nil) imageSvc := imageSvc.NewService(&imageClient) svc := NewService(&client, imageSvc) @@ -468,7 +490,11 @@ func (t *PetServiceTest) TestUpdateSuccess() { client := &petmock.PetClientMock{} client.On("Update", protoReq).Return(protoResp, nil) + findByPetIdResp := &imgproto.FindImageByPetIdResponse{ + Images: t.Images, + } imageClient := imagemock.ImageClientMock{} + imageClient.On("FindByPetId", t.FindByPetIdReq).Return(findByPetIdResp, nil) imageSvc := imageSvc.NewService(&imageClient) svc := NewService(client, imageSvc) diff --git a/src/app/utils/pet/pet.utils.go b/src/app/utils/pet/pet.utils.go index 4741024..c474746 100644 --- a/src/app/utils/pet/pet.utils.go +++ b/src/app/utils/pet/pet.utils.go @@ -2,7 +2,6 @@ package pet import ( "errors" - "fmt" "strconv" "github.com/isd-sgcu/johnjud-gateway/src/app/dto" @@ -11,19 +10,16 @@ import ( imgproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" ) -func MockImageList(n int) [][]*imgproto.Image { - var imagesList [][]*imgproto.Image - for i := 0; i <= n; i++ { - var images []*imgproto.Image - for j := 0; j <= 3; j++ { - images = append(images, &imgproto.Image{ - Id: fmt.Sprintf("%v%v", i, j), - PetId: fmt.Sprintf("%v%v", i, j), - ImageUrl: fmt.Sprintf("%v%v", i, j), - ObjectKey: fmt.Sprintf("%v%v", i, j), - }) +func ImageList(in []*dto.ImageResponse) map[string][]*imgproto.Image { + imagesList := make(map[string][]*imgproto.Image) + for _, image := range in { + img := &imgproto.Image{ + Id: image.Id, + PetId: image.PetId, + ImageUrl: image.Url, + ObjectKey: image.ObjectKey, } - imagesList = append(imagesList, images) + imagesList[image.PetId] = append(imagesList[image.PetId], img) } return imagesList @@ -34,6 +30,7 @@ func ImageProtoToDto(images []*imgproto.Image) []*dto.ImageResponse { for _, image := range images { imageDto = append(imageDto, &dto.ImageResponse{ Id: image.Id, + PetId: image.PetId, Url: image.ImageUrl, ObjectKey: image.ObjectKey, }) @@ -48,6 +45,7 @@ func ImageListProtoToDto(imagesList [][]*imgproto.Image) [][]*dto.ImageResponse for _, image := range images { imageDto = append(imageDto, &dto.ImageResponse{ Id: image.Id, + PetId: image.PetId, Url: image.ImageUrl, ObjectKey: image.ObjectKey, }) @@ -129,9 +127,9 @@ func UpdateDtoToProto(id string, in *dto.UpdatePetRequest) *petproto.UpdatePetRe return req } -func ProtoToDtoList(in []*petproto.Pet, imagesList [][]*imgproto.Image) []*dto.PetResponse { +func ProtoToDtoList(in []*petproto.Pet, imagesList map[string][]*imgproto.Image) []*dto.PetResponse { var resp []*dto.PetResponse - for i, p := range in { + for _, p := range in { pet := &dto.PetResponse{ Id: p.Id, Type: p.Type, @@ -150,7 +148,7 @@ func ProtoToDtoList(in []*petproto.Pet, imagesList [][]*imgproto.Image) []*dto.P Address: p.Address, Contact: p.Contact, AdoptBy: p.AdoptBy, - Images: ImageProtoToDto(imagesList[i]), + Images: ImageProtoToDto(imagesList[p.Id]), } resp = append(resp, pet) } From c68bbdbf04f3e55cf9e1ca39bcd1dec6f893e960 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 16 Feb 2024 20:23:03 +0700 Subject: [PATCH 057/104] fix: get one pet unauth --- src/constant/auth/auth.constant.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/constant/auth/auth.constant.go b/src/constant/auth/auth.constant.go index 733f5ae..e41e96b 100644 --- a/src/constant/auth/auth.constant.go +++ b/src/constant/auth/auth.constant.go @@ -8,6 +8,7 @@ var ExcludePath = map[string]struct{}{ "PUT /auth/reset-password": {}, "GET /user/:id": {}, "GET /pets": {}, + "GET /pets/:id": {}, "GET /adopt": {}, } From 76fc556f815f7eea3b989e23fb98def0a1a5d913 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 16 Feb 2024 21:32:49 +0700 Subject: [PATCH 058/104] feat: add auto imagetag change --- .github/workflows/build.yml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a0e9ba1..1c0c0db 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -52,4 +52,28 @@ jobs: push: true tags: ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }},${{ env.IMAGE_NAME }}:latest cache-from: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache - cache-to: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache,mode=max \ No newline at end of file + cache-to: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache,mode=max + + update-gitops: + name: Update gitops repository + runs-on: ubuntu-latest + + steps: + - name: Checkout gitops repository + uses: actions/checkout@v4 + with: + repository: isd-sgcu/isd-gitops + token: ${{ secrets.GITOPS_TOKEN }} + + - name: Update image tag + uses: mikefarah/yq@master + env: + NEW_TAG: ${{ github.ref_type == 'tag' && github.ref_name || env.IMAGE_TAG }} + with: + cmd: yq -i '.gateway.imageTag = strenv(NEW_TAG)' projects/johnjud/values/gateway-dev.values.yaml + + - name: Commit & Push changes + uses: actions-js/push@v1.4 + with: + github_token: ${{ secrets.GITOPS_TOKEN }} + repository: isd-sgcu/isd-gitops \ No newline at end of file From a3a3933ba0909f3f3be7ad89e64846d705e6bb14 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sat, 17 Feb 2024 13:15:40 +0700 Subject: [PATCH 059/104] feat: img svc add deletebypetid --- src/app/service/image/image.service.go | 42 ++++++++++++++++++++++++++ src/mocks/service/image/image.mock.go | 15 +++++++++ src/pkg/service/image/image.service.go | 1 + 3 files changed, 58 insertions(+) diff --git a/src/app/service/image/image.service.go b/src/app/service/image/image.service.go index 4a08c46..1ead4af 100644 --- a/src/app/service/image/image.service.go +++ b/src/app/service/image/image.service.go @@ -167,6 +167,48 @@ func (s *Service) Delete(id string) (*dto.DeleteImageResponse, *dto.ResponseErr) }, nil } +func (s *Service) DeleteByPetId(petId string) (*dto.DeleteImageResponse, *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + request := &proto.DeleteByPetIdRequest{ + PetId: petId, + } + + res, errRes := s.client.DeleteByPetId(ctx, request) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Err(errRes). + Str("service", "image"). + Str("module", "delete by pet id"). + Msg(st.Message()) + switch st.Code() { + case codes.NotFound: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.ImageNotFoundMessage, + Data: nil, + } + case codes.Unavailable: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + default: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + } + return &dto.DeleteImageResponse{ + Success: res.Success, + }, nil +} + func (s *Service) AssignPet(in *dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() diff --git a/src/mocks/service/image/image.mock.go b/src/mocks/service/image/image.mock.go index 37bcdae..bb59c31 100644 --- a/src/mocks/service/image/image.mock.go +++ b/src/mocks/service/image/image.mock.go @@ -64,6 +64,21 @@ func (mr *MockServiceMockRecorder) Delete(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), arg0) } +// DeleteByPetId mocks base method. +func (m *MockService) DeleteByPetId(arg0 string) (*dto.DeleteImageResponse, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteByPetId", arg0) + ret0, _ := ret[0].(*dto.DeleteImageResponse) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// DeleteByPetId indicates an expected call of DeleteByPetId. +func (mr *MockServiceMockRecorder) DeleteByPetId(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteByPetId", reflect.TypeOf((*MockService)(nil).DeleteByPetId), arg0) +} + // FindAll mocks base method. func (m *MockService) FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) { m.ctrl.T.Helper() diff --git a/src/pkg/service/image/image.service.go b/src/pkg/service/image/image.service.go index bb9b976..d4f92d8 100644 --- a/src/pkg/service/image/image.service.go +++ b/src/pkg/service/image/image.service.go @@ -9,5 +9,6 @@ type Service interface { FindByPetId(string) ([]*dto.ImageResponse, *dto.ResponseErr) Upload(*dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) Delete(string) (*dto.DeleteImageResponse, *dto.ResponseErr) + DeleteByPetId(string) (*dto.DeleteImageResponse, *dto.ResponseErr) AssignPet(*dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) } From 932ff3b8424ebcb191ee1b8613474da71fa04d58 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sat, 17 Feb 2024 13:16:09 +0700 Subject: [PATCH 060/104] feat: pet svc delete use image's deletebypetid --- src/app/service/pet/pet.service.go | 6 ++++++ src/app/service/pet/pet.service_test.go | 13 ++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index 41a6aad..3ab604a 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -253,6 +253,12 @@ func (s *Service) Delete(id string) (result *dto.DeleteResponse, err *dto.Respon } } } + + _, errSvc := s.imageService.DeleteByPetId(id) + if errSvc != nil { + return nil, errSvc + } + return &dto.DeleteResponse{ Success: res.Success, }, nil diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 84f92e6..653376b 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -543,19 +543,26 @@ func (t *PetServiceTest) TestUpdateUnavailableServiceError() { } func (t *PetServiceTest) TestDeleteSuccess() { - protoReq := &petproto.DeletePetRequest{ + petProtoReq := &petproto.DeletePetRequest{ Id: t.Pet.Id, } - protoResp := &petproto.DeletePetResponse{ + petProtoResp := &petproto.DeletePetResponse{ + Success: true, + } + imageProtoReq := &imgproto.DeleteByPetIdRequest{ + PetId: t.Pet.Id, + } + imageProtoResp := &imgproto.DeleteByPetIdResponse{ Success: true, } expected := &dto.DeleteResponse{Success: true} client := &petmock.PetClientMock{} - client.On("Delete", protoReq).Return(protoResp, nil) + client.On("Delete", petProtoReq).Return(petProtoResp, nil) imageClient := imagemock.ImageClientMock{} + imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) imageSvc := imageSvc.NewService(&imageClient) svc := NewService(client, imageSvc) From 507b44ec203813482f6881ff587859a4f722adb0 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sat, 17 Feb 2024 22:35:07 +0700 Subject: [PATCH 061/104] fix: updatepetproto add bool fields --- src/app/utils/pet/pet.utils.go | 46 +++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/app/utils/pet/pet.utils.go b/src/app/utils/pet/pet.utils.go index c474746..310b91f 100644 --- a/src/app/utils/pet/pet.utils.go +++ b/src/app/utils/pet/pet.utils.go @@ -104,23 +104,39 @@ func CreateDtoToProto(in *dto.CreatePetRequest) *petproto.CreatePetRequest { } func UpdateDtoToProto(id string, in *dto.UpdatePetRequest) *petproto.UpdatePetRequest { + isSterile := false + if in.IsSterile != nil { + isSterile = *in.IsSterile + } + isVaccinated := false + if in.IsVaccinated != nil { + isVaccinated = *in.IsVaccinated + } + isVisible := false + if in.IsVisible != nil { + isVisible = *in.IsVisible + } + req := &petproto.UpdatePetRequest{ Pet: &petproto.Pet{ - Id: id, - Type: in.Type, - Name: in.Name, - Birthdate: in.Birthdate, - Gender: string(in.Gender), - Color: in.Color, - Pattern: in.Pattern, - Habit: in.Habit, - Caption: in.Caption, - Images: []*imgproto.Image{}, - Status: string(in.Status), - Origin: in.Origin, - Address: in.Address, - Contact: in.Contact, - AdoptBy: in.AdoptBy, + Id: id, + Type: in.Type, + Name: in.Name, + Birthdate: in.Birthdate, + Gender: string(in.Gender), + Color: in.Color, + Pattern: in.Pattern, + Habit: in.Habit, + Caption: in.Caption, + Images: []*imgproto.Image{}, + Status: string(in.Status), + IsSterile: isSterile, + IsVaccinated: isVaccinated, + IsVisible: isVisible, + Origin: in.Origin, + Address: in.Address, + Contact: in.Contact, + AdoptBy: in.AdoptBy, }, } From 716462400972004d491416a764ee8e1d35249032 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sat, 17 Feb 2024 23:00:48 +0700 Subject: [PATCH 062/104] fix: visivle not required, adopt remove pet_id body --- src/app/dto/pet.dto.go | 3 +-- src/app/service/pet/pet.service.go | 2 +- src/app/service/pet/pet.service_test.go | 1 - src/docs/docs.go | 10 +++------- src/docs/swagger.json | 10 +++------- src/docs/swagger.yaml | 7 ++----- 6 files changed, 10 insertions(+), 23 deletions(-) diff --git a/src/app/dto/pet.dto.go b/src/app/dto/pet.dto.go index cece7bf..8894c88 100644 --- a/src/app/dto/pet.dto.go +++ b/src/app/dto/pet.dto.go @@ -72,7 +72,7 @@ type CreatePetRequest struct { } type ChangeViewPetRequest struct { - Visible bool `json:"visible" validate:"required"` + Visible bool `json:"visible"` } type ChangeViewPetResponse struct { @@ -81,7 +81,6 @@ type ChangeViewPetResponse struct { type AdoptByRequest struct { UserID string `json:"user_id" validate:"required"` - PetID string `json:"pet_id" validate:"required"` } type AdoptByResponse struct { diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index 3ab604a..68eccab 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -317,7 +317,7 @@ func (s *Service) Adopt(petId string, in *dto.AdoptByRequest) (result *dto.Adopt res, errRes := s.petClient.AdoptPet(ctx, &petproto.AdoptPetRequest{ UserId: in.UserID, - PetId: in.PetID, + PetId: petId, }) if errRes != nil { st, _ := status.FromError(errRes) diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 653376b..87119e5 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -219,7 +219,6 @@ func (t *PetServiceTest) SetupTest() { t.AdoptDto = &dto.AdoptByRequest{ UserID: t.Pet.AdoptBy, - PetID: t.Pet.Id, } t.FindAllImageReq = &imgproto.FindAllImageRequest{} diff --git a/src/docs/docs.go b/src/docs/docs.go index 8e9ba2f..93be1fb 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -951,13 +951,9 @@ const docTemplate = `{ "dto.AdoptByRequest": { "type": "object", "required": [ - "pet_id", "user_id" ], "properties": { - "pet_id": { - "type": "string" - }, "user_id": { "type": "string" } @@ -985,9 +981,6 @@ const docTemplate = `{ }, "dto.ChangeViewPetRequest": { "type": "object", - "required": [ - "visible" - ], "properties": { "visible": { "type": "boolean" @@ -1146,6 +1139,9 @@ const docTemplate = `{ "object_key": { "type": "string" }, + "pet_id": { + "type": "string" + }, "url": { "type": "string" } diff --git a/src/docs/swagger.json b/src/docs/swagger.json index 1350d3d..86894ef 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -947,13 +947,9 @@ "dto.AdoptByRequest": { "type": "object", "required": [ - "pet_id", "user_id" ], "properties": { - "pet_id": { - "type": "string" - }, "user_id": { "type": "string" } @@ -981,9 +977,6 @@ }, "dto.ChangeViewPetRequest": { "type": "object", - "required": [ - "visible" - ], "properties": { "visible": { "type": "boolean" @@ -1142,6 +1135,9 @@ "object_key": { "type": "string" }, + "pet_id": { + "type": "string" + }, "url": { "type": "string" } diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 8c9baca..5b00a7d 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -1,12 +1,9 @@ definitions: dto.AdoptByRequest: properties: - pet_id: - type: string user_id: type: string required: - - pet_id - user_id type: object dto.AdoptByResponse: @@ -26,8 +23,6 @@ definitions: properties: visible: type: boolean - required: - - visible type: object dto.ChangeViewPetResponse: properties: @@ -130,6 +125,8 @@ definitions: type: string object_key: type: string + pet_id: + type: string url: type: string type: object From 23292bbfbcbdb069afe828370c4af33e27bbd4ba Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Tue, 20 Feb 2024 17:00:32 +0700 Subject: [PATCH 063/104] fix: pet delete image before pet --- src/app/service/pet/pet.service.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index 68eccab..f15d67a 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -222,6 +222,11 @@ func (s *Service) Delete(id string) (result *dto.DeleteResponse, err *dto.Respon ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() + _, errSvc := s.imageService.DeleteByPetId(id) + if errSvc != nil { + return nil, errSvc + } + res, errRes := s.petClient.Delete(ctx, &petproto.DeletePetRequest{ Id: id, }) @@ -254,11 +259,6 @@ func (s *Service) Delete(id string) (result *dto.DeleteResponse, err *dto.Respon } } - _, errSvc := s.imageService.DeleteByPetId(id) - if errSvc != nil { - return nil, errSvc - } - return &dto.DeleteResponse{ Success: res.Success, }, nil From cb4ff1319e6e8f0588166bd3986360726d889036 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Tue, 20 Feb 2024 17:44:49 +0700 Subject: [PATCH 064/104] fix: unit test pet --- src/app/service/pet/pet.service_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 87119e5..72f1bfd 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -578,6 +578,13 @@ func (t *PetServiceTest) TestDeleteNotFound() { protoResp := &petproto.DeletePetResponse{ Success: false, } + imageProtoReq := &imgproto.DeleteByPetIdRequest{ + PetId: t.Pet.Id, + } + imageProtoResp := &imgproto.DeleteByPetIdResponse{ + Success: true, + } + clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) expected := t.NotFoundErr @@ -586,6 +593,7 @@ func (t *PetServiceTest) TestDeleteNotFound() { client.On("Delete", protoReq).Return(protoResp, clientErr) imageClient := imagemock.ImageClientMock{} + imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) imageSvc := imageSvc.NewService(&imageClient) svc := NewService(client, imageSvc) @@ -602,6 +610,13 @@ func (t *PetServiceTest) TestDeleteServiceUnavailableError() { protoResp := &petproto.DeletePetResponse{ Success: false, } + imageProtoReq := &imgproto.DeleteByPetIdRequest{ + PetId: t.Pet.Id, + } + imageProtoResp := &imgproto.DeleteByPetIdResponse{ + Success: true, + } + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) expected := t.UnavailableServiceErr @@ -610,6 +625,7 @@ func (t *PetServiceTest) TestDeleteServiceUnavailableError() { client.On("Delete", protoReq).Return(protoResp, clientErr) imageClient := imagemock.ImageClientMock{} + imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) imageSvc := imageSvc.NewService(&imageClient) svc := NewService(client, imageSvc) From 8f3c9c43e518937be6fcd66c49944c4d557093e3 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Feb 2024 23:46:17 +0700 Subject: [PATCH 065/104] feat: isAdmin pet findall --- go.mod | 4 ++-- go.sum | 8 +++---- src/app/handler/pet/pet.handler.go | 31 +++++++++++++++++++++++-- src/app/handler/pet/pet.handler_test.go | 4 ++-- src/app/service/pet/pet.service.go | 6 ++--- src/app/service/pet/pet.service_test.go | 8 +++---- src/app/utils/pet/pet.utils.go | 8 +++++-- src/constant/auth/auth.constant.go | 1 + src/main.go | 1 + src/mocks/service/pet/pet.mock.go | 8 +++---- src/pkg/service/pet/pet.service.go | 2 +- 11 files changed, 57 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index b9fcea2..3a00ffe 100644 --- a/go.mod +++ b/go.mod @@ -12,12 +12,12 @@ require ( github.com/gofiber/fiber/v2 v2.52.0 github.com/golang/mock v1.6.0 github.com/google/uuid v1.5.0 - github.com/isd-sgcu/johnjud-go-proto v0.6.0 + github.com/isd-sgcu/johnjud-go-proto v0.6.1 github.com/rs/zerolog v1.31.0 github.com/spf13/viper v1.18.1 github.com/stretchr/testify v1.8.4 github.com/swaggo/swag v1.16.2 - google.golang.org/grpc v1.61.0 + google.golang.org/grpc v1.61.1 ) require ( diff --git a/go.sum b/go.sum index df32434..9663fd7 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.6.0 h1:sOWGjsqXwzpSaweSlNqPlttExZryp8mV76ob95LppjM= -github.com/isd-sgcu/johnjud-go-proto v0.6.0/go.mod h1:Yfajs+jSTcuVAKK9xLcVbZkUvCBO3exZV8bOGdelvW0= +github.com/isd-sgcu/johnjud-go-proto v0.6.1 h1:9gGBsMOONhuIsSEavMb9FiD7d+naX26niSQPwQGHOM0= +github.com/isd-sgcu/johnjud-go-proto v0.6.1/go.mod h1:0728XfYpZw/4K/+NmXsyVt1z7Cxwbc4nxLg7LpowIE4= 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= @@ -244,8 +244,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= -google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= -google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= +google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= 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.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= diff --git a/src/app/handler/pet/pet.handler.go b/src/app/handler/pet/pet.handler.go index dfce616..c35048b 100644 --- a/src/app/handler/pet/pet.handler.go +++ b/src/app/handler/pet/pet.handler.go @@ -23,7 +23,7 @@ func NewHandler(service petSvc.Service, imageService imageSvc.Service, validate return &Handler{service, imageService, validate} } -// FindAll is a function that returns all pets in database +// FindAll is a function that returns all VISIBLE pets in database // @Summary finds all pets // @Description Returns the data of pets if successful // @Tags pet @@ -40,7 +40,34 @@ func (h *Handler) FindAll(c router.IContext) { c.JSON(http.StatusBadRequest, err) } - response, respErr := h.service.FindAll(request) + response, respErr := h.service.FindAll(request, false) + if respErr != nil { + c.JSON(respErr.StatusCode, respErr) + return + } + + c.JSON(http.StatusOK, response) + return +} + +// FindAllAdmin is a function that returns ALL pets in database +// @Summary finds all pets +// @Description Returns the data of pets if successful +// @Tags pet +// @Accept json +// @Produce json +// @Success 200 {object} []dto.PetResponse +// @Failure 500 {object} dto.ResponseInternalErr "Internal service error" +// @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" +// @Router /v1/pets/admin [get] +func (h *Handler) FindAllAdmin(c router.IContext) { + queries := c.Queries() + request, err := petUtils.QueriesToFindAllDto(queries) + if err != nil { + c.JSON(http.StatusBadRequest, err) + } + + response, respErr := h.service.FindAll(request, true) if respErr != nil { c.JSON(respErr.StatusCode, respErr) return diff --git a/src/app/handler/pet/pet.handler_test.go b/src/app/handler/pet/pet.handler_test.go index 96cc980..aa337d2 100644 --- a/src/app/handler/pet/pet.handler_test.go +++ b/src/app/handler/pet/pet.handler_test.go @@ -169,7 +169,7 @@ func (t *PetHandlerTest) SetupTest() { } func (t *PetHandlerTest) TestFindAllSuccess() { - findAllResponse := utils.ProtoToDtoList(t.Pets, t.ImagesList) + findAllResponse := utils.ProtoToDtoList(t.Pets, t.ImagesList, false) metadataResponse := t.Metadata expectedResponse := &dto.FindAllPetResponse{ Pets: findAllResponse, @@ -184,7 +184,7 @@ func (t *PetHandlerTest) TestFindAllSuccess() { context := routerMock.NewMockIContext(controller) context.EXPECT().Queries().Return(t.QueriesMock) - petSvc.EXPECT().FindAll(t.FindAllPetRequest).Return(expectedResponse, nil) + petSvc.EXPECT().FindAll(t.FindAllPetRequest, false).Return(expectedResponse, nil) context.EXPECT().JSON(http.StatusOK, expectedResponse) handler := NewHandler(petSvc, imageSvc, validator) diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index f15d67a..be98fa4 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -28,11 +28,11 @@ func NewService(petClient petproto.PetServiceClient, imageService imageSvc.Servi } } -func (s *Service) FindAll(in *dto.FindAllPetRequest) (result *dto.FindAllPetResponse, err *dto.ResponseErr) { +func (s *Service) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result *dto.FindAllPetResponse, err *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - res, errRes := s.petClient.FindAll(ctx, utils.FindAllDtoToProto(in)) + res, errRes := s.petClient.FindAll(ctx, utils.FindAllDtoToProto(in, isAdmin)) if errRes != nil { st, _ := status.FromError(errRes) log.Error(). @@ -61,7 +61,7 @@ func (s *Service) FindAll(in *dto.FindAllPetRequest) (result *dto.FindAllPetResp } imagesList := utils.ImageList(images) - findAllDto := utils.ProtoToDtoList(res.Pets, imagesList) + findAllDto := utils.ProtoToDtoList(res.Pets, imagesList, isAdmin) metaData := utils.MetadataProtoToDto(res.Metadata) return &dto.FindAllPetResponse{ diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 72f1bfd..3d4bdfe 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -199,7 +199,7 @@ func (t *PetServiceTest) SetupTest() { AdoptBy: t.Pet.AdoptBy, } - t.FindAllPetReq = utils.FindAllDtoToProto(t.FindAllPetDto) + t.FindAllPetReq = utils.FindAllDtoToProto(t.FindAllPetDto, true) t.CreatePetReq = utils.CreateDtoToProto(t.CreatePetDto) t.UpdatePetReq = utils.UpdateDtoToProto(t.Pet.Id, t.UpdatePetDto) @@ -268,7 +268,7 @@ func (t *PetServiceTest) TestFindAllSuccess() { Metadata: t.MetadataProto, } - findAllPPetsDto := utils.ProtoToDtoList(t.Pets, t.ImagesList) + findAllPPetsDto := utils.ProtoToDtoList(t.Pets, t.ImagesList, false) metadataDto := t.MetadataDto expected := &dto.FindAllPetResponse{ @@ -287,7 +287,7 @@ func (t *PetServiceTest) TestFindAllSuccess() { imageSvc := imageSvc.NewService(&imageClient) svc := NewService(&client, imageSvc) - actual, err := svc.FindAll(t.FindAllPetDto) + actual, err := svc.FindAll(t.FindAllPetDto, true) assert.Nil(t.T(), err) assert.Equal(t.T(), expected, actual) @@ -305,7 +305,7 @@ func (t *PetServiceTest) TestFindAllUnavailableServiceError() { imageSvc := imageSvc.NewService(&imageClient) svc := NewService(&client, imageSvc) - actual, err := svc.FindAll(t.FindAllPetDto) + actual, err := svc.FindAll(t.FindAllPetDto, true) assert.Nil(t.T(), actual) assert.Equal(t.T(), expected, err) diff --git a/src/app/utils/pet/pet.utils.go b/src/app/utils/pet/pet.utils.go index 310b91f..54b5205 100644 --- a/src/app/utils/pet/pet.utils.go +++ b/src/app/utils/pet/pet.utils.go @@ -143,9 +143,12 @@ func UpdateDtoToProto(id string, in *dto.UpdatePetRequest) *petproto.UpdatePetRe return req } -func ProtoToDtoList(in []*petproto.Pet, imagesList map[string][]*imgproto.Image) []*dto.PetResponse { +func ProtoToDtoList(in []*petproto.Pet, imagesList map[string][]*imgproto.Image, isAdmin bool) []*dto.PetResponse { var resp []*dto.PetResponse for _, p := range in { + if !isAdmin && !p.IsVisible { + continue + } pet := &dto.PetResponse{ Id: p.Id, Type: p.Type, @@ -182,7 +185,7 @@ func extractImages(images []*imgproto.Image) []dto.ImageResponse { return result } -func FindAllDtoToProto(in *dto.FindAllPetRequest) *petproto.FindAllPetRequest { +func FindAllDtoToProto(in *dto.FindAllPetRequest, isAdmin bool) *petproto.FindAllPetRequest { return &petproto.FindAllPetRequest{ Search: in.Search, Type: in.Type, @@ -194,6 +197,7 @@ func FindAllDtoToProto(in *dto.FindAllPetRequest) *petproto.FindAllPetRequest { Page: int32(in.Page), MaxAge: int32(in.MaxAge), MinAge: int32(in.MinAge), + IsAdmin: isAdmin, } } diff --git a/src/constant/auth/auth.constant.go b/src/constant/auth/auth.constant.go index e41e96b..615b0c8 100644 --- a/src/constant/auth/auth.constant.go +++ b/src/constant/auth/auth.constant.go @@ -14,6 +14,7 @@ var ExcludePath = map[string]struct{}{ var AdminPath = map[string]struct{}{ // "DELETE /user/:id": {}, + // "GET /pets/admin": {}, // "POST /pets": {}, // "PUT /pets/:id": {}, // "PUT /pets/:id/visible": {}, diff --git a/src/main.go b/src/main.go index 0538fa1..04e7a66 100644 --- a/src/main.go +++ b/src/main.go @@ -144,6 +144,7 @@ func main() { r.GetHealthCheck("", hc.HealthCheck) r.GetPet("", petHandler.FindAll) + r.GetPet("/admin", petHandler.FindAllAdmin) r.GetPet("/:id", petHandler.FindOne) r.PostPet("", petHandler.Create) r.PutPet("/:id", petHandler.Update) diff --git a/src/mocks/service/pet/pet.mock.go b/src/mocks/service/pet/pet.mock.go index eba3652..2e5ff16 100644 --- a/src/mocks/service/pet/pet.mock.go +++ b/src/mocks/service/pet/pet.mock.go @@ -95,18 +95,18 @@ func (mr *MockServiceMockRecorder) Delete(arg0 interface{}) *gomock.Call { } // FindAll mocks base method. -func (m *MockService) FindAll(arg0 *dto.FindAllPetRequest) (*dto.FindAllPetResponse, *dto.ResponseErr) { +func (m *MockService) FindAll(arg0 *dto.FindAllPetRequest, arg1 bool) (*dto.FindAllPetResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindAll", arg0) + ret := m.ctrl.Call(m, "FindAll", arg0, arg1) ret0, _ := ret[0].(*dto.FindAllPetResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // FindAll indicates an expected call of FindAll. -func (mr *MockServiceMockRecorder) FindAll(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) FindAll(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAll", reflect.TypeOf((*MockService)(nil).FindAll), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAll", reflect.TypeOf((*MockService)(nil).FindAll), arg0, arg1) } // FindOne mocks base method. diff --git a/src/pkg/service/pet/pet.service.go b/src/pkg/service/pet/pet.service.go index fbbe5bc..302e947 100644 --- a/src/pkg/service/pet/pet.service.go +++ b/src/pkg/service/pet/pet.service.go @@ -5,7 +5,7 @@ import ( ) type Service interface { - FindAll(*dto.FindAllPetRequest) (*dto.FindAllPetResponse, *dto.ResponseErr) + FindAll(*dto.FindAllPetRequest, bool) (*dto.FindAllPetResponse, *dto.ResponseErr) FindOne(string) (*dto.PetResponse, *dto.ResponseErr) Create(*dto.CreatePetRequest) (*dto.PetResponse, *dto.ResponseErr) Update(string, *dto.UpdatePetRequest) (*dto.PetResponse, *dto.ResponseErr) From 0e276b28ac0709089488e195408d2d2952ff7559 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Thu, 22 Feb 2024 00:21:58 +0700 Subject: [PATCH 066/104] tmp: log findall --- src/app/service/pet/pet.service.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index be98fa4..70c0223 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -54,6 +54,9 @@ func (s *Service) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result *dto. Data: nil, } } + log.Info(). + Str("service", "pet"). + Str("module", "petClient.FindAll").Interface("res", res).Msg("") images, errSvc := s.imageService.FindAll() if errSvc != nil { @@ -63,6 +66,9 @@ func (s *Service) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result *dto. imagesList := utils.ImageList(images) findAllDto := utils.ProtoToDtoList(res.Pets, imagesList, isAdmin) metaData := utils.MetadataProtoToDto(res.Metadata) + log.Info(). + Str("service", "pet"). + Str("module", "findAllDto").Interface("dto", findAllDto).Msg("") return &dto.FindAllPetResponse{ Pets: findAllDto, From cdfcf26acc8b4019d7baaf7d52a77df85de743d7 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Thu, 22 Feb 2024 13:20:09 +0700 Subject: [PATCH 067/104] fix: remove tmp logs --- src/app/service/pet/pet.service.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index 70c0223..be98fa4 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -54,9 +54,6 @@ func (s *Service) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result *dto. Data: nil, } } - log.Info(). - Str("service", "pet"). - Str("module", "petClient.FindAll").Interface("res", res).Msg("") images, errSvc := s.imageService.FindAll() if errSvc != nil { @@ -66,9 +63,6 @@ func (s *Service) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result *dto. imagesList := utils.ImageList(images) findAllDto := utils.ProtoToDtoList(res.Pets, imagesList, isAdmin) metaData := utils.MetadataProtoToDto(res.Metadata) - log.Info(). - Str("service", "pet"). - Str("module", "findAllDto").Interface("dto", findAllDto).Msg("") return &dto.FindAllPetResponse{ Pets: findAllDto, From 8a00e462cb3c92eba8f3ff1157fd5250b4b39e97 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sat, 16 Mar 2024 15:41:09 +0700 Subject: [PATCH 068/104] feat: open admin auth --- src/constant/auth/auth.constant.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/constant/auth/auth.constant.go b/src/constant/auth/auth.constant.go index 615b0c8..abca37d 100644 --- a/src/constant/auth/auth.constant.go +++ b/src/constant/auth/auth.constant.go @@ -13,16 +13,15 @@ var ExcludePath = map[string]struct{}{ } var AdminPath = map[string]struct{}{ - // "DELETE /user/:id": {}, - // "GET /pets/admin": {}, - // "POST /pets": {}, - // "PUT /pets/:id": {}, - // "PUT /pets/:id/visible": {}, - // "DELETE /pets/:id": {}, - // "POST /images/assign/:pet_id": {}, - // "DELETE /images/:id": {}, - // "POST /images/": {}, - // "GET /images/:id": {}, + "DELETE /user/:id": {}, + "GET /pets/admin": {}, + "POST /pets": {}, + "PUT /pets/:id": {}, + "PUT /pets/:id/visible": {}, + "DELETE /pets/:id": {}, + "POST /images/assign/:pet_id": {}, + "DELETE /images/:id": {}, + "POST /images/": {}, } var VersionList = map[string]struct{}{ From 015013c6c589e544aec3568bb10a250fdf043af7 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sun, 24 Mar 2024 12:37:44 +0700 Subject: [PATCH 069/104] fix: reset password url --- src/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.go b/src/main.go index 04e7a66..6e3abbb 100644 --- a/src/main.go +++ b/src/main.go @@ -139,7 +139,7 @@ func main() { //r.PostAuth("/me", authHandler.Validate) r.PostAuth("/refreshToken", authHandler.RefreshToken) r.PostAuth("/forgot-password", authHandler.ForgotPassword) - r.PutAuth("/reset-password", authHandler.ResetPassword) + r.PutAuth("/admin/reset-password", authHandler.ResetPassword) r.GetHealthCheck("", hc.HealthCheck) From f6383ae6955e8da839a0ed13cf3219f06f607626 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sun, 12 May 2024 17:54:23 +0700 Subject: [PATCH 070/104] feat: add owner, tel in pet --- go.mod | 17 +++++------ go.sum | 39 ++++++++++--------------- src/app/dto/pet.dto.go | 11 +++---- src/app/handler/pet/pet.handler_test.go | 8 ++--- src/app/service/pet/pet.service_test.go | 20 ++++++------- src/app/utils/pet/pet.utils.go | 16 +++++----- 6 files changed, 52 insertions(+), 59 deletions(-) diff --git a/go.mod b/go.mod index 3a00ffe..99ce8ee 100644 --- a/go.mod +++ b/go.mod @@ -11,13 +11,13 @@ require ( github.com/go-playground/validator/v10 v10.16.0 github.com/gofiber/fiber/v2 v2.52.0 github.com/golang/mock v1.6.0 - github.com/google/uuid v1.5.0 - github.com/isd-sgcu/johnjud-go-proto v0.6.1 + github.com/google/uuid v1.6.0 + github.com/isd-sgcu/johnjud-go-proto v0.7.1 github.com/rs/zerolog v1.31.0 github.com/spf13/viper v1.18.1 github.com/stretchr/testify v1.8.4 github.com/swaggo/swag v1.16.2 - google.golang.org/grpc v1.61.1 + google.golang.org/grpc v1.63.2 ) require ( @@ -30,7 +30,6 @@ require ( github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/spec v0.20.13 // indirect github.com/go-openapi/swag v0.22.7 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.4 // indirect @@ -58,14 +57,14 @@ require ( github.com/valyala/tcplisten v1.0.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/crypto v0.16.0 // indirect + golang.org/x/crypto v0.19.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sys v0.17.0 // indirect 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.32.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/protobuf v1.34.1 // 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 9663fd7..5604213 100644 --- a/go.sum +++ b/go.sum @@ -55,19 +55,15 @@ github.com/gofiber/fiber/v2 v2.52.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/ github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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/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.6.1 h1:9gGBsMOONhuIsSEavMb9FiD7d+naX26niSQPwQGHOM0= -github.com/isd-sgcu/johnjud-go-proto v0.6.1/go.mod h1:0728XfYpZw/4K/+NmXsyVt1z7Cxwbc4nxLg7LpowIE4= +github.com/isd-sgcu/johnjud-go-proto v0.7.1 h1:sdwyEvFcGoLmoypjOuZRgQZGeuX9jcXdiPcUWJw3VoA= +github.com/isd-sgcu/johnjud-go-proto v0.7.1/go.mod h1:C1oOvRz1bYqX2EGG3Iy+1mbB9buvhwudR/hYwWKkAwE= 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= @@ -177,8 +173,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -196,8 +192,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -218,8 +214,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -240,16 +236,13 @@ golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= -google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= -google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= -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.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/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/pet.dto.go b/src/app/dto/pet.dto.go index 8894c88..337faad 100644 --- a/src/app/dto/pet.dto.go +++ b/src/app/dto/pet.dto.go @@ -19,9 +19,9 @@ type PetResponse struct { IsVaccinated *bool `json:"is_vaccinated"` IsVisible *bool `json:"is_visible"` Origin string `json:"origin"` - Address string `json:"address"` + Owner string `json:"owner"` Contact string `json:"contact"` - AdoptBy string `json:"adopt_by"` + Tel string `json:"tel"` Images []*ImageResponse `json:"images"` } @@ -66,8 +66,9 @@ type CreatePetRequest struct { IsVisible *bool `json:"is_visible" validate:"required"` Origin string `json:"origin" validate:"required"` Address string `json:"address"` + Owner string `json:"owner"` Contact string `json:"contact"` - AdoptBy string `json:"adopt_by"` + Tel string `json:"tel"` Images []string `json:"images"` } @@ -101,9 +102,9 @@ type UpdatePetRequest struct { IsVaccinated *bool `json:"is_vaccinated"` IsVisible *bool `json:"is_visible"` Origin string `json:"origin"` - Address string `json:"address"` + Owner string `json:"owner"` Contact string `json:"contact"` - AdoptBy string `json:"adopt_by"` + Tel string `json:"tel"` Images []string `json:"images"` } type DeleteRequest struct { diff --git a/src/app/handler/pet/pet.handler_test.go b/src/app/handler/pet/pet.handler_test.go index aa337d2..ca4f694 100644 --- a/src/app/handler/pet/pet.handler_test.go +++ b/src/app/handler/pet/pet.handler_test.go @@ -84,9 +84,9 @@ func (t *PetHandlerTest) SetupTest() { IsVaccinated: true, IsVisible: true, Origin: faker.Paragraph(), - Address: faker.Paragraph(), + Owner: faker.Paragraph(), Contact: faker.Paragraph(), - AdoptBy: "", + Tel: "", } pets = append(pets, pet) @@ -117,9 +117,9 @@ func (t *PetHandlerTest) SetupTest() { IsVaccinated: &t.Pet.IsVaccinated, IsVisible: &t.Pet.IsVisible, Origin: t.Pet.Origin, - Address: t.Pet.Address, + Owner: t.Pet.Owner, Contact: t.Pet.Contact, - AdoptBy: t.Pet.AdoptBy, + Tel: t.Pet.Tel, } t.QueriesMock = map[string]string{ diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 3d4bdfe..1fe08a8 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -99,9 +99,9 @@ func (t *PetServiceTest) SetupTest() { IsVaccinated: true, IsVisible: true, Origin: faker.Paragraph(), - Address: faker.Paragraph(), + Owner: faker.Paragraph(), Contact: faker.Paragraph(), - AdoptBy: faker.UUIDDigit(), + Tel: faker.UUIDDigit(), } pets = append(pets, pet) @@ -140,9 +140,9 @@ func (t *PetServiceTest) SetupTest() { IsVaccinated: t.Pet.IsVaccinated, IsVisible: false, Origin: t.Pet.Origin, - Address: t.Pet.Address, + Owner: t.Pet.Owner, Contact: t.Pet.Contact, - AdoptBy: t.Pet.AdoptBy, + Tel: t.Pet.Tel, } t.PetDto = utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Pet.Images)) @@ -174,9 +174,9 @@ func (t *PetServiceTest) SetupTest() { IsVaccinated: &t.Pet.IsVaccinated, IsVisible: &t.Pet.IsVisible, Origin: t.Pet.Origin, - Address: t.Pet.Address, + Owner: t.Pet.Owner, Contact: t.Pet.Contact, - AdoptBy: t.Pet.AdoptBy, + Tel: t.Pet.Tel, } t.UpdatePetDto = &dto.UpdatePetRequest{ @@ -194,9 +194,9 @@ func (t *PetServiceTest) SetupTest() { IsVaccinated: &t.Pet.IsVaccinated, IsVisible: &t.Pet.IsVisible, Origin: t.Pet.Origin, - Address: t.Pet.Address, + Owner: t.Pet.Owner, Contact: t.Pet.Contact, - AdoptBy: t.Pet.AdoptBy, + Tel: t.Pet.Tel, } t.FindAllPetReq = utils.FindAllDtoToProto(t.FindAllPetDto, true) @@ -214,11 +214,11 @@ func (t *PetServiceTest) SetupTest() { t.AdoptReq = &petproto.AdoptPetRequest{ PetId: t.Pet.Id, - UserId: t.Pet.AdoptBy, + UserId: t.Pet.Owner, } t.AdoptDto = &dto.AdoptByRequest{ - UserID: t.Pet.AdoptBy, + UserID: t.Pet.Owner, } t.FindAllImageReq = &imgproto.FindAllImageRequest{} diff --git a/src/app/utils/pet/pet.utils.go b/src/app/utils/pet/pet.utils.go index 54b5205..e0a02fd 100644 --- a/src/app/utils/pet/pet.utils.go +++ b/src/app/utils/pet/pet.utils.go @@ -71,9 +71,9 @@ func ProtoToDto(in *petproto.Pet, images []*dto.ImageResponse) *dto.PetResponse IsVaccinated: &in.IsVaccinated, IsVisible: &in.IsVisible, Origin: in.Origin, - Address: in.Address, + Owner: in.Owner, Contact: in.Contact, - AdoptBy: in.AdoptBy, + Tel: in.Tel, Images: images, } return pet @@ -96,9 +96,9 @@ func CreateDtoToProto(in *dto.CreatePetRequest) *petproto.CreatePetRequest { IsVaccinated: *in.IsVaccinated, IsVisible: *in.IsVisible, Origin: in.Origin, - Address: in.Address, + Owner: in.Owner, Contact: in.Contact, - AdoptBy: in.AdoptBy, + Tel: in.Tel, }, } } @@ -134,9 +134,9 @@ func UpdateDtoToProto(id string, in *dto.UpdatePetRequest) *petproto.UpdatePetRe IsVaccinated: isVaccinated, IsVisible: isVisible, Origin: in.Origin, - Address: in.Address, + Owner: in.Owner, Contact: in.Contact, - AdoptBy: in.AdoptBy, + Tel: in.Tel, }, } @@ -164,9 +164,9 @@ func ProtoToDtoList(in []*petproto.Pet, imagesList map[string][]*imgproto.Image, IsVaccinated: &p.IsVaccinated, IsVisible: &p.IsVisible, Origin: p.Origin, - Address: p.Address, + Owner: p.Owner, Contact: p.Contact, - AdoptBy: p.AdoptBy, + Tel: p.Tel, Images: ImageProtoToDto(imagesList[p.Id]), } resp = append(resp, pet) From 396fb40f54513f7ed0fb5fc758c2cfddf146098f Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Sun, 12 May 2024 18:01:12 +0700 Subject: [PATCH 071/104] fix: remove address from CreatePetRequest --- src/app/dto/pet.dto.go | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/dto/pet.dto.go b/src/app/dto/pet.dto.go index 337faad..b53978e 100644 --- a/src/app/dto/pet.dto.go +++ b/src/app/dto/pet.dto.go @@ -65,7 +65,6 @@ type CreatePetRequest struct { IsVaccinated *bool `json:"is_vaccinated" validate:"required"` IsVisible *bool `json:"is_visible" validate:"required"` Origin string `json:"origin" validate:"required"` - Address string `json:"address"` Owner string `json:"owner"` Contact string `json:"contact"` Tel string `json:"tel"` From 9ee6ca1a53b842a2b57884b55ba3335d9354a746 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 17 May 2024 16:01:52 +0700 Subject: [PATCH 072/104] fix: add refreshToken to excludePath --- src/constant/auth/auth.constant.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/constant/auth/auth.constant.go b/src/constant/auth/auth.constant.go index abca37d..1145e9b 100644 --- a/src/constant/auth/auth.constant.go +++ b/src/constant/auth/auth.constant.go @@ -6,6 +6,7 @@ var ExcludePath = map[string]struct{}{ "POST /auth/verify": {}, "POST /auth/forgot-password": {}, "PUT /auth/reset-password": {}, + "POST /auth/refreshToken": {}, "GET /user/:id": {}, "GET /pets": {}, "GET /pets/:id": {}, From 35dccbf4271c094adfe27e982c39ef662b9c52ce Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Tue, 20 Aug 2024 15:42:23 +0700 Subject: [PATCH 073/104] internal folder --- Makefile | 16 +++++----- {src => cmd}/main.go | 32 +++++++++---------- {src/config => config}/config.go | 0 .../auth/auth.constant.go | 0 .../constant => constant}/error.constant.go | 0 .../file/file.constant.go | 0 .../like/like.constant.go | 0 .../constant => constant}/pet/pet.constant.go | 0 .../user/user.constant.go | 0 {src => internal}/docs/docs.go | 0 {src => internal}/docs/markdown/api.md | 0 {src => internal}/docs/markdown/auth.md | 0 {src => internal}/docs/markdown/image.md | 0 {src => internal}/docs/markdown/pet.md | 0 {src => internal}/docs/markdown/user.md | 0 {src => internal}/docs/swagger.json | 0 {src => internal}/docs/swagger.yaml | 0 {src/app => internal}/dto/auth.dto.go | 0 {src/app => internal}/dto/common.dto.go | 0 {src/app => internal}/dto/image.dto.go | 0 {src/app => internal}/dto/like.dto.go | 0 {src/app => internal}/dto/pet.dto.go | 2 +- {src/app => internal}/dto/user.dto.go | 0 .../handler/auth/auth.handler.go | 13 ++++---- .../handler/auth/auth.handler_test.go | 12 +++---- .../healthcheck/healthcheck.handler.go | 2 +- .../handler/image/image.handler.go | 12 +++---- .../handler/like/like.handler.go | 10 +++--- .../handler/like/like.handler_test.go | 12 +++---- .../handler/pet/pet.handler.go | 14 ++++---- .../handler/pet/pet.handler_test.go | 20 ++++++------ .../handler/user/user.handler.go | 10 +++--- .../handler/user/user.handler_test.go | 12 +++---- .../middleware/auth/auth.middleware.go | 14 ++++---- .../pkg/service/auth/auth.service.go | 4 +-- .../pkg/service/image/image.service.go | 4 +-- .../pkg/service/like/like.service.go | 2 +- .../pkg/service/pet/pet.service.go | 4 +-- .../pkg/service/user/user.service.go | 4 +-- {src/app => internal}/router/auth.router.go | 0 {src/app => internal}/router/context.go | 4 +-- .../router/healthcheck.router.go | 0 {src/app => internal}/router/image.router.go | 0 {src/app => internal}/router/like.router.go | 0 {src/app => internal}/router/pet.router.go | 0 {src/app => internal}/router/router.go | 4 +-- {src/app => internal}/router/user.router.go | 0 .../service/auth/auth.service.go | 4 +-- .../service/auth/auth.service_test.go | 6 ++-- .../service/image/image.service.go | 6 ++-- .../service/like/like.service.go | 6 ++-- .../service/like/like.service_test.go | 8 ++--- .../service/pet/pet.service.go | 8 ++--- .../service/pet/pet.service_test.go | 14 ++++---- .../service/user/user.service.go | 4 +-- .../service/user/user.service_test.go | 6 ++-- .../app => internal}/utils/auth/auth.utils.go | 0 {src/app => internal}/utils/common.utils.go | 0 .../utils/image/image.utils.go | 2 +- .../app => internal}/utils/like/like.utils.go | 2 +- {src/app => internal}/utils/pet/pet.utils.go | 4 +-- {src/app => internal}/validator/validator.go | 2 +- {src/mocks => mocks}/client/auth/auth.mock.go | 0 .../client/image/image.mock.go | 0 {src/mocks => mocks}/client/like/like.mock.go | 0 {src/mocks => mocks}/client/pet/pet.mock.go | 0 {src/mocks => mocks}/client/user/user.mock.go | 0 {src/mocks => mocks}/router/context.mock.go | 4 +-- .../mocks => mocks}/service/auth/auth.mock.go | 4 +-- .../service/image/image.mock.go | 4 +-- .../mocks => mocks}/service/like/like.mock.go | 4 +-- {src/mocks => mocks}/service/pet/pet.mock.go | 4 +-- .../mocks => mocks}/service/user/user.mock.go | 4 +-- .../validator/validator.mock.go | 4 +-- 74 files changed, 150 insertions(+), 157 deletions(-) rename {src => cmd}/main.go (85%) rename {src/config => config}/config.go (100%) rename {src/constant => constant}/auth/auth.constant.go (100%) rename {src/app/constant => constant}/error.constant.go (100%) rename {src/constant => constant}/file/file.constant.go (100%) rename {src/constant => constant}/like/like.constant.go (100%) rename {src/constant => constant}/pet/pet.constant.go (100%) rename {src/constant => constant}/user/user.constant.go (100%) rename {src => internal}/docs/docs.go (100%) rename {src => internal}/docs/markdown/api.md (100%) rename {src => internal}/docs/markdown/auth.md (100%) rename {src => internal}/docs/markdown/image.md (100%) rename {src => internal}/docs/markdown/pet.md (100%) rename {src => internal}/docs/markdown/user.md (100%) rename {src => internal}/docs/swagger.json (100%) rename {src => internal}/docs/swagger.yaml (100%) rename {src/app => internal}/dto/auth.dto.go (100%) rename {src/app => internal}/dto/common.dto.go (100%) rename {src/app => internal}/dto/image.dto.go (100%) rename {src/app => internal}/dto/like.dto.go (100%) rename {src/app => internal}/dto/pet.dto.go (98%) rename {src/app => internal}/dto/user.dto.go (100%) rename {src/app => internal}/handler/auth/auth.handler.go (96%) rename {src/app => internal}/handler/auth/auth.handler_test.go (97%) rename {src/app => internal}/handler/healthcheck/healthcheck.handler.go (82%) rename {src/app => internal}/handler/image/image.handler.go (88%) rename {src/app => internal}/handler/like/like.handler.go (87%) rename {src/app => internal}/handler/like/like.handler_test.go (95%) rename {src/app => internal}/handler/pet/pet.handler.go (95%) rename {src/app => internal}/handler/pet/pet.handler_test.go (96%) rename {src/app => internal}/handler/user/user.handler.go (92%) rename {src/app => internal}/handler/user/user.handler_test.go (96%) rename {src/app => internal}/middleware/auth/auth.middleware.go (78%) rename {src => internal}/pkg/service/auth/auth.service.go (89%) rename {src => internal}/pkg/service/image/image.service.go (87%) rename {src => internal}/pkg/service/like/like.service.go (80%) rename {src => internal}/pkg/service/pet/pet.service.go (89%) rename {src => internal}/pkg/service/user/user.service.go (77%) rename {src/app => internal}/router/auth.router.go (100%) rename {src/app => internal}/router/context.go (96%) rename {src/app => internal}/router/healthcheck.router.go (100%) rename {src/app => internal}/router/image.router.go (100%) rename {src/app => internal}/router/like.router.go (100%) rename {src/app => internal}/router/pet.router.go (100%) rename {src/app => internal}/router/router.go (93%) rename {src/app => internal}/router/user.router.go (100%) rename {src/app => internal}/service/auth/auth.service.go (98%) rename {src/app => internal}/service/auth/auth.service_test.go (99%) rename {src/app => internal}/service/image/image.service.go (97%) rename {src/app => internal}/service/like/like.service.go (95%) rename {src/app => internal}/service/like/like.service_test.go (96%) rename {src/app => internal}/service/pet/pet.service.go (97%) rename {src/app => internal}/service/pet/pet.service_test.go (97%) rename {src/app => internal}/service/user/user.service.go (97%) rename {src/app => internal}/service/user/user.service_test.go (97%) rename {src/app => internal}/utils/auth/auth.utils.go (100%) rename {src/app => internal}/utils/common.utils.go (100%) rename {src/app => internal}/utils/image/image.utils.go (95%) rename {src/app => internal}/utils/like/like.utils.go (92%) rename {src/app => internal}/utils/pet/pet.utils.go (98%) rename {src/app => internal}/validator/validator.go (96%) rename {src/mocks => mocks}/client/auth/auth.mock.go (100%) rename {src/mocks => mocks}/client/image/image.mock.go (100%) rename {src/mocks => mocks}/client/like/like.mock.go (100%) rename {src/mocks => mocks}/client/pet/pet.mock.go (100%) rename {src/mocks => mocks}/client/user/user.mock.go (100%) rename {src/mocks => mocks}/router/context.mock.go (98%) rename {src/mocks => mocks}/service/auth/auth.mock.go (97%) rename {src/mocks => mocks}/service/image/image.mock.go (97%) rename {src/mocks => mocks}/service/like/like.mock.go (95%) rename {src/mocks => mocks}/service/pet/pet.mock.go (97%) rename {src/mocks => mocks}/service/user/user.mock.go (95%) rename {src/mocks => mocks}/validator/validator.mock.go (93%) diff --git a/Makefile b/Makefile index 9225211..aa62d83 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ publish: test: go vet ./... - go test -v -coverpkg ./src/app/... -coverprofile coverage.out -covermode count ./src/app/... + go test -v -coverpkg ./internal/... -coverprofile coverage.out -covermode count ./internal/... go tool cover -func=coverage.out go tool cover -html=coverage.out -o coverage.html @@ -16,13 +16,13 @@ server: . ./tools/export-env.sh ; go run ./src/. mock-gen: - mockgen -source ./src/pkg/service/auth/auth.service.go -destination ./src/mocks/service/auth/auth.mock.go - mockgen -source ./src/pkg/service/user/user.service.go -destination ./src/mocks/service/user/user.mock.go - mockgen -source ./src/pkg/service/pet/pet.service.go -destination ./src/mocks/service/pet/pet.mock.go - mockgen -source ./src/pkg/service/like/like.service.go -destination ./src/mocks/service/like/like.mock.go - mockgen -source ./src/pkg/service/image/image.service.go -destination ./src/mocks/service/image/image.mock.go - mockgen -source ./src/app/validator/validator.go -destination ./src/mocks/validator/validator.mock.go - mockgen -source ./src/app/router/context.go -destination ./src/mocks/router/context.mock.go + mockgen -source ./internal/pkg/service/auth/auth.service.go -destination ./mocks/service/auth/auth.mock.go + mockgen -source ./internal/pkg/service/user/user.service.go -destination ./mocks/service/user/user.mock.go + mockgen -source ./internal/pkg/service/pet/pet.service.go -destination ./mocks/service/pet/pet.mock.go + mockgen -source ./internal/pkg/service/like/like.service.go -destination ./mocks/service/like/like.mock.go + mockgen -source ./internal/pkg/service/image/image.service.go -destination ./mocks/service/image/image.mock.go + mockgen -source ./internal/validator/validator.go -destination ./mocks/validator/validator.mock.go + mockgen -source ./internal/router/context.go -destination ./mocks/router/context.mock.go create-doc: swag init -d ./src -o ./src/docs -md ./src/docs/markdown \ No newline at end of file diff --git a/src/main.go b/cmd/main.go similarity index 85% rename from src/main.go rename to cmd/main.go index 6e3abbb..97545b3 100644 --- a/src/main.go +++ b/cmd/main.go @@ -10,22 +10,22 @@ import ( "syscall" "time" - authHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/auth" - "github.com/isd-sgcu/johnjud-gateway/src/app/handler/healthcheck" - imageHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/image" - likeHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/like" - petHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/pet" - userHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/user" - guard "github.com/isd-sgcu/johnjud-gateway/src/app/middleware/auth" - "github.com/isd-sgcu/johnjud-gateway/src/app/router" - authSvc "github.com/isd-sgcu/johnjud-gateway/src/app/service/auth" - imageSvc "github.com/isd-sgcu/johnjud-gateway/src/app/service/image" - likeSvc "github.com/isd-sgcu/johnjud-gateway/src/app/service/like" - petSvc "github.com/isd-sgcu/johnjud-gateway/src/app/service/pet" - userSvc "github.com/isd-sgcu/johnjud-gateway/src/app/service/user" - "github.com/isd-sgcu/johnjud-gateway/src/app/validator" - "github.com/isd-sgcu/johnjud-gateway/src/config" - "github.com/isd-sgcu/johnjud-gateway/src/constant/auth" + "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/isd-sgcu/johnjud-gateway/constant/auth" + authHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/auth" + "github.com/isd-sgcu/johnjud-gateway/internal/handler/healthcheck" + imageHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/image" + likeHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/like" + petHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/pet" + userHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/user" + guard "github.com/isd-sgcu/johnjud-gateway/internal/middleware/auth" + "github.com/isd-sgcu/johnjud-gateway/internal/router" + authSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/auth" + imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/image" + likeSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/like" + petSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/pet" + userSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/user" + "github.com/isd-sgcu/johnjud-gateway/internal/validator" authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" userProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" diff --git a/src/config/config.go b/config/config.go similarity index 100% rename from src/config/config.go rename to config/config.go diff --git a/src/constant/auth/auth.constant.go b/constant/auth/auth.constant.go similarity index 100% rename from src/constant/auth/auth.constant.go rename to constant/auth/auth.constant.go diff --git a/src/app/constant/error.constant.go b/constant/error.constant.go similarity index 100% rename from src/app/constant/error.constant.go rename to constant/error.constant.go diff --git a/src/constant/file/file.constant.go b/constant/file/file.constant.go similarity index 100% rename from src/constant/file/file.constant.go rename to constant/file/file.constant.go diff --git a/src/constant/like/like.constant.go b/constant/like/like.constant.go similarity index 100% rename from src/constant/like/like.constant.go rename to constant/like/like.constant.go diff --git a/src/constant/pet/pet.constant.go b/constant/pet/pet.constant.go similarity index 100% rename from src/constant/pet/pet.constant.go rename to constant/pet/pet.constant.go diff --git a/src/constant/user/user.constant.go b/constant/user/user.constant.go similarity index 100% rename from src/constant/user/user.constant.go rename to constant/user/user.constant.go diff --git a/src/docs/docs.go b/internal/docs/docs.go similarity index 100% rename from src/docs/docs.go rename to internal/docs/docs.go diff --git a/src/docs/markdown/api.md b/internal/docs/markdown/api.md similarity index 100% rename from src/docs/markdown/api.md rename to internal/docs/markdown/api.md diff --git a/src/docs/markdown/auth.md b/internal/docs/markdown/auth.md similarity index 100% rename from src/docs/markdown/auth.md rename to internal/docs/markdown/auth.md diff --git a/src/docs/markdown/image.md b/internal/docs/markdown/image.md similarity index 100% rename from src/docs/markdown/image.md rename to internal/docs/markdown/image.md diff --git a/src/docs/markdown/pet.md b/internal/docs/markdown/pet.md similarity index 100% rename from src/docs/markdown/pet.md rename to internal/docs/markdown/pet.md diff --git a/src/docs/markdown/user.md b/internal/docs/markdown/user.md similarity index 100% rename from src/docs/markdown/user.md rename to internal/docs/markdown/user.md diff --git a/src/docs/swagger.json b/internal/docs/swagger.json similarity index 100% rename from src/docs/swagger.json rename to internal/docs/swagger.json diff --git a/src/docs/swagger.yaml b/internal/docs/swagger.yaml similarity index 100% rename from src/docs/swagger.yaml rename to internal/docs/swagger.yaml diff --git a/src/app/dto/auth.dto.go b/internal/dto/auth.dto.go similarity index 100% rename from src/app/dto/auth.dto.go rename to internal/dto/auth.dto.go diff --git a/src/app/dto/common.dto.go b/internal/dto/common.dto.go similarity index 100% rename from src/app/dto/common.dto.go rename to internal/dto/common.dto.go diff --git a/src/app/dto/image.dto.go b/internal/dto/image.dto.go similarity index 100% rename from src/app/dto/image.dto.go rename to internal/dto/image.dto.go diff --git a/src/app/dto/like.dto.go b/internal/dto/like.dto.go similarity index 100% rename from src/app/dto/like.dto.go rename to internal/dto/like.dto.go diff --git a/src/app/dto/pet.dto.go b/internal/dto/pet.dto.go similarity index 98% rename from src/app/dto/pet.dto.go rename to internal/dto/pet.dto.go index b53978e..9dde323 100644 --- a/src/app/dto/pet.dto.go +++ b/internal/dto/pet.dto.go @@ -1,7 +1,7 @@ package dto import ( - "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" + "github.com/isd-sgcu/johnjud-gateway/constant/pet" ) type PetResponse struct { diff --git a/src/app/dto/user.dto.go b/internal/dto/user.dto.go similarity index 100% rename from src/app/dto/user.dto.go rename to internal/dto/user.dto.go diff --git a/src/app/handler/auth/auth.handler.go b/internal/handler/auth/auth.handler.go similarity index 96% rename from src/app/handler/auth/auth.handler.go rename to internal/handler/auth/auth.handler.go index 1db143d..38af0b1 100644 --- a/src/app/handler/auth/auth.handler.go +++ b/internal/handler/auth/auth.handler.go @@ -1,14 +1,15 @@ package auth import ( - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - "github.com/isd-sgcu/johnjud-gateway/src/app/router" - "github.com/isd-sgcu/johnjud-gateway/src/app/validator" - "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/auth" - "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/user" "net/http" "strings" + + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/auth" + "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/user" + "github.com/isd-sgcu/johnjud-gateway/internal/router" + "github.com/isd-sgcu/johnjud-gateway/internal/validator" ) type Handler struct { diff --git a/src/app/handler/auth/auth.handler_test.go b/internal/handler/auth/auth.handler_test.go similarity index 97% rename from src/app/handler/auth/auth.handler_test.go rename to internal/handler/auth/auth.handler_test.go index f653c11..c3bb150 100644 --- a/src/app/handler/auth/auth.handler_test.go +++ b/internal/handler/auth/auth.handler_test.go @@ -7,12 +7,12 @@ import ( "github.com/go-faker/faker/v4" "github.com/golang/mock/gomock" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - routerMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/router" - authMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/auth" - userMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/user" - validatorMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/validator" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" + authMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/auth" + userMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/user" + validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" "github.com/stretchr/testify/suite" ) diff --git a/src/app/handler/healthcheck/healthcheck.handler.go b/internal/handler/healthcheck/healthcheck.handler.go similarity index 82% rename from src/app/handler/healthcheck/healthcheck.handler.go rename to internal/handler/healthcheck/healthcheck.handler.go index 25dd99c..3935ded 100644 --- a/src/app/handler/healthcheck/healthcheck.handler.go +++ b/internal/handler/healthcheck/healthcheck.handler.go @@ -3,7 +3,7 @@ package healthcheck import ( "net/http" - "github.com/isd-sgcu/johnjud-gateway/src/app/router" + "github.com/isd-sgcu/johnjud-gateway/internal/router" ) type Handler struct { diff --git a/src/app/handler/image/image.handler.go b/internal/handler/image/image.handler.go similarity index 88% rename from src/app/handler/image/image.handler.go rename to internal/handler/image/image.handler.go index c16f3d2..ec38174 100644 --- a/src/app/handler/image/image.handler.go +++ b/internal/handler/image/image.handler.go @@ -3,12 +3,12 @@ package image import ( "net/http" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - "github.com/isd-sgcu/johnjud-gateway/src/app/router" - "github.com/isd-sgcu/johnjud-gateway/src/app/validator" - "github.com/isd-sgcu/johnjud-gateway/src/constant/file" - imageSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/image" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/constant/file" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/image" + "github.com/isd-sgcu/johnjud-gateway/internal/router" + "github.com/isd-sgcu/johnjud-gateway/internal/validator" "github.com/rs/zerolog/log" ) diff --git a/src/app/handler/like/like.handler.go b/internal/handler/like/like.handler.go similarity index 87% rename from src/app/handler/like/like.handler.go rename to internal/handler/like/like.handler.go index accafc0..485c1bf 100644 --- a/src/app/handler/like/like.handler.go +++ b/internal/handler/like/like.handler.go @@ -4,11 +4,11 @@ import ( "net/http" "strings" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - "github.com/isd-sgcu/johnjud-gateway/src/app/router" - "github.com/isd-sgcu/johnjud-gateway/src/app/validator" - likeSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/like" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + likeSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/like" + "github.com/isd-sgcu/johnjud-gateway/internal/router" + "github.com/isd-sgcu/johnjud-gateway/internal/validator" ) type Handler struct { diff --git a/src/app/handler/like/like.handler_test.go b/internal/handler/like/like.handler_test.go similarity index 95% rename from src/app/handler/like/like.handler_test.go rename to internal/handler/like/like.handler_test.go index ed7debe..3cecacc 100644 --- a/src/app/handler/like/like.handler_test.go +++ b/internal/handler/like/like.handler_test.go @@ -6,12 +6,12 @@ import ( "github.com/bxcodec/faker/v4" "github.com/golang/mock/gomock" - errConst "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/like" - routerMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/router" - likeMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/like" - validatorMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/validator" + errConst "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/like" + routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" + likeMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/like" + validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" "github.com/stretchr/testify/suite" ) diff --git a/src/app/handler/pet/pet.handler.go b/internal/handler/pet/pet.handler.go similarity index 95% rename from src/app/handler/pet/pet.handler.go rename to internal/handler/pet/pet.handler.go index c35048b..9de9daa 100644 --- a/src/app/handler/pet/pet.handler.go +++ b/internal/handler/pet/pet.handler.go @@ -4,13 +4,13 @@ import ( "net/http" "strings" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - "github.com/isd-sgcu/johnjud-gateway/src/app/router" - petUtils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/pet" - "github.com/isd-sgcu/johnjud-gateway/src/app/validator" - imageSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/image" - petSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/pet" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/image" + petSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/pet" + "github.com/isd-sgcu/johnjud-gateway/internal/router" + petUtils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" + "github.com/isd-sgcu/johnjud-gateway/internal/validator" ) type Handler struct { diff --git a/src/app/handler/pet/pet.handler_test.go b/internal/handler/pet/pet.handler_test.go similarity index 96% rename from src/app/handler/pet/pet.handler_test.go rename to internal/handler/pet/pet.handler_test.go index ca4f694..d95c1aa 100644 --- a/src/app/handler/pet/pet.handler_test.go +++ b/internal/handler/pet/pet.handler_test.go @@ -7,16 +7,16 @@ import ( "github.com/bxcodec/faker/v4" "github.com/golang/mock/gomock" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" - routerMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/router" - imageMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/image" - petMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/pet" - validatorMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/validator" - - errConst "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/pet" - petConst "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" + "github.com/isd-sgcu/johnjud-gateway/constant/pet" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" + imageMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/image" + petMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/pet" + validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" + + errConst "github.com/isd-sgcu/johnjud-gateway/constant" + petConst "github.com/isd-sgcu/johnjud-gateway/constant/pet" + utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" imgProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" diff --git a/src/app/handler/user/user.handler.go b/internal/handler/user/user.handler.go similarity index 92% rename from src/app/handler/user/user.handler.go rename to internal/handler/user/user.handler.go index 4277361..f20a32d 100644 --- a/src/app/handler/user/user.handler.go +++ b/internal/handler/user/user.handler.go @@ -4,11 +4,11 @@ import ( "net/http" "strings" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - "github.com/isd-sgcu/johnjud-gateway/src/app/router" - "github.com/isd-sgcu/johnjud-gateway/src/app/validator" - "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/user" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/user" + "github.com/isd-sgcu/johnjud-gateway/internal/router" + "github.com/isd-sgcu/johnjud-gateway/internal/validator" ) type Handler struct { diff --git a/src/app/handler/user/user.handler_test.go b/internal/handler/user/user.handler_test.go similarity index 96% rename from src/app/handler/user/user.handler_test.go rename to internal/handler/user/user.handler_test.go index 8757d2f..36c1919 100644 --- a/src/app/handler/user/user.handler_test.go +++ b/internal/handler/user/user.handler_test.go @@ -8,13 +8,13 @@ import ( "github.com/go-faker/faker/v4" "github.com/golang/mock/gomock" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - routerMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/router" - userMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/user" - validatorMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/validator" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" + userMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/user" + validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" - errConst "github.com/isd-sgcu/johnjud-gateway/src/app/constant" + errConst "github.com/isd-sgcu/johnjud-gateway/constant" proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" "github.com/stretchr/testify/suite" diff --git a/src/app/middleware/auth/auth.middleware.go b/internal/middleware/auth/auth.middleware.go similarity index 78% rename from src/app/middleware/auth/auth.middleware.go rename to internal/middleware/auth/auth.middleware.go index 3660164..b1e647b 100644 --- a/src/app/middleware/auth/auth.middleware.go +++ b/internal/middleware/auth/auth.middleware.go @@ -3,13 +3,13 @@ package auth import ( "net/http" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - "github.com/isd-sgcu/johnjud-gateway/src/app/router" - "github.com/isd-sgcu/johnjud-gateway/src/app/utils" - "github.com/isd-sgcu/johnjud-gateway/src/app/utils/auth" - "github.com/isd-sgcu/johnjud-gateway/src/config" - "github.com/isd-sgcu/johnjud-gateway/src/constant/user" - authPkg "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/auth" + "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/isd-sgcu/johnjud-gateway/constant/user" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + authPkg "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/auth" + "github.com/isd-sgcu/johnjud-gateway/internal/router" + "github.com/isd-sgcu/johnjud-gateway/internal/utils" + "github.com/isd-sgcu/johnjud-gateway/internal/utils/auth" ) type Guard struct { diff --git a/src/pkg/service/auth/auth.service.go b/internal/pkg/service/auth/auth.service.go similarity index 89% rename from src/pkg/service/auth/auth.service.go rename to internal/pkg/service/auth/auth.service.go index 0bd4875..424ef2c 100644 --- a/src/pkg/service/auth/auth.service.go +++ b/internal/pkg/service/auth/auth.service.go @@ -1,8 +1,6 @@ package auth -import ( - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" -) +import "github.com/isd-sgcu/johnjud-gateway/internal/dto" type Service interface { Signup(*dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) diff --git a/src/pkg/service/image/image.service.go b/internal/pkg/service/image/image.service.go similarity index 87% rename from src/pkg/service/image/image.service.go rename to internal/pkg/service/image/image.service.go index d4f92d8..4cd646a 100644 --- a/src/pkg/service/image/image.service.go +++ b/internal/pkg/service/image/image.service.go @@ -1,8 +1,6 @@ package image -import ( - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" -) +import "github.com/isd-sgcu/johnjud-gateway/internal/dto" type Service interface { FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) diff --git a/src/pkg/service/like/like.service.go b/internal/pkg/service/like/like.service.go similarity index 80% rename from src/pkg/service/like/like.service.go rename to internal/pkg/service/like/like.service.go index e260a4b..5cbbf1c 100644 --- a/src/pkg/service/like/like.service.go +++ b/internal/pkg/service/like/like.service.go @@ -1,6 +1,6 @@ package like -import "github.com/isd-sgcu/johnjud-gateway/src/app/dto" +import "github.com/isd-sgcu/johnjud-gateway/internal/dto" type Service interface { FindByUserId(string) ([]*dto.LikeResponse, *dto.ResponseErr) diff --git a/src/pkg/service/pet/pet.service.go b/internal/pkg/service/pet/pet.service.go similarity index 89% rename from src/pkg/service/pet/pet.service.go rename to internal/pkg/service/pet/pet.service.go index 302e947..8b44ebd 100644 --- a/src/pkg/service/pet/pet.service.go +++ b/internal/pkg/service/pet/pet.service.go @@ -1,8 +1,6 @@ package pet -import ( - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" -) +import "github.com/isd-sgcu/johnjud-gateway/internal/dto" type Service interface { FindAll(*dto.FindAllPetRequest, bool) (*dto.FindAllPetResponse, *dto.ResponseErr) diff --git a/src/pkg/service/user/user.service.go b/internal/pkg/service/user/user.service.go similarity index 77% rename from src/pkg/service/user/user.service.go rename to internal/pkg/service/user/user.service.go index 731063b..a7ff4ca 100644 --- a/src/pkg/service/user/user.service.go +++ b/internal/pkg/service/user/user.service.go @@ -1,8 +1,6 @@ package user -import ( - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" -) +import "github.com/isd-sgcu/johnjud-gateway/internal/dto" type Service interface { FindOne(string) (*dto.User, *dto.ResponseErr) diff --git a/src/app/router/auth.router.go b/internal/router/auth.router.go similarity index 100% rename from src/app/router/auth.router.go rename to internal/router/auth.router.go diff --git a/src/app/router/context.go b/internal/router/context.go similarity index 96% rename from src/app/router/context.go rename to internal/router/context.go index 50afddb..43dac98 100644 --- a/src/app/router/context.go +++ b/internal/router/context.go @@ -9,8 +9,8 @@ import ( "github.com/gofiber/fiber/v2" "github.com/google/uuid" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - "github.com/isd-sgcu/johnjud-gateway/src/app/utils" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-gateway/internal/utils" ) type IContext interface { diff --git a/src/app/router/healthcheck.router.go b/internal/router/healthcheck.router.go similarity index 100% rename from src/app/router/healthcheck.router.go rename to internal/router/healthcheck.router.go diff --git a/src/app/router/image.router.go b/internal/router/image.router.go similarity index 100% rename from src/app/router/image.router.go rename to internal/router/image.router.go diff --git a/src/app/router/like.router.go b/internal/router/like.router.go similarity index 100% rename from src/app/router/like.router.go rename to internal/router/like.router.go diff --git a/src/app/router/pet.router.go b/internal/router/pet.router.go similarity index 100% rename from src/app/router/pet.router.go rename to internal/router/pet.router.go diff --git a/src/app/router/router.go b/internal/router/router.go similarity index 93% rename from src/app/router/router.go rename to internal/router/router.go index f24910d..8b2eecc 100644 --- a/src/app/router/router.go +++ b/internal/router/router.go @@ -5,8 +5,8 @@ import ( "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/logger" - "github.com/isd-sgcu/johnjud-gateway/src/config" - _ "github.com/isd-sgcu/johnjud-gateway/src/docs" + "github.com/isd-sgcu/johnjud-gateway/config" + _ "github.com/isd-sgcu/johnjud-gateway/internal/docs" ) type FiberRouter struct { diff --git a/src/app/router/user.router.go b/internal/router/user.router.go similarity index 100% rename from src/app/router/user.router.go rename to internal/router/user.router.go diff --git a/src/app/service/auth/auth.service.go b/internal/service/auth/auth.service.go similarity index 98% rename from src/app/service/auth/auth.service.go rename to internal/service/auth/auth.service.go index dd60984..e42aaa8 100644 --- a/src/app/service/auth/auth.service.go +++ b/internal/service/auth/auth.service.go @@ -5,8 +5,8 @@ import ( "net/http" "time" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" diff --git a/src/app/service/auth/auth.service_test.go b/internal/service/auth/auth.service_test.go similarity index 99% rename from src/app/service/auth/auth.service_test.go rename to internal/service/auth/auth.service_test.go index 9379fd3..1e03d2c 100644 --- a/src/app/service/auth/auth.service_test.go +++ b/internal/service/auth/auth.service_test.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/go-faker/faker/v4" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - "github.com/isd-sgcu/johnjud-gateway/src/mocks/client/auth" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-gateway/mocks/client/auth" authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" diff --git a/src/app/service/image/image.service.go b/internal/service/image/image.service.go similarity index 97% rename from src/app/service/image/image.service.go rename to internal/service/image/image.service.go index 1ead4af..9333af7 100644 --- a/src/app/service/image/image.service.go +++ b/internal/service/image/image.service.go @@ -5,9 +5,9 @@ import ( "net/http" "time" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/image" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/image" proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" diff --git a/src/app/service/like/like.service.go b/internal/service/like/like.service.go similarity index 95% rename from src/app/service/like/like.service.go rename to internal/service/like/like.service.go index b966ae3..8ec1f3d 100644 --- a/src/app/service/like/like.service.go +++ b/internal/service/like/like.service.go @@ -5,9 +5,9 @@ import ( "net/http" "time" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/like" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/like" likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" diff --git a/src/app/service/like/like.service_test.go b/internal/service/like/like.service_test.go similarity index 96% rename from src/app/service/like/like.service_test.go rename to internal/service/like/like.service_test.go index c76c74c..86b4532 100644 --- a/src/app/service/like/like.service_test.go +++ b/internal/service/like/like.service_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/bxcodec/faker/v4" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/like" - likeMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/client/like" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/like" + likeMock "github.com/isd-sgcu/johnjud-gateway/mocks/client/like" likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" diff --git a/src/app/service/pet/pet.service.go b/internal/service/pet/pet.service.go similarity index 97% rename from src/app/service/pet/pet.service.go rename to internal/service/pet/pet.service.go index be98fa4..71599c4 100644 --- a/src/app/service/pet/pet.service.go +++ b/internal/service/pet/pet.service.go @@ -5,11 +5,11 @@ import ( "net/http" "time" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" - utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/pet" - imageSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/image" + imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/image" + utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" diff --git a/src/app/service/pet/pet.service_test.go b/internal/service/pet/pet.service_test.go similarity index 97% rename from src/app/service/pet/pet.service_test.go rename to internal/service/pet/pet.service_test.go index 1fe08a8..dd8bd11 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/internal/service/pet/pet.service_test.go @@ -6,13 +6,13 @@ import ( "testing" "github.com/go-faker/faker/v4" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - imageSvc "github.com/isd-sgcu/johnjud-gateway/src/app/service/image" - utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/pet" - "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" - imagemock "github.com/isd-sgcu/johnjud-gateway/src/mocks/client/image" - petmock "github.com/isd-sgcu/johnjud-gateway/src/mocks/client/pet" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/constant/pet" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/image" + utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" + imagemock "github.com/isd-sgcu/johnjud-gateway/mocks/client/image" + petmock "github.com/isd-sgcu/johnjud-gateway/mocks/client/pet" petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" imgproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" "github.com/stretchr/testify/assert" diff --git a/src/app/service/user/user.service.go b/internal/service/user/user.service.go similarity index 97% rename from src/app/service/user/user.service.go rename to internal/service/user/user.service.go index d4186f2..c151b34 100644 --- a/src/app/service/user/user.service.go +++ b/internal/service/user/user.service.go @@ -5,8 +5,8 @@ import ( "net/http" "time" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" diff --git a/src/app/service/user/user.service_test.go b/internal/service/user/user.service_test.go similarity index 97% rename from src/app/service/user/user.service_test.go rename to internal/service/user/user.service_test.go index 9630508..4011eab 100644 --- a/src/app/service/user/user.service_test.go +++ b/internal/service/user/user.service_test.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/go-faker/faker/v4" - "github.com/isd-sgcu/johnjud-gateway/src/app/constant" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - "github.com/isd-sgcu/johnjud-gateway/src/mocks/client/user" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-gateway/mocks/client/user" proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" diff --git a/src/app/utils/auth/auth.utils.go b/internal/utils/auth/auth.utils.go similarity index 100% rename from src/app/utils/auth/auth.utils.go rename to internal/utils/auth/auth.utils.go diff --git a/src/app/utils/common.utils.go b/internal/utils/common.utils.go similarity index 100% rename from src/app/utils/common.utils.go rename to internal/utils/common.utils.go diff --git a/src/app/utils/image/image.utils.go b/internal/utils/image/image.utils.go similarity index 95% rename from src/app/utils/image/image.utils.go rename to internal/utils/image/image.utils.go index c30c346..1b45ee8 100644 --- a/src/app/utils/image/image.utils.go +++ b/internal/utils/image/image.utils.go @@ -1,7 +1,7 @@ package image import ( - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" imageProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" ) diff --git a/src/app/utils/like/like.utils.go b/internal/utils/like/like.utils.go similarity index 92% rename from src/app/utils/like/like.utils.go rename to internal/utils/like/like.utils.go index 1349010..b48689a 100644 --- a/src/app/utils/like/like.utils.go +++ b/internal/utils/like/like.utils.go @@ -1,7 +1,7 @@ package like import ( - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" ) diff --git a/src/app/utils/pet/pet.utils.go b/internal/utils/pet/pet.utils.go similarity index 98% rename from src/app/utils/pet/pet.utils.go rename to internal/utils/pet/pet.utils.go index e0a02fd..dfae5c0 100644 --- a/src/app/utils/pet/pet.utils.go +++ b/internal/utils/pet/pet.utils.go @@ -4,8 +4,8 @@ import ( "errors" "strconv" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" + "github.com/isd-sgcu/johnjud-gateway/constant/pet" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" imgproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" ) diff --git a/src/app/validator/validator.go b/internal/validator/validator.go similarity index 96% rename from src/app/validator/validator.go rename to internal/validator/validator.go index 2028a4e..6699018 100644 --- a/src/app/validator/validator.go +++ b/internal/validator/validator.go @@ -8,7 +8,7 @@ import ( ut "github.com/go-playground/universal-translator" "github.com/go-playground/validator/v10" en_translations "github.com/go-playground/validator/v10/translations/en" - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" "github.com/rs/zerolog/log" ) diff --git a/src/mocks/client/auth/auth.mock.go b/mocks/client/auth/auth.mock.go similarity index 100% rename from src/mocks/client/auth/auth.mock.go rename to mocks/client/auth/auth.mock.go diff --git a/src/mocks/client/image/image.mock.go b/mocks/client/image/image.mock.go similarity index 100% rename from src/mocks/client/image/image.mock.go rename to mocks/client/image/image.mock.go diff --git a/src/mocks/client/like/like.mock.go b/mocks/client/like/like.mock.go similarity index 100% rename from src/mocks/client/like/like.mock.go rename to mocks/client/like/like.mock.go diff --git a/src/mocks/client/pet/pet.mock.go b/mocks/client/pet/pet.mock.go similarity index 100% rename from src/mocks/client/pet/pet.mock.go rename to mocks/client/pet/pet.mock.go diff --git a/src/mocks/client/user/user.mock.go b/mocks/client/user/user.mock.go similarity index 100% rename from src/mocks/client/user/user.mock.go rename to mocks/client/user/user.mock.go diff --git a/src/mocks/router/context.mock.go b/mocks/router/context.mock.go similarity index 98% rename from src/mocks/router/context.mock.go rename to mocks/router/context.mock.go index 7a371c7..97487a1 100644 --- a/src/mocks/router/context.mock.go +++ b/mocks/router/context.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./src/app/router/context.go +// Source: ./internal/router/context.go // Package mock_router is a generated GoMock package. package mock_router @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" ) // MockIContext is a mock of IContext interface. diff --git a/src/mocks/service/auth/auth.mock.go b/mocks/service/auth/auth.mock.go similarity index 97% rename from src/mocks/service/auth/auth.mock.go rename to mocks/service/auth/auth.mock.go index 52e1c8d..7a7efc5 100644 --- a/src/mocks/service/auth/auth.mock.go +++ b/mocks/service/auth/auth.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./src/pkg/service/auth/auth.service.go +// Source: ./internal/pkg/service/auth/auth.service.go // Package mock_auth is a generated GoMock package. package mock_auth @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" ) // MockService is a mock of Service interface. diff --git a/src/mocks/service/image/image.mock.go b/mocks/service/image/image.mock.go similarity index 97% rename from src/mocks/service/image/image.mock.go rename to mocks/service/image/image.mock.go index bb59c31..4b6c523 100644 --- a/src/mocks/service/image/image.mock.go +++ b/mocks/service/image/image.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./src/pkg/service/image/image.service.go +// Source: ./internal/pkg/service/image/image.service.go // Package mock_image is a generated GoMock package. package mock_image @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" ) // MockService is a mock of Service interface. diff --git a/src/mocks/service/like/like.mock.go b/mocks/service/like/like.mock.go similarity index 95% rename from src/mocks/service/like/like.mock.go rename to mocks/service/like/like.mock.go index 1e05b67..8ea1d1e 100644 --- a/src/mocks/service/like/like.mock.go +++ b/mocks/service/like/like.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./src/pkg/service/like/like.service.go +// Source: ./internal/pkg/service/like/like.service.go // Package mock_like is a generated GoMock package. package mock_like @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" ) // MockService is a mock of Service interface. diff --git a/src/mocks/service/pet/pet.mock.go b/mocks/service/pet/pet.mock.go similarity index 97% rename from src/mocks/service/pet/pet.mock.go rename to mocks/service/pet/pet.mock.go index 2e5ff16..14a90db 100644 --- a/src/mocks/service/pet/pet.mock.go +++ b/mocks/service/pet/pet.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./src/pkg/service/pet/pet.service.go +// Source: ./internal/pkg/service/pet/pet.service.go // Package mock_pet is a generated GoMock package. package mock_pet @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" ) // MockService is a mock of Service interface. diff --git a/src/mocks/service/user/user.mock.go b/mocks/service/user/user.mock.go similarity index 95% rename from src/mocks/service/user/user.mock.go rename to mocks/service/user/user.mock.go index ba40d67..c722930 100644 --- a/src/mocks/service/user/user.mock.go +++ b/mocks/service/user/user.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./src/pkg/service/user/user.service.go +// Source: ./internal/pkg/service/user/user.service.go // Package mock_user is a generated GoMock package. package mock_user @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" ) // MockService is a mock of Service interface. diff --git a/src/mocks/validator/validator.mock.go b/mocks/validator/validator.mock.go similarity index 93% rename from src/mocks/validator/validator.mock.go rename to mocks/validator/validator.mock.go index 67f9a22..eb2eb4b 100644 --- a/src/mocks/validator/validator.mock.go +++ b/mocks/validator/validator.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./src/app/validator/validator.go +// Source: ./internal/validator/validator.go // Package mock_validator is a generated GoMock package. package mock_validator @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" ) // MockIDtoValidator is a mock of IDtoValidator interface. From 010ecc514753700f80fa340dbb864f2bdf4f3cd2 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Tue, 20 Aug 2024 15:48:18 +0700 Subject: [PATCH 074/104] constant folder --- cmd/main.go | 4 +- constant/{auth => }/auth.constant.go | 2 +- constant/{file => }/file.constant.go | 2 +- constant/{like => }/like.constant.go | 2 +- constant/{pet => }/pet.constant.go | 2 +- constant/{user => }/user.constant.go | 2 +- internal/dto/pet.dto.go | 74 ++++++++++----------- internal/handler/image/image.handler.go | 3 +- internal/handler/pet/pet.handler_test.go | 11 ++- internal/middleware/auth/auth.middleware.go | 4 +- internal/service/pet/pet.service_test.go | 13 ++-- internal/utils/pet/pet.utils.go | 10 +-- 12 files changed, 63 insertions(+), 66 deletions(-) rename constant/{auth => }/auth.constant.go (97%) rename constant/{file => }/file.constant.go (87%) rename constant/{like => }/like.constant.go (90%) rename constant/{pet => }/pet.constant.go (98%) rename constant/{user => }/user.constant.go (93%) diff --git a/cmd/main.go b/cmd/main.go index 97545b3..acb1827 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -11,7 +11,7 @@ import ( "time" "github.com/isd-sgcu/johnjud-gateway/config" - "github.com/isd-sgcu/johnjud-gateway/constant/auth" + "github.com/isd-sgcu/johnjud-gateway/constant" authHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/auth" "github.com/isd-sgcu/johnjud-gateway/internal/handler/healthcheck" imageHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/image" @@ -113,7 +113,7 @@ func main() { authService := authSvc.NewService(authClient) authHandler := authHdr.NewHandler(authService, userService, v) - authGuard := guard.NewAuthGuard(authService, auth.ExcludePath, auth.AdminPath, conf.App, auth.VersionList) + authGuard := guard.NewAuthGuard(authService, constant.ExcludePath, constant.AdminPath, conf.App, constant.VersionList) imageClient := imageProto.NewImageServiceClient(fileConn) imageService := imageSvc.NewService(imageClient) diff --git a/constant/auth/auth.constant.go b/constant/auth.constant.go similarity index 97% rename from constant/auth/auth.constant.go rename to constant/auth.constant.go index 1145e9b..085d9de 100644 --- a/constant/auth/auth.constant.go +++ b/constant/auth.constant.go @@ -1,4 +1,4 @@ -package auth +package constant var ExcludePath = map[string]struct{}{ "POST /auth/signup": {}, diff --git a/constant/file/file.constant.go b/constant/file.constant.go similarity index 87% rename from constant/file/file.constant.go rename to constant/file.constant.go index 0b6ffcd..1fc7ed8 100644 --- a/constant/file/file.constant.go +++ b/constant/file.constant.go @@ -1,4 +1,4 @@ -package file +package constant var AllowContentType = map[string]struct{}{ "image/jpeg": {}, diff --git a/constant/like/like.constant.go b/constant/like.constant.go similarity index 90% rename from constant/like/like.constant.go rename to constant/like.constant.go index 35960ae..52ca2ea 100644 --- a/constant/like/like.constant.go +++ b/constant/like.constant.go @@ -1,4 +1,4 @@ -package like +package constant const FindLikeSuccessMessage = "find likes success" const CreateLikeSuccessMessage = "create like success" diff --git a/constant/pet/pet.constant.go b/constant/pet.constant.go similarity index 98% rename from constant/pet/pet.constant.go rename to constant/pet.constant.go index d2428f6..d45aeea 100644 --- a/constant/pet/pet.constant.go +++ b/constant/pet.constant.go @@ -1,4 +1,4 @@ -package pet +package constant import ( "encoding/json" diff --git a/constant/user/user.constant.go b/constant/user.constant.go similarity index 93% rename from constant/user/user.constant.go rename to constant/user.constant.go index cf1991e..f96620b 100644 --- a/constant/user/user.constant.go +++ b/constant/user.constant.go @@ -1,4 +1,4 @@ -package user +package constant const FindOneUserSuccessMessage = "find one user success" const UpdateUserSuccessMessage = "update user success" diff --git a/internal/dto/pet.dto.go b/internal/dto/pet.dto.go index 9dde323..2ccd682 100644 --- a/internal/dto/pet.dto.go +++ b/internal/dto/pet.dto.go @@ -1,7 +1,7 @@ package dto import ( - "github.com/isd-sgcu/johnjud-gateway/constant/pet" + "github.com/isd-sgcu/johnjud-gateway/constant" ) type PetResponse struct { @@ -9,12 +9,12 @@ type PetResponse struct { Type string `json:"type"` Name string `json:"name"` Birthdate string `json:"birthdate"` - Gender pet.Gender `json:"gender"` + Gender constant.Gender `json:"gender"` Color string `json:"color"` Pattern string `json:"pattern"` Habit string `json:"habit"` Caption string `json:"caption"` - Status pet.Status `json:"status"` + Status constant.Status `json:"status"` IsSterile *bool `json:"is_sterile"` IsVaccinated *bool `json:"is_vaccinated"` IsVisible *bool `json:"is_visible"` @@ -52,23 +52,23 @@ type FindAllPetResponse struct { } type CreatePetRequest struct { - Type string `json:"type" validate:"required"` - Name string `json:"name" validate:"required"` - Birthdate string `json:"birthdate" validate:"required"` - Gender pet.Gender `json:"gender" validate:"required" example:"male"` - Color string `json:"color" validate:"required"` - Pattern string `json:"pattern" validate:"required"` - Habit string `json:"habit" validate:"required"` - Caption string `json:"caption"` - Status pet.Status `json:"status" validate:"required" example:"findhome"` - IsSterile *bool `json:"is_sterile" validate:"required"` - IsVaccinated *bool `json:"is_vaccinated" validate:"required"` - IsVisible *bool `json:"is_visible" validate:"required"` - Origin string `json:"origin" validate:"required"` - Owner string `json:"owner"` - Contact string `json:"contact"` - Tel string `json:"tel"` - Images []string `json:"images"` + Type string `json:"type" validate:"required"` + Name string `json:"name" validate:"required"` + Birthdate string `json:"birthdate" validate:"required"` + Gender constant.Gender `json:"gender" validate:"required" example:"male"` + Color string `json:"color" validate:"required"` + Pattern string `json:"pattern" validate:"required"` + Habit string `json:"habit" validate:"required"` + Caption string `json:"caption"` + Status constant.Status `json:"status" validate:"required" example:"findhome"` + IsSterile *bool `json:"is_sterile" validate:"required"` + IsVaccinated *bool `json:"is_vaccinated" validate:"required"` + IsVisible *bool `json:"is_visible" validate:"required"` + Origin string `json:"origin" validate:"required"` + Owner string `json:"owner"` + Contact string `json:"contact"` + Tel string `json:"tel"` + Images []string `json:"images"` } type ChangeViewPetRequest struct { @@ -88,23 +88,23 @@ type AdoptByResponse struct { } type UpdatePetRequest struct { - Type string `json:"type"` - Name string `json:"name"` - Birthdate string `json:"birthdate"` - Gender pet.Gender `json:"gender"` - Color string `json:"color"` - Pattern string `json:"pattern"` - Habit string `json:"habit"` - Caption string `json:"caption"` - Status pet.Status `json:"status"` - IsSterile *bool `json:"is_sterile"` - IsVaccinated *bool `json:"is_vaccinated"` - IsVisible *bool `json:"is_visible"` - Origin string `json:"origin"` - Owner string `json:"owner"` - Contact string `json:"contact"` - Tel string `json:"tel"` - Images []string `json:"images"` + Type string `json:"type"` + Name string `json:"name"` + Birthdate string `json:"birthdate"` + Gender constant.Gender `json:"gender"` + Color string `json:"color"` + Pattern string `json:"pattern"` + Habit string `json:"habit"` + Caption string `json:"caption"` + Status constant.Status `json:"status"` + IsSterile *bool `json:"is_sterile"` + IsVaccinated *bool `json:"is_vaccinated"` + IsVisible *bool `json:"is_visible"` + Origin string `json:"origin"` + Owner string `json:"owner"` + Contact string `json:"contact"` + Tel string `json:"tel"` + Images []string `json:"images"` } type DeleteRequest struct { Id string `json:"id" validate:"required"` diff --git a/internal/handler/image/image.handler.go b/internal/handler/image/image.handler.go index ec38174..ecfb6b2 100644 --- a/internal/handler/image/image.handler.go +++ b/internal/handler/image/image.handler.go @@ -4,7 +4,6 @@ import ( "net/http" "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/constant/file" "github.com/isd-sgcu/johnjud-gateway/internal/dto" imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/image" "github.com/isd-sgcu/johnjud-gateway/internal/router" @@ -40,7 +39,7 @@ func NewHandler(service imageSvc.Service, validate validator.IDtoValidator, maxF // @Router /v1/images [post] func (h *Handler) Upload(c *router.FiberCtx) { petId := c.GetFormData("pet_id") - file, err := c.File("file", file.AllowContentType, h.maxFileSize) + file, err := c.File("file", constant.AllowContentType, h.maxFileSize) if err != nil { log.Error(). Err(err). diff --git a/internal/handler/pet/pet.handler_test.go b/internal/handler/pet/pet.handler_test.go index d95c1aa..4e1d1f4 100644 --- a/internal/handler/pet/pet.handler_test.go +++ b/internal/handler/pet/pet.handler_test.go @@ -7,7 +7,7 @@ import ( "github.com/bxcodec/faker/v4" "github.com/golang/mock/gomock" - "github.com/isd-sgcu/johnjud-gateway/constant/pet" + "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" imageMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/image" @@ -15,7 +15,6 @@ import ( validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" errConst "github.com/isd-sgcu/johnjud-gateway/constant" - petConst "github.com/isd-sgcu/johnjud-gateway/constant/pet" utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" imgProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" @@ -64,8 +63,8 @@ func (t *PetHandlerTest) SetupTest() { t.ImagesList = imagesList t.Images = imagesList[petIds[0]] var pets []*petProto.Pet - genders := []petConst.Gender{petConst.MALE, petConst.FEMALE} - statuses := []petConst.Status{petConst.ADOPTED, petConst.FINDHOME} + genders := []constant.Gender{constant.MALE, constant.FEMALE} + statuses := []constant.Status{constant.ADOPTED, constant.FINDHOME} for i := 0; i <= 3; i++ { pet := &petProto.Pet{ @@ -107,12 +106,12 @@ func (t *PetHandlerTest) SetupTest() { Type: t.Pet.Type, Name: t.Pet.Name, Birthdate: t.Pet.Birthdate, - Gender: pet.Gender(t.Pet.Gender), + Gender: constant.Gender(t.Pet.Gender), Color: t.Pet.Color, Pattern: t.Pet.Pattern, Habit: t.Pet.Habit, Caption: t.Pet.Caption, - Status: pet.Status(t.Pet.Status), + Status: constant.Status(t.Pet.Status), IsSterile: &t.Pet.IsSterile, IsVaccinated: &t.Pet.IsVaccinated, IsVisible: &t.Pet.IsVisible, diff --git a/internal/middleware/auth/auth.middleware.go b/internal/middleware/auth/auth.middleware.go index b1e647b..f260dd3 100644 --- a/internal/middleware/auth/auth.middleware.go +++ b/internal/middleware/auth/auth.middleware.go @@ -4,7 +4,7 @@ import ( "net/http" "github.com/isd-sgcu/johnjud-gateway/config" - "github.com/isd-sgcu/johnjud-gateway/constant/user" + "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" authPkg "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/auth" "github.com/isd-sgcu/johnjud-gateway/internal/router" @@ -59,7 +59,7 @@ func (m *Guard) Use(ctx router.IContext) error { ctx.StoreValue("UserId", payload.UserId) ctx.StoreValue("Role", payload.Role) - if utils.IsExisted(m.adminpath, path) && payload.Role != string(user.ADMIN) { + if utils.IsExisted(m.adminpath, path) && payload.Role != string(constant.ADMIN) { ctx.JSON(http.StatusUnauthorized, dto.ResponseErr{ StatusCode: http.StatusUnauthorized, Message: "Limited access", diff --git a/internal/service/pet/pet.service_test.go b/internal/service/pet/pet.service_test.go index dd8bd11..6171130 100644 --- a/internal/service/pet/pet.service_test.go +++ b/internal/service/pet/pet.service_test.go @@ -7,7 +7,6 @@ import ( "github.com/go-faker/faker/v4" "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/constant/pet" "github.com/isd-sgcu/johnjud-gateway/internal/dto" imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/image" utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" @@ -78,8 +77,8 @@ func (t *PetServiceTest) SetupTest() { } t.ImagesList = imagesList t.Images = imagesList[petIds[0]] - genders := []pet.Gender{pet.MALE, pet.FEMALE} - statuses := []pet.Status{pet.ADOPTED, pet.FINDHOME} + genders := []constant.Gender{constant.MALE, constant.FEMALE} + statuses := []constant.Status{constant.ADOPTED, constant.FINDHOME} var pets []*petproto.Pet for i := 0; i <= 3; i++ { @@ -163,13 +162,13 @@ func (t *PetServiceTest) SetupTest() { Type: t.Pet.Type, Name: t.Pet.Name, Birthdate: t.Pet.Birthdate, - Gender: pet.Gender(t.Pet.Gender), + Gender: constant.Gender(t.Pet.Gender), Color: t.Pet.Color, Pattern: t.Pet.Pattern, Habit: t.Pet.Habit, Caption: t.Pet.Caption, Images: []string{}, - Status: pet.Status(t.Pet.Status), + Status: constant.Status(t.Pet.Status), IsSterile: &t.Pet.IsSterile, IsVaccinated: &t.Pet.IsVaccinated, IsVisible: &t.Pet.IsVisible, @@ -183,13 +182,13 @@ func (t *PetServiceTest) SetupTest() { Type: t.Pet.Type, Name: t.Pet.Name, Birthdate: t.Pet.Birthdate, - Gender: pet.Gender(t.Pet.Gender), + Gender: constant.Gender(t.Pet.Gender), Color: t.Pet.Color, Pattern: t.Pet.Pattern, Habit: t.Pet.Habit, Caption: t.Pet.Caption, Images: []string{}, - Status: pet.Status(t.Pet.Status), + Status: constant.Status(t.Pet.Status), IsSterile: &t.Pet.IsSterile, IsVaccinated: &t.Pet.IsVaccinated, IsVisible: &t.Pet.IsVisible, diff --git a/internal/utils/pet/pet.utils.go b/internal/utils/pet/pet.utils.go index dfae5c0..95f8865 100644 --- a/internal/utils/pet/pet.utils.go +++ b/internal/utils/pet/pet.utils.go @@ -4,7 +4,7 @@ import ( "errors" "strconv" - "github.com/isd-sgcu/johnjud-gateway/constant/pet" + "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" imgproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" @@ -61,12 +61,12 @@ func ProtoToDto(in *petproto.Pet, images []*dto.ImageResponse) *dto.PetResponse Type: in.Type, Name: in.Name, Birthdate: in.Birthdate, - Gender: pet.Gender(in.Gender), + Gender: constant.Gender(in.Gender), Color: in.Color, Pattern: in.Pattern, Habit: in.Habit, Caption: in.Caption, - Status: pet.Status(in.Status), + Status: constant.Status(in.Status), IsSterile: &in.IsSterile, IsVaccinated: &in.IsVaccinated, IsVisible: &in.IsVisible, @@ -154,12 +154,12 @@ func ProtoToDtoList(in []*petproto.Pet, imagesList map[string][]*imgproto.Image, Type: p.Type, Name: p.Name, Birthdate: p.Birthdate, - Gender: pet.Gender(p.Gender), + Gender: constant.Gender(p.Gender), Color: p.Color, Pattern: p.Pattern, Habit: p.Habit, Caption: p.Caption, - Status: pet.Status(p.Status), + Status: constant.Status(p.Status), IsSterile: &p.IsSterile, IsVaccinated: &p.IsVaccinated, IsVisible: &p.IsVisible, From 6127a1aa57294623769c498472972cc4ff00187c Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Tue, 20 Aug 2024 17:34:48 +0700 Subject: [PATCH 075/104] auth --- cmd/main.go | 7 +- internal/{handler => }/auth/auth.handler.go | 21 ++- internal/{service => }/auth/auth.service.go | 30 ++-- internal/{utils => }/auth/auth.utils.go | 0 .../auth => auth/test}/auth.handler_test.go | 47 +++--- .../auth => auth/test}/auth.service_test.go | 137 +++++++++--------- internal/middleware/auth/auth.middleware.go | 7 +- internal/pkg/service/auth/auth.service.go | 12 -- 8 files changed, 129 insertions(+), 132 deletions(-) rename internal/{handler => }/auth/auth.handler.go (93%) rename internal/{service => }/auth/auth.service.go (87%) rename internal/{utils => }/auth/auth.utils.go (100%) rename internal/{handler/auth => auth/test}/auth.handler_test.go (92%) rename internal/{service/auth => auth/test}/auth.service_test.go (89%) diff --git a/cmd/main.go b/cmd/main.go index acb1827..4c959be 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -12,7 +12,7 @@ import ( "github.com/isd-sgcu/johnjud-gateway/config" "github.com/isd-sgcu/johnjud-gateway/constant" - authHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/auth" + "github.com/isd-sgcu/johnjud-gateway/internal/auth" "github.com/isd-sgcu/johnjud-gateway/internal/handler/healthcheck" imageHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/image" likeHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/like" @@ -20,7 +20,6 @@ import ( userHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/user" guard "github.com/isd-sgcu/johnjud-gateway/internal/middleware/auth" "github.com/isd-sgcu/johnjud-gateway/internal/router" - authSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/auth" imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/image" likeSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/like" petSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/pet" @@ -110,8 +109,8 @@ func main() { userHandler := userHdr.NewHandler(userService, v) authClient := authProto.NewAuthServiceClient(authConn) - authService := authSvc.NewService(authClient) - authHandler := authHdr.NewHandler(authService, userService, v) + authService := auth.NewService(authClient) + authHandler := auth.NewHandler(authService, userService, v) authGuard := guard.NewAuthGuard(authService, constant.ExcludePath, constant.AdminPath, conf.App, constant.VersionList) diff --git a/internal/handler/auth/auth.handler.go b/internal/auth/auth.handler.go similarity index 93% rename from internal/handler/auth/auth.handler.go rename to internal/auth/auth.handler.go index 38af0b1..b7ef768 100644 --- a/internal/handler/auth/auth.handler.go +++ b/internal/auth/auth.handler.go @@ -6,20 +6,19 @@ import ( "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/auth" "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/user" "github.com/isd-sgcu/johnjud-gateway/internal/router" "github.com/isd-sgcu/johnjud-gateway/internal/validator" ) -type Handler struct { - service auth.Service +type handlerImpl struct { + service Service userService user.Service validate validator.IDtoValidator } -func NewHandler(service auth.Service, userService user.Service, validate validator.IDtoValidator) *Handler { - return &Handler{service, userService, validate} +func NewHandler(service Service, userService user.Service, validate validator.IDtoValidator) *handlerImpl { + return &handlerImpl{service, userService, validate} } // Signup is a function that create user in database @@ -35,7 +34,7 @@ func NewHandler(service auth.Service, userService user.Service, validate validat // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/auth/signup [post] -func (h *Handler) Signup(c router.IContext) { +func (h *handlerImpl) Signup(c router.IContext) { request := &dto.SignupRequest{} err := c.Bind(request) if err != nil { @@ -82,7 +81,7 @@ func (h *Handler) Signup(c router.IContext) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/auth/signin [post] -func (h *Handler) SignIn(c router.IContext) { +func (h *handlerImpl) SignIn(c router.IContext) { request := &dto.SignInRequest{} err := c.Bind(request) if err != nil { @@ -127,7 +126,7 @@ func (h *Handler) SignIn(c router.IContext) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/auth/signout [post] -func (h *Handler) SignOut(c router.IContext) { +func (h *handlerImpl) SignOut(c router.IContext) { token := c.Token() response, respErr := h.service.SignOut(token) @@ -152,7 +151,7 @@ func (h *Handler) SignOut(c router.IContext) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/auth/refreshToken [post] -func (h *Handler) RefreshToken(c router.IContext) { +func (h *handlerImpl) RefreshToken(c router.IContext) { request := &dto.RefreshTokenRequest{} err := c.Bind(request) if err != nil { @@ -198,7 +197,7 @@ func (h *Handler) RefreshToken(c router.IContext) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/auth/forgot-password [post] -func (h *Handler) ForgotPassword(c router.IContext) { +func (h *handlerImpl) ForgotPassword(c router.IContext) { request := &dto.ForgotPasswordRequest{} err := c.Bind(request) if err != nil { @@ -244,7 +243,7 @@ func (h *Handler) ForgotPassword(c router.IContext) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/auth/reset-password [put] -func (h *Handler) ResetPassword(c router.IContext) { +func (h *handlerImpl) ResetPassword(c router.IContext) { request := &dto.ResetPasswordRequest{} err := c.Bind(request) if err != nil { diff --git a/internal/service/auth/auth.service.go b/internal/auth/auth.service.go similarity index 87% rename from internal/service/auth/auth.service.go rename to internal/auth/auth.service.go index e42aaa8..702dfe3 100644 --- a/internal/service/auth/auth.service.go +++ b/internal/auth/auth.service.go @@ -13,17 +13,27 @@ import ( "google.golang.org/grpc/status" ) -type Service struct { +type Service interface { + Signup(*dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) + SignIn(*dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) + SignOut(string) (*dto.SignOutResponse, *dto.ResponseErr) + Validate(string) (*dto.TokenPayloadAuth, *dto.ResponseErr) + RefreshToken(*dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) + ForgotPassword(*dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) + ResetPassword(*dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) +} + +type serviceImpl struct { client authProto.AuthServiceClient } -func NewService(client authProto.AuthServiceClient) *Service { - return &Service{ +func NewService(client authProto.AuthServiceClient) Service { + return &serviceImpl{ client: client, } } -func (s *Service) Signup(request *dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) { +func (s *serviceImpl) Signup(request *dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -82,7 +92,7 @@ func (s *Service) Signup(request *dto.SignupRequest) (*dto.SignupResponse, *dto. }, nil } -func (s *Service) SignIn(request *dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) { +func (s *serviceImpl) SignIn(request *dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -138,7 +148,7 @@ func (s *Service) SignIn(request *dto.SignInRequest) (*dto.Credential, *dto.Resp }, nil } -func (s *Service) SignOut(token string) (*dto.SignOutResponse, *dto.ResponseErr) { +func (s *serviceImpl) SignOut(token string) (*dto.SignOutResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -185,7 +195,7 @@ func (s *Service) SignOut(token string) (*dto.SignOutResponse, *dto.ResponseErr) }, nil } -func (s *Service) Validate(token string) (*dto.TokenPayloadAuth, *dto.ResponseErr) { +func (s *serviceImpl) Validate(token string) (*dto.TokenPayloadAuth, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -233,7 +243,7 @@ func (s *Service) Validate(token string) (*dto.TokenPayloadAuth, *dto.ResponseEr }, nil } -func (s *Service) RefreshToken(request *dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) { +func (s *serviceImpl) RefreshToken(request *dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -289,7 +299,7 @@ func (s *Service) RefreshToken(request *dto.RefreshTokenRequest) (*dto.Credentia }, nil } -func (s *Service) ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) { +func (s *serviceImpl) ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -342,7 +352,7 @@ func (s *Service) ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.Forgo }, nil } -func (s *Service) ResetPassword(request *dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) { +func (s *serviceImpl) ResetPassword(request *dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() diff --git a/internal/utils/auth/auth.utils.go b/internal/auth/auth.utils.go similarity index 100% rename from internal/utils/auth/auth.utils.go rename to internal/auth/auth.utils.go diff --git a/internal/handler/auth/auth.handler_test.go b/internal/auth/test/auth.handler_test.go similarity index 92% rename from internal/handler/auth/auth.handler_test.go rename to internal/auth/test/auth.handler_test.go index c3bb150..08dd64b 100644 --- a/internal/handler/auth/auth.handler_test.go +++ b/internal/auth/test/auth.handler_test.go @@ -1,4 +1,4 @@ -package auth +package test import ( "errors" @@ -8,6 +8,7 @@ import ( "github.com/go-faker/faker/v4" "github.com/golang/mock/gomock" "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/auth" "github.com/isd-sgcu/johnjud-gateway/internal/dto" routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" authMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/auth" @@ -79,7 +80,7 @@ func (t *AuthHandlerTest) TestSignupSuccess() { authSvc.EXPECT().Signup(t.signupRequest).Return(signupResponse, nil) context.EXPECT().JSON(http.StatusOK, signupResponse) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) handler.Signup(context) } @@ -101,7 +102,7 @@ func (t *AuthHandlerTest) TestSignupBindFailed() { context.EXPECT().Bind(t.signupRequest).Return(t.bindErr) context.EXPECT().JSON(http.StatusBadRequest, errResponse) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) handler.Signup(context) } @@ -124,7 +125,7 @@ func (t *AuthHandlerTest) TestSignupValidateFailed() { validator.EXPECT().Validate(t.signupRequest).Return(t.validateErr) context.EXPECT().JSON(http.StatusBadRequest, errResponse) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) handler.Signup(context) } @@ -148,7 +149,7 @@ func (t *AuthHandlerTest) TestSignupServiceError() { authSvc.EXPECT().Signup(t.signupRequest).Return(nil, signupError) context.EXPECT().JSON(http.StatusInternalServerError, signupError) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) handler.Signup(context) } @@ -172,7 +173,7 @@ func (t *AuthHandlerTest) TestSignInSuccess() { authSvc.EXPECT().SignIn(t.signInRequest).Return(signInResponse, nil) context.EXPECT().JSON(http.StatusOK, signInResponse) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) handler.SignIn(context) } @@ -194,7 +195,7 @@ func (t *AuthHandlerTest) TestSignInBindFailed() { context.EXPECT().Bind(t.signInRequest).Return(t.bindErr) context.EXPECT().JSON(http.StatusBadRequest, errResponse) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) handler.SignIn(context) } @@ -217,7 +218,7 @@ func (t *AuthHandlerTest) TestSignInValidateFailed() { validator.EXPECT().Validate(t.signInRequest).Return(t.validateErr) context.EXPECT().JSON(http.StatusBadRequest, errResponse) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) handler.SignIn(context) } @@ -241,7 +242,7 @@ func (t *AuthHandlerTest) TestSignInServiceError() { authSvc.EXPECT().SignIn(t.signInRequest).Return(nil, signInErrResponse) context.EXPECT().JSON(http.StatusInternalServerError, signInErrResponse) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) handler.SignIn(context) } @@ -263,7 +264,7 @@ func (t *AuthHandlerTest) TestSignOutSuccess() { authSvc.EXPECT().SignOut(token).Return(signOutResponse, nil) context.EXPECT().JSON(http.StatusOK, signOutResponse) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) handler.SignOut(context) } @@ -283,7 +284,7 @@ func (t *AuthHandlerTest) TestSignOutServiceError() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Token().Return(token) authSvc.EXPECT().SignOut(token).Return(nil, errResponse) @@ -306,7 +307,7 @@ func (t *AuthHandlerTest) TestRefreshTokenSuccess() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.refreshTokenRequest).Return(nil) validator.EXPECT().Validate(t.refreshTokenRequest).Return(nil) @@ -330,7 +331,7 @@ func (t *AuthHandlerTest) TestRefreshTokenBindFailed() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.refreshTokenRequest).Return(t.bindErr) context.EXPECT().JSON(http.StatusBadRequest, errResponse) @@ -352,7 +353,7 @@ func (t *AuthHandlerTest) TestRefreshTokenValidateFailed() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.refreshTokenRequest).Return(nil) validator.EXPECT().Validate(t.refreshTokenRequest).Return(t.validateErr) @@ -375,7 +376,7 @@ func (t *AuthHandlerTest) TestRefreshTokenServiceError() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.refreshTokenRequest).Return(nil) validator.EXPECT().Validate(t.refreshTokenRequest).Return(nil) @@ -397,7 +398,7 @@ func (t *AuthHandlerTest) TestForgotPasswordSuccess() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.forgotPasswordRequest).Return(nil) validator.EXPECT().Validate(t.forgotPasswordRequest).Return(nil) @@ -421,7 +422,7 @@ func (t *AuthHandlerTest) TestForgotPasswordBindFailed() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.forgotPasswordRequest).Return(t.bindErr) context.EXPECT().JSON(http.StatusBadRequest, errResponse) @@ -442,7 +443,7 @@ func (t *AuthHandlerTest) TestForgotPasswordValidateFailed() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.forgotPasswordRequest).Return(nil) validator.EXPECT().Validate(t.forgotPasswordRequest).Return(t.validateErr) @@ -465,7 +466,7 @@ func (t *AuthHandlerTest) TestForgotPasswordServiceError() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.forgotPasswordRequest).Return(nil) validator.EXPECT().Validate(t.forgotPasswordRequest).Return(nil) @@ -487,7 +488,7 @@ func (t *AuthHandlerTest) TestResetPasswordSuccess() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.resetPasswordRequest).Return(nil) validator.EXPECT().Validate(t.resetPasswordRequest).Return(nil) @@ -511,7 +512,7 @@ func (t *AuthHandlerTest) TestResetPasswordBindFailed() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.resetPasswordRequest).Return(t.bindErr) context.EXPECT().JSON(http.StatusBadRequest, errResponse) @@ -533,7 +534,7 @@ func (t *AuthHandlerTest) TestResetPasswordValidateFailed() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.resetPasswordRequest).Return(nil) validator.EXPECT().Validate(t.resetPasswordRequest).Return(t.validateErr) @@ -556,7 +557,7 @@ func (t *AuthHandlerTest) TestResetPasswordServiceError() { validator := validatorMock.NewMockIDtoValidator(controller) context := routerMock.NewMockIContext(controller) - handler := NewHandler(authSvc, userSvc, validator) + handler := auth.NewHandler(authSvc, userSvc, validator) context.EXPECT().Bind(t.resetPasswordRequest).Return(nil) validator.EXPECT().Validate(t.resetPasswordRequest).Return(nil) diff --git a/internal/service/auth/auth.service_test.go b/internal/auth/test/auth.service_test.go similarity index 89% rename from internal/service/auth/auth.service_test.go rename to internal/auth/test/auth.service_test.go index 1e03d2c..3633086 100644 --- a/internal/service/auth/auth.service_test.go +++ b/internal/auth/test/auth.service_test.go @@ -1,4 +1,4 @@ -package auth +package test import ( "errors" @@ -7,8 +7,9 @@ import ( "github.com/go-faker/faker/v4" "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/auth" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/mocks/client/auth" + mockAuth "github.com/isd-sgcu/johnjud-gateway/mocks/client/auth" authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" @@ -82,11 +83,11 @@ func (t *AuthServiceTest) TestSignupSuccess() { Lastname: t.signupRequestDto.Lastname, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignUp", protoReq).Return(protoResp, nil) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.Signup(t.signupRequestDto) assert.Nil(t.T(), err) @@ -111,10 +112,10 @@ func (t *AuthServiceTest) TestSignupConflict() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignUp", protoReq).Return(nil, clientErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.Signup(t.signupRequestDto) assert.Nil(t.T(), actual) @@ -136,10 +137,10 @@ func (t *AuthServiceTest) TestSignupInternalError() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignUp", protoReq).Return(nil, clientErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.Signup(t.signupRequestDto) assert.Nil(t.T(), actual) @@ -161,10 +162,10 @@ func (t *AuthServiceTest) TestSignupUnavailableService() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignUp", protoReq).Return(nil, clientErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.Signup(t.signupRequestDto) assert.Nil(t.T(), actual) @@ -186,10 +187,10 @@ func (t *AuthServiceTest) TestSignupUnknownError() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignUp", protoReq).Return(nil, clientErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.Signup(t.signupRequestDto) assert.Nil(t.T(), actual) @@ -215,11 +216,11 @@ func (t *AuthServiceTest) TestSignInSuccess() { ExpiresIn: int(protoResp.Credential.ExpiresIn), } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignIn", protoReq).Return(protoResp, nil) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.SignIn(t.signInDto) assert.Nil(t.T(), err) @@ -239,11 +240,11 @@ func (t *AuthServiceTest) TestSignInForbidden() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignIn", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.SignIn(t.signInDto) assert.Nil(t.T(), actual) @@ -263,11 +264,11 @@ func (t *AuthServiceTest) TestSignInInternalError() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignIn", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.SignIn(t.signInDto) assert.Nil(t.T(), actual) @@ -287,10 +288,10 @@ func (t *AuthServiceTest) TestSignInUnavailableService() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignIn", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.SignIn(t.signInDto) assert.Nil(t.T(), actual) @@ -310,11 +311,11 @@ func (t *AuthServiceTest) TestSignInUnknownError() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignIn", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.SignIn(t.signInDto) assert.Nil(t.T(), actual) @@ -331,10 +332,10 @@ func (t *AuthServiceTest) TestSignOutSuccess() { expected := &dto.SignOutResponse{IsSuccess: true} - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignOut", protoReq).Return(protoResp, nil) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.SignOut(t.token) assert.Nil(t.T(), err) @@ -353,10 +354,10 @@ func (t *AuthServiceTest) TestSignOutInternalError() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignOut", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.SignOut(t.token) assert.Nil(t.T(), actual) @@ -375,10 +376,10 @@ func (t *AuthServiceTest) TestSignOutUnavailableService() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignOut", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.SignOut(t.token) assert.Nil(t.T(), actual) @@ -397,10 +398,10 @@ func (t *AuthServiceTest) TestSignOutUnknownError() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("SignOut", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.SignOut(t.token) assert.Nil(t.T(), actual) @@ -421,10 +422,10 @@ func (t *AuthServiceTest) TestValidateSuccess() { Role: protoResp.Role, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("Validate", protoReq).Return(protoResp, nil) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.Validate(t.token) assert.Nil(t.T(), err) @@ -443,10 +444,10 @@ func (t *AuthServiceTest) TestValidateUnauthorized() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("Validate", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.Validate(t.token) assert.Nil(t.T(), actual) @@ -465,10 +466,10 @@ func (t *AuthServiceTest) TestValidateUnavailableService() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("Validate", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.Validate(t.token) assert.Nil(t.T(), actual) @@ -487,10 +488,10 @@ func (t *AuthServiceTest) TestValidateUnknownError() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("Validate", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.Validate(t.token) assert.Nil(t.T(), actual) @@ -515,10 +516,10 @@ func (t *AuthServiceTest) TestRefreshTokenSuccess() { ExpiresIn: int(protoResp.Credential.ExpiresIn), } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("RefreshToken", protoReq).Return(protoResp, nil) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.RefreshToken(t.refreshTokenRequest) assert.Nil(t.T(), err) @@ -537,10 +538,10 @@ func (t *AuthServiceTest) TestRefreshTokenInvalidToken() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("RefreshToken", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.RefreshToken(t.refreshTokenRequest) assert.Nil(t.T(), actual) @@ -559,10 +560,10 @@ func (t *AuthServiceTest) TestRefreshTokenInternalError() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("RefreshToken", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.RefreshToken(t.refreshTokenRequest) assert.Nil(t.T(), actual) @@ -581,10 +582,10 @@ func (t *AuthServiceTest) TestRefreshTokenUnavailableService() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("RefreshToken", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.RefreshToken(t.refreshTokenRequest) assert.Nil(t.T(), actual) @@ -603,10 +604,10 @@ func (t *AuthServiceTest) TestRefreshTokenUnknownError() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("RefreshToken", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.RefreshToken(t.refreshTokenRequest) assert.Nil(t.T(), actual) @@ -624,10 +625,10 @@ func (t *AuthServiceTest) TestForgotPasswordSuccess() { IsSuccess: true, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("ForgotPassword", protoReq).Return(protoResp, nil) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.ForgotPassword(t.forgotPasswordRequest) assert.Nil(t.T(), err) @@ -646,10 +647,10 @@ func (t *AuthServiceTest) TestForgotPasswordNotFound() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("ForgotPassword", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.ForgotPassword(t.forgotPasswordRequest) assert.Nil(t.T(), actual) @@ -668,10 +669,10 @@ func (t *AuthServiceTest) TestForgotPasswordInternalErr() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("ForgotPassword", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.ForgotPassword(t.forgotPasswordRequest) assert.Nil(t.T(), actual) @@ -690,10 +691,10 @@ func (t *AuthServiceTest) TestForgotPasswordUnavailableService() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("ForgotPassword", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.ForgotPassword(t.forgotPasswordRequest) assert.Nil(t.T(), actual) @@ -712,10 +713,10 @@ func (t *AuthServiceTest) TestForgotPasswordUnknownErr() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("ForgotPassword", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.ForgotPassword(t.forgotPasswordRequest) assert.Nil(t.T(), actual) @@ -735,10 +736,10 @@ func (t *AuthServiceTest) TestResetPasswordSuccess() { IsSuccess: true, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("ResetPassword", protoReq).Return(protoResp, nil) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.ResetPassword(t.resetPasswordRequest) assert.Nil(t.T(), err) @@ -758,10 +759,10 @@ func (t *AuthServiceTest) TestResetPasswordInvalid() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("ResetPassword", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.ResetPassword(t.resetPasswordRequest) assert.Nil(t.T(), actual) @@ -781,10 +782,10 @@ func (t *AuthServiceTest) TestResetPasswordInternalErr() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("ResetPassword", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.ResetPassword(t.resetPasswordRequest) assert.Nil(t.T(), actual) @@ -804,10 +805,10 @@ func (t *AuthServiceTest) TestResetPasswordUnavailableService() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("ResetPassword", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.ResetPassword(t.resetPasswordRequest) assert.Nil(t.T(), actual) @@ -827,10 +828,10 @@ func (t *AuthServiceTest) TestResetPasswordUnknownErr() { Data: nil, } - client := auth.AuthClientMock{} + client := mockAuth.AuthClientMock{} client.On("ResetPassword", protoReq).Return(nil, protoErr) - svc := NewService(&client) + svc := auth.NewService(&client) actual, err := svc.ResetPassword(t.resetPasswordRequest) assert.Nil(t.T(), actual) diff --git a/internal/middleware/auth/auth.middleware.go b/internal/middleware/auth/auth.middleware.go index f260dd3..956b681 100644 --- a/internal/middleware/auth/auth.middleware.go +++ b/internal/middleware/auth/auth.middleware.go @@ -5,22 +5,21 @@ import ( "github.com/isd-sgcu/johnjud-gateway/config" "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/auth" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - authPkg "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/auth" "github.com/isd-sgcu/johnjud-gateway/internal/router" "github.com/isd-sgcu/johnjud-gateway/internal/utils" - "github.com/isd-sgcu/johnjud-gateway/internal/utils/auth" ) type Guard struct { - service authPkg.Service + service auth.Service excludes map[string]struct{} adminpath map[string]struct{} conf config.App versionList map[string]struct{} } -func NewAuthGuard(s authPkg.Service, e map[string]struct{}, a map[string]struct{}, conf config.App, versionList map[string]struct{}) Guard { +func NewAuthGuard(s auth.Service, e map[string]struct{}, a map[string]struct{}, conf config.App, versionList map[string]struct{}) Guard { return Guard{ service: s, excludes: e, diff --git a/internal/pkg/service/auth/auth.service.go b/internal/pkg/service/auth/auth.service.go index 424ef2c..8832b06 100644 --- a/internal/pkg/service/auth/auth.service.go +++ b/internal/pkg/service/auth/auth.service.go @@ -1,13 +1 @@ package auth - -import "github.com/isd-sgcu/johnjud-gateway/internal/dto" - -type Service interface { - Signup(*dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) - SignIn(*dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) - SignOut(string) (*dto.SignOutResponse, *dto.ResponseErr) - Validate(string) (*dto.TokenPayloadAuth, *dto.ResponseErr) - RefreshToken(*dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) - ForgotPassword(*dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) - ResetPassword(*dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) -} From 96b83ef79a9cbf316a92d40d59ef1b8124c0947a Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 18:15:03 +0700 Subject: [PATCH 076/104] remove like --- Makefile | 5 +- cmd/main.go | 11 - internal/handler/like/like.handler.go | 98 ------- internal/handler/like/like.handler_test.go | 267 ----------------- internal/pkg/service/auth/auth.service.go | 1 - internal/pkg/service/like/like.service.go | 9 - internal/service/like/like.service.go | 139 --------- internal/service/like/like.service_test.go | 315 --------------------- mocks/service/auth/auth.mock.go | 2 +- 9 files changed, 3 insertions(+), 844 deletions(-) delete mode 100644 internal/handler/like/like.handler.go delete mode 100644 internal/handler/like/like.handler_test.go delete mode 100644 internal/pkg/service/auth/auth.service.go delete mode 100644 internal/pkg/service/like/like.service.go delete mode 100644 internal/service/like/like.service.go delete mode 100644 internal/service/like/like.service_test.go diff --git a/Makefile b/Makefile index aa62d83..93b4f52 100644 --- a/Makefile +++ b/Makefile @@ -13,13 +13,12 @@ test: go tool cover -html=coverage.out -o coverage.html server: - . ./tools/export-env.sh ; go run ./src/. + . ./tools/export-env.sh ; go run ./cmd/. mock-gen: - mockgen -source ./internal/pkg/service/auth/auth.service.go -destination ./mocks/service/auth/auth.mock.go + mockgen -source ./internal/auth/auth.service.go -destination ./mocks/service/auth/auth.mock.go mockgen -source ./internal/pkg/service/user/user.service.go -destination ./mocks/service/user/user.mock.go mockgen -source ./internal/pkg/service/pet/pet.service.go -destination ./mocks/service/pet/pet.mock.go - mockgen -source ./internal/pkg/service/like/like.service.go -destination ./mocks/service/like/like.mock.go mockgen -source ./internal/pkg/service/image/image.service.go -destination ./mocks/service/image/image.mock.go mockgen -source ./internal/validator/validator.go -destination ./mocks/validator/validator.mock.go mockgen -source ./internal/router/context.go -destination ./mocks/router/context.mock.go diff --git a/cmd/main.go b/cmd/main.go index 4c959be..17d8270 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -15,19 +15,16 @@ import ( "github.com/isd-sgcu/johnjud-gateway/internal/auth" "github.com/isd-sgcu/johnjud-gateway/internal/handler/healthcheck" imageHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/image" - likeHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/like" petHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/pet" userHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/user" guard "github.com/isd-sgcu/johnjud-gateway/internal/middleware/auth" "github.com/isd-sgcu/johnjud-gateway/internal/router" imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/image" - likeSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/like" petSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/pet" userSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/user" "github.com/isd-sgcu/johnjud-gateway/internal/validator" authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" userProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" - likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" imageProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" "github.com/rs/zerolog/log" @@ -122,10 +119,6 @@ func main() { petService := petSvc.NewService(petClient, imageService) petHandler := petHdr.NewHandler(petService, imageService, v) - likeClient := likeProto.NewLikeServiceClient(backendConn) - likeService := likeSvc.NewService(likeClient) - likeHandler := likeHdr.NewHandler(likeService, v) - r := router.NewFiberRouter(&authGuard, conf.App) r.GetUser("/:id", userHandler.FindOne) @@ -151,10 +144,6 @@ func main() { r.PutPet("/:id/visible", petHandler.ChangeView) r.DeletePet("/:id", petHandler.Delete) - r.GetLike("/:id", likeHandler.FindByUserId) - r.PostLike("", likeHandler.Create) - r.DeleteLike("/:id", likeHandler.Delete) - r.PostImage("", imageHandler.Upload) r.DeleteImage("/:id", imageHandler.Delete) diff --git a/internal/handler/like/like.handler.go b/internal/handler/like/like.handler.go deleted file mode 100644 index 485c1bf..0000000 --- a/internal/handler/like/like.handler.go +++ /dev/null @@ -1,98 +0,0 @@ -package auth - -import ( - "net/http" - "strings" - - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - likeSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/like" - "github.com/isd-sgcu/johnjud-gateway/internal/router" - "github.com/isd-sgcu/johnjud-gateway/internal/validator" -) - -type Handler struct { - service likeSvc.Service - validate validator.IDtoValidator -} - -func NewHandler(service likeSvc.Service, validate validator.IDtoValidator) *Handler { - return &Handler{service, validate} -} - -func (h *Handler) FindByUserId(c router.IContext) { - id, err := c.Param("id") - if err != nil { - c.JSON(http.StatusBadRequest, dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InvalidIDMessage, - Data: nil, - }) - return - } - - response, respErr := h.service.FindByUserId(id) - if respErr != nil { - c.JSON(respErr.StatusCode, respErr) - return - } - - c.JSON(http.StatusOK, response) - return -} - -func (h *Handler) Create(c router.IContext) { - request := &dto.CreateLikeRequest{} - 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 - } - - response, respErr := h.service.Create(request) - if respErr != nil { - c.JSON(respErr.StatusCode, respErr) - return - } - - c.JSON(http.StatusCreated, response) - return -} - -func (h *Handler) Delete(c router.IContext) { - id, err := c.Param("id") - if err != nil { - c.JSON(http.StatusBadRequest, dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: err.Error(), - Data: nil, - }) - return - } - - res, errRes := h.service.Delete(id) - if errRes != nil { - c.JSON(errRes.StatusCode, errRes) - return - } - - c.JSON(http.StatusOK, res) - return -} diff --git a/internal/handler/like/like.handler_test.go b/internal/handler/like/like.handler_test.go deleted file mode 100644 index 3cecacc..0000000 --- a/internal/handler/like/like.handler_test.go +++ /dev/null @@ -1,267 +0,0 @@ -package auth - -import ( - "net/http" - "testing" - - "github.com/bxcodec/faker/v4" - "github.com/golang/mock/gomock" - errConst "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/like" - routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" - likeMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/like" - validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" - likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" - "github.com/stretchr/testify/suite" -) - -type LikeHandlerTest struct { - suite.Suite - Likes []*likeProto.Like - Like *likeProto.Like - LikeResponse *dto.LikeResponse - CreateLikeRequest *dto.CreateLikeRequest - DeleteLikeRequest *dto.DeleteLikeRequest - NotFoundErr *dto.ResponseErr - - UnavailableServiceErr *dto.ResponseErr - InvalidArgumentErr *dto.ResponseErr - BindErr *dto.ResponseErr - InternalErr *dto.ResponseErr -} - -func TestLikeHandler(t *testing.T) { - suite.Run(t, new(LikeHandlerTest)) -} - -func (t *LikeHandlerTest) SetupTest() { - var likes []*likeProto.Like - for i := 0; i <= 3; i++ { - like := &likeProto.Like{ - Id: faker.UUIDDigit(), - UserId: faker.UUIDDigit(), - PetId: faker.UUIDDigit(), - } - likes = append(likes, like) - } - - t.Likes = likes - t.Like = likes[0] - - t.CreateLikeRequest = &dto.CreateLikeRequest{} - t.DeleteLikeRequest = &dto.DeleteLikeRequest{} - - t.NotFoundErr = &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: errConst.UserNotFoundMessage, - Data: nil, - } - - t.InternalErr = &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: errConst.InternalErrorMessage, - Data: nil, - } - - t.UnavailableServiceErr = &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: errConst.UnavailableServiceMessage, - Data: nil, - } -} - -func (t *LikeHandlerTest) TestFindLikesSuccess() { - findLikeResponse := utils.ProtoToDtoList(t.Likes) - expectedResponse := findLikeResponse - - controller := gomock.NewController(t.T()) - - likeSvc := likeMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Param("id").Return(t.Like.UserId, nil) - likeSvc.EXPECT().FindByUserId(t.Like.UserId).Return(utils.ProtoToDtoList(t.Likes), nil) - context.EXPECT().JSON(http.StatusOK, expectedResponse) - - handler := NewHandler(likeSvc, validator) - handler.FindByUserId(context) -} - -func (t *LikeHandlerTest) TestFindLikeNotFoundError() { - findLikeErrorResponse := t.NotFoundErr - - controller := gomock.NewController(t.T()) - - petSvc := likeMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Param("id").Return(t.Like.UserId, nil) - petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, findLikeErrorResponse) - context.EXPECT().JSON(http.StatusNotFound, findLikeErrorResponse) - - handler := NewHandler(petSvc, validator) - handler.FindByUserId(context) -} - -func (t *LikeHandlerTest) TestFindLikeServiceUnavailableError() { - findLikeErrorResponse := t.UnavailableServiceErr - - controller := gomock.NewController(t.T()) - - petSvc := likeMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Param("id").Return(t.Like.UserId, nil) - petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, findLikeErrorResponse) - context.EXPECT().JSON(http.StatusServiceUnavailable, findLikeErrorResponse) - - handler := NewHandler(petSvc, validator) - handler.FindByUserId(context) -} - -func (t *LikeHandlerTest) TestFindLikeInternalError() { - findLikeErrorResponse := t.InternalErr - - controller := gomock.NewController(t.T()) - - petSvc := likeMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Param("id").Return(t.Like.UserId, nil) - petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, findLikeErrorResponse) - context.EXPECT().JSON(http.StatusInternalServerError, findLikeErrorResponse) - - handler := NewHandler(petSvc, validator) - handler.FindByUserId(context) -} - -func (t *LikeHandlerTest) TestCreateSuccess() { - createLikeResponse := utils.ProtoToDto(t.Like) - expectedResponse := createLikeResponse - - controller := gomock.NewController(t.T()) - - likeSvc := likeMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Bind(t.CreateLikeRequest).Return(nil) - validator.EXPECT().Validate(t.CreateLikeRequest).Return(nil) - likeSvc.EXPECT().Create(t.CreateLikeRequest).Return(createLikeResponse, nil) - context.EXPECT().JSON(http.StatusCreated, expectedResponse) - - handler := NewHandler(likeSvc, validator) - handler.Create(context) -} - -func (t *LikeHandlerTest) TestCreateUnavailableServiceError() { - createLikeErrorResponse := t.UnavailableServiceErr - - controller := gomock.NewController(t.T()) - - likeSvc := likeMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Bind(t.CreateLikeRequest).Return(nil) - validator.EXPECT().Validate(t.CreateLikeRequest).Return(nil) - likeSvc.EXPECT().Create(t.CreateLikeRequest).Return(nil, createLikeErrorResponse) - context.EXPECT().JSON(http.StatusServiceUnavailable, createLikeErrorResponse) - - handler := NewHandler(likeSvc, validator) - handler.Create(context) -} - -func (t *LikeHandlerTest) TestCreateInternalError() { - createLikeErrorResponse := t.InternalErr - - controller := gomock.NewController(t.T()) - - likeSvc := likeMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Bind(t.CreateLikeRequest).Return(nil) - validator.EXPECT().Validate(t.CreateLikeRequest).Return(nil) - likeSvc.EXPECT().Create(t.CreateLikeRequest).Return(nil, createLikeErrorResponse) - context.EXPECT().JSON(http.StatusInternalServerError, createLikeErrorResponse) - - handler := NewHandler(likeSvc, validator) - handler.Create(context) -} - -func (t *LikeHandlerTest) TestDeleteSuccess() { - deleteResponse := &dto.DeleteLikeResponse{ - Success: true, - } - expectedResponse := deleteResponse - - controller := gomock.NewController(t.T()) - - likeSvc := likeMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Param("id").Return(t.Like.UserId, nil) - likeSvc.EXPECT().Delete(t.Like.UserId).Return(deleteResponse, nil) - context.EXPECT().JSON(http.StatusOK, expectedResponse) - - handler := NewHandler(likeSvc, validator) - handler.Delete(context) -} - -func (t *LikeHandlerTest) TestDeleteNotFoundError() { - deleteErrorResponse := t.NotFoundErr - - controller := gomock.NewController(t.T()) - - petSvc := likeMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Param("id").Return(t.Like.UserId, nil) - petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, deleteErrorResponse) - context.EXPECT().JSON(http.StatusNotFound, deleteErrorResponse) - - handler := NewHandler(petSvc, validator) - handler.FindByUserId(context) -} - -func (t *LikeHandlerTest) TestDeleteServiceUnavailableError() { - deleteErrorResponse := t.UnavailableServiceErr - - controller := gomock.NewController(t.T()) - - petSvc := likeMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Param("id").Return(t.Like.UserId, nil) - petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, deleteErrorResponse) - context.EXPECT().JSON(http.StatusServiceUnavailable, deleteErrorResponse) - - handler := NewHandler(petSvc, validator) - handler.FindByUserId(context) -} - -func (t *LikeHandlerTest) TestDeleteInternalError() { - deleteErrorResponse := t.InternalErr - - controller := gomock.NewController(t.T()) - - petSvc := likeMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Param("id").Return(t.Like.UserId, nil) - petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, deleteErrorResponse) - context.EXPECT().JSON(http.StatusInternalServerError, deleteErrorResponse) - - handler := NewHandler(petSvc, validator) - handler.FindByUserId(context) -} diff --git a/internal/pkg/service/auth/auth.service.go b/internal/pkg/service/auth/auth.service.go deleted file mode 100644 index 8832b06..0000000 --- a/internal/pkg/service/auth/auth.service.go +++ /dev/null @@ -1 +0,0 @@ -package auth diff --git a/internal/pkg/service/like/like.service.go b/internal/pkg/service/like/like.service.go deleted file mode 100644 index 5cbbf1c..0000000 --- a/internal/pkg/service/like/like.service.go +++ /dev/null @@ -1,9 +0,0 @@ -package like - -import "github.com/isd-sgcu/johnjud-gateway/internal/dto" - -type Service interface { - FindByUserId(string) ([]*dto.LikeResponse, *dto.ResponseErr) - Create(*dto.CreateLikeRequest) (*dto.LikeResponse, *dto.ResponseErr) - Delete(string) (*dto.DeleteLikeResponse, *dto.ResponseErr) -} diff --git a/internal/service/like/like.service.go b/internal/service/like/like.service.go deleted file mode 100644 index 8ec1f3d..0000000 --- a/internal/service/like/like.service.go +++ /dev/null @@ -1,139 +0,0 @@ -package like - -import ( - "context" - "net/http" - "time" - - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/like" - likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" - "github.com/rs/zerolog/log" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -type Service struct { - client likeProto.LikeServiceClient -} - -func NewService(client likeProto.LikeServiceClient) *Service { - return &Service{ - client: client, - } -} - -func (s *Service) FindByUserId(userId string) ([]*dto.LikeResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - res, errRes := s.client.FindByUserId(ctx, &likeProto.FindLikeByUserIdRequest{UserId: userId}) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Str("service", "like"). - Str("module", "find by user id"). - Msg(st.Message()) - switch st.Code() { - case codes.NotFound: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.UserNotFoundMessage, - Data: nil, - } - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } - } - return utils.ProtoToDtoList(res.Likes), nil -} - -func (s *Service) Create(in *dto.CreateLikeRequest) (*dto.LikeResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - request := utils.CreateDtoToProto(in) - res, errRes := s.client.Create(ctx, request) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). - Str("service", "like"). - Str("module", "create"). - Msg(st.Message()) - switch st.Code() { - case codes.InvalidArgument: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidArgumentMessage, - Data: nil, - } - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } - } - return utils.ProtoToDto(res.Like), nil -} - -func (s *Service) Delete(id string) (*dto.DeleteLikeResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - request := &likeProto.DeleteLikeRequest{ - Id: id, - } - - res, errRes := s.client.Delete(ctx, request) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). - Str("service", "like"). - Str("module", "delete"). - Msg(st.Message()) - switch st.Code() { - case codes.NotFound: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.UserNotFoundMessage, - Data: nil, - } - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } - } - return &dto.DeleteLikeResponse{ - Success: res.Success, - }, nil -} diff --git a/internal/service/like/like.service_test.go b/internal/service/like/like.service_test.go deleted file mode 100644 index 86b4532..0000000 --- a/internal/service/like/like.service_test.go +++ /dev/null @@ -1,315 +0,0 @@ -package like - -import ( - "net/http" - "testing" - - "github.com/bxcodec/faker/v4" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/like" - likeMock "github.com/isd-sgcu/johnjud-gateway/mocks/client/like" - likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -type LikeServiceTest struct { - suite.Suite - Likes []*likeProto.Like - Like *likeProto.Like - LikeResponse *dto.LikeResponse - CreateLikeProtoReq *likeProto.CreateLikeRequest - CreateLikeDtoReq *dto.CreateLikeRequest - DeleteLikeProtoReq *likeProto.DeleteLikeRequest - DeleteLikeDtoReq *dto.DeleteLikeRequest - NotFoundErr *dto.ResponseErr - - UnavailableServiceErr *dto.ResponseErr - InvalidArgumentErr *dto.ResponseErr - InternalErr *dto.ResponseErr -} - -func TestLikeService(t *testing.T) { - suite.Run(t, new(LikeServiceTest)) -} - -func (t *LikeServiceTest) SetupTest() { - var likes []*likeProto.Like - for i := 0; i <= 3; i++ { - like := &likeProto.Like{ - Id: faker.UUIDDigit(), - UserId: faker.UUIDDigit(), - PetId: faker.UUIDDigit(), - } - likes = append(likes, like) - } - - t.Likes = likes - t.Like = likes[0] - - t.CreateLikeProtoReq = &likeProto.CreateLikeRequest{ - Like: &likeProto.Like{ - UserId: t.Like.UserId, - PetId: t.Like.PetId, - }, - } - - t.CreateLikeDtoReq = &dto.CreateLikeRequest{ - UserID: t.Like.UserId, - PetID: t.Like.PetId, - } - - t.DeleteLikeProtoReq = &likeProto.DeleteLikeRequest{ - Id: t.Like.Id, - } - - t.UnavailableServiceErr = &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - - t.NotFoundErr = &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.UserNotFoundMessage, - Data: nil, - } - - t.InternalErr = &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - t.InvalidArgumentErr = &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidArgumentMessage, - Data: nil, - } -} - -func (t *LikeServiceTest) TestFindByUserIdSuccess() { - protoReq := &likeProto.FindLikeByUserIdRequest{ - UserId: t.Like.UserId, - } - protoResp := &likeProto.FindLikeByUserIdResponse{ - Likes: t.Likes, - } - - expected := utils.ProtoToDtoList(t.Likes) - - client := likeMock.LikeClientMock{} - client.On("FindByUserId", protoReq).Return(protoResp, nil) - - svc := NewService(&client) - actual, err := svc.FindByUserId(t.Like.UserId) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) -} - -func (t *LikeServiceTest) TestFindByUserIdNotFoundError() { - protoReq := &likeProto.FindLikeByUserIdRequest{ - UserId: t.Like.UserId, - } - - clientErr := status.Error(codes.NotFound, constant.UserNotFoundMessage) - - expected := t.NotFoundErr - - client := likeMock.LikeClientMock{} - client.On("FindByUserId", protoReq).Return(nil, clientErr) - - svc := NewService(&client) - actual, err := svc.FindByUserId(t.Like.UserId) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *LikeServiceTest) TestFindByUserIdUnavailableServiceError() { - protoReq := &likeProto.FindLikeByUserIdRequest{ - UserId: t.Like.UserId, - } - - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) - - expected := t.UnavailableServiceErr - - client := likeMock.LikeClientMock{} - client.On("FindByUserId", protoReq).Return(nil, clientErr) - - svc := NewService(&client) - actual, err := svc.FindByUserId(t.Like.UserId) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *LikeServiceTest) TestFindByUserIdInternalError() { - protoReq := &likeProto.FindLikeByUserIdRequest{ - UserId: t.Like.UserId, - } - - clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) - - expected := t.InternalErr - - client := likeMock.LikeClientMock{} - client.On("FindByUserId", protoReq).Return(nil, clientErr) - - svc := NewService(&client) - actual, err := svc.FindByUserId(t.Like.UserId) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *LikeServiceTest) TestCreateSuccess() { - protoReq := t.CreateLikeProtoReq - protoResp := &likeProto.CreateLikeResponse{ - Like: t.Like, - } - - expected := utils.ProtoToDto(t.Like) - - client := &likeMock.LikeClientMock{} - client.On("Create", protoReq).Return(protoResp, nil) - - svc := NewService(client) - actual, err := svc.Create(t.CreateLikeDtoReq) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) -} - -func (t *LikeServiceTest) TestCreateInvalidArgumentError() { - protoReq := t.CreateLikeProtoReq - - expected := t.InvalidArgumentErr - - clientErr := status.Error(codes.InvalidArgument, constant.InvalidArgumentMessage) - - client := &likeMock.LikeClientMock{} - client.On("Create", protoReq).Return(nil, clientErr) - - svc := NewService(client) - actual, err := svc.Create(t.CreateLikeDtoReq) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *LikeServiceTest) TestCreateInternalError() { - protoReq := t.CreateLikeProtoReq - - expected := t.InvalidArgumentErr - - clientErr := status.Error(codes.InvalidArgument, constant.InvalidArgumentMessage) - - client := &likeMock.LikeClientMock{} - client.On("Create", protoReq).Return(nil, clientErr) - - svc := NewService(client) - actual, err := svc.Create(t.CreateLikeDtoReq) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *LikeServiceTest) TestCreateUnavailableServiceError() { - protoReq := t.CreateLikeProtoReq - - expected := t.UnavailableServiceErr - - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) - - client := &likeMock.LikeClientMock{} - client.On("Create", protoReq).Return(nil, clientErr) - - svc := NewService(client) - actual, err := svc.Create(t.CreateLikeDtoReq) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *LikeServiceTest) TestDeleteSuccess() { - protoReq := &likeProto.DeleteLikeRequest{ - Id: t.Like.Id, - } - protoResp := &likeProto.DeleteLikeResponse{ - Success: true, - } - - expected := &dto.DeleteLikeResponse{Success: true} - - client := &likeMock.LikeClientMock{} - client.On("Delete", protoReq).Return(protoResp, nil) - - svc := NewService(client) - actual, err := svc.Delete(t.Like.Id) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) -} - -func (t *LikeServiceTest) TestDeleteNotFoundError() { - protoReq := &likeProto.DeleteLikeRequest{ - Id: t.Like.Id, - } - - clientErr := status.Error(codes.NotFound, constant.UserNotFoundMessage) - - expected := t.NotFoundErr - - client := &likeMock.LikeClientMock{} - client.On("Delete", protoReq).Return(nil, clientErr) - - svc := NewService(client) - actual, err := svc.Delete(t.Like.Id) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *LikeServiceTest) TestDeleteUnavailableServiceError() { - protoReq := &likeProto.DeleteLikeRequest{ - Id: t.Like.Id, - } - - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) - - expected := t.UnavailableServiceErr - - client := &likeMock.LikeClientMock{} - client.On("Delete", protoReq).Return(nil, clientErr) - - svc := NewService(client) - actual, err := svc.Delete(t.Like.Id) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *LikeServiceTest) TestDeleteInternalError() { - protoReq := &likeProto.DeleteLikeRequest{ - Id: t.Like.Id, - } - - clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) - - expected := t.InternalErr - - client := &likeMock.LikeClientMock{} - client.On("Delete", protoReq).Return(nil, clientErr) - - svc := NewService(client) - actual, err := svc.Delete(t.Like.Id) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} diff --git a/mocks/service/auth/auth.mock.go b/mocks/service/auth/auth.mock.go index 7a7efc5..0a2236b 100644 --- a/mocks/service/auth/auth.mock.go +++ b/mocks/service/auth/auth.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./internal/pkg/service/auth/auth.service.go +// Source: ./internal/auth/auth.service.go // Package mock_auth is a generated GoMock package. package mock_auth From 20daef76c4e6bb39612c36cd929077497ea06530 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 18:17:12 +0700 Subject: [PATCH 077/104] dc --- .gitignore | 4 +++- docker-compose.yaml => docker-compose.example.yaml | 0 2 files changed, 3 insertions(+), 1 deletion(-) rename docker-compose.yaml => docker-compose.example.yaml (100%) diff --git a/.gitignore b/.gitignore index f7f6a1e..ecd6a68 100644 --- a/.gitignore +++ b/.gitignore @@ -54,4 +54,6 @@ github.com coverage.out coverage.html -token.txt \ No newline at end of file +token.txt + +docker-compose.qa.yaml \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.example.yaml similarity index 100% rename from docker-compose.yaml rename to docker-compose.example.yaml From fe1f4d0f9d0bc3b24299ab625d6dfd7f23a24a62 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 21:00:00 +0700 Subject: [PATCH 078/104] image svc --- Makefile | 2 +- cmd/main.go | 7 +++-- internal/handler/pet/pet.handler.go | 14 +++------- internal/handler/pet/pet.handler_test.go | 7 +++-- internal/{handler => }/image/image.handler.go | 15 +++++------ internal/{service => }/image/image.service.go | 27 ++++++++++++------- internal/pkg/service/image/image.service.go | 12 --------- internal/service/pet/pet.service.go | 6 ++--- internal/service/pet/pet.service_test.go | 2 +- mocks/service/image/image.mock.go | 2 +- 10 files changed, 39 insertions(+), 55 deletions(-) rename internal/{handler => }/image/image.handler.go (87%) rename internal/{service => }/image/image.service.go (85%) delete mode 100644 internal/pkg/service/image/image.service.go diff --git a/Makefile b/Makefile index 93b4f52..729eb09 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ mock-gen: mockgen -source ./internal/auth/auth.service.go -destination ./mocks/service/auth/auth.mock.go mockgen -source ./internal/pkg/service/user/user.service.go -destination ./mocks/service/user/user.mock.go mockgen -source ./internal/pkg/service/pet/pet.service.go -destination ./mocks/service/pet/pet.mock.go - mockgen -source ./internal/pkg/service/image/image.service.go -destination ./mocks/service/image/image.mock.go + mockgen -source ./internal/image/image.service.go -destination ./mocks/service/image/image.mock.go mockgen -source ./internal/validator/validator.go -destination ./mocks/validator/validator.mock.go mockgen -source ./internal/router/context.go -destination ./mocks/router/context.mock.go diff --git a/cmd/main.go b/cmd/main.go index 17d8270..4fb4852 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -14,12 +14,11 @@ import ( "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/auth" "github.com/isd-sgcu/johnjud-gateway/internal/handler/healthcheck" - imageHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/image" petHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/pet" userHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/user" + "github.com/isd-sgcu/johnjud-gateway/internal/image" guard "github.com/isd-sgcu/johnjud-gateway/internal/middleware/auth" "github.com/isd-sgcu/johnjud-gateway/internal/router" - imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/image" petSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/pet" userSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/user" "github.com/isd-sgcu/johnjud-gateway/internal/validator" @@ -112,8 +111,8 @@ func main() { authGuard := guard.NewAuthGuard(authService, constant.ExcludePath, constant.AdminPath, conf.App, constant.VersionList) imageClient := imageProto.NewImageServiceClient(fileConn) - imageService := imageSvc.NewService(imageClient) - imageHandler := imageHdr.NewHandler(imageService, v, conf.App.MaxFileSize) + imageService := image.NewService(imageClient) + imageHandler := image.NewHandler(imageService, v, conf.App.MaxFileSize) petClient := petProto.NewPetServiceClient(backendConn) petService := petSvc.NewService(petClient, imageService) diff --git a/internal/handler/pet/pet.handler.go b/internal/handler/pet/pet.handler.go index 9de9daa..7912c93 100644 --- a/internal/handler/pet/pet.handler.go +++ b/internal/handler/pet/pet.handler.go @@ -6,7 +6,7 @@ import ( "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/image" + "github.com/isd-sgcu/johnjud-gateway/internal/image" petSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/pet" "github.com/isd-sgcu/johnjud-gateway/internal/router" petUtils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" @@ -15,11 +15,11 @@ import ( type Handler struct { service petSvc.Service - imageService imageSvc.Service + imageService image.Service validate validator.IDtoValidator } -func NewHandler(service petSvc.Service, imageService imageSvc.Service, validate validator.IDtoValidator) *Handler { +func NewHandler(service petSvc.Service, imageService image.Service, validate validator.IDtoValidator) *Handler { return &Handler{service, imageService, validate} } @@ -47,7 +47,6 @@ func (h *Handler) FindAll(c router.IContext) { } c.JSON(http.StatusOK, response) - return } // FindAllAdmin is a function that returns ALL pets in database @@ -74,7 +73,6 @@ func (h *Handler) FindAllAdmin(c router.IContext) { } c.JSON(http.StatusOK, response) - return } // FindOne is a function that returns a pet by id in database @@ -107,7 +105,6 @@ func (h *Handler) FindOne(c router.IContext) { } c.JSON(http.StatusOK, response) - return } // Create is a function that creates pet in database @@ -154,7 +151,6 @@ func (h *Handler) Create(c router.IContext) { } c.JSON(http.StatusCreated, response) - return } // Update is a function that updates pet in database @@ -213,7 +209,6 @@ func (h *Handler) Update(c router.IContext) { } c.JSON(http.StatusOK, pet) - return } // ChangeView is a function that changes visibility of pet in database @@ -272,7 +267,6 @@ func (h *Handler) ChangeView(c router.IContext) { } c.JSON(http.StatusOK, res) - return } // Delete is a function that deletes pet in database @@ -305,7 +299,6 @@ func (h *Handler) Delete(c router.IContext) { } c.JSON(http.StatusOK, res) - return } // Adopt is a function that handles the adoption of a pet in the database @@ -363,5 +356,4 @@ func (h *Handler) Adopt(c router.IContext) { } c.JSON(http.StatusOK, res) - return } diff --git a/internal/handler/pet/pet.handler_test.go b/internal/handler/pet/pet.handler_test.go index 4e1d1f4..4c2d646 100644 --- a/internal/handler/pet/pet.handler_test.go +++ b/internal/handler/pet/pet.handler_test.go @@ -14,7 +14,6 @@ import ( petMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/pet" validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" - errConst "github.com/isd-sgcu/johnjud-gateway/constant" utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" imgProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" @@ -151,18 +150,18 @@ func (t *PetHandlerTest) SetupTest() { t.NotFoundErr = &dto.ResponseErr{ StatusCode: http.StatusNotFound, - Message: errConst.PetNotFoundMessage, + Message: constant.PetNotFoundMessage, Data: nil, } t.BindErr = &dto.ResponseErr{ StatusCode: http.StatusBadRequest, - Message: errConst.InvalidIDMessage, + Message: constant.InvalidIDMessage, } t.InternalErr = &dto.ResponseErr{ StatusCode: http.StatusInternalServerError, - Message: errConst.InternalErrorMessage, + Message: constant.InternalErrorMessage, Data: nil, } } diff --git a/internal/handler/image/image.handler.go b/internal/image/image.handler.go similarity index 87% rename from internal/handler/image/image.handler.go rename to internal/image/image.handler.go index ecfb6b2..d040b6c 100644 --- a/internal/handler/image/image.handler.go +++ b/internal/image/image.handler.go @@ -5,20 +5,19 @@ import ( "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/image" "github.com/isd-sgcu/johnjud-gateway/internal/router" "github.com/isd-sgcu/johnjud-gateway/internal/validator" "github.com/rs/zerolog/log" ) -type Handler struct { - service imageSvc.Service +type handlerImpl struct { + service Service validate validator.IDtoValidator maxFileSize int64 } -func NewHandler(service imageSvc.Service, validate validator.IDtoValidator, maxFileSize int64) *Handler { - return &Handler{ +func NewHandler(service Service, validate validator.IDtoValidator, maxFileSize int64) *handlerImpl { + return &handlerImpl{ service: service, validate: validate, maxFileSize: int64(maxFileSize * 1024 * 1024), @@ -37,7 +36,7 @@ func NewHandler(service imageSvc.Service, validate validator.IDtoValidator, maxF // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/images [post] -func (h *Handler) Upload(c *router.FiberCtx) { +func (h *handlerImpl) Upload(c *router.FiberCtx) { petId := c.GetFormData("pet_id") file, err := c.File("file", constant.AllowContentType, h.maxFileSize) if err != nil { @@ -67,7 +66,6 @@ func (h *Handler) Upload(c *router.FiberCtx) { } c.JSON(http.StatusCreated, response) - return } // Delete is a function for deleting image from bucket @@ -81,7 +79,7 @@ func (h *Handler) Upload(c *router.FiberCtx) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/images/{id} [delete] -func (h *Handler) Delete(c *router.FiberCtx) { +func (h *handlerImpl) Delete(c *router.FiberCtx) { id, err := c.ID() if err != nil { c.JSON(http.StatusBadRequest, dto.ResponseErr{ @@ -99,5 +97,4 @@ func (h *Handler) Delete(c *router.FiberCtx) { } c.JSON(http.StatusOK, res.Success) - return } diff --git a/internal/service/image/image.service.go b/internal/image/image.service.go similarity index 85% rename from internal/service/image/image.service.go rename to internal/image/image.service.go index 9333af7..e65e990 100644 --- a/internal/service/image/image.service.go +++ b/internal/image/image.service.go @@ -14,17 +14,26 @@ import ( "google.golang.org/grpc/status" ) -type Service struct { +type Service interface { + FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) + FindByPetId(string) ([]*dto.ImageResponse, *dto.ResponseErr) + Upload(*dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) + Delete(string) (*dto.DeleteImageResponse, *dto.ResponseErr) + DeleteByPetId(string) (*dto.DeleteImageResponse, *dto.ResponseErr) + AssignPet(*dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) +} + +type serviceImpl struct { client proto.ImageServiceClient } -func NewService(client proto.ImageServiceClient) *Service { - return &Service{ +func NewService(client proto.ImageServiceClient) Service { + return &serviceImpl{ client: client, } } -func (s *Service) FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) { +func (s *serviceImpl) FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -53,7 +62,7 @@ func (s *Service) FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) { return utils.ProtoToDtoList(res.Images), nil } -func (s *Service) FindByPetId(petId string) ([]*dto.ImageResponse, *dto.ResponseErr) { +func (s *serviceImpl) FindByPetId(petId string) ([]*dto.ImageResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -88,7 +97,7 @@ func (s *Service) FindByPetId(petId string) ([]*dto.ImageResponse, *dto.Response return utils.ProtoToDtoList(res.Images), nil } -func (s *Service) Upload(in *dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) { +func (s *serviceImpl) Upload(in *dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -125,7 +134,7 @@ func (s *Service) Upload(in *dto.UploadImageRequest) (*dto.ImageResponse, *dto.R return utils.ProtoToDto(res.Image), nil } -func (s *Service) Delete(id string) (*dto.DeleteImageResponse, *dto.ResponseErr) { +func (s *serviceImpl) Delete(id string) (*dto.DeleteImageResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -167,7 +176,7 @@ func (s *Service) Delete(id string) (*dto.DeleteImageResponse, *dto.ResponseErr) }, nil } -func (s *Service) DeleteByPetId(petId string) (*dto.DeleteImageResponse, *dto.ResponseErr) { +func (s *serviceImpl) DeleteByPetId(petId string) (*dto.DeleteImageResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -209,7 +218,7 @@ func (s *Service) DeleteByPetId(petId string) (*dto.DeleteImageResponse, *dto.Re }, nil } -func (s *Service) AssignPet(in *dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) { +func (s *serviceImpl) AssignPet(in *dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() diff --git a/internal/pkg/service/image/image.service.go b/internal/pkg/service/image/image.service.go deleted file mode 100644 index 4cd646a..0000000 --- a/internal/pkg/service/image/image.service.go +++ /dev/null @@ -1,12 +0,0 @@ -package image - -import "github.com/isd-sgcu/johnjud-gateway/internal/dto" - -type Service interface { - FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) - FindByPetId(string) ([]*dto.ImageResponse, *dto.ResponseErr) - Upload(*dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) - Delete(string) (*dto.DeleteImageResponse, *dto.ResponseErr) - DeleteByPetId(string) (*dto.DeleteImageResponse, *dto.ResponseErr) - AssignPet(*dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) -} diff --git a/internal/service/pet/pet.service.go b/internal/service/pet/pet.service.go index 71599c4..8207eab 100644 --- a/internal/service/pet/pet.service.go +++ b/internal/service/pet/pet.service.go @@ -7,8 +7,8 @@ import ( "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-gateway/internal/image" - imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/image" utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" "github.com/rs/zerolog/log" @@ -18,10 +18,10 @@ import ( type Service struct { petClient petproto.PetServiceClient - imageService imageSvc.Service + imageService image.Service } -func NewService(petClient petproto.PetServiceClient, imageService imageSvc.Service) *Service { +func NewService(petClient petproto.PetServiceClient, imageService image.Service) *Service { return &Service{ petClient: petClient, imageService: imageService, diff --git a/internal/service/pet/pet.service_test.go b/internal/service/pet/pet.service_test.go index 6171130..7e04aaa 100644 --- a/internal/service/pet/pet.service_test.go +++ b/internal/service/pet/pet.service_test.go @@ -8,7 +8,7 @@ import ( "github.com/go-faker/faker/v4" "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/image" + imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/image" utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" imagemock "github.com/isd-sgcu/johnjud-gateway/mocks/client/image" petmock "github.com/isd-sgcu/johnjud-gateway/mocks/client/pet" diff --git a/mocks/service/image/image.mock.go b/mocks/service/image/image.mock.go index 4b6c523..cec33b2 100644 --- a/mocks/service/image/image.mock.go +++ b/mocks/service/image/image.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./internal/pkg/service/image/image.service.go +// Source: ./internal/image/image.service.go // Package mock_image is a generated GoMock package. package mock_image From 982ae86d6414bff3d81f3b263c7048bb10b5a51a Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 21:03:30 +0700 Subject: [PATCH 079/104] pet --- Makefile | 2 +- cmd/main.go | 7 ++- internal/{handler => }/pet/pet.handler.go | 5 +-- internal/{service => }/pet/pet.service.go | 30 ++++++++----- .../pet => pet/test}/pet.handler_test.go | 37 ++++++++-------- .../pet => pet/test}/pet.service_test.go | 43 ++++++++++--------- internal/pkg/service/pet/pet.service.go | 13 ------ mocks/service/pet/pet.mock.go | 2 +- 8 files changed, 68 insertions(+), 71 deletions(-) rename internal/{handler => }/pet/pet.handler.go (97%) rename internal/{service => }/pet/pet.service.go (85%) rename internal/{handler/pet => pet/test}/pet.handler_test.go (94%) rename internal/{service/pet => pet/test}/pet.service_test.go (95%) delete mode 100644 internal/pkg/service/pet/pet.service.go diff --git a/Makefile b/Makefile index 729eb09..edb88a4 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ server: mock-gen: mockgen -source ./internal/auth/auth.service.go -destination ./mocks/service/auth/auth.mock.go mockgen -source ./internal/pkg/service/user/user.service.go -destination ./mocks/service/user/user.mock.go - mockgen -source ./internal/pkg/service/pet/pet.service.go -destination ./mocks/service/pet/pet.mock.go + mockgen -source ./internal/pet/pet.service.go -destination ./mocks/service/pet/pet.mock.go mockgen -source ./internal/image/image.service.go -destination ./mocks/service/image/image.mock.go mockgen -source ./internal/validator/validator.go -destination ./mocks/validator/validator.mock.go mockgen -source ./internal/router/context.go -destination ./mocks/router/context.mock.go diff --git a/cmd/main.go b/cmd/main.go index 4fb4852..9837614 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -14,12 +14,11 @@ import ( "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/auth" "github.com/isd-sgcu/johnjud-gateway/internal/handler/healthcheck" - petHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/pet" userHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/user" "github.com/isd-sgcu/johnjud-gateway/internal/image" guard "github.com/isd-sgcu/johnjud-gateway/internal/middleware/auth" + "github.com/isd-sgcu/johnjud-gateway/internal/pet" "github.com/isd-sgcu/johnjud-gateway/internal/router" - petSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/pet" userSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/user" "github.com/isd-sgcu/johnjud-gateway/internal/validator" authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" @@ -115,8 +114,8 @@ func main() { imageHandler := image.NewHandler(imageService, v, conf.App.MaxFileSize) petClient := petProto.NewPetServiceClient(backendConn) - petService := petSvc.NewService(petClient, imageService) - petHandler := petHdr.NewHandler(petService, imageService, v) + petService := pet.NewService(petClient, imageService) + petHandler := pet.NewHandler(petService, imageService, v) r := router.NewFiberRouter(&authGuard, conf.App) diff --git a/internal/handler/pet/pet.handler.go b/internal/pet/pet.handler.go similarity index 97% rename from internal/handler/pet/pet.handler.go rename to internal/pet/pet.handler.go index 7912c93..a8f879b 100644 --- a/internal/handler/pet/pet.handler.go +++ b/internal/pet/pet.handler.go @@ -7,19 +7,18 @@ import ( "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" "github.com/isd-sgcu/johnjud-gateway/internal/image" - petSvc "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/pet" "github.com/isd-sgcu/johnjud-gateway/internal/router" petUtils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" "github.com/isd-sgcu/johnjud-gateway/internal/validator" ) type Handler struct { - service petSvc.Service + service Service imageService image.Service validate validator.IDtoValidator } -func NewHandler(service petSvc.Service, imageService image.Service, validate validator.IDtoValidator) *Handler { +func NewHandler(service Service, imageService image.Service, validate validator.IDtoValidator) *Handler { return &Handler{service, imageService, validate} } diff --git a/internal/service/pet/pet.service.go b/internal/pet/pet.service.go similarity index 85% rename from internal/service/pet/pet.service.go rename to internal/pet/pet.service.go index 8207eab..41768db 100644 --- a/internal/service/pet/pet.service.go +++ b/internal/pet/pet.service.go @@ -16,19 +16,29 @@ import ( "google.golang.org/grpc/status" ) -type Service struct { +type Service interface { + FindAll(*dto.FindAllPetRequest, bool) (*dto.FindAllPetResponse, *dto.ResponseErr) + FindOne(string) (*dto.PetResponse, *dto.ResponseErr) + Create(*dto.CreatePetRequest) (*dto.PetResponse, *dto.ResponseErr) + Update(string, *dto.UpdatePetRequest) (*dto.PetResponse, *dto.ResponseErr) + Delete(string) (*dto.DeleteResponse, *dto.ResponseErr) + ChangeView(string, *dto.ChangeViewPetRequest) (*dto.ChangeViewPetResponse, *dto.ResponseErr) + Adopt(string, *dto.AdoptByRequest) (*dto.AdoptByResponse, *dto.ResponseErr) +} + +type serviceImpl struct { petClient petproto.PetServiceClient imageService image.Service } -func NewService(petClient petproto.PetServiceClient, imageService image.Service) *Service { - return &Service{ +func NewService(petClient petproto.PetServiceClient, imageService image.Service) Service { + return &serviceImpl{ petClient: petClient, imageService: imageService, } } -func (s *Service) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result *dto.FindAllPetResponse, err *dto.ResponseErr) { +func (s *serviceImpl) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result *dto.FindAllPetResponse, err *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -70,7 +80,7 @@ func (s *Service) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result *dto. }, nil } -func (s *Service) FindOne(id string) (result *dto.PetResponse, err *dto.ResponseErr) { +func (s *serviceImpl) FindOne(id string) (result *dto.PetResponse, err *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -114,7 +124,7 @@ func (s *Service) FindOne(id string) (result *dto.PetResponse, err *dto.Response return findOneResponse, nil } -func (s *Service) Create(in *dto.CreatePetRequest) (result *dto.PetResponse, err *dto.ResponseErr) { +func (s *serviceImpl) Create(in *dto.CreatePetRequest) (result *dto.PetResponse, err *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -167,7 +177,7 @@ func (s *Service) Create(in *dto.CreatePetRequest) (result *dto.PetResponse, err return createPetResponse, nil } -func (s *Service) Update(id string, in *dto.UpdatePetRequest) (result *dto.PetResponse, err *dto.ResponseErr) { +func (s *serviceImpl) Update(id string, in *dto.UpdatePetRequest) (result *dto.PetResponse, err *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -218,7 +228,7 @@ func (s *Service) Update(id string, in *dto.UpdatePetRequest) (result *dto.PetRe return updatePetResponse, nil } -func (s *Service) Delete(id string) (result *dto.DeleteResponse, err *dto.ResponseErr) { +func (s *serviceImpl) Delete(id string) (result *dto.DeleteResponse, err *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -264,7 +274,7 @@ func (s *Service) Delete(id string) (result *dto.DeleteResponse, err *dto.Respon }, nil } -func (s *Service) ChangeView(id string, in *dto.ChangeViewPetRequest) (result *dto.ChangeViewPetResponse, err *dto.ResponseErr) { +func (s *serviceImpl) ChangeView(id string, in *dto.ChangeViewPetRequest) (result *dto.ChangeViewPetResponse, err *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -311,7 +321,7 @@ func (s *Service) ChangeView(id string, in *dto.ChangeViewPetRequest) (result *d }, nil } -func (s *Service) Adopt(petId string, in *dto.AdoptByRequest) (result *dto.AdoptByResponse, err *dto.ResponseErr) { +func (s *serviceImpl) Adopt(petId string, in *dto.AdoptByRequest) (result *dto.AdoptByResponse, err *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() diff --git a/internal/handler/pet/pet.handler_test.go b/internal/pet/test/pet.handler_test.go similarity index 94% rename from internal/handler/pet/pet.handler_test.go rename to internal/pet/test/pet.handler_test.go index 4c2d646..8b727f1 100644 --- a/internal/handler/pet/pet.handler_test.go +++ b/internal/pet/test/pet.handler_test.go @@ -9,6 +9,7 @@ import ( "github.com/golang/mock/gomock" "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-gateway/internal/pet" routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" imageMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/image" petMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/pet" @@ -185,7 +186,7 @@ func (t *PetHandlerTest) TestFindAllSuccess() { petSvc.EXPECT().FindAll(t.FindAllPetRequest, false).Return(expectedResponse, nil) context.EXPECT().JSON(http.StatusOK, expectedResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.FindAll(context) } @@ -204,7 +205,7 @@ func (t *PetHandlerTest) TestFindOneSuccess() { petSvc.EXPECT().FindOne(t.Pet.Id).Return(findOneResponse, nil) context.EXPECT().JSON(http.StatusOK, expectedResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.FindOne(context) } @@ -222,7 +223,7 @@ func (t *PetHandlerTest) TestFindOneNotFoundErr() { petSvc.EXPECT().FindOne(t.Pet.Id).Return(nil, findOneResponse) context.EXPECT().JSON(http.StatusNotFound, findOneResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.FindOne(context) } @@ -240,7 +241,7 @@ func (t *PetHandlerTest) TestFindOneGrpcErr() { petSvc.EXPECT().FindOne(t.Pet.Id).Return(nil, findOneResponse) context.EXPECT().JSON(http.StatusServiceUnavailable, findOneResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.FindOne(context) } @@ -260,7 +261,7 @@ func (t *PetHandlerTest) TestCreateSuccess() { petSvc.EXPECT().Create(t.CreatePetRequest).Return(createResponse, nil) context.EXPECT().JSON(http.StatusCreated, expectedResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.Create(context) } @@ -279,7 +280,7 @@ func (t *PetHandlerTest) TestCreateGrpcErr() { petSvc.EXPECT().Create(t.CreatePetRequest).Return(nil, createErrorResponse) context.EXPECT().JSON(http.StatusServiceUnavailable, createErrorResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.Create(context) } @@ -300,7 +301,7 @@ func (t *PetHandlerTest) TestUpdateSuccess() { petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(updateResponse, nil) context.EXPECT().JSON(http.StatusOK, expectedResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.Update(context) } @@ -320,7 +321,7 @@ func (t *PetHandlerTest) TestUpdateNotFound() { petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(nil, updateResponse) context.EXPECT().JSON(http.StatusNotFound, updateResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.Update(context) } @@ -340,7 +341,7 @@ func (t *PetHandlerTest) TestUpdateGrpcErr() { petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(nil, updateResponse) context.EXPECT().JSON(http.StatusServiceUnavailable, updateResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.Update(context) } @@ -361,7 +362,7 @@ func (t *PetHandlerTest) TestDeleteSuccess() { petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, nil) context.EXPECT().JSON(http.StatusOK, expectedResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.Delete(context) } func (t *PetHandlerTest) TestDeleteNotFound() { @@ -380,7 +381,7 @@ func (t *PetHandlerTest) TestDeleteNotFound() { petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, t.NotFoundErr) context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.Delete(context) } @@ -400,7 +401,7 @@ func (t *PetHandlerTest) TestDeleteGrpcErr() { petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, t.ServiceDownErr) context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.Delete(context) } @@ -423,7 +424,7 @@ func (t *PetHandlerTest) TestChangeViewSuccess() { petSvc.EXPECT().ChangeView(t.Pet.Id, t.ChangeViewPetRequest).Return(changeViewResponse, nil) context.EXPECT().JSON(http.StatusOK, expectedResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.ChangeView(context) } @@ -445,7 +446,7 @@ func (t *PetHandlerTest) TestChangeViewNotFound() { petSvc.EXPECT().ChangeView(t.Pet.Id, t.ChangeViewPetRequest).Return(changeViewResponse, t.NotFoundErr) context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.ChangeView(context) } @@ -467,7 +468,7 @@ func (t *PetHandlerTest) TestChangeViewGrpcErr() { petSvc.EXPECT().ChangeView(t.Pet.Id, t.ChangeViewPetRequest).Return(changeViewResponse, t.ServiceDownErr) context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.ChangeView(context) } @@ -490,7 +491,7 @@ func (t *PetHandlerTest) TestAdoptSuccess() { petSvc.EXPECT().Adopt(t.Pet.Id, t.AdoptByRequest).Return(adoptByResponse, nil) context.EXPECT().JSON(http.StatusOK, expectedResponse) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.Adopt(context) } @@ -512,7 +513,7 @@ func (t *PetHandlerTest) TestAdoptNotFound() { petSvc.EXPECT().Adopt(t.Pet.Id, t.AdoptByRequest).Return(adoptByResponse, t.NotFoundErr) context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.Adopt(context) } @@ -534,6 +535,6 @@ func (t *PetHandlerTest) TestAdoptGrpcErr() { petSvc.EXPECT().Adopt(t.Pet.Id, t.AdoptByRequest).Return(adoptByResponse, t.ServiceDownErr) context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - handler := NewHandler(petSvc, imageSvc, validator) + handler := pet.NewHandler(petSvc, imageSvc, validator) handler.Adopt(context) } diff --git a/internal/service/pet/pet.service_test.go b/internal/pet/test/pet.service_test.go similarity index 95% rename from internal/service/pet/pet.service_test.go rename to internal/pet/test/pet.service_test.go index 7e04aaa..4dbb841 100644 --- a/internal/service/pet/pet.service_test.go +++ b/internal/pet/test/pet.service_test.go @@ -9,6 +9,7 @@ import ( "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/image" + "github.com/isd-sgcu/johnjud-gateway/internal/pet" utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" imagemock "github.com/isd-sgcu/johnjud-gateway/mocks/client/image" petmock "github.com/isd-sgcu/johnjud-gateway/mocks/client/pet" @@ -285,7 +286,7 @@ func (t *PetServiceTest) TestFindAllSuccess() { imageClient.On("FindAll", t.FindAllImageReq).Return(findAllImageResp, nil) imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(&client, imageSvc) + svc := pet.NewService(&client, imageSvc) actual, err := svc.FindAll(t.FindAllPetDto, true) assert.Nil(t.T(), err) @@ -303,7 +304,7 @@ func (t *PetServiceTest) TestFindAllUnavailableServiceError() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(&client, imageSvc) + svc := pet.NewService(&client, imageSvc) actual, err := svc.FindAll(t.FindAllPetDto, true) assert.Nil(t.T(), actual) @@ -332,7 +333,7 @@ func (t *PetServiceTest) TestFindOneSuccess() { imageClient.On("FindByPetId", findByPetIdReq).Return(findByPetIdResp, nil) imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(&client, imageSvc) + svc := pet.NewService(&client, imageSvc) actual, err := svc.FindOne(t.Pet.Id) assert.Nil(t.T(), err) @@ -354,7 +355,7 @@ func (t *PetServiceTest) TestFindOneNotFoundError() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(&client, imageSvc) + svc := pet.NewService(&client, imageSvc) actual, err := svc.FindOne(t.Pet.Id) assert.Nil(t.T(), actual) @@ -377,7 +378,7 @@ func (t *PetServiceTest) TestFindOneUnavailableServiceError() { imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(&client, imageSvc) + svc := pet.NewService(&client, imageSvc) actual, err := svc.FindOne(t.Pet.Id) assert.Nil(t.T(), actual) @@ -410,7 +411,7 @@ func (t *PetServiceTest) TestCreateSuccess() { imageClient.On("FindByPetId", findByPetIdReq).Return(findByPetIdResp, nil) imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Create(t.CreatePetDto) assert.Nil(t.T(), err) @@ -430,7 +431,7 @@ func (t *PetServiceTest) TestCreateInvalidArgumentError() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Create(t.CreatePetDto) assert.Nil(t.T(), actual) @@ -450,7 +451,7 @@ func (t *PetServiceTest) TestCreateInternalError() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Create(t.CreatePetDto) assert.Nil(t.T(), actual) @@ -470,7 +471,7 @@ func (t *PetServiceTest) TestCreateUnavailableServiceError() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Create(t.CreatePetDto) assert.Nil(t.T(), actual) @@ -495,7 +496,7 @@ func (t *PetServiceTest) TestUpdateSuccess() { imageClient.On("FindByPetId", t.FindByPetIdReq).Return(findByPetIdResp, nil) imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) assert.Nil(t.T(), err) @@ -514,7 +515,7 @@ func (t *PetServiceTest) TestUpdateNotFound() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) assert.Nil(t.T(), actual) @@ -533,7 +534,7 @@ func (t *PetServiceTest) TestUpdateUnavailableServiceError() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) assert.Nil(t.T(), actual) @@ -563,7 +564,7 @@ func (t *PetServiceTest) TestDeleteSuccess() { imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Delete(t.Pet.Id) assert.Nil(t.T(), err) @@ -595,7 +596,7 @@ func (t *PetServiceTest) TestDeleteNotFound() { imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Delete(t.Pet.Id) assert.Nil(t.T(), actual) @@ -627,7 +628,7 @@ func (t *PetServiceTest) TestDeleteServiceUnavailableError() { imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Delete(t.Pet.Id) assert.Nil(t.T(), actual) @@ -646,7 +647,7 @@ func (t *PetServiceTest) TestChangeViewSuccess() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) assert.Nil(t.T(), err) @@ -669,7 +670,7 @@ func (t *PetServiceTest) TestChangeViewNotFoundError() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) assert.Equal(t.T(), &dto.ChangeViewPetResponse{Success: false}, actual) @@ -692,7 +693,7 @@ func (t *PetServiceTest) TestChangeViewUnavailableServiceError() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) assert.Equal(t.T(), &dto.ChangeViewPetResponse{Success: false}, actual) @@ -711,7 +712,7 @@ func (t *PetServiceTest) TestAdoptSuccess() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) assert.Nil(t.T(), err) @@ -731,7 +732,7 @@ func (t *PetServiceTest) TestAdoptNotFoundError() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) assert.Nil(t.T(), actual) @@ -751,7 +752,7 @@ func (t *PetServiceTest) TestAdoptUnavailableServiceError() { imageClient := imagemock.ImageClientMock{} imageSvc := imageSvc.NewService(&imageClient) - svc := NewService(client, imageSvc) + svc := pet.NewService(client, imageSvc) actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) assert.Nil(t.T(), actual) diff --git a/internal/pkg/service/pet/pet.service.go b/internal/pkg/service/pet/pet.service.go deleted file mode 100644 index 8b44ebd..0000000 --- a/internal/pkg/service/pet/pet.service.go +++ /dev/null @@ -1,13 +0,0 @@ -package pet - -import "github.com/isd-sgcu/johnjud-gateway/internal/dto" - -type Service interface { - FindAll(*dto.FindAllPetRequest, bool) (*dto.FindAllPetResponse, *dto.ResponseErr) - FindOne(string) (*dto.PetResponse, *dto.ResponseErr) - Create(*dto.CreatePetRequest) (*dto.PetResponse, *dto.ResponseErr) - Update(string, *dto.UpdatePetRequest) (*dto.PetResponse, *dto.ResponseErr) - Delete(string) (*dto.DeleteResponse, *dto.ResponseErr) - ChangeView(string, *dto.ChangeViewPetRequest) (*dto.ChangeViewPetResponse, *dto.ResponseErr) - Adopt(string, *dto.AdoptByRequest) (*dto.AdoptByResponse, *dto.ResponseErr) -} diff --git a/mocks/service/pet/pet.mock.go b/mocks/service/pet/pet.mock.go index 14a90db..17563e0 100644 --- a/mocks/service/pet/pet.mock.go +++ b/mocks/service/pet/pet.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./internal/pkg/service/pet/pet.service.go +// Source: ./internal/pet/pet.service.go // Package mock_pet is a generated GoMock package. package mock_pet From b44c4d4b7a2ca328480bb8d048f03b5fed749f59 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 21:03:51 +0700 Subject: [PATCH 080/104] pr tmp --- .github/{PULL_REQUEST_TEMPLATE => }/pull_request_template.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{PULL_REQUEST_TEMPLATE => }/pull_request_template.md (100%) diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/pull_request_template.md similarity index 100% rename from .github/PULL_REQUEST_TEMPLATE/pull_request_template.md rename to .github/pull_request_template.md From f3219edaaebb3639cd3a076745f8e5e2ef124b6b Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 21:10:40 +0700 Subject: [PATCH 081/104] user --- Makefile | 2 +- cmd/main.go | 9 ++-- internal/auth/auth.handler.go | 2 +- internal/auth/auth.utils.go | 5 +- .../healthcheck/healthcheck.handler.go | 0 internal/pet/pet.handler.go | 22 ++++----- internal/pet/test/pet.handler_test.go | 2 +- internal/pet/test/pet.service_test.go | 2 +- internal/pkg/service/user/user.service.go | 9 ---- .../user => user/test}/user.handler_test.go | 42 ++++++++--------- .../user => user/test}/user.service_test.go | 47 ++++++++++--------- internal/{handler => }/user/user.handler.go | 8 +--- internal/{service => }/user/user.service.go | 18 ++++--- mocks/service/user/user.mock.go | 2 +- 14 files changed, 80 insertions(+), 90 deletions(-) rename internal/{handler => }/healthcheck/healthcheck.handler.go (100%) delete mode 100644 internal/pkg/service/user/user.service.go rename internal/{handler/user => user/test}/user.handler_test.go (91%) rename internal/{service/user => user/test}/user.service_test.go (87%) rename internal/{handler => }/user/user.handler.go (94%) rename internal/{service => }/user/user.service.go (85%) diff --git a/Makefile b/Makefile index edb88a4..4794c6c 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ server: mock-gen: mockgen -source ./internal/auth/auth.service.go -destination ./mocks/service/auth/auth.mock.go - mockgen -source ./internal/pkg/service/user/user.service.go -destination ./mocks/service/user/user.mock.go + mockgen -source ./internal/user/user.service.go -destination ./mocks/service/user/user.mock.go mockgen -source ./internal/pet/pet.service.go -destination ./mocks/service/pet/pet.mock.go mockgen -source ./internal/image/image.service.go -destination ./mocks/service/image/image.mock.go mockgen -source ./internal/validator/validator.go -destination ./mocks/validator/validator.mock.go diff --git a/cmd/main.go b/cmd/main.go index 9837614..9baf3f8 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -13,13 +13,12 @@ import ( "github.com/isd-sgcu/johnjud-gateway/config" "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/auth" - "github.com/isd-sgcu/johnjud-gateway/internal/handler/healthcheck" - userHdr "github.com/isd-sgcu/johnjud-gateway/internal/handler/user" + "github.com/isd-sgcu/johnjud-gateway/internal/healthcheck" "github.com/isd-sgcu/johnjud-gateway/internal/image" guard "github.com/isd-sgcu/johnjud-gateway/internal/middleware/auth" "github.com/isd-sgcu/johnjud-gateway/internal/pet" "github.com/isd-sgcu/johnjud-gateway/internal/router" - userSvc "github.com/isd-sgcu/johnjud-gateway/internal/service/user" + "github.com/isd-sgcu/johnjud-gateway/internal/user" "github.com/isd-sgcu/johnjud-gateway/internal/validator" authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" userProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" @@ -100,8 +99,8 @@ func main() { hc := healthcheck.NewHandler() userClient := userProto.NewUserServiceClient(authConn) - userService := userSvc.NewService(userClient) - userHandler := userHdr.NewHandler(userService, v) + userService := user.NewService(userClient) + userHandler := user.NewHandler(userService, v) authClient := authProto.NewAuthServiceClient(authConn) authService := auth.NewService(authClient) diff --git a/internal/auth/auth.handler.go b/internal/auth/auth.handler.go index b7ef768..6494673 100644 --- a/internal/auth/auth.handler.go +++ b/internal/auth/auth.handler.go @@ -6,8 +6,8 @@ import ( "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/user" "github.com/isd-sgcu/johnjud-gateway/internal/router" + "github.com/isd-sgcu/johnjud-gateway/internal/user" "github.com/isd-sgcu/johnjud-gateway/internal/validator" ) diff --git a/internal/auth/auth.utils.go b/internal/auth/auth.utils.go index 5a05f51..4afb249 100644 --- a/internal/auth/auth.utils.go +++ b/internal/auth/auth.utils.go @@ -10,10 +10,7 @@ import ( func IsExisted(e map[string]struct{}, key string) bool { _, ok := e[key] - if ok { - return true - } - return false + return ok } func FormatPath(method string, path string, keys []string) string { diff --git a/internal/handler/healthcheck/healthcheck.handler.go b/internal/healthcheck/healthcheck.handler.go similarity index 100% rename from internal/handler/healthcheck/healthcheck.handler.go rename to internal/healthcheck/healthcheck.handler.go diff --git a/internal/pet/pet.handler.go b/internal/pet/pet.handler.go index a8f879b..f6ed770 100644 --- a/internal/pet/pet.handler.go +++ b/internal/pet/pet.handler.go @@ -12,14 +12,14 @@ import ( "github.com/isd-sgcu/johnjud-gateway/internal/validator" ) -type Handler struct { +type handlerImpl struct { service Service imageService image.Service validate validator.IDtoValidator } -func NewHandler(service Service, imageService image.Service, validate validator.IDtoValidator) *Handler { - return &Handler{service, imageService, validate} +func NewHandler(service Service, imageService image.Service, validate validator.IDtoValidator) *handlerImpl { + return &handlerImpl{service, imageService, validate} } // FindAll is a function that returns all VISIBLE pets in database @@ -32,7 +32,7 @@ func NewHandler(service Service, imageService image.Service, validate validator. // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/pets/ [get] -func (h *Handler) FindAll(c router.IContext) { +func (h *handlerImpl) FindAll(c router.IContext) { queries := c.Queries() request, err := petUtils.QueriesToFindAllDto(queries) if err != nil { @@ -58,7 +58,7 @@ func (h *Handler) FindAll(c router.IContext) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/pets/admin [get] -func (h *Handler) FindAllAdmin(c router.IContext) { +func (h *handlerImpl) FindAllAdmin(c router.IContext) { queries := c.Queries() request, err := petUtils.QueriesToFindAllDto(queries) if err != nil { @@ -86,7 +86,7 @@ func (h *Handler) FindAllAdmin(c router.IContext) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/pets/{id} [get] -func (h *Handler) FindOne(c router.IContext) { +func (h *handlerImpl) FindOne(c router.IContext) { id, err := c.Param("id") if err != nil { c.JSON(http.StatusInternalServerError, dto.ResponseErr{ @@ -118,7 +118,7 @@ func (h *Handler) FindOne(c router.IContext) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/pets/create [post] -func (h *Handler) Create(c router.IContext) { +func (h *handlerImpl) Create(c router.IContext) { request := &dto.CreatePetRequest{} err := c.Bind(request) if err != nil { @@ -165,7 +165,7 @@ func (h *Handler) Create(c router.IContext) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/pets/{id} [put] -func (h *Handler) Update(c router.IContext) { +func (h *handlerImpl) Update(c router.IContext) { petId, err := c.Param("id") if err != nil { c.JSON(http.StatusInternalServerError, &dto.ResponseErr{ @@ -223,7 +223,7 @@ func (h *Handler) Update(c router.IContext) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/pets/{id}/visible [put] -func (h *Handler) ChangeView(c router.IContext) { +func (h *handlerImpl) ChangeView(c router.IContext) { id, err := c.Param("id") if err != nil { c.JSON(http.StatusBadRequest, dto.ResponseErr{ @@ -280,7 +280,7 @@ func (h *Handler) ChangeView(c router.IContext) { // @Failure 500 {object} dto.ResponseInternalErr "Internal service error" // @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" // @Router /v1/pets/{id} [delete] -func (h *Handler) Delete(c router.IContext) { +func (h *handlerImpl) Delete(c router.IContext) { id, err := c.Param("id") if err != nil { c.JSON(http.StatusBadRequest, dto.ResponseErr{ @@ -313,7 +313,7 @@ func (h *Handler) Delete(c router.IContext) { // @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) { +func (h *handlerImpl) Adopt(c router.IContext) { petId, err := c.Param("id") if err != nil { c.JSON(http.StatusBadRequest, &dto.ResponseErr{ diff --git a/internal/pet/test/pet.handler_test.go b/internal/pet/test/pet.handler_test.go index 8b727f1..99b9634 100644 --- a/internal/pet/test/pet.handler_test.go +++ b/internal/pet/test/pet.handler_test.go @@ -1,4 +1,4 @@ -package pet +package test import ( "math/rand" diff --git a/internal/pet/test/pet.service_test.go b/internal/pet/test/pet.service_test.go index 4dbb841..6f7b177 100644 --- a/internal/pet/test/pet.service_test.go +++ b/internal/pet/test/pet.service_test.go @@ -1,4 +1,4 @@ -package pet +package test import ( "math/rand" diff --git a/internal/pkg/service/user/user.service.go b/internal/pkg/service/user/user.service.go deleted file mode 100644 index a7ff4ca..0000000 --- a/internal/pkg/service/user/user.service.go +++ /dev/null @@ -1,9 +0,0 @@ -package user - -import "github.com/isd-sgcu/johnjud-gateway/internal/dto" - -type Service interface { - FindOne(string) (*dto.User, *dto.ResponseErr) - Update(string, *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) - Delete(string) (*dto.DeleteUserResponse, *dto.ResponseErr) -} diff --git a/internal/handler/user/user.handler_test.go b/internal/user/test/user.handler_test.go similarity index 91% rename from internal/handler/user/user.handler_test.go rename to internal/user/test/user.handler_test.go index 36c1919..198d469 100644 --- a/internal/handler/user/user.handler_test.go +++ b/internal/user/test/user.handler_test.go @@ -10,11 +10,11 @@ import ( "github.com/golang/mock/gomock" "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-gateway/internal/user" routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" userMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/user" validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" - errConst "github.com/isd-sgcu/johnjud-gateway/constant" proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" "github.com/stretchr/testify/suite" @@ -63,30 +63,30 @@ func (t *UserHandlerTest) SetupTest() { t.NotFoundErr = &dto.ResponseErr{ StatusCode: http.StatusNotFound, - Message: errConst.UserNotFoundMessage, + Message: constant.UserNotFoundMessage, Data: nil, } t.InvalidIDErr = &dto.ResponseErr{ StatusCode: http.StatusBadRequest, - Message: errConst.InvalidIDMessage, + Message: constant.InvalidIDMessage, Data: nil, } t.BindErr = &dto.ResponseErr{ StatusCode: http.StatusBadRequest, - Message: errConst.InvalidIDMessage, + Message: constant.InvalidIDMessage, } t.DuplicateEmailErr = &dto.ResponseErr{ StatusCode: http.StatusConflict, - Message: errConst.DuplicateEmailMessage, + Message: constant.DuplicateEmailMessage, Data: nil, } t.InternalErr = &dto.ResponseErr{ StatusCode: http.StatusInternalServerError, - Message: errConst.InternalErrorMessage, + Message: constant.InternalErrorMessage, Data: nil, } } @@ -105,7 +105,7 @@ func (t *UserHandlerTest) TestFindOneSuccess() { userSvc.EXPECT().FindOne(t.User.Id).Return(svcResp, nil) context.EXPECT().JSON(http.StatusOK, expectedResp) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.FindOne(context) } @@ -120,7 +120,7 @@ func (t *UserHandlerTest) TestFindOneNotFoundErr() { userSvc.EXPECT().FindOne(t.User.Id).Return(nil, t.NotFoundErr) context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.FindOne(context) } @@ -134,7 +134,7 @@ func (t *UserHandlerTest) TestFindOneInvalidIDErr() { context.EXPECT().ID().Return("", errors.New("Invalid ID")) context.EXPECT().JSON(http.StatusBadRequest, t.InvalidIDErr) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.FindOne(context) } @@ -149,7 +149,7 @@ func (t *UserHandlerTest) TestFindOneInternalErr() { userSvc.EXPECT().FindOne(t.User.Id).Return(nil, t.InternalErr) context.EXPECT().JSON(http.StatusInternalServerError, t.InternalErr) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.FindOne(context) } @@ -164,7 +164,7 @@ func (t *UserHandlerTest) TestFindOneGrpcErr() { userSvc.EXPECT().FindOne(t.User.Id).Return(nil, t.ServiceDownErr) context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.FindOne(context) } @@ -184,7 +184,7 @@ func (t *UserHandlerTest) TestUpdateSuccess() { userSvc.EXPECT().Update(t.User.Id, t.UpdateUserRequest).Return(svcResp, nil) context.EXPECT().JSON(http.StatusOK, expectedResp) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.Update(context) } @@ -206,7 +206,7 @@ func (t *UserHandlerTest) TestUpdateBindErr() { context.EXPECT().Bind(t.UpdateUserRequest).Return(bindErr) context.EXPECT().JSON(http.StatusBadRequest, expectedResp) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.Update(context) } @@ -239,7 +239,7 @@ func (t *UserHandlerTest) TestUpdateValidateErr() { validator.EXPECT().Validate(t.UpdateUserRequest).Return(validateErr) context.EXPECT().JSON(http.StatusBadRequest, expectedResp) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.Update(context) } @@ -262,7 +262,7 @@ func (t *UserHandlerTest) TestUpdateDuplicateEmailErr() { userSvc.EXPECT().Update(t.User.Id, t.UpdateUserRequest).Return(nil, t.DuplicateEmailErr) context.EXPECT().JSON(http.StatusConflict, expectedResp) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.Update(context) } @@ -279,7 +279,7 @@ func (t *UserHandlerTest) TestUpdateInternalErr() { userSvc.EXPECT().Update(t.User.Id, t.UpdateUserRequest).Return(nil, t.InternalErr) context.EXPECT().JSON(http.StatusInternalServerError, t.InternalErr) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.Update(context) } @@ -296,7 +296,7 @@ func (t *UserHandlerTest) TestUpdateGrpcErr() { userSvc.EXPECT().Update(t.User.Id, t.UpdateUserRequest).Return(nil, t.ServiceDownErr) context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.Update(context) } @@ -316,7 +316,7 @@ func (t *UserHandlerTest) TestDeleteSuccess() { userSvc.EXPECT().Delete(t.User.Id).Return(deleteResp, nil) context.EXPECT().JSON(http.StatusOK, expectedResp) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.Delete(context) } @@ -330,7 +330,7 @@ func (t *UserHandlerTest) TestDeleteInvalidIDErr() { context.EXPECT().ID().Return("", errors.New("Invalid ID")) context.EXPECT().JSON(http.StatusBadRequest, t.InvalidIDErr) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.Delete(context) } @@ -345,7 +345,7 @@ func (t *UserHandlerTest) TestDeleteInternalErr() { userSvc.EXPECT().Delete(t.User.Id).Return(nil, t.InternalErr) context.EXPECT().JSON(http.StatusInternalServerError, t.InternalErr) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.Delete(context) } @@ -360,6 +360,6 @@ func (t *UserHandlerTest) TestDeleteGrpcErr() { userSvc.EXPECT().Delete(t.User.Id).Return(nil, t.ServiceDownErr) context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - handler := NewHandler(userSvc, validator) + handler := user.NewHandler(userSvc, validator) handler.Delete(context) } diff --git a/internal/service/user/user.service_test.go b/internal/user/test/user.service_test.go similarity index 87% rename from internal/service/user/user.service_test.go rename to internal/user/test/user.service_test.go index 4011eab..9b12076 100644 --- a/internal/service/user/user.service_test.go +++ b/internal/user/test/user.service_test.go @@ -7,7 +7,8 @@ import ( "github.com/go-faker/faker/v4" "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/mocks/client/user" + "github.com/isd-sgcu/johnjud-gateway/internal/user" + mockUser "github.com/isd-sgcu/johnjud-gateway/mocks/client/user" proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" @@ -108,10 +109,10 @@ func (t *UserServiceTest) TestFindOneSuccess() { Lastname: t.User.Lastname, } - client := user.UserClientMock{} + client := mockUser.UserClientMock{} client.On("FindOne", t.FindOneUserReq).Return(protoResp, nil) - svc := NewService(&client) + svc := user.NewService(&client) actual, err := svc.FindOne(t.User.Id) assert.Nil(t.T(), err) @@ -121,11 +122,11 @@ func (t *UserServiceTest) TestFindOneSuccess() { func (t *UserServiceTest) TestFindOneNotFoundError() { expected := t.NotFoundErr - client := user.UserClientMock{} + client := mockUser.UserClientMock{} clienErr := status.Error(codes.NotFound, constant.UserNotFoundMessage) client.On("FindOne", t.FindOneUserReq).Return(nil, clienErr) - svc := NewService(&client) + svc := user.NewService(&client) actual, err := svc.FindOne(t.User.Id) assert.Nil(t.T(), actual) @@ -135,11 +136,11 @@ func (t *UserServiceTest) TestFindOneNotFoundError() { func (t *UserServiceTest) TestFindOneUnavailableServiceError() { expected := t.UnavailableServiceErr - client := user.UserClientMock{} + client := mockUser.UserClientMock{} clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) client.On("FindOne", t.FindOneUserReq).Return(nil, clientErr) - svc := NewService(&client) + svc := user.NewService(&client) actual, err := svc.FindOne(t.User.Id) assert.Nil(t.T(), actual) @@ -149,11 +150,11 @@ func (t *UserServiceTest) TestFindOneUnavailableServiceError() { func (t *UserServiceTest) TestFindOneInternalError() { expected := t.InternalErr - client := user.UserClientMock{} + client := mockUser.UserClientMock{} clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) client.On("FindOne", t.FindOneUserReq).Return(nil, clientErr) - svc := NewService(&client) + svc := user.NewService(&client) actual, err := svc.FindOne(t.User.Id) assert.Nil(t.T(), actual) @@ -178,10 +179,10 @@ func (t *UserServiceTest) TestUpdateSuccess() { Lastname: t.User.Lastname, } - client := user.UserClientMock{} + client := mockUser.UserClientMock{} client.On("Update", t.UpdateUserReq).Return(protoResp, nil) - svc := NewService(&client) + svc := user.NewService(&client) actual, err := svc.Update(t.User.Id, t.UpdateUserDto) assert.Nil(t.T(), err) @@ -191,11 +192,11 @@ func (t *UserServiceTest) TestUpdateSuccess() { func (t *UserServiceTest) TestUpdateDuplicateEmail() { expected := t.ConflictErr - client := user.UserClientMock{} + client := mockUser.UserClientMock{} clientErr := status.Error(codes.AlreadyExists, constant.DuplicateEmailMessage) client.On("Update", t.UpdateUserReq).Return(nil, clientErr) - svc := NewService(&client) + svc := user.NewService(&client) actual, err := svc.Update(t.User.Id, t.UpdateUserDto) assert.Nil(t.T(), actual) @@ -205,11 +206,11 @@ func (t *UserServiceTest) TestUpdateDuplicateEmail() { func (t *UserServiceTest) TestUpdateUnavailableServiceError() { expected := t.UnavailableServiceErr - client := user.UserClientMock{} + client := mockUser.UserClientMock{} clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) client.On("Update", t.UpdateUserReq).Return(nil, clientErr) - svc := NewService(&client) + svc := user.NewService(&client) actual, err := svc.Update(t.User.Id, t.UpdateUserDto) assert.Nil(t.T(), actual) @@ -219,11 +220,11 @@ func (t *UserServiceTest) TestUpdateUnavailableServiceError() { func (t *UserServiceTest) TestUpdateInternalError() { expected := t.InternalErr - client := user.UserClientMock{} + client := mockUser.UserClientMock{} clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) client.On("Update", t.UpdateUserReq).Return(nil, clientErr) - svc := NewService(&client) + svc := user.NewService(&client) actual, err := svc.Update(t.User.Id, t.UpdateUserDto) assert.Nil(t.T(), actual) @@ -239,10 +240,10 @@ func (t *UserServiceTest) TestDeleteSuccess() { Success: true, } - client := user.UserClientMock{} + client := mockUser.UserClientMock{} client.On("Delete", t.DeleteUserReq).Return(protoResp, nil) - svc := NewService(&client) + svc := user.NewService(&client) actual, err := svc.Delete(t.User.Id) assert.Nil(t.T(), err) @@ -252,11 +253,11 @@ func (t *UserServiceTest) TestDeleteSuccess() { func (t *UserServiceTest) TestDeleteUnavailableServiceError() { expected := t.UnavailableServiceErr - client := user.UserClientMock{} + client := mockUser.UserClientMock{} clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) client.On("Delete", t.DeleteUserReq).Return(nil, clientErr) - svc := NewService(&client) + svc := user.NewService(&client) actual, err := svc.Delete(t.User.Id) assert.Nil(t.T(), actual) @@ -266,11 +267,11 @@ func (t *UserServiceTest) TestDeleteUnavailableServiceError() { func (t *UserServiceTest) TestDeleteInternalError() { expected := t.InternalErr - client := user.UserClientMock{} + client := mockUser.UserClientMock{} clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) client.On("Delete", t.DeleteUserReq).Return(nil, clientErr) - svc := NewService(&client) + svc := user.NewService(&client) actual, err := svc.Delete(t.User.Id) assert.Nil(t.T(), actual) diff --git a/internal/handler/user/user.handler.go b/internal/user/user.handler.go similarity index 94% rename from internal/handler/user/user.handler.go rename to internal/user/user.handler.go index f20a32d..ef28aea 100644 --- a/internal/handler/user/user.handler.go +++ b/internal/user/user.handler.go @@ -6,17 +6,16 @@ import ( "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/pkg/service/user" "github.com/isd-sgcu/johnjud-gateway/internal/router" "github.com/isd-sgcu/johnjud-gateway/internal/validator" ) type Handler struct { - service user.Service + service Service validate validator.IDtoValidator } -func NewHandler(service user.Service, validate validator.IDtoValidator) *Handler { +func NewHandler(service Service, validate validator.IDtoValidator) *Handler { return &Handler{service, validate} } @@ -50,7 +49,6 @@ func (h *Handler) FindOne(c router.IContext) { } c.JSON(http.StatusOK, user) - return } // Update is a function that updates user in database @@ -100,7 +98,6 @@ func (h *Handler) Update(c router.IContext) { } c.JSON(http.StatusOK, user) - return } // Delete is a function that deletes user in database @@ -134,5 +131,4 @@ func (h *Handler) Delete(c router.IContext) { } c.JSON(http.StatusOK, res) - return } diff --git a/internal/service/user/user.service.go b/internal/user/user.service.go similarity index 85% rename from internal/service/user/user.service.go rename to internal/user/user.service.go index c151b34..0885530 100644 --- a/internal/service/user/user.service.go +++ b/internal/user/user.service.go @@ -13,17 +13,23 @@ import ( "google.golang.org/grpc/status" ) -type Service struct { +type Service interface { + FindOne(string) (*dto.User, *dto.ResponseErr) + Update(string, *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) + Delete(string) (*dto.DeleteUserResponse, *dto.ResponseErr) +} + +type serviceImpl struct { client proto.UserServiceClient } -func NewService(client proto.UserServiceClient) *Service { - return &Service{ +func NewService(client proto.UserServiceClient) *serviceImpl { + return &serviceImpl{ client: client, } } -func (s *Service) FindOne(id string) (*dto.User, *dto.ResponseErr) { +func (s *serviceImpl) FindOne(id string) (*dto.User, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -68,7 +74,7 @@ func (s *Service) FindOne(id string) (*dto.User, *dto.ResponseErr) { }, nil } -func (s *Service) Update(id string, in *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) { +func (s *serviceImpl) Update(id string, in *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -117,7 +123,7 @@ func (s *Service) Update(id string, in *dto.UpdateUserRequest) (*dto.User, *dto. }, nil } -func (s *Service) Delete(id string) (*dto.DeleteUserResponse, *dto.ResponseErr) { +func (s *serviceImpl) Delete(id string) (*dto.DeleteUserResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() diff --git a/mocks/service/user/user.mock.go b/mocks/service/user/user.mock.go index c722930..c329791 100644 --- a/mocks/service/user/user.mock.go +++ b/mocks/service/user/user.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./internal/pkg/service/user/user.service.go +// Source: ./internal/user/user.service.go // Package mock_user is a generated GoMock package. package mock_user From 2b48473adae299300641e96a6a133fc7d1006357 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 21:13:21 +0700 Subject: [PATCH 082/104] utils --- internal/image/image.service.go | 9 +++---- internal/{utils => }/image/image.utils.go | 0 internal/pet/pet.handler.go | 5 ++-- internal/pet/pet.service.go | 19 +++++++------ internal/{utils => }/pet/pet.utils.go | 0 internal/pet/test/pet.handler_test.go | 9 +++---- internal/pet/test/pet.service_test.go | 17 ++++++------ internal/utils/like/like.utils.go | 33 ----------------------- 8 files changed, 27 insertions(+), 65 deletions(-) rename internal/{utils => }/image/image.utils.go (100%) rename internal/{utils => }/pet/pet.utils.go (100%) delete mode 100644 internal/utils/like/like.utils.go diff --git a/internal/image/image.service.go b/internal/image/image.service.go index e65e990..8fc97a7 100644 --- a/internal/image/image.service.go +++ b/internal/image/image.service.go @@ -7,7 +7,6 @@ import ( "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/image" proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" @@ -59,7 +58,7 @@ func (s *serviceImpl) FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) { } } } - return utils.ProtoToDtoList(res.Images), nil + return ProtoToDtoList(res.Images), nil } func (s *serviceImpl) FindByPetId(petId string) ([]*dto.ImageResponse, *dto.ResponseErr) { @@ -94,14 +93,14 @@ func (s *serviceImpl) FindByPetId(petId string) ([]*dto.ImageResponse, *dto.Resp } } } - return utils.ProtoToDtoList(res.Images), nil + return ProtoToDtoList(res.Images), nil } func (s *serviceImpl) Upload(in *dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - request := utils.CreateDtoToProto(in) + request := CreateDtoToProto(in) res, errRes := s.client.Upload(ctx, request) if errRes != nil { st, _ := status.FromError(errRes) @@ -131,7 +130,7 @@ func (s *serviceImpl) Upload(in *dto.UploadImageRequest) (*dto.ImageResponse, *d } } } - return utils.ProtoToDto(res.Image), nil + return ProtoToDto(res.Image), nil } func (s *serviceImpl) Delete(id string) (*dto.DeleteImageResponse, *dto.ResponseErr) { diff --git a/internal/utils/image/image.utils.go b/internal/image/image.utils.go similarity index 100% rename from internal/utils/image/image.utils.go rename to internal/image/image.utils.go diff --git a/internal/pet/pet.handler.go b/internal/pet/pet.handler.go index f6ed770..f91e1bd 100644 --- a/internal/pet/pet.handler.go +++ b/internal/pet/pet.handler.go @@ -8,7 +8,6 @@ import ( "github.com/isd-sgcu/johnjud-gateway/internal/dto" "github.com/isd-sgcu/johnjud-gateway/internal/image" "github.com/isd-sgcu/johnjud-gateway/internal/router" - petUtils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" "github.com/isd-sgcu/johnjud-gateway/internal/validator" ) @@ -34,7 +33,7 @@ func NewHandler(service Service, imageService image.Service, validate validator. // @Router /v1/pets/ [get] func (h *handlerImpl) FindAll(c router.IContext) { queries := c.Queries() - request, err := petUtils.QueriesToFindAllDto(queries) + request, err := QueriesToFindAllDto(queries) if err != nil { c.JSON(http.StatusBadRequest, err) } @@ -60,7 +59,7 @@ func (h *handlerImpl) FindAll(c router.IContext) { // @Router /v1/pets/admin [get] func (h *handlerImpl) FindAllAdmin(c router.IContext) { queries := c.Queries() - request, err := petUtils.QueriesToFindAllDto(queries) + request, err := QueriesToFindAllDto(queries) if err != nil { c.JSON(http.StatusBadRequest, err) } diff --git a/internal/pet/pet.service.go b/internal/pet/pet.service.go index 41768db..d4bcb1a 100644 --- a/internal/pet/pet.service.go +++ b/internal/pet/pet.service.go @@ -9,7 +9,6 @@ import ( "github.com/isd-sgcu/johnjud-gateway/internal/dto" "github.com/isd-sgcu/johnjud-gateway/internal/image" - utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" @@ -42,7 +41,7 @@ func (s *serviceImpl) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result * ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - res, errRes := s.petClient.FindAll(ctx, utils.FindAllDtoToProto(in, isAdmin)) + res, errRes := s.petClient.FindAll(ctx, FindAllDtoToProto(in, isAdmin)) if errRes != nil { st, _ := status.FromError(errRes) log.Error(). @@ -70,9 +69,9 @@ func (s *serviceImpl) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result * return nil, errSvc } - imagesList := utils.ImageList(images) - findAllDto := utils.ProtoToDtoList(res.Pets, imagesList, isAdmin) - metaData := utils.MetadataProtoToDto(res.Metadata) + imagesList := ImageList(images) + findAllDto := ProtoToDtoList(res.Pets, imagesList, isAdmin) + metaData := MetadataProtoToDto(res.Metadata) return &dto.FindAllPetResponse{ Pets: findAllDto, @@ -120,7 +119,7 @@ func (s *serviceImpl) FindOne(id string) (result *dto.PetResponse, err *dto.Resp return nil, imgErrRes } - findOneResponse := utils.ProtoToDto(res.Pet, imgRes) + findOneResponse := ProtoToDto(res.Pet, imgRes) return findOneResponse, nil } @@ -128,7 +127,7 @@ func (s *serviceImpl) Create(in *dto.CreatePetRequest) (result *dto.PetResponse, ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - request := utils.CreateDtoToProto(in) + request := CreateDtoToProto(in) res, errRes := s.petClient.Create(ctx, request) if errRes != nil { @@ -173,7 +172,7 @@ func (s *serviceImpl) Create(in *dto.CreatePetRequest) (result *dto.PetResponse, return nil, imgErrRes } - createPetResponse := utils.ProtoToDto(res.Pet, imgRes) + createPetResponse := ProtoToDto(res.Pet, imgRes) return createPetResponse, nil } @@ -181,7 +180,7 @@ func (s *serviceImpl) Update(id string, in *dto.UpdatePetRequest) (result *dto.P ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - request := utils.UpdateDtoToProto(id, in) + request := UpdateDtoToProto(id, in) res, errRes := s.petClient.Update(ctx, request) if errRes != nil { @@ -224,7 +223,7 @@ func (s *serviceImpl) Update(id string, in *dto.UpdatePetRequest) (result *dto.P return nil, errSvc } - updatePetResponse := utils.ProtoToDto(res.Pet, images) + updatePetResponse := ProtoToDto(res.Pet, images) return updatePetResponse, nil } diff --git a/internal/utils/pet/pet.utils.go b/internal/pet/pet.utils.go similarity index 100% rename from internal/utils/pet/pet.utils.go rename to internal/pet/pet.utils.go diff --git a/internal/pet/test/pet.handler_test.go b/internal/pet/test/pet.handler_test.go index 99b9634..3632492 100644 --- a/internal/pet/test/pet.handler_test.go +++ b/internal/pet/test/pet.handler_test.go @@ -15,7 +15,6 @@ import ( petMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/pet" validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" - utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" imgProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" @@ -168,7 +167,7 @@ func (t *PetHandlerTest) SetupTest() { } func (t *PetHandlerTest) TestFindAllSuccess() { - findAllResponse := utils.ProtoToDtoList(t.Pets, t.ImagesList, false) + findAllResponse := pet.ProtoToDtoList(t.Pets, t.ImagesList, false) metadataResponse := t.Metadata expectedResponse := &dto.FindAllPetResponse{ Pets: findAllResponse, @@ -191,7 +190,7 @@ func (t *PetHandlerTest) TestFindAllSuccess() { } func (t *PetHandlerTest) TestFindOneSuccess() { - findOneResponse := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Images)) + findOneResponse := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Images)) expectedResponse := findOneResponse controller := gomock.NewController(t.T()) @@ -246,7 +245,7 @@ func (t *PetHandlerTest) TestFindOneGrpcErr() { } func (t *PetHandlerTest) TestCreateSuccess() { - createResponse := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Images)) + createResponse := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Images)) expectedResponse := createResponse controller := gomock.NewController(t.T()) @@ -285,7 +284,7 @@ func (t *PetHandlerTest) TestCreateGrpcErr() { } func (t *PetHandlerTest) TestUpdateSuccess() { - updateResponse := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Images)) + updateResponse := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Images)) expectedResponse := updateResponse controller := gomock.NewController(t.T()) diff --git a/internal/pet/test/pet.service_test.go b/internal/pet/test/pet.service_test.go index 6f7b177..d5f9df2 100644 --- a/internal/pet/test/pet.service_test.go +++ b/internal/pet/test/pet.service_test.go @@ -10,7 +10,6 @@ import ( "github.com/isd-sgcu/johnjud-gateway/internal/dto" imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/image" "github.com/isd-sgcu/johnjud-gateway/internal/pet" - utils "github.com/isd-sgcu/johnjud-gateway/internal/utils/pet" imagemock "github.com/isd-sgcu/johnjud-gateway/mocks/client/image" petmock "github.com/isd-sgcu/johnjud-gateway/mocks/client/pet" petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" @@ -145,7 +144,7 @@ func (t *PetServiceTest) SetupTest() { Tel: t.Pet.Tel, } - t.PetDto = utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Pet.Images)) + t.PetDto = pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) t.FindAllPetDto = &dto.FindAllPetRequest{ Search: "", @@ -199,9 +198,9 @@ func (t *PetServiceTest) SetupTest() { Tel: t.Pet.Tel, } - t.FindAllPetReq = utils.FindAllDtoToProto(t.FindAllPetDto, true) - t.CreatePetReq = utils.CreateDtoToProto(t.CreatePetDto) - t.UpdatePetReq = utils.UpdateDtoToProto(t.Pet.Id, t.UpdatePetDto) + t.FindAllPetReq = pet.FindAllDtoToProto(t.FindAllPetDto, true) + t.CreatePetReq = pet.CreateDtoToProto(t.CreatePetDto) + t.UpdatePetReq = pet.UpdateDtoToProto(t.Pet.Id, t.UpdatePetDto) t.ChangeViewPetReq = &petproto.ChangeViewPetRequest{ Id: t.Pet.Id, @@ -268,7 +267,7 @@ func (t *PetServiceTest) TestFindAllSuccess() { Metadata: t.MetadataProto, } - findAllPPetsDto := utils.ProtoToDtoList(t.Pets, t.ImagesList, false) + findAllPPetsDto := pet.ProtoToDtoList(t.Pets, t.ImagesList, false) metadataDto := t.MetadataDto expected := &dto.FindAllPetResponse{ @@ -324,7 +323,7 @@ func (t *PetServiceTest) TestFindOneSuccess() { Images: t.Images, } - expected := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Pet.Images)) + expected := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) client := petmock.PetClientMock{} client.On("FindOne", protoReq).Return(protoResp, nil) @@ -401,7 +400,7 @@ func (t *PetServiceTest) TestCreateSuccess() { Images: t.Images, } - expected := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Pet.Images)) + expected := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) client := &petmock.PetClientMock{} client.On("Create", protoReq).Return(protoResp, nil) @@ -484,7 +483,7 @@ func (t *PetServiceTest) TestUpdateSuccess() { Pet: t.Pet, } - expected := utils.ProtoToDto(t.Pet, utils.ImageProtoToDto(t.Pet.Images)) + expected := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) client := &petmock.PetClientMock{} client.On("Update", protoReq).Return(protoResp, nil) diff --git a/internal/utils/like/like.utils.go b/internal/utils/like/like.utils.go deleted file mode 100644 index b48689a..0000000 --- a/internal/utils/like/like.utils.go +++ /dev/null @@ -1,33 +0,0 @@ -package like - -import ( - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" -) - -func ProtoToDto(in *likeProto.Like) *dto.LikeResponse { - return &dto.LikeResponse{ - UserID: in.UserId, - PetID: in.PetId, - } -} - -func ProtoToDtoList(in []*likeProto.Like) []*dto.LikeResponse { - var res []*dto.LikeResponse - for _, i := range in { - res = append(res, &dto.LikeResponse{ - UserID: i.UserId, - PetID: i.PetId, - }) - } - return res -} - -func CreateDtoToProto(in *dto.CreateLikeRequest) *likeProto.CreateLikeRequest { - return &likeProto.CreateLikeRequest{ - Like: &likeProto.Like{ - UserId: in.UserID, - PetId: in.PetID, - }, - } -} From 6d1da74a28703af811b222301d7efd19bc7d56bb Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 21:30:05 +0700 Subject: [PATCH 083/104] config, air --- .air.toml | 51 ++++++++++++++++ .gitignore | 2 +- Makefile | 5 +- config/config.go | 68 ++++++++++++--------- go.mod | 18 +----- go.sum | 38 +----------- internal/middleware/auth/auth.middleware.go | 4 +- internal/router/context.go | 6 +- internal/router/router.go | 4 +- tools/export-env.sh | 16 ----- 10 files changed, 106 insertions(+), 106 deletions(-) create mode 100644 .air.toml delete mode 100644 tools/export-env.sh diff --git a/.air.toml b/.air.toml new file mode 100644 index 0000000..2bc7176 --- /dev/null +++ b/.air.toml @@ -0,0 +1,51 @@ +root = "." +testdata_dir = "testdata" +tmp_dir = "tmp" + +[build] + args_bin = [] + bin = "./tmp/main" + cmd = "go build -o ./tmp/main ./cmd/main.go" + delay = 1000 + exclude_dir = ["assets", "tmp", "vendor", "testdata"] + exclude_file = [] + exclude_regex = ["_test.go"] + exclude_unchanged = false + follow_symlink = false + full_bin = "" + include_dir = [] + include_ext = ["go", "tpl", "tmpl", "html"] + include_file = [] + kill_delay = "0s" + log = "build-errors.log" + poll = false + poll_interval = 0 + post_cmd = [] + pre_cmd = [] + rerun = false + rerun_delay = 500 + send_interrupt = false + stop_on_error = false + +[color] + app = "" + build = "yellow" + main = "magenta" + runner = "green" + watcher = "cyan" + +[log] + main_only = false + time = false + +[misc] + clean_on_exit = false + +[proxy] + app_port = 0 + enabled = false + proxy_port = 0 + +[screen] + clear_on_rebuild = false + keep_scroll = true diff --git a/.gitignore b/.gitignore index ecd6a68..a6cfd98 100644 --- a/.gitignore +++ b/.gitignore @@ -55,5 +55,5 @@ coverage.out coverage.html token.txt - +tmp docker-compose.qa.yaml \ No newline at end of file diff --git a/Makefile b/Makefile index 4794c6c..45aa554 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,10 @@ test: go tool cover -html=coverage.out -o coverage.html server: - . ./tools/export-env.sh ; go run ./cmd/. + go run ./cmd/. + +docker-qa: + docker-compose -f docker-compose.qa.yaml up mock-gen: mockgen -source ./internal/auth/auth.service.go -destination ./mocks/service/auth/auth.mock.go diff --git a/config/config.go b/config/config.go index 10e1db2..4ff7b6d 100644 --- a/config/config.go +++ b/config/config.go @@ -1,53 +1,65 @@ package config import ( - "github.com/spf13/viper" + "os" + "strconv" + + "github.com/joho/godotenv" ) -type App struct { - Port int `mapstructure:"PORT"` - Env string `mapstructure:"ENV"` - MaxFileSize int64 `mapstructure:"MAX_FILE_SIZE"` +type AppConfig struct { + Port int + Env string + MaxFileSize int64 } -type Service struct { - Auth string `mapstructure:"AUTH"` - Backend string `mapstructure:"BACKEND"` - File string `mapstructure:"FILE"` +type ServiceConfig struct { + Auth string + Backend string + File string } type Config struct { - App App - Service Service + App AppConfig + Service ServiceConfig } func LoadConfig() (*Config, error) { - appCfgLdr := viper.New() - appCfgLdr.SetEnvPrefix("APP") - appCfgLdr.AutomaticEnv() - appCfgLdr.AllowEmptyEnv(false) - appConfig := App{} - if err := appCfgLdr.Unmarshal(&appConfig); err != nil { - return nil, err + if os.Getenv("APP_ENV") == "" { + err := godotenv.Load(".env") + if err != nil { + return nil, err + } } - serviceCfgLdr := viper.New() - serviceCfgLdr.SetEnvPrefix("SERVICE") - serviceCfgLdr.AutomaticEnv() - serviceCfgLdr.AllowEmptyEnv(false) - serviceConfig := Service{} - if err := serviceCfgLdr.Unmarshal(&serviceConfig); err != nil { + port, err := strconv.ParseInt(os.Getenv("APP_PORT"), 10, 64) + if err != nil { + return nil, err + } + maxFileSize, err := strconv.ParseInt(os.Getenv("APP_MAX_FILE_SIZE"), 10, 64) + if err != nil { return nil, err } - config := &Config{ + appConfig := AppConfig{ + Port: int(port), + Env: os.Getenv("APP_ENV"), + MaxFileSize: maxFileSize, + } + + serviceConfig := ServiceConfig{ + Auth: os.Getenv("SERVICE_AUTH"), + Backend: os.Getenv("SERVICE_BACKEND"), + File: os.Getenv("SERVICE_FILE"), + } + + return &Config{ App: appConfig, Service: serviceConfig, - } + }, nil - return config, nil } -func (ac *App) IsDevelopment() bool { +func (ac *AppConfig) IsDevelopment() bool { return ac.Env == "development" } diff --git a/go.mod b/go.mod index 99ce8ee..49e9263 100644 --- a/go.mod +++ b/go.mod @@ -13,8 +13,8 @@ require ( github.com/golang/mock v1.6.0 github.com/google/uuid v1.6.0 github.com/isd-sgcu/johnjud-go-proto v0.7.1 + github.com/joho/godotenv v1.5.1 github.com/rs/zerolog v1.31.0 - github.com/spf13/viper v1.18.1 github.com/stretchr/testify v1.8.4 github.com/swaggo/swag v1.16.2 google.golang.org/grpc v1.63.2 @@ -24,47 +24,31 @@ require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/andybalholm/brotli v1.0.6 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/spec v0.20.13 // indirect github.com/go-openapi/swag v0.22.7 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect - github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.4.4 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect - github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect - github.com/subosito/gotenv v1.6.0 // indirect github.com/swaggo/files v1.0.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.51.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.9.0 // indirect golang.org/x/crypto v0.19.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/sys v0.17.0 // indirect 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-20240227224415-6ceb2ff114de // indirect google.golang.org/protobuf v1.34.1 // 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 5604213..cdadaef 100644 --- a/go.sum +++ b/go.sum @@ -18,10 +18,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -60,10 +56,10 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN 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/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.7.1 h1:sdwyEvFcGoLmoypjOuZRgQZGeuX9jcXdiPcUWJw3VoA= github.com/isd-sgcu/johnjud-go-proto v0.7.1/go.mod h1:C1oOvRz1bYqX2EGG3Iy+1mbB9buvhwudR/hYwWKkAwE= +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= 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= @@ -79,8 +75,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -94,16 +88,12 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= @@ -117,23 +107,9 @@ github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= -github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= -github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.18.1 h1:rmuU42rScKWlhhJDyXZRKJQHXFX02chSVW1IvkPGiVM= -github.com/spf13/viper v1.18.1/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= 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 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= @@ -146,8 +122,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w= github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= @@ -165,18 +139,12 @@ github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7Fw github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= @@ -248,8 +216,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/internal/middleware/auth/auth.middleware.go b/internal/middleware/auth/auth.middleware.go index 956b681..3e82039 100644 --- a/internal/middleware/auth/auth.middleware.go +++ b/internal/middleware/auth/auth.middleware.go @@ -15,11 +15,11 @@ type Guard struct { service auth.Service excludes map[string]struct{} adminpath map[string]struct{} - conf config.App + conf config.AppConfig versionList map[string]struct{} } -func NewAuthGuard(s auth.Service, e map[string]struct{}, a map[string]struct{}, conf config.App, versionList map[string]struct{}) Guard { +func NewAuthGuard(s auth.Service, e map[string]struct{}, a map[string]struct{}, conf config.AppConfig, versionList map[string]struct{}) Guard { return Guard{ service: s, excludes: e, diff --git a/internal/router/context.go b/internal/router/context.go index 43dac98..9b43440 100644 --- a/internal/router/context.go +++ b/internal/router/context.go @@ -111,15 +111,15 @@ func (c *FiberCtx) File(key string, allowContent map[string]struct{}, maxSize in } if !utils.IsExisted(allowContent, file.Header["Content-Type"][0]) { - return nil, errors.New("Not allow content") + return nil, errors.New("not allow content") } if file.Size > maxSize { - return nil, errors.New(fmt.Sprintf("Max file size is %v", maxSize)) + return nil, fmt.Errorf("max file size is %v", maxSize) } content, err := file.Open() if err != nil { - return nil, errors.New("Cannot read file") + return nil, errors.New("cannot read file") } defer content.Close() diff --git a/internal/router/router.go b/internal/router/router.go index 8b2eecc..f27c81e 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -22,7 +22,7 @@ type IGuard interface { Use(IContext) error } -func NewAPIv1(r *FiberRouter, conf config.App) *fiber.App { +func NewAPIv1(r *FiberRouter, conf config.AppConfig) *fiber.App { if conf.IsDevelopment() { r.Use(logger.New(logger.Config{Next: func(c *fiber.Ctx) bool { return c.Path() == "/v1/" @@ -41,7 +41,7 @@ func NewAPIv1(r *FiberRouter, conf config.App) *fiber.App { return app } -func NewFiberRouter(authGuard IGuard, conf config.App) *FiberRouter { +func NewFiberRouter(authGuard IGuard, conf config.AppConfig) *FiberRouter { r := fiber.New(fiber.Config{ BodyLimit: int(conf.MaxFileSize * 1024 * 1024), }) diff --git a/tools/export-env.sh b/tools/export-env.sh deleted file mode 100644 index 39688ee..0000000 --- a/tools/export-env.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -## Usage: -## . ./export-env.sh ; $COMMAND -## . ./export-env.sh ; echo ${MINIENTREGA_FECHALIMITE} - -unamestr=$(uname) -if [ "$unamestr" = 'Linux' ]; then - - export $(grep -v '^#' .env | xargs -d '\n') - -elif [ "$unamestr" = 'FreeBSD' ] || [ "$unamestr" = 'Darwin' ]; then - - export $(grep -v '^#' .env | xargs -0) - -fi \ No newline at end of file From 234ad389a0c508be4aa6a20fa14fc5f9d62e325e Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 21:34:05 +0700 Subject: [PATCH 084/104] model, constant --- constant/email.constant.go | 4 ++++ constant/error.constant.go | 9 +++++++++ go.mod | 3 +++ go.sum | 6 ++++++ internal/model/auth.model.go | 8 ++++++++ internal/model/common.model.go | 20 ++++++++++++++++++++ internal/model/user.model.go | 12 ++++++++++++ 7 files changed, 62 insertions(+) create mode 100644 constant/email.constant.go create mode 100644 internal/model/auth.model.go create mode 100644 internal/model/common.model.go create mode 100644 internal/model/user.model.go diff --git a/constant/email.constant.go b/constant/email.constant.go new file mode 100644 index 0000000..427ace7 --- /dev/null +++ b/constant/email.constant.go @@ -0,0 +1,4 @@ +package constant + +// auth +const ResetPasswordSubject = "Reset Password Request" diff --git a/constant/error.constant.go b/constant/error.constant.go index ac7036e..61cdecd 100644 --- a/constant/error.constant.go +++ b/constant/error.constant.go @@ -17,3 +17,12 @@ const UserNotFoundMessage = "User not found" const ImageNotFoundMessage = "Image not found" const InvalidContentMessage = "Invalid content" + +// auth +const InvalidTokenErrorMessage = "Invalid token" +const IncorrectEmailPasswordErrorMessage = "Incorrect email or password" +const IncorrectPasswordErrorMessage = "New password should not be the same as the previous one" +const DuplicateEmailErrorMessage = "Duplicate email" +const InternalServerErrorMessage = "Internal server error" + +const UserNotFoundErrorMessage = "User not found" diff --git a/go.mod b/go.mod index 49e9263..a8d818c 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,8 @@ require ( github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/spec v0.20.13 // indirect github.com/go-openapi/swag v0.22.7 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect @@ -51,4 +53,5 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + gorm.io/gorm v1.25.11 // indirect ) diff --git a/go.sum b/go.sum index cdadaef..534a5ef 100644 --- a/go.sum +++ b/go.sum @@ -58,6 +58,10 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/isd-sgcu/johnjud-go-proto v0.7.1 h1:sdwyEvFcGoLmoypjOuZRgQZGeuX9jcXdiPcUWJw3VoA= github.com/isd-sgcu/johnjud-go-proto v0.7.1/go.mod h1:C1oOvRz1bYqX2EGG3Iy+1mbB9buvhwudR/hYwWKkAwE= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= 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= @@ -223,3 +227,5 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg= +gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= diff --git a/internal/model/auth.model.go b/internal/model/auth.model.go new file mode 100644 index 0000000..0596f5e --- /dev/null +++ b/internal/model/auth.model.go @@ -0,0 +1,8 @@ +package model + +import "github.com/google/uuid" + +type AuthSession struct { + Base + UserID uuid.UUID `json:"user_id"` +} diff --git a/internal/model/common.model.go b/internal/model/common.model.go new file mode 100644 index 0000000..a63abd8 --- /dev/null +++ b/internal/model/common.model.go @@ -0,0 +1,20 @@ +package model + +import ( + "github.com/google/uuid" + "gorm.io/gorm" + "time" +) + +type Base struct { + ID uuid.UUID `json:"id" gorm:"primary_key"` + CreatedAt time.Time `json:"created_at" gorm:"type:timestamp;autoCreateTime:nano"` + UpdatedAt time.Time `json:"updated_at" gorm:"type:timestamp;autoUpdateTime:nano"` + DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index;type:timestamp"` +} + +func (b *Base) BeforeCreate(_ *gorm.DB) error { + b.ID = uuid.New() + + return nil +} diff --git a/internal/model/user.model.go b/internal/model/user.model.go new file mode 100644 index 0000000..8f2cefb --- /dev/null +++ b/internal/model/user.model.go @@ -0,0 +1,12 @@ +package model + +import "github.com/isd-sgcu/johnjud-gateway/constant" + +type User struct { + Base + Email string `json:"email" gorm:"tinytext;unique"` + Password string `json:"password" gorm:"tinytext"` + Firstname string `json:"firstname" gorm:"tinytext"` + Lastname string `json:"lastname" gorm:"tinytext"` + Role constant.Role `json:"role" gorm:"tinytext"` +} From 045cf5bdec6784e8efd7c9d0b15abfc9d490cbef Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 22:04:12 +0700 Subject: [PATCH 085/104] imrgate token jwt --- Makefile | 2 + config/config.go | 101 ++- go.mod | 7 + go.sum | 13 + internal/auth/email/email.service.go | 41 + internal/auth/jwt/jwt.service.go | 59 ++ internal/auth/jwt/jwt.utils.go | 36 + internal/auth/jwt/test/jwt.service_test.go | 154 ++++ internal/auth/token/strategy/jwt.strategy.go | 29 + .../auth/token/strategy/jwt.strategy_test.go | 55 ++ .../auth/token/test/token.service_test.go | 739 ++++++++++++++++++ internal/auth/token/token.service.go | 218 ++++++ internal/cache/cache.repository.go | 54 ++ internal/cache/test/cache.repository_test.go | 78 ++ internal/dto/token.dto.go | 35 + internal/middleware/auth/auth.middleware.go | 4 +- internal/router/router.go | 4 +- internal/utils/uuid.utils.go | 18 + mocks/repository/cache/cache.mock.go | 76 ++ mocks/service/jwt/jwt.mock.go | 35 + mocks/service/token/token.mock.go | 168 ++++ mocks/strategy/strategy.mock.go | 18 + mocks/utils/bcrypt.mock.go | 25 + mocks/utils/jwt.mock.go | 39 + mocks/utils/uuid.mock.go | 15 + 25 files changed, 2009 insertions(+), 14 deletions(-) create mode 100644 internal/auth/email/email.service.go create mode 100644 internal/auth/jwt/jwt.service.go create mode 100644 internal/auth/jwt/jwt.utils.go create mode 100644 internal/auth/jwt/test/jwt.service_test.go create mode 100644 internal/auth/token/strategy/jwt.strategy.go create mode 100644 internal/auth/token/strategy/jwt.strategy_test.go create mode 100644 internal/auth/token/test/token.service_test.go create mode 100644 internal/auth/token/token.service.go create mode 100644 internal/cache/cache.repository.go create mode 100644 internal/cache/test/cache.repository_test.go create mode 100644 internal/dto/token.dto.go create mode 100644 internal/utils/uuid.utils.go create mode 100644 mocks/repository/cache/cache.mock.go create mode 100644 mocks/service/jwt/jwt.mock.go create mode 100644 mocks/service/token/token.mock.go create mode 100644 mocks/strategy/strategy.mock.go create mode 100644 mocks/utils/bcrypt.mock.go create mode 100644 mocks/utils/jwt.mock.go create mode 100644 mocks/utils/uuid.mock.go diff --git a/Makefile b/Makefile index 45aa554..b30b5f7 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,8 @@ docker-qa: docker-compose -f docker-compose.qa.yaml up mock-gen: + mockgen -source ./internal/cache/cache.repository.go -destination ./mocks/repository/cache/cache.mock.go + mockgen -source ./internal/auth/token/token.service.go -destination ./mocks/service/token/token.mock.go mockgen -source ./internal/auth/auth.service.go -destination ./mocks/service/auth/auth.mock.go mockgen -source ./internal/user/user.service.go -destination ./mocks/service/user/user.mock.go mockgen -source ./internal/pet/pet.service.go -destination ./mocks/service/pet/pet.mock.go diff --git a/config/config.go b/config/config.go index 4ff7b6d..28daf98 100644 --- a/config/config.go +++ b/config/config.go @@ -7,21 +7,54 @@ import ( "github.com/joho/godotenv" ) -type AppConfig struct { +type App struct { Port int Env string MaxFileSize int64 } -type ServiceConfig struct { +type Service struct { Auth string Backend string File string } +type Database struct { + Url string +} + +type Redis struct { + Host string + Port int + Password string +} + +type Jwt struct { + Secret string + ExpiresIn int + RefreshTokenTTL int + Issuer string + ResetTokenTTL int +} + +type Auth struct { + ClientURL string +} + +type Sendgrid struct { + ApiKey string + Name string + Address string +} + type Config struct { - App AppConfig - Service ServiceConfig + App App + Service Service + Database Database + Redis Redis + Jwt Jwt + Auth Auth + Sendgrid Sendgrid } func LoadConfig() (*Config, error) { @@ -40,26 +73,74 @@ func LoadConfig() (*Config, error) { if err != nil { return nil, err } - - appConfig := AppConfig{ + app := App{ Port: int(port), Env: os.Getenv("APP_ENV"), MaxFileSize: maxFileSize, } - serviceConfig := ServiceConfig{ + service := Service{ Auth: os.Getenv("SERVICE_AUTH"), Backend: os.Getenv("SERVICE_BACKEND"), File: os.Getenv("SERVICE_FILE"), } + database := Database{ + Url: os.Getenv("DATABASE_URL"), + } + + redisPort, err := strconv.Atoi(os.Getenv("REDIS_PORT")) + if err != nil { + return nil, err + } + redis := Redis{ + Host: os.Getenv("REDIS_HOST"), + Port: redisPort, + Password: os.Getenv("REDIS_PASSWORD"), + } + + jwtExpiresIn, err := strconv.Atoi(os.Getenv("JWT_EXPIRES_IN")) + if err != nil { + return nil, err + } + jwtRefreshTokenTTL, err := strconv.Atoi(os.Getenv("JWT_REFRESH_TOKEN_TTL")) + if err != nil { + return nil, err + } + jwtResetTokenTTL, err := strconv.Atoi(os.Getenv("JWT_RESET_TOKEN_TTL")) + if err != nil { + return nil, err + } + jwt := Jwt{ + Secret: os.Getenv("JWT_SECRET"), + ExpiresIn: jwtExpiresIn, + RefreshTokenTTL: jwtRefreshTokenTTL, + Issuer: os.Getenv("JWT_ISSUER"), + ResetTokenTTL: jwtResetTokenTTL, + } + + auth := Auth{ + ClientURL: os.Getenv("AUTH_CLIENT_URL"), + } + + sendgrid := Sendgrid{ + ApiKey: os.Getenv("SENDGRID_API_KEY"), + Name: os.Getenv("SENDGRID_NAME"), + Address: os.Getenv("SENDGRID_ADDRESS"), + } + return &Config{ - App: appConfig, - Service: serviceConfig, + App: app, + Service: service, + Database: database, + Redis: redis, + Jwt: jwt, + Auth: auth, + Sendgrid: sendgrid, }, nil } -func (ac *AppConfig) IsDevelopment() bool { +func (ac *App) IsDevelopment() bool { return ac.Env == "development" } diff --git a/go.mod b/go.mod index a8d818c..0dbf899 100644 --- a/go.mod +++ b/go.mod @@ -23,12 +23,15 @@ require ( require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/andybalholm/brotli v1.0.6 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/spec v0.20.13 // indirect github.com/go-openapi/swag v0.22.7 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -38,8 +41,12 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/redis/go-redis/v9 v9.6.1 // indirect github.com/rivo/uniseg v0.4.4 // indirect + github.com/sendgrid/rest v2.6.9+incompatible // indirect + github.com/sendgrid/sendgrid-go v3.15.0+incompatible // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/swaggo/files v1.0.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect diff --git a/go.sum b/go.sum index 534a5ef..f5688ec 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,8 @@ github.com/arsmn/fiber-swagger/v2 v2.31.1 h1:VmX+flXiGGNqLX3loMEEzL3BMOZFSPwBEWR github.com/arsmn/fiber-swagger/v2 v2.31.1/go.mod h1:ZHhMprtB3M6jd2mleG03lPGhHH0lk9u3PtfWS1cBhMA= github.com/bxcodec/faker/v4 v4.0.0-beta.3 h1:gqYNBvN72QtzKkYohNDKQlm+pg+uwBDVMN28nWHS18k= github.com/bxcodec/faker/v4 v4.0.0-beta.3/go.mod h1:m6+Ch1Lj3fqW/unZmvkXIdxWS5+XQWPWxcbbQW2X+Ho= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -18,6 +20,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -49,6 +53,8 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/gofiber/fiber/v2 v2.31.0/go.mod h1:1Ega6O199a3Y7yDGuM9FyXDPYQfv+7/y48wl6WCwUF4= github.com/gofiber/fiber/v2 v2.52.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/UE= github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -98,10 +104,13 @@ github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= +github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -111,6 +120,10 @@ github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0= +github.com/sendgrid/rest v2.6.9+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE= +github.com/sendgrid/sendgrid-go v3.15.0+incompatible h1:oB6ujJD2aFcQRjmZLmmXiiUF9CBYKzsvYdPAS/71cSU= +github.com/sendgrid/sendgrid-go v3.15.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= diff --git a/internal/auth/email/email.service.go b/internal/auth/email/email.service.go new file mode 100644 index 0000000..26d5b36 --- /dev/null +++ b/internal/auth/email/email.service.go @@ -0,0 +1,41 @@ +package email + +import ( + "fmt" + "net/http" + + "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/pkg/errors" + "github.com/sendgrid/sendgrid-go" + "github.com/sendgrid/sendgrid-go/helpers/mail" +) + +type Service interface { + SendEmail(subject string, toName string, toAddress string, content string) error +} + +type serviceImpl struct { + config config.Sendgrid + client *sendgrid.Client +} + +func NewService(config config.Sendgrid) Service { + client := sendgrid.NewSendClient(config.ApiKey) + return &serviceImpl{config: config, client: client} +} + +func (s *serviceImpl) SendEmail(subject string, toName string, toAddress string, content string) error { + from := mail.NewEmail(s.config.Name, s.config.Address) + to := mail.NewEmail(toName, toAddress) + message := mail.NewSingleEmail(from, subject, to, content, content) + + resp, err := s.client.Send(message) + if err != nil { + return err + } + if resp.StatusCode != http.StatusAccepted { + return errors.New(fmt.Sprintf("%d status code", resp.StatusCode)) + } + + return nil +} diff --git a/internal/auth/jwt/jwt.service.go b/internal/auth/jwt/jwt.service.go new file mode 100644 index 0000000..7a630b3 --- /dev/null +++ b/internal/auth/jwt/jwt.service.go @@ -0,0 +1,59 @@ +package jwt + +import ( + "fmt" + "time" + + _jwt "github.com/golang-jwt/jwt/v4" + + "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/auth/token/strategy" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/pkg/errors" +) + +type Service interface { + SignAuth(userId string, role constant.Role, authSessionId string) (string, error) + VerifyAuth(token string) (*_jwt.Token, error) + GetConfig() *config.Jwt +} + +type serviceImpl struct { + config config.Jwt + strategy strategy.JwtStrategy + jwtUtil IJwtUtil +} + +func NewService(config config.Jwt, strategy strategy.JwtStrategy, jwtUtil IJwtUtil) Service { + return &serviceImpl{config: config, strategy: strategy, jwtUtil: jwtUtil} +} + +func (s *serviceImpl) SignAuth(userId string, role constant.Role, authSessionId string) (string, error) { + payloads := dto.AuthPayload{ + RegisteredClaims: _jwt.RegisteredClaims{ + Issuer: s.config.Issuer, + ExpiresAt: s.jwtUtil.GetNumericDate(time.Now().Add(time.Second * time.Duration(s.config.ExpiresIn))), + IssuedAt: s.jwtUtil.GetNumericDate(time.Now()), + }, + UserID: userId, + AuthSessionID: authSessionId, + } + + token := s.jwtUtil.GenerateJwtToken(_jwt.SigningMethodHS256, payloads) + + tokenStr, err := s.jwtUtil.SignedTokenString(token, s.config.Secret) + if err != nil { + return "", errors.New(fmt.Sprintf("Error while signing the token due to: %s", err.Error())) + } + + return tokenStr, nil +} + +func (s *serviceImpl) VerifyAuth(token string) (*_jwt.Token, error) { + return s.jwtUtil.ParseToken(token, s.strategy.AuthDecode) +} + +func (s *serviceImpl) GetConfig() *config.Jwt { + return &s.config +} diff --git a/internal/auth/jwt/jwt.utils.go b/internal/auth/jwt/jwt.utils.go new file mode 100644 index 0000000..23e14d6 --- /dev/null +++ b/internal/auth/jwt/jwt.utils.go @@ -0,0 +1,36 @@ +package jwt + +import ( + "time" + + "github.com/golang-jwt/jwt/v4" +) + +type IJwtUtil interface { + GenerateJwtToken(method jwt.SigningMethod, payloads jwt.Claims) *jwt.Token + GetNumericDate(time time.Time) *jwt.NumericDate + SignedTokenString(token *jwt.Token, secret string) (string, error) + ParseToken(tokenStr string, keyFunc jwt.Keyfunc) (*jwt.Token, error) +} + +type jwtUtilImpl struct{} + +func NewJwtUtil() IJwtUtil { + return &jwtUtilImpl{} +} + +func (u *jwtUtilImpl) GenerateJwtToken(method jwt.SigningMethod, payloads jwt.Claims) *jwt.Token { + return jwt.NewWithClaims(method, payloads) +} + +func (u *jwtUtilImpl) GetNumericDate(time time.Time) *jwt.NumericDate { + return jwt.NewNumericDate(time) +} + +func (u *jwtUtilImpl) SignedTokenString(token *jwt.Token, secret string) (string, error) { + return token.SignedString([]byte(secret)) +} + +func (u *jwtUtilImpl) ParseToken(tokenStr string, keyFunc jwt.Keyfunc) (*jwt.Token, error) { + return jwt.Parse(tokenStr, keyFunc) +} diff --git a/internal/auth/jwt/test/jwt.service_test.go b/internal/auth/jwt/test/jwt.service_test.go new file mode 100644 index 0000000..c234aa7 --- /dev/null +++ b/internal/auth/jwt/test/jwt.service_test.go @@ -0,0 +1,154 @@ +package test + +import ( + "fmt" + "testing" + "time" + + "github.com/go-faker/faker/v4" + "github.com/golang-jwt/jwt/v4" + "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/isd-sgcu/johnjud-gateway/constant" + _jwt "github.com/isd-sgcu/johnjud-gateway/internal/auth/jwt" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-gateway/mocks/strategy" + "github.com/isd-sgcu/johnjud-gateway/mocks/utils" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/suite" +) + +type JwtServiceTest struct { + suite.Suite + config config.Jwt + userId string + role constant.Role + authSessionId string + numericDate *jwt.NumericDate + payloads dto.AuthPayload + token *jwt.Token +} + +func TestJwtService(t *testing.T) { + suite.Run(t, new(JwtServiceTest)) +} + +func (t *JwtServiceTest) SetupTest() { + config := config.Jwt{ + Secret: "testSecret", + ExpiresIn: 3600, + Issuer: "testIssuer", + } + + userId := faker.UUIDDigit() + role := constant.USER + authSessionId := faker.UUIDDigit() + numericDate := jwt.NewNumericDate(time.Now()) + + payloads := dto.AuthPayload{ + RegisteredClaims: jwt.RegisteredClaims{ + Issuer: t.config.Issuer, + ExpiresAt: numericDate, + IssuedAt: numericDate, + }, + UserID: userId, + AuthSessionID: authSessionId, + } + + token := &jwt.Token{ + Header: map[string]interface{}{ + "typ": "JWT", + "alg": jwt.SigningMethodHS256.Alg(), + }, + Method: jwt.SigningMethodHS256, + Claims: payloads, + } + + t.config = config + t.userId = userId + t.role = role + t.authSessionId = authSessionId + t.numericDate = numericDate + t.payloads = payloads + t.token = token +} + +func (t *JwtServiceTest) TestSignAuthSuccess() { + expected := "signedTokenStr" + + jwtStrategy := strategy.JwtStrategyMock{} + jwtUtil := utils.JwtUtilMock{} + + jwtUtil.On("GetNumericDate", mock.AnythingOfType("time.Time")).Return(t.numericDate) + jwtUtil.On("GenerateJwtToken", jwt.SigningMethodHS256, t.payloads).Return(t.token) + jwtUtil.On("SignedTokenString", t.token, t.config.Secret).Return(expected, nil) + + jwtSvc := _jwt.NewService(t.config, &jwtStrategy, &jwtUtil) + actual, err := jwtSvc.SignAuth(t.userId, t.role, t.authSessionId) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *JwtServiceTest) TestSignAuthSignedStringFailed() { + signedTokenError := errors.New("Some Error") + expected := errors.New(fmt.Sprintf("Error while signing the token due to: %s", signedTokenError.Error())) + + jwtStrategy := strategy.JwtStrategyMock{} + jwtUtil := utils.JwtUtilMock{} + + jwtUtil.On("GetNumericDate", mock.AnythingOfType("time.Time")).Return(t.numericDate) + jwtUtil.On("GenerateJwtToken", jwt.SigningMethodHS256, t.payloads).Return(t.token) + jwtUtil.On("SignedTokenString", t.token, t.config.Secret).Return("", signedTokenError) + + jwtSvc := _jwt.NewService(t.config, &jwtStrategy, &jwtUtil) + actual, err := jwtSvc.SignAuth(t.userId, t.role, t.authSessionId) + + assert.Equal(t.T(), "", actual) + assert.Equal(t.T(), expected.Error(), err.Error()) +} + +func (t *JwtServiceTest) TestVerifyAuthSuccess() { + tokenStr := "validSignedToken" + expected := t.token + + jwtStrategy := strategy.JwtStrategyMock{} + jwtUtil := utils.JwtUtilMock{} + + jwtUtil.On("ParseToken", tokenStr, mock.AnythingOfType("jwt.Keyfunc")).Return(expected, nil) + + jwtSvc := _jwt.NewService(t.config, &jwtStrategy, &jwtUtil) + actual, err := jwtSvc.VerifyAuth(tokenStr) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), *expected, *actual) +} + +func (t *JwtServiceTest) TestVerifyAuthFailed() { + tokenStr := "invalidSignedToken" + expected := errors.New("invalid token") + + jwtStrategy := strategy.JwtStrategyMock{} + jwtUtil := utils.JwtUtilMock{} + + jwtUtil.On("ParseToken", tokenStr, mock.AnythingOfType("jwt.Keyfunc")).Return(nil, expected) + + jwtSvc := _jwt.NewService(t.config, &jwtStrategy, &jwtUtil) + actual, err := jwtSvc.VerifyAuth(tokenStr) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *JwtServiceTest) TestGetConfigSuccess() { + expected := &t.config + + jwtStrategy := strategy.JwtStrategyMock{} + jwtUtil := utils.JwtUtilMock{} + + jwtSvc := _jwt.NewService(t.config, &jwtStrategy, &jwtUtil) + actual := jwtSvc.GetConfig() + + assert.Equal(t.T(), *expected, *actual) +} diff --git a/internal/auth/token/strategy/jwt.strategy.go b/internal/auth/token/strategy/jwt.strategy.go new file mode 100644 index 0000000..f84f33d --- /dev/null +++ b/internal/auth/token/strategy/jwt.strategy.go @@ -0,0 +1,29 @@ +package strategy + +import ( + "fmt" + + "github.com/golang-jwt/jwt/v4" + + "github.com/pkg/errors" +) + +type JwtStrategy interface { + AuthDecode(token *jwt.Token) (interface{}, error) +} + +type jwtStrategyImpl struct { + secret string +} + +func NewJwtStrategy(secret string) JwtStrategy { + return &jwtStrategyImpl{secret: secret} +} + +func (s *jwtStrategyImpl) AuthDecode(token *jwt.Token) (interface{}, error) { + if _, isValid := token.Method.(*jwt.SigningMethodHMAC); !isValid { + return nil, errors.New(fmt.Sprintf("invalid token %v\n", token.Header["alg"])) + } + + return []byte(s.secret), nil +} diff --git a/internal/auth/token/strategy/jwt.strategy_test.go b/internal/auth/token/strategy/jwt.strategy_test.go new file mode 100644 index 0000000..865f8bb --- /dev/null +++ b/internal/auth/token/strategy/jwt.strategy_test.go @@ -0,0 +1,55 @@ +package strategy + +import ( + "fmt" + "github.com/golang-jwt/jwt/v4" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "testing" +) + +type JwtStrategyTest struct { + suite.Suite + secret string +} + +func TestJwtStrategy(t *testing.T) { + suite.Run(t, new(JwtStrategyTest)) +} + +func (t *JwtStrategyTest) SetupTest() { + secret := "testSecret" + + t.secret = secret +} + +func (t *JwtStrategyTest) TestAuthDecodeSuccess() { + token := &jwt.Token{ + Method: jwt.SigningMethodHS256, + } + expected := []byte(t.secret) + + jwtStrategy := NewJwtStrategy(t.secret) + actual, err := jwtStrategy.AuthDecode(token) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *JwtStrategyTest) TestAuthDecodeFailed() { + token := &jwt.Token{ + Method: jwt.SigningMethodES256, + Header: map[string]interface{}{ + "typ": "JWT", + "alg": jwt.SigningMethodES256.Alg(), + }, + } + expected := errors.New(fmt.Sprintf("invalid token %v\n", token.Header["alg"])) + + jwtStrategy := NewJwtStrategy(t.secret) + actual, err := jwtStrategy.AuthDecode(token) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected.Error(), err.Error()) +} diff --git a/internal/auth/token/test/token.service_test.go b/internal/auth/token/test/token.service_test.go new file mode 100644 index 0000000..f3e8aae --- /dev/null +++ b/internal/auth/token/test/token.service_test.go @@ -0,0 +1,739 @@ +package token + +import ( + "testing" + "time" + + "github.com/go-faker/faker/v4" + _jwt "github.com/golang-jwt/jwt/v4" + "github.com/golang/mock/gomock" + "github.com/google/uuid" + "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/auth/token" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + mock_cache "github.com/isd-sgcu/johnjud-gateway/mocks/repository/cache" + "github.com/isd-sgcu/johnjud-gateway/mocks/service/jwt" + "github.com/isd-sgcu/johnjud-gateway/mocks/utils" + authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" + "github.com/pkg/errors" + "github.com/redis/go-redis/v9" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type TokenServiceTest struct { + suite.Suite + userId string + role constant.Role + authSessionId string + accessToken string + refreshToken *uuid.UUID + jwtConfig *config.Jwt + validateToken string +} + +func TestTokenService(t *testing.T) { + suite.Run(t, new(TokenServiceTest)) +} + +func (t *TokenServiceTest) SetupTest() { + userId := faker.UUIDDigit() + role := constant.USER + authSessionId := faker.UUIDDigit() + accessToken := "testAccessToken" + refreshToken := uuid.New() + jwtConfig := &config.Jwt{ + Secret: "testSecret", + ExpiresIn: 3600, + RefreshTokenTTL: 604800, + Issuer: "testIssuer", + ResetTokenTTL: 900, + } + validateToken := "" + + t.userId = userId + t.role = role + t.authSessionId = authSessionId + t.accessToken = accessToken + t.refreshToken = &refreshToken + t.jwtConfig = jwtConfig + t.validateToken = validateToken +} + +func (t *TokenServiceTest) TestCreateCredentialSuccess() { + accessTokenCache := &dto.AccessTokenCache{ + Token: t.accessToken, + Role: t.role, + RefreshToken: t.refreshToken.String(), + } + refreshTokenCache := &dto.RefreshTokenCache{ + AuthSessionID: t.authSessionId, + UserID: t.userId, + Role: t.role, + } + + expected := authProto.Credential{ + AccessToken: t.accessToken, + RefreshToken: t.refreshToken.String(), + ExpiresIn: int32(t.jwtConfig.ExpiresIn), + } + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + jwtService.On("SignAuth", t.userId, t.role, t.authSessionId).Return(t.accessToken, nil) + jwtService.On("GetConfig").Return(t.jwtConfig) + uuidUtil.On("GetNewUUID").Return(t.refreshToken) + accessTokenRepo.EXPECT().SetValue(t.authSessionId, accessTokenCache, t.jwtConfig.ExpiresIn).Return(nil) + refreshTokenRepo.EXPECT().SetValue(t.refreshToken.String(), refreshTokenCache, t.jwtConfig.RefreshTokenTTL).Return(nil) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.CreateCredential(t.userId, t.role, t.authSessionId) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected.AccessToken, actual.AccessToken) + assert.Equal(t.T(), expected.RefreshToken, actual.RefreshToken) + assert.Equal(t.T(), expected.ExpiresIn, actual.ExpiresIn) +} + +func (t *TokenServiceTest) TestCreateCredentialSignAuthFailed() { + signAuthError := errors.New("Error while signing token") + expected := errors.New("Error while signing token") + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + jwtService.On("SignAuth", t.userId, t.role, t.authSessionId).Return("", signAuthError) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.CreateCredential(t.userId, t.role, t.authSessionId) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected.Error(), err.Error()) +} + +func (t *TokenServiceTest) TestCreateCredentialSetAccessTokenFailed() { + accessTokenCache := &dto.AccessTokenCache{ + Token: t.accessToken, + Role: t.role, + RefreshToken: t.refreshToken.String(), + } + setCacheErr := errors.New("Internal server error") + expected := setCacheErr + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + jwtService.On("SignAuth", t.userId, t.role, t.authSessionId).Return(t.accessToken, nil) + jwtService.On("GetConfig").Return(t.jwtConfig) + uuidUtil.On("GetNewUUID").Return(t.refreshToken) + accessTokenRepo.EXPECT().SetValue(t.authSessionId, accessTokenCache, t.jwtConfig.ExpiresIn).Return(setCacheErr) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.CreateCredential(t.userId, t.role, t.authSessionId) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected.Error(), err.Error()) +} + +func (t *TokenServiceTest) TestCreateCredentialSetRefreshTokenFailed() { + accessTokenCache := &dto.AccessTokenCache{ + Token: t.accessToken, + Role: t.role, + RefreshToken: t.refreshToken.String(), + } + refreshTokenCache := &dto.RefreshTokenCache{ + AuthSessionID: t.authSessionId, + UserID: t.userId, + Role: t.role, + } + setCacheErr := errors.New("Internal server error") + expected := setCacheErr + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + jwtService.On("SignAuth", t.userId, t.role, t.authSessionId).Return(t.accessToken, nil) + jwtService.On("GetConfig").Return(t.jwtConfig) + uuidUtil.On("GetNewUUID").Return(t.refreshToken) + accessTokenRepo.EXPECT().SetValue(t.authSessionId, accessTokenCache, t.jwtConfig.ExpiresIn).Return(nil) + refreshTokenRepo.EXPECT().SetValue(t.refreshToken.String(), refreshTokenCache, t.jwtConfig.RefreshTokenTTL).Return(setCacheErr) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.CreateCredential(t.userId, t.role, t.authSessionId) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected.Error(), err.Error()) +} + +func (t *TokenServiceTest) TestValidateSuccess() { + expected := &dto.UserCredential{ + UserID: t.userId, + Role: "", + AuthSessionID: t.authSessionId, + RefreshToken: "", + } + payloads := _jwt.MapClaims{ + "iss": t.jwtConfig.Issuer, + "exp": float64(_jwt.NewNumericDate(time.Now().Add(time.Second * time.Duration(t.jwtConfig.ExpiresIn))).Unix()), + "iat": float64(_jwt.NewNumericDate(time.Now()).Unix()), + "user_id": t.userId, + "auth_session_id": t.authSessionId, + } + jwtToken := &_jwt.Token{ + Method: _jwt.SigningMethodHS256, + Claims: payloads, + } + accessTokenCache := &dto.AccessTokenCache{} + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + jwtService.On("VerifyAuth", t.validateToken).Return(jwtToken, nil) + jwtService.On("GetConfig").Return(t.jwtConfig) + accessTokenRepo.EXPECT().GetValue(payloads["auth_session_id"].(string), accessTokenCache).Return(nil) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.Validate(t.validateToken) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), *expected, *actual) +} + +func (t *TokenServiceTest) TestValidateInvalidIssuer() { + expected := errors.New("invalid token") + + payloads := _jwt.MapClaims{ + "iss": "invalid issuer", + "exp": float64(_jwt.NewNumericDate(time.Now().Add(time.Second * time.Duration(t.jwtConfig.ExpiresIn))).Unix()), + "iat": float64(_jwt.NewNumericDate(time.Now()).Unix()), + "user_id": t.userId, + "auth_session_id": t.authSessionId, + } + + jwtToken := &_jwt.Token{ + Method: _jwt.SigningMethodHS256, + Claims: payloads, + } + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + jwtService.On("VerifyAuth", t.validateToken).Return(jwtToken, nil) + jwtService.On("GetConfig").Return(t.jwtConfig) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.Validate(t.validateToken) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected.Error(), err.Error()) +} + +func (t *TokenServiceTest) TestValidateExpireToken() { + expected := errors.New("expired token") + + payloads := _jwt.MapClaims{ + "iss": t.jwtConfig.Issuer, + "exp": float64(_jwt.NewNumericDate(time.Now().Add(time.Second * (-time.Duration(t.jwtConfig.ExpiresIn)))).Unix()), + "iat": float64(_jwt.NewNumericDate(time.Now()).Unix()), + "user_id": t.userId, + "auth_session_id": t.authSessionId, + } + jwtToken := &_jwt.Token{ + Method: _jwt.SigningMethodHS256, + Claims: payloads, + } + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + jwtService.On("VerifyAuth", t.validateToken).Return(jwtToken, nil) + jwtService.On("GetConfig").Return(t.jwtConfig) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.Validate(t.validateToken) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected.Error(), err.Error()) +} + +func (t *TokenServiceTest) TestValidateVerifyFailed() { + expected := errors.New("invalid token") + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + jwtService.On("VerifyAuth", t.validateToken).Return(nil, expected) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.Validate(t.validateToken) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected.Error(), err.Error()) +} + +func (t *TokenServiceTest) TestValidateGetCacheKeyNotFound() { + expected := errors.New("invalid token") + + payloads := _jwt.MapClaims{ + "iss": t.jwtConfig.Issuer, + "exp": float64(_jwt.NewNumericDate(time.Now().Add(time.Second * time.Duration(t.jwtConfig.ExpiresIn))).Unix()), + "iat": float64(_jwt.NewNumericDate(time.Now()).Unix()), + "user_id": t.userId, + "auth_session_id": t.authSessionId, + } + jwtToken := &_jwt.Token{ + Method: _jwt.SigningMethodHS256, + Claims: payloads, + } + accessTokenCache := &dto.AccessTokenCache{} + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + jwtService.On("VerifyAuth", t.validateToken).Return(jwtToken, nil) + jwtService.On("GetConfig").Return(t.jwtConfig) + accessTokenRepo.EXPECT().GetValue(payloads["auth_session_id"].(string), accessTokenCache).Return(redis.Nil) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.Validate(t.validateToken) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected.Error(), err.Error()) +} + +func (t *TokenServiceTest) TestValidateGetCacheInternalFailed() { + payloads := _jwt.MapClaims{ + "iss": t.jwtConfig.Issuer, + "exp": float64(_jwt.NewNumericDate(time.Now().Add(time.Second * time.Duration(t.jwtConfig.ExpiresIn))).Unix()), + "iat": float64(_jwt.NewNumericDate(time.Now()).Unix()), + "user_id": t.userId, + "auth_session_id": t.authSessionId, + } + jwtToken := &_jwt.Token{ + Method: _jwt.SigningMethodHS256, + Claims: payloads, + } + accessTokenCache := &dto.AccessTokenCache{} + getCacheErr := errors.New("internal server error") + + expected := getCacheErr + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + jwtService.On("VerifyAuth", t.validateToken).Return(jwtToken, nil) + jwtService.On("GetConfig").Return(t.jwtConfig) + accessTokenRepo.EXPECT().GetValue(payloads["auth_session_id"].(string), accessTokenCache).Return(getCacheErr) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.Validate(t.validateToken) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected.Error(), err.Error()) +} + +func (t *TokenServiceTest) TestValidateInvalidToken() { + invalidToken := faker.Word() + expected := errors.New("invalid token") + + payloads := _jwt.MapClaims{ + "iss": t.jwtConfig.Issuer, + "exp": float64(_jwt.NewNumericDate(time.Now().Add(time.Second * time.Duration(t.jwtConfig.ExpiresIn))).Unix()), + "iat": float64(_jwt.NewNumericDate(time.Now()).Unix()), + "user_id": t.userId, + "auth_session_id": t.authSessionId, + } + jwtToken := &_jwt.Token{ + Method: _jwt.SigningMethodHS256, + Claims: payloads, + } + accessTokenCache := &dto.AccessTokenCache{} + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + jwtService.On("VerifyAuth", invalidToken).Return(jwtToken, nil) + jwtService.On("GetConfig").Return(t.jwtConfig) + accessTokenRepo.EXPECT().GetValue(payloads["auth_session_id"].(string), accessTokenCache).Return(nil) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.Validate(invalidToken) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected.Error(), err.Error()) +} + +func (t *TokenServiceTest) TestCreateRefreshTokenSuccess() { + expected := t.refreshToken.String() + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + uuidUtil.On("GetNewUUID").Return(t.refreshToken) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual := tokenSvc.CreateRefreshToken() + + assert.Equal(t.T(), expected, actual) +} + +func (t *TokenServiceTest) TestRemoveAccessTokenCacheSuccess() { + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + accessTokenRepo.EXPECT().DeleteValue(t.authSessionId).Return(nil) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + err := tokenSvc.RemoveAccessTokenCache(t.authSessionId) + + assert.Nil(t.T(), err) +} + +func (t *TokenServiceTest) TestRemoveAccessTokenCacheDeleteInternalFailed() { + deleteAccessTokenCacheErr := errors.New("internal server error") + + expected := deleteAccessTokenCacheErr + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + accessTokenRepo.EXPECT().DeleteValue(t.authSessionId).Return(deleteAccessTokenCacheErr) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + err := tokenSvc.RemoveAccessTokenCache(t.authSessionId) + + assert.Equal(t.T(), expected, err) +} + +func (t *TokenServiceTest) TestFindRefreshTokenCacheSuccess() { + expected := &dto.RefreshTokenCache{} + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + refreshTokenRepo.EXPECT().GetValue(t.refreshToken.String(), &dto.RefreshTokenCache{}).Return(nil) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.FindRefreshTokenCache(t.refreshToken.String()) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *TokenServiceTest) TestFindRefreshTokenCacheInvalid() { + getCacheErr := redis.Nil + + expected := status.Error(codes.InvalidArgument, getCacheErr.Error()) + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + refreshTokenRepo.EXPECT().GetValue(t.refreshToken.String(), &dto.RefreshTokenCache{}).Return(getCacheErr) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.FindRefreshTokenCache(t.refreshToken.String()) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *TokenServiceTest) TestFindRefreshTokenCacheInternalError() { + getCacheErr := errors.New("internal server error") + + expected := status.Error(codes.Internal, getCacheErr.Error()) + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + refreshTokenRepo.EXPECT().GetValue(t.refreshToken.String(), &dto.RefreshTokenCache{}).Return(getCacheErr) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.FindRefreshTokenCache(t.refreshToken.String()) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *TokenServiceTest) TestRemoveRefreshTokenCacheSuccess() { + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + refreshTokenRepo.EXPECT().DeleteValue(t.refreshToken.String()).Return(nil) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + err := tokenSvc.RemoveRefreshTokenCache(t.refreshToken.String()) + + assert.Nil(t.T(), err) +} + +func (t *TokenServiceTest) TestRemoveRefreshTokenCacheDeleteInternalFailed() { + deleteRefreshTokenCacheErr := errors.New("internal server error") + + expected := deleteRefreshTokenCacheErr + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + refreshTokenRepo.EXPECT().DeleteValue(t.refreshToken.String()).Return(deleteRefreshTokenCacheErr) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + err := tokenSvc.RemoveRefreshTokenCache(t.refreshToken.String()) + + assert.Equal(t.T(), expected, err) +} + +func (t *TokenServiceTest) TestCreateResetPasswordTokenSuccess() { + tokenCache := &dto.ResetPasswordTokenCache{ + UserID: t.userId, + } + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + uuidUtil.On("GetNewUUID").Return(t.refreshToken) + jwtService.On("GetConfig").Return(t.jwtConfig) + resetPasswordTokenRepo.EXPECT().SetValue(t.refreshToken.String(), tokenCache, t.jwtConfig.ResetTokenTTL).Return(nil) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.CreateResetPasswordToken(t.userId) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), t.refreshToken.String(), actual) +} + +func (t *TokenServiceTest) TestCreateResetPasswordTokenFailed() { + tokenCache := &dto.ResetPasswordTokenCache{ + UserID: t.userId, + } + cacheErr := errors.New("Internal error") + + expected := cacheErr + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + uuidUtil.On("GetNewUUID").Return(t.refreshToken) + jwtService.On("GetConfig").Return(t.jwtConfig) + resetPasswordTokenRepo.EXPECT().SetValue(t.refreshToken.String(), tokenCache, t.jwtConfig.ResetTokenTTL).Return(cacheErr) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.CreateResetPasswordToken(t.userId) + + assert.Equal(t.T(), "", actual) + assert.Equal(t.T(), expected, err) +} + +func (t *TokenServiceTest) TestFindResetPasswordTokenSuccess() { + tokenCache := &dto.ResetPasswordTokenCache{} + + expected := tokenCache + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + resetPasswordTokenRepo.EXPECT().GetValue(t.refreshToken.String(), tokenCache).Return(nil) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.FindResetPasswordToken(t.refreshToken.String()) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *TokenServiceTest) TestFindResetPasswordTokenNotFound() { + tokenCache := &dto.ResetPasswordTokenCache{} + cacheErr := redis.Nil + + expected := status.Error(codes.InvalidArgument, cacheErr.Error()) + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + resetPasswordTokenRepo.EXPECT().GetValue(t.refreshToken.String(), tokenCache).Return(cacheErr) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.FindResetPasswordToken(t.refreshToken.String()) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *TokenServiceTest) TestFindResetPasswordTokenInternalError() { + tokenCache := &dto.ResetPasswordTokenCache{} + cacheErr := errors.New("Internal error") + + expected := status.Error(codes.Internal, cacheErr.Error()) + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + resetPasswordTokenRepo.EXPECT().GetValue(t.refreshToken.String(), tokenCache).Return(cacheErr) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + actual, err := tokenSvc.FindResetPasswordToken(t.refreshToken.String()) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *TokenServiceTest) TestRemoveResetPasswordTokenSuccess() { + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + resetPasswordTokenRepo.EXPECT().DeleteValue(t.refreshToken.String()).Return(nil) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + err := tokenSvc.RemoveResetPasswordToken(t.refreshToken.String()) + + assert.Nil(t.T(), err) +} + +func (t *TokenServiceTest) TestRemoveResetPasswordTokenFailed() { + cacheErr := errors.New("Internal error") + + expected := cacheErr + + controller := gomock.NewController(t.T()) + + jwtService := jwt.JwtServiceMock{} + accessTokenRepo := mock_cache.NewMockRepository(controller) + refreshTokenRepo := mock_cache.NewMockRepository(controller) + resetPasswordTokenRepo := mock_cache.NewMockRepository(controller) + uuidUtil := utils.UuidUtilMock{} + + resetPasswordTokenRepo.EXPECT().DeleteValue(t.refreshToken.String()).Return(cacheErr) + + tokenSvc := token.NewService(&jwtService, accessTokenRepo, refreshTokenRepo, resetPasswordTokenRepo, &uuidUtil) + err := tokenSvc.RemoveResetPasswordToken(t.refreshToken.String()) + + assert.Equal(t.T(), expected, err) +} diff --git a/internal/auth/token/token.service.go b/internal/auth/token/token.service.go new file mode 100644 index 0000000..4447c22 --- /dev/null +++ b/internal/auth/token/token.service.go @@ -0,0 +1,218 @@ +package token + +import ( + "time" + + _jwt "github.com/golang-jwt/jwt/v4" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/auth/jwt" + "github.com/isd-sgcu/johnjud-gateway/internal/cache" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-gateway/internal/utils" + authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" + "github.com/pkg/errors" + "github.com/redis/go-redis/v9" + "github.com/rs/zerolog/log" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type Service interface { + CreateCredential(userId string, role constant.Role, authSessionId string) (*authProto.Credential, error) + Validate(token string) (*dto.UserCredential, error) + CreateRefreshToken() string + RemoveAccessTokenCache(authSessionId string) error + FindRefreshTokenCache(refreshToken string) (*dto.RefreshTokenCache, error) + RemoveRefreshTokenCache(refreshToken string) error + CreateResetPasswordToken(userId string) (string, error) + FindResetPasswordToken(token string) (*dto.ResetPasswordTokenCache, error) + RemoveResetPasswordToken(token string) error +} + +type serviceImpl struct { + jwtService jwt.Service + accessTokenCache cache.Repository + refreshTokenCache cache.Repository + resetPasswordTokenCache cache.Repository + uuidUtil utils.IUuidUtil +} + +func NewService(jwtService jwt.Service, accessTokenCache cache.Repository, refreshTokenCache cache.Repository, resetPasswordTokenCache cache.Repository, uuidUtil utils.IUuidUtil) Service { + return &serviceImpl{ + jwtService: jwtService, + accessTokenCache: accessTokenCache, + refreshTokenCache: refreshTokenCache, + resetPasswordTokenCache: resetPasswordTokenCache, + uuidUtil: uuidUtil, + } +} + +func (s *serviceImpl) CreateCredential(userId string, role constant.Role, authSessionId string) (*authProto.Credential, error) { + accessToken, err := s.jwtService.SignAuth(userId, role, authSessionId) + if err != nil { + log.Error(). + Err(err). + Str("service", "token"). + Str("module", "CreateCredential"). + Msg("Error signing jwt access token") + return nil, err + } + + refreshToken := s.CreateRefreshToken() + jwtConf := s.jwtService.GetConfig() + + accessTokenCache := &dto.AccessTokenCache{ + Token: accessToken, + Role: role, + RefreshToken: refreshToken, + } + err = s.accessTokenCache.SetValue(authSessionId, accessTokenCache, jwtConf.ExpiresIn) + if err != nil { + log.Error(). + Err(err). + Str("service", "token"). + Str("module", "CreateCredential"). + Msg("Error setting value to access token cache") + return nil, err + } + + refreshTokenCache := &dto.RefreshTokenCache{ + AuthSessionID: authSessionId, + UserID: userId, + Role: role, + } + err = s.refreshTokenCache.SetValue(refreshToken, refreshTokenCache, jwtConf.RefreshTokenTTL) + if err != nil { + log.Error(). + Err(err). + Str("service", "token"). + Str("module", "CreateCredential"). + Msg("Error setting value to refresh token cache") + return nil, err + } + + credential := &authProto.Credential{ + AccessToken: accessToken, + RefreshToken: refreshToken, + ExpiresIn: int32(jwtConf.ExpiresIn), + } + + return credential, nil +} + +func (s *serviceImpl) Validate(token string) (*dto.UserCredential, error) { + jwtToken, err := s.jwtService.VerifyAuth(token) + if err != nil { + return nil, err + } + + payloads := jwtToken.Claims.(_jwt.MapClaims) + if payloads["iss"] != s.jwtService.GetConfig().Issuer { + return nil, errors.New("invalid token") + } + + if time.Unix(int64(payloads["exp"].(float64)), 0).Before(time.Now()) { + return nil, errors.New("expired token") + } + + accessTokenCache := &dto.AccessTokenCache{} + err = s.accessTokenCache.GetValue(payloads["auth_session_id"].(string), accessTokenCache) + if err != nil { + if err != redis.Nil { + return nil, err + } + return nil, errors.New("invalid token") + } + + if token != accessTokenCache.Token { + return nil, errors.New("invalid token") + } + + userCredential := &dto.UserCredential{ + UserID: payloads["user_id"].(string), + Role: accessTokenCache.Role, + AuthSessionID: payloads["auth_session_id"].(string), + RefreshToken: accessTokenCache.RefreshToken, + } + return userCredential, nil +} + +func (s *serviceImpl) CreateRefreshToken() string { + return s.uuidUtil.GetNewUUID().String() +} + +func (s *serviceImpl) RemoveAccessTokenCache(authSessionId string) error { + err := s.accessTokenCache.DeleteValue(authSessionId) + if err != nil { + if err != redis.Nil { + return err + } + } + + return nil +} + +func (s *serviceImpl) FindRefreshTokenCache(refreshToken string) (*dto.RefreshTokenCache, error) { + refreshTokenCache := &dto.RefreshTokenCache{} + err := s.refreshTokenCache.GetValue(refreshToken, refreshTokenCache) + if err != nil { + log.Error(). + Err(err). + Str("service", "token"). + Str("module", "FindRefreshTokenCache"). + Msg("Error getting value from redis") + if err != redis.Nil { + return nil, status.Error(codes.Internal, err.Error()) + } + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + return refreshTokenCache, nil +} + +func (s *serviceImpl) RemoveRefreshTokenCache(refreshToken string) error { + err := s.refreshTokenCache.DeleteValue(refreshToken) + if err != nil { + if err != redis.Nil { + return err + } + } + + return nil +} + +func (s *serviceImpl) CreateResetPasswordToken(userId string) (string, error) { + resetPasswordToken := s.CreateRefreshToken() + tokenCache := &dto.ResetPasswordTokenCache{ + UserID: userId, + } + err := s.resetPasswordTokenCache.SetValue(resetPasswordToken, tokenCache, s.jwtService.GetConfig().ResetTokenTTL) + if err != nil { + return "", err + } + return resetPasswordToken, nil +} + +func (s *serviceImpl) FindResetPasswordToken(token string) (*dto.ResetPasswordTokenCache, error) { + tokenCache := &dto.ResetPasswordTokenCache{} + err := s.resetPasswordTokenCache.GetValue(token, tokenCache) + if err != nil { + if err != redis.Nil { + return nil, status.Error(codes.Internal, err.Error()) + } + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + return tokenCache, nil +} + +func (s *serviceImpl) RemoveResetPasswordToken(token string) error { + err := s.resetPasswordTokenCache.DeleteValue(token) + if err != nil { + if err != redis.Nil { + return err + } + } + + return nil +} diff --git a/internal/cache/cache.repository.go b/internal/cache/cache.repository.go new file mode 100644 index 0000000..ce78d06 --- /dev/null +++ b/internal/cache/cache.repository.go @@ -0,0 +1,54 @@ +package cache + +import ( + "context" + "encoding/json" + "time" + + "github.com/redis/go-redis/v9" +) + +type Repository interface { + SetValue(key string, value interface{}, ttl int) error + GetValue(key string, value interface{}) error + DeleteValue(key string) error +} + +type repositoryImpl struct { + client *redis.Client +} + +func NewRepository(client *redis.Client) Repository { + return &repositoryImpl{client: client} +} + +func (r *repositoryImpl) SetValue(key string, value interface{}, ttl int) error { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + v, err := json.Marshal(value) + if err != nil { + return err + } + + return r.client.Set(ctx, key, v, time.Duration(ttl)*time.Second).Err() +} + +func (r *repositoryImpl) GetValue(key string, value interface{}) error { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + v, err := r.client.Get(ctx, key).Result() + if err != nil { + return err + } + + return json.Unmarshal([]byte(v), value) +} + +func (r *repositoryImpl) DeleteValue(key string) error { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + return r.client.Del(ctx, key).Err() +} diff --git a/internal/cache/test/cache.repository_test.go b/internal/cache/test/cache.repository_test.go new file mode 100644 index 0000000..90f181e --- /dev/null +++ b/internal/cache/test/cache.repository_test.go @@ -0,0 +1,78 @@ +package test + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/go-faker/faker/v4" + "github.com/isd-sgcu/johnjud-gateway/internal/cache" + "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/redis/go-redis/v9" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +type CacheRepositoryTest struct { + suite.Suite + cacheDb *redis.Client + cacheRepo cache.Repository + key string + value *dto.AccessTokenCache +} + +func TestCacheRepository(t *testing.T) { + suite.Run(t, new(CacheRepositoryTest)) +} + +func (t *CacheRepositoryTest) SetupTest() { + addr := fmt.Sprintf("%s:%d", "localhost", 6379) + cacheDb := redis.NewClient(&redis.Options{ + Addr: addr, + Password: "", + DB: 0, + }) + cacheRepo := cache.NewRepository(cacheDb) + key := faker.UUIDDigit() + value := &dto.AccessTokenCache{ + Token: faker.Word(), + RefreshToken: faker.UUIDDigit(), + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + err := cacheDb.FlushDB(ctx).Err() + assert.Nil(t.T(), err) + + err = cacheRepo.SetValue(key, value, 60) + assert.Nil(t.T(), err) + + t.cacheDb = cacheDb + t.cacheRepo = cacheRepo + t.key = key + t.value = value +} + +func (t *CacheRepositoryTest) TestSetValueSuccess() { + key := faker.UUIDDigit() + value := &dto.AccessTokenCache{ + Token: faker.Word(), + RefreshToken: faker.UUIDDigit(), + } + err := t.cacheRepo.SetValue(key, value, 60) + assert.Nil(t.T(), err) +} + +func (t *CacheRepositoryTest) TestGetValueSuccess() { + value := &dto.AccessTokenCache{} + err := t.cacheRepo.GetValue(t.key, value) + assert.Nil(t.T(), err) + assert.Equal(t.T(), t.value, value) +} + +func (t *CacheRepositoryTest) TestDeleteValueSuccess() { + err := t.cacheRepo.DeleteValue(t.key) + assert.Nil(t.T(), err) +} diff --git a/internal/dto/token.dto.go b/internal/dto/token.dto.go new file mode 100644 index 0000000..3aef3e7 --- /dev/null +++ b/internal/dto/token.dto.go @@ -0,0 +1,35 @@ +package dto + +import ( + "github.com/golang-jwt/jwt/v4" + "github.com/isd-sgcu/johnjud-gateway/constant" +) + +type UserCredential struct { + UserID string `json:"user_id"` + Role constant.Role `json:"role"` + AuthSessionID string `json:"auth_session_id"` + RefreshToken string `json:"refresh_token"` +} + +type AuthPayload struct { + jwt.RegisteredClaims + UserID string `json:"user_id"` + AuthSessionID string `json:"auth_session_id"` +} + +type AccessTokenCache struct { + Token string `json:"token"` + Role constant.Role `json:"role"` + RefreshToken string `json:"refresh_token"` +} + +type RefreshTokenCache struct { + AuthSessionID string `json:"auth_session_id"` + UserID string `json:"user_id"` + Role constant.Role `json:"role"` +} + +type ResetPasswordTokenCache struct { + UserID string `json:"user_id"` +} diff --git a/internal/middleware/auth/auth.middleware.go b/internal/middleware/auth/auth.middleware.go index 3e82039..956b681 100644 --- a/internal/middleware/auth/auth.middleware.go +++ b/internal/middleware/auth/auth.middleware.go @@ -15,11 +15,11 @@ type Guard struct { service auth.Service excludes map[string]struct{} adminpath map[string]struct{} - conf config.AppConfig + conf config.App versionList map[string]struct{} } -func NewAuthGuard(s auth.Service, e map[string]struct{}, a map[string]struct{}, conf config.AppConfig, versionList map[string]struct{}) Guard { +func NewAuthGuard(s auth.Service, e map[string]struct{}, a map[string]struct{}, conf config.App, versionList map[string]struct{}) Guard { return Guard{ service: s, excludes: e, diff --git a/internal/router/router.go b/internal/router/router.go index f27c81e..8b2eecc 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -22,7 +22,7 @@ type IGuard interface { Use(IContext) error } -func NewAPIv1(r *FiberRouter, conf config.AppConfig) *fiber.App { +func NewAPIv1(r *FiberRouter, conf config.App) *fiber.App { if conf.IsDevelopment() { r.Use(logger.New(logger.Config{Next: func(c *fiber.Ctx) bool { return c.Path() == "/v1/" @@ -41,7 +41,7 @@ func NewAPIv1(r *FiberRouter, conf config.AppConfig) *fiber.App { return app } -func NewFiberRouter(authGuard IGuard, conf config.AppConfig) *FiberRouter { +func NewFiberRouter(authGuard IGuard, conf config.App) *FiberRouter { r := fiber.New(fiber.Config{ BodyLimit: int(conf.MaxFileSize * 1024 * 1024), }) diff --git a/internal/utils/uuid.utils.go b/internal/utils/uuid.utils.go new file mode 100644 index 0000000..2480403 --- /dev/null +++ b/internal/utils/uuid.utils.go @@ -0,0 +1,18 @@ +package utils + +import "github.com/google/uuid" + +type IUuidUtil interface { + GetNewUUID() *uuid.UUID +} + +type uuidUtil struct{} + +func NewUuidUtil() IUuidUtil { + return &uuidUtil{} +} + +func (u *uuidUtil) GetNewUUID() *uuid.UUID { + uuid := uuid.New() + return &uuid +} diff --git a/mocks/repository/cache/cache.mock.go b/mocks/repository/cache/cache.mock.go new file mode 100644 index 0000000..306d388 --- /dev/null +++ b/mocks/repository/cache/cache.mock.go @@ -0,0 +1,76 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./internal/cache/cache.repository.go + +// Package mock_cache is a generated GoMock package. +package mock_cache + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockRepository is a mock of Repository interface. +type MockRepository struct { + ctrl *gomock.Controller + recorder *MockRepositoryMockRecorder +} + +// MockRepositoryMockRecorder is the mock recorder for MockRepository. +type MockRepositoryMockRecorder struct { + mock *MockRepository +} + +// NewMockRepository creates a new mock instance. +func NewMockRepository(ctrl *gomock.Controller) *MockRepository { + mock := &MockRepository{ctrl: ctrl} + mock.recorder = &MockRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { + return m.recorder +} + +// DeleteValue mocks base method. +func (m *MockRepository) DeleteValue(key string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteValue", key) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteValue indicates an expected call of DeleteValue. +func (mr *MockRepositoryMockRecorder) DeleteValue(key interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteValue", reflect.TypeOf((*MockRepository)(nil).DeleteValue), key) +} + +// GetValue mocks base method. +func (m *MockRepository) GetValue(key string, value interface{}) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetValue", key, value) + ret0, _ := ret[0].(error) + return ret0 +} + +// GetValue indicates an expected call of GetValue. +func (mr *MockRepositoryMockRecorder) GetValue(key, value interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValue", reflect.TypeOf((*MockRepository)(nil).GetValue), key, value) +} + +// SetValue mocks base method. +func (m *MockRepository) SetValue(key string, value interface{}, ttl int) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetValue", key, value, ttl) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetValue indicates an expected call of SetValue. +func (mr *MockRepositoryMockRecorder) SetValue(key, value, ttl interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetValue", reflect.TypeOf((*MockRepository)(nil).SetValue), key, value, ttl) +} diff --git a/mocks/service/jwt/jwt.mock.go b/mocks/service/jwt/jwt.mock.go new file mode 100644 index 0000000..458da93 --- /dev/null +++ b/mocks/service/jwt/jwt.mock.go @@ -0,0 +1,35 @@ +package jwt + +import ( + "github.com/golang-jwt/jwt/v4" + "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/stretchr/testify/mock" +) + +type JwtServiceMock struct { + mock.Mock +} + +func (m *JwtServiceMock) SignAuth(userId string, role constant.Role, authSessionId string) (string, error) { + args := m.Called(userId, role, authSessionId) + if args.Get(0) != "" { + return args.Get(0).(string), nil + } + + return "", args.Error(1) +} + +func (m *JwtServiceMock) VerifyAuth(token string) (*jwt.Token, error) { + args := m.Called(token) + if args.Get(0) != nil { + return args.Get(0).(*jwt.Token), nil + } + + return nil, args.Error(1) +} + +func (m *JwtServiceMock) GetConfig() *config.Jwt { + args := m.Called() + return args.Get(0).(*config.Jwt) +} diff --git a/mocks/service/token/token.mock.go b/mocks/service/token/token.mock.go new file mode 100644 index 0000000..ee299f7 --- /dev/null +++ b/mocks/service/token/token.mock.go @@ -0,0 +1,168 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./internal/auth/token/token.service.go + +// Package mock_token is a generated GoMock package. +package mock_token + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + constant "github.com/isd-sgcu/johnjud-gateway/constant" + dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" + v1 "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" +) + +// 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 +} + +// CreateCredential mocks base method. +func (m *MockService) CreateCredential(userId string, role constant.Role, authSessionId string) (*v1.Credential, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateCredential", userId, role, authSessionId) + ret0, _ := ret[0].(*v1.Credential) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateCredential indicates an expected call of CreateCredential. +func (mr *MockServiceMockRecorder) CreateCredential(userId, role, authSessionId interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateCredential", reflect.TypeOf((*MockService)(nil).CreateCredential), userId, role, authSessionId) +} + +// CreateRefreshToken mocks base method. +func (m *MockService) CreateRefreshToken() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateRefreshToken") + ret0, _ := ret[0].(string) + return ret0 +} + +// CreateRefreshToken indicates an expected call of CreateRefreshToken. +func (mr *MockServiceMockRecorder) CreateRefreshToken() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRefreshToken", reflect.TypeOf((*MockService)(nil).CreateRefreshToken)) +} + +// CreateResetPasswordToken mocks base method. +func (m *MockService) CreateResetPasswordToken(userId string) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateResetPasswordToken", userId) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateResetPasswordToken indicates an expected call of CreateResetPasswordToken. +func (mr *MockServiceMockRecorder) CreateResetPasswordToken(userId interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateResetPasswordToken", reflect.TypeOf((*MockService)(nil).CreateResetPasswordToken), userId) +} + +// FindRefreshTokenCache mocks base method. +func (m *MockService) FindRefreshTokenCache(refreshToken string) (*dto.RefreshTokenCache, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindRefreshTokenCache", refreshToken) + ret0, _ := ret[0].(*dto.RefreshTokenCache) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FindRefreshTokenCache indicates an expected call of FindRefreshTokenCache. +func (mr *MockServiceMockRecorder) FindRefreshTokenCache(refreshToken interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindRefreshTokenCache", reflect.TypeOf((*MockService)(nil).FindRefreshTokenCache), refreshToken) +} + +// FindResetPasswordToken mocks base method. +func (m *MockService) FindResetPasswordToken(token string) (*dto.ResetPasswordTokenCache, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindResetPasswordToken", token) + ret0, _ := ret[0].(*dto.ResetPasswordTokenCache) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FindResetPasswordToken indicates an expected call of FindResetPasswordToken. +func (mr *MockServiceMockRecorder) FindResetPasswordToken(token interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindResetPasswordToken", reflect.TypeOf((*MockService)(nil).FindResetPasswordToken), token) +} + +// RemoveAccessTokenCache mocks base method. +func (m *MockService) RemoveAccessTokenCache(authSessionId string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveAccessTokenCache", authSessionId) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveAccessTokenCache indicates an expected call of RemoveAccessTokenCache. +func (mr *MockServiceMockRecorder) RemoveAccessTokenCache(authSessionId interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveAccessTokenCache", reflect.TypeOf((*MockService)(nil).RemoveAccessTokenCache), authSessionId) +} + +// RemoveRefreshTokenCache mocks base method. +func (m *MockService) RemoveRefreshTokenCache(refreshToken string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveRefreshTokenCache", refreshToken) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveRefreshTokenCache indicates an expected call of RemoveRefreshTokenCache. +func (mr *MockServiceMockRecorder) RemoveRefreshTokenCache(refreshToken interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveRefreshTokenCache", reflect.TypeOf((*MockService)(nil).RemoveRefreshTokenCache), refreshToken) +} + +// RemoveResetPasswordToken mocks base method. +func (m *MockService) RemoveResetPasswordToken(token string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveResetPasswordToken", token) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveResetPasswordToken indicates an expected call of RemoveResetPasswordToken. +func (mr *MockServiceMockRecorder) RemoveResetPasswordToken(token interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveResetPasswordToken", reflect.TypeOf((*MockService)(nil).RemoveResetPasswordToken), token) +} + +// Validate mocks base method. +func (m *MockService) Validate(token string) (*dto.UserCredential, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Validate", token) + ret0, _ := ret[0].(*dto.UserCredential) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Validate indicates an expected call of Validate. +func (mr *MockServiceMockRecorder) Validate(token interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Validate", reflect.TypeOf((*MockService)(nil).Validate), token) +} diff --git a/mocks/strategy/strategy.mock.go b/mocks/strategy/strategy.mock.go new file mode 100644 index 0000000..fe71def --- /dev/null +++ b/mocks/strategy/strategy.mock.go @@ -0,0 +1,18 @@ +package strategy + +import ( + "github.com/golang-jwt/jwt/v4" + "github.com/stretchr/testify/mock" +) + +type JwtStrategyMock struct { + mock.Mock +} + +func (m *JwtStrategyMock) AuthDecode(token *jwt.Token) (interface{}, error) { + args := m.Called(token) + if args.Get(0) != nil { + return args.Get(0), nil + } + return nil, args.Error(1) +} diff --git a/mocks/utils/bcrypt.mock.go b/mocks/utils/bcrypt.mock.go new file mode 100644 index 0000000..0881d92 --- /dev/null +++ b/mocks/utils/bcrypt.mock.go @@ -0,0 +1,25 @@ +package utils + +import "github.com/stretchr/testify/mock" + +type BcryptUtilMock struct { + mock.Mock +} + +func (m *BcryptUtilMock) GenerateHashedPassword(password string) (string, error) { + args := m.Called(password) + if args.Get(0) != "" { + return args.Get(0).(string), nil + } + + return "", args.Error(1) +} + +func (m *BcryptUtilMock) CompareHashedPassword(hashedPassword string, plainPassword string) error { + args := m.Called(hashedPassword, plainPassword) + if args.Get(0) == nil { + return nil + } + + return args.Error(0) +} diff --git a/mocks/utils/jwt.mock.go b/mocks/utils/jwt.mock.go new file mode 100644 index 0000000..f2f8746 --- /dev/null +++ b/mocks/utils/jwt.mock.go @@ -0,0 +1,39 @@ +package utils + +import ( + "github.com/golang-jwt/jwt/v4" + "github.com/stretchr/testify/mock" + "time" +) + +type JwtUtilMock struct { + mock.Mock +} + +func (m *JwtUtilMock) GenerateJwtToken(method jwt.SigningMethod, payloads jwt.Claims) *jwt.Token { + args := m.Called(method, payloads) + return args.Get(0).(*jwt.Token) +} + +func (m *JwtUtilMock) GetNumericDate(time time.Time) *jwt.NumericDate { + args := m.Called(time) + return args.Get(0).(*jwt.NumericDate) +} + +func (m *JwtUtilMock) SignedTokenString(token *jwt.Token, secret string) (string, error) { + args := m.Called(token, secret) + if args.Get(0) != "" { + return args.Get(0).(string), nil + } + + return "", args.Error(1) +} + +func (m *JwtUtilMock) ParseToken(tokenStr string, keyFunc jwt.Keyfunc) (*jwt.Token, error) { + args := m.Called(tokenStr, keyFunc) + if args.Get(0) != nil { + return args.Get(0).(*jwt.Token), nil + } + + return nil, args.Error(1) +} diff --git a/mocks/utils/uuid.mock.go b/mocks/utils/uuid.mock.go new file mode 100644 index 0000000..537cdf3 --- /dev/null +++ b/mocks/utils/uuid.mock.go @@ -0,0 +1,15 @@ +package utils + +import ( + "github.com/google/uuid" + "github.com/stretchr/testify/mock" +) + +type UuidUtilMock struct { + mock.Mock +} + +func (m *UuidUtilMock) GetNewUUID() *uuid.UUID { + args := m.Called() + return args.Get(0).(*uuid.UUID) +} From b45903fa4f659c0daa83cc360ba69416509015a4 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 23:00:10 +0700 Subject: [PATCH 086/104] migrate auth --- Makefile | 2 +- cmd/main.go | 59 +- database/postgresql.connection.go | 29 + database/redis.connection.go | 24 + go.mod | 18 +- go.sum | 16 + internal/auth/auth.repository.go | 27 + internal/auth/auth.service.go | 494 ++++------- internal/auth/jwt/jwt.strategy.go | 29 + internal/auth/test/auth.service_test.go | 839 ------------------ .../auth/token/test/token.service_test.go | 5 +- internal/auth/token/token.service.go | 9 +- internal/dto/common.dto.go | 30 + internal/user/test/user.handler_test.go | 365 -------- internal/user/test/user.service_test.go | 295 ++---- internal/user/user.repository.go | 47 + internal/user/user.service.go | 172 ++-- internal/utils/bcrypt.utils.go | 23 + internal/utils/common.utils.go | 5 +- mocks/repository/auth/auth.mock.go | 63 ++ mocks/repository/user/user.mock.go | 66 ++ mocks/service/email/email.service.go | 5 + 22 files changed, 738 insertions(+), 1884 deletions(-) create mode 100644 database/postgresql.connection.go create mode 100644 database/redis.connection.go create mode 100644 internal/auth/auth.repository.go create mode 100644 internal/auth/jwt/jwt.strategy.go delete mode 100644 internal/auth/test/auth.service_test.go delete mode 100644 internal/user/test/user.handler_test.go create mode 100644 internal/user/user.repository.go create mode 100644 internal/utils/bcrypt.utils.go create mode 100644 mocks/repository/auth/auth.mock.go create mode 100644 mocks/repository/user/user.mock.go create mode 100644 mocks/service/email/email.service.go diff --git a/Makefile b/Makefile index b30b5f7..5d2984c 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ docker-qa: mock-gen: mockgen -source ./internal/cache/cache.repository.go -destination ./mocks/repository/cache/cache.mock.go - mockgen -source ./internal/auth/token/token.service.go -destination ./mocks/service/token/token.mock.go + mockgen -source ./internal/auth/auth.repository.go -destination ./mocks/repository/auth/auth.mock.go mockgen -source ./internal/auth/auth.service.go -destination ./mocks/service/auth/auth.mock.go mockgen -source ./internal/user/user.service.go -destination ./mocks/service/user/user.mock.go mockgen -source ./internal/pet/pet.service.go -destination ./mocks/service/pet/pet.mock.go diff --git a/cmd/main.go b/cmd/main.go index 9baf3f8..5671043 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -12,16 +12,20 @@ import ( "github.com/isd-sgcu/johnjud-gateway/config" "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/database" "github.com/isd-sgcu/johnjud-gateway/internal/auth" + "github.com/isd-sgcu/johnjud-gateway/internal/auth/email" + "github.com/isd-sgcu/johnjud-gateway/internal/auth/jwt" + "github.com/isd-sgcu/johnjud-gateway/internal/auth/token" + "github.com/isd-sgcu/johnjud-gateway/internal/cache" "github.com/isd-sgcu/johnjud-gateway/internal/healthcheck" "github.com/isd-sgcu/johnjud-gateway/internal/image" guard "github.com/isd-sgcu/johnjud-gateway/internal/middleware/auth" "github.com/isd-sgcu/johnjud-gateway/internal/pet" "github.com/isd-sgcu/johnjud-gateway/internal/router" "github.com/isd-sgcu/johnjud-gateway/internal/user" + "github.com/isd-sgcu/johnjud-gateway/internal/utils" "github.com/isd-sgcu/johnjud-gateway/internal/validator" - authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" - userProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" imageProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" "github.com/rs/zerolog/log" @@ -64,27 +68,35 @@ func main() { Msg("Failed to start service") } - v, err := validator.NewIValidator() + db, err := database.InitPostgresDatabase(&conf.Database, conf.App.IsDevelopment()) if err != nil { log.Fatal(). Err(err). - Str("service", "validator"). - Msg("Failed to start service") + Str("service", "auth"). + Msg("Failed to init postgres connection") } - backendConn, err := grpc.Dial(conf.Service.Backend, grpc.WithTransportCredentials(insecure.NewCredentials())) + cacheDb, err := database.InitRedisConnection(&conf.Redis) if err != nil { log.Fatal(). Err(err). - Str("service", "johnjud-backend"). - Msg("Cannot connect to service") + Str("service", "auth"). + Msg("Failed to init redis connection") + } + + v, err := validator.NewIValidator() + if err != nil { + log.Fatal(). + Err(err). + Str("service", "validator"). + Msg("Failed to start service") } - authConn, err := grpc.Dial(conf.Service.Auth, grpc.WithTransportCredentials(insecure.NewCredentials())) + backendConn, err := grpc.Dial(conf.Service.Backend, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { log.Fatal(). Err(err). - Str("service", "johnjud-auth"). + Str("service", "johnjud-backend"). Msg("Cannot connect to service") } @@ -98,15 +110,28 @@ func main() { hc := healthcheck.NewHandler() - userClient := userProto.NewUserServiceClient(authConn) - userService := user.NewService(userClient) - userHandler := user.NewHandler(userService, v) + uuidUtil := utils.NewUuidUtil() + bcryptUtil := utils.NewBcryptUtil() + + accessTokenCache := cache.NewRepository(cacheDb) + refreshTokenCache := cache.NewRepository(cacheDb) + resetPasswordCache := cache.NewRepository(cacheDb) + + bcryptUtils := utils.NewBcryptUtil() + userRepo := user.NewRepository(db) + userSvc := user.NewService(userRepo, bcryptUtils) + userHandler := user.NewHandler(userSvc, v) - authClient := authProto.NewAuthServiceClient(authConn) - authService := auth.NewService(authClient) - authHandler := auth.NewHandler(authService, userService, v) + jwtStrat := jwt.NewJwtStrategy(conf.Jwt.Secret) + jwtUtils := jwt.NewJwtUtil() + jwtSvc := jwt.NewService(conf.Jwt, jwtStrat, jwtUtils) + tokenSvc := token.NewService(jwtSvc, accessTokenCache, refreshTokenCache, resetPasswordCache, uuidUtil) + emailSvc := email.NewService(conf.Sendgrid) + authRepo := auth.NewRepository(db) + authSvc := auth.NewService(authRepo, userRepo, tokenSvc, emailSvc, bcryptUtil, conf.Auth) + authHandler := auth.NewHandler(authSvc, userSvc, v) - authGuard := guard.NewAuthGuard(authService, constant.ExcludePath, constant.AdminPath, conf.App, constant.VersionList) + authGuard := guard.NewAuthGuard(authSvc, constant.ExcludePath, constant.AdminPath, conf.App, constant.VersionList) imageClient := imageProto.NewImageServiceClient(fileConn) imageService := image.NewService(imageClient) diff --git a/database/postgresql.connection.go b/database/postgresql.connection.go new file mode 100644 index 0000000..9d1135f --- /dev/null +++ b/database/postgresql.connection.go @@ -0,0 +1,29 @@ +package database + +import ( + "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "gorm.io/driver/postgres" + "gorm.io/gorm" + gormLogger "gorm.io/gorm/logger" +) + +func InitPostgresDatabase(conf *config.Database, isDebug bool) (db *gorm.DB, err error) { + gormConf := &gorm.Config{TranslateError: true} + + if !isDebug { + gormConf.Logger = gormLogger.Default.LogMode(gormLogger.Silent) + } + + db, err = gorm.Open(postgres.Open(conf.Url), gormConf) + if err != nil { + return nil, err + } + + err = db.AutoMigrate(&model.User{}, &model.AuthSession{}) + if err != nil { + return nil, err + } + + return +} diff --git a/database/redis.connection.go b/database/redis.connection.go new file mode 100644 index 0000000..e7158bb --- /dev/null +++ b/database/redis.connection.go @@ -0,0 +1,24 @@ +package database + +import ( + "fmt" + + "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/pkg/errors" + "github.com/redis/go-redis/v9" +) + +func InitRedisConnection(conf *config.Redis) (*redis.Client, error) { + addr := fmt.Sprintf("%s:%d", conf.Host, conf.Port) + + cache := redis.NewClient(&redis.Options{ + Addr: addr, + Password: conf.Password, + }) + + if cache == nil { + return nil, errors.New("Failed to connect to redis server") + } + + return cache, nil +} diff --git a/go.mod b/go.mod index 0dbf899..d223bf8 100644 --- a/go.mod +++ b/go.mod @@ -10,14 +10,21 @@ require ( github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/validator/v10 v10.16.0 github.com/gofiber/fiber/v2 v2.52.0 + github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang/mock v1.6.0 github.com/google/uuid v1.6.0 github.com/isd-sgcu/johnjud-go-proto v0.7.1 github.com/joho/godotenv v1.5.1 + github.com/pkg/errors v0.9.1 + github.com/redis/go-redis/v9 v9.6.1 github.com/rs/zerolog v1.31.0 + github.com/sendgrid/sendgrid-go v3.15.0+incompatible github.com/stretchr/testify v1.8.4 github.com/swaggo/swag v1.16.2 + golang.org/x/crypto v0.19.0 google.golang.org/grpc v1.63.2 + gorm.io/driver/postgres v1.5.9 + gorm.io/gorm v1.25.11 ) require ( @@ -31,7 +38,10 @@ require ( github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/spec v0.20.13 // indirect github.com/go-openapi/swag v0.22.7 // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgx/v5 v5.5.5 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -41,24 +51,20 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/redis/go-redis/v9 v9.6.1 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/sendgrid/rest v2.6.9+incompatible // indirect - github.com/sendgrid/sendgrid-go v3.15.0+incompatible // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/swaggo/files v1.0.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.51.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect - golang.org/x/crypto v0.19.0 // indirect golang.org/x/net v0.21.0 // indirect + golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.17.0 // indirect 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-20240227224415-6ceb2ff114de // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - gorm.io/gorm v1.25.11 // indirect ) diff --git a/go.sum b/go.sum index f5688ec..37e2548 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,10 @@ github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sx github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/arsmn/fiber-swagger/v2 v2.31.1 h1:VmX+flXiGGNqLX3loMEEzL3BMOZFSPwBEWR04GA6Mco= github.com/arsmn/fiber-swagger/v2 v2.31.1/go.mod h1:ZHhMprtB3M6jd2mleG03lPGhHH0lk9u3PtfWS1cBhMA= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/bxcodec/faker/v4 v4.0.0-beta.3 h1:gqYNBvN72QtzKkYohNDKQlm+pg+uwBDVMN28nWHS18k= github.com/bxcodec/faker/v4 v4.0.0-beta.3/go.mod h1:m6+Ch1Lj3fqW/unZmvkXIdxWS5+XQWPWxcbbQW2X+Ho= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -64,6 +68,14 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/isd-sgcu/johnjud-go-proto v0.7.1 h1:sdwyEvFcGoLmoypjOuZRgQZGeuX9jcXdiPcUWJw3VoA= github.com/isd-sgcu/johnjud-go-proto v0.7.1/go.mod h1:C1oOvRz1bYqX2EGG3Iy+1mbB9buvhwudR/hYwWKkAwE= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= @@ -182,6 +194,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -240,5 +254,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8= +gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI= gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg= gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= diff --git a/internal/auth/auth.repository.go b/internal/auth/auth.repository.go new file mode 100644 index 0000000..d62c331 --- /dev/null +++ b/internal/auth/auth.repository.go @@ -0,0 +1,27 @@ +package auth + +import ( + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "gorm.io/gorm" +) + +type Repository interface { + Create(auth *model.AuthSession) error + Delete(id string) error +} + +type repositoryImpl struct { + Db *gorm.DB +} + +func NewRepository(db *gorm.DB) Repository { + return &repositoryImpl{Db: db} +} + +func (r *repositoryImpl) Create(auth *model.AuthSession) error { + return r.Db.Create(auth).Error +} + +func (r *repositoryImpl) Delete(id string) error { + return r.Db.Delete(&model.AuthSession{}, "id = ?", id).Error +} diff --git a/internal/auth/auth.service.go b/internal/auth/auth.service.go index 702dfe3..248d081 100644 --- a/internal/auth/auth.service.go +++ b/internal/auth/auth.service.go @@ -1,407 +1,243 @@ package auth import ( - "context" + "fmt" "net/http" - "time" + "github.com/isd-sgcu/johnjud-gateway/config" "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-gateway/internal/auth/email" + "github.com/isd-sgcu/johnjud-gateway/internal/auth/token" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-gateway/internal/user" + "github.com/isd-sgcu/johnjud-gateway/internal/utils" "github.com/rs/zerolog/log" + + "github.com/pkg/errors" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "gorm.io/gorm" ) type Service interface { - Signup(*dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) - SignIn(*dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) - SignOut(string) (*dto.SignOutResponse, *dto.ResponseErr) - Validate(string) (*dto.TokenPayloadAuth, *dto.ResponseErr) - RefreshToken(*dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) - ForgotPassword(*dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) - ResetPassword(*dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) + Validate(refreshToken string) (*dto.TokenPayloadAuth, *dto.ResponseErr) + RefreshToken(request *dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) + Signup(request *dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) + SignIn(request *dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) + SignOut(accessToken string) (*dto.SignOutResponse, *dto.ResponseErr) + ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) + ResetPassword(request *dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) } type serviceImpl struct { - client authProto.AuthServiceClient + authRepo Repository + userRepo user.Repository + tokenService token.Service + emailService email.Service + bcryptUtil utils.IBcryptUtil + config config.Auth } -func NewService(client authProto.AuthServiceClient) Service { +func NewService(authRepo Repository, userRepo user.Repository, tokenService token.Service, emailService email.Service, bcryptUtil utils.IBcryptUtil, config config.Auth) Service { return &serviceImpl{ - client: client, + authRepo: authRepo, + userRepo: userRepo, + tokenService: tokenService, + emailService: emailService, + bcryptUtil: bcryptUtil, + config: config, } } -func (s *serviceImpl) Signup(request *dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - resp, err := s.client.SignUp(ctx, &authProto.SignUpRequest{ - FirstName: request.Firstname, - LastName: request.Lastname, - Email: request.Email, - Password: request.Password, - }) +func (s *serviceImpl) Validate(refreshToken string) (*dto.TokenPayloadAuth, *dto.ResponseErr) { + userCredential, err := s.tokenService.Validate(refreshToken) if err != nil { - st, ok := status.FromError(err) - log.Error(). - Str("service", "auth"). - Str("action", "SignUp"). - Str("email", request.Email). - Msg(st.Message()) - if !ok { - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } - switch st.Code() { - case codes.AlreadyExists: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusConflict, - Message: constant.DuplicateEmailMessage, - Data: nil, - } - case codes.Internal: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } + return nil, &dto.ResponseErr{ + StatusCode: http.StatusUnauthorized, + Message: constant.InvalidTokenErrorMessage, } } - log.Info(). - Str("service", "auth"). - Str("action", "SignUp"). - Str("email", request.Email). - Msg("sign up successfully") - return &dto.SignupResponse{ - Id: resp.Id, - Email: resp.Email, - Firstname: resp.FirstName, - Lastname: resp.LastName, + return &dto.TokenPayloadAuth{ + UserId: userCredential.UserID, + Role: string(userCredential.Role), }, nil } -func (s *serviceImpl) SignIn(request *dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - resp, err := s.client.SignIn(ctx, &authProto.SignInRequest{ - Email: request.Email, - Password: request.Password, - }) +func (s *serviceImpl) RefreshToken(request *dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) { + refreshTokenCache, err := s.tokenService.FindRefreshTokenCache(request.RefreshToken) if err != nil { - st, ok := status.FromError(err) - log.Error(). - Str("service", "auth"). - Str("action", "SignIn"). - Str("email", request.Email). - Msg(st.Message()) - if !ok { - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } + st, _ := status.FromError(err) switch st.Code() { - case codes.PermissionDenied: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusForbidden, - Message: constant.IncorrectEmailPasswordMessage, - Data: nil, - } - case codes.Internal: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } + case codes.InvalidArgument: + return nil, dto.BadRequestError(constant.InvalidTokenErrorMessage) default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) } } + credential, err := s.tokenService.CreateCredential(refreshTokenCache.UserID, refreshTokenCache.Role, refreshTokenCache.AuthSessionID) + if err != nil { + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } - log.Info(). - Str("service", "auth"). - Str("action", "SignIn"). - Str("email", request.Email). - Msg("sign in successfully") - return &dto.Credential{ - AccessToken: resp.Credential.AccessToken, - RefreshToken: resp.Credential.RefreshToken, - ExpiresIn: int(resp.Credential.ExpiresIn), - }, nil + err = s.tokenService.RemoveRefreshTokenCache(request.RefreshToken) + if err != nil { + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } + + return credential, nil } -func (s *serviceImpl) SignOut(token string) (*dto.SignOutResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() +func (s *serviceImpl) Signup(request *dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) { + hashPassword, err := s.bcryptUtil.GenerateHashedPassword(request.Password) + if err != nil { + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } - response, err := s.client.SignOut(ctx, &authProto.SignOutRequest{ - Token: token, - }) + createUser := &model.User{ + Email: request.Email, + Password: hashPassword, + Firstname: request.Firstname, + Lastname: request.Lastname, + Role: constant.USER, + } + err = s.userRepo.Create(createUser) if err != nil { - st, ok := status.FromError(err) - log.Error(). - Str("service", "auth"). - Str("action", "SignOut"). - Str("token", token). - Msg(st.Message()) - if !ok { - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } - switch st.Code() { - case codes.Internal: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } + if errors.Is(err, gorm.ErrDuplicatedKey) { + return nil, dto.ConflictError(constant.DuplicateEmailErrorMessage) } + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) } - log.Info(). - Str("service", "auth"). - Str("action", "SignOut"). - Str("token", token). - Msg("sign out successfully") - return &dto.SignOutResponse{ - IsSuccess: response.IsSuccess, + return &dto.SignupResponse{ + Id: createUser.ID.String(), + Firstname: createUser.Firstname, + Lastname: createUser.Lastname, + Email: createUser.Email, }, nil } -func (s *serviceImpl) Validate(token string) (*dto.TokenPayloadAuth, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() +func (s *serviceImpl) SignIn(request *dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) { + user := &model.User{} + err := s.userRepo.FindByEmail(request.Email, user) + if err != nil { + return nil, dto.UnauthorizedError(constant.IncorrectEmailPasswordErrorMessage) + } + + err = s.bcryptUtil.CompareHashedPassword(user.Password, request.Password) + if err != nil { + return nil, dto.UnauthorizedError(constant.IncorrectEmailPasswordErrorMessage) + } - response, err := s.client.Validate(ctx, &authProto.ValidateRequest{ - Token: token, - }) + createAuthSession := &model.AuthSession{ + UserID: user.ID, + } + err = s.authRepo.Create(createAuthSession) if err != nil { - st, ok := status.FromError(err) log.Error(). + Err(err). Str("service", "auth"). - Str("action", "Validate"). - Str("token", token). - Msg(st.Message()) - if !ok { - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } - switch st.Code() { - case codes.Unauthenticated: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusUnauthorized, - Message: constant.UnauthorizedMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - } + Str("module", "signin"). + Msg("Error creating auth session") + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) } - log.Info(). - Str("service", "auth"). - Str("action", "Validate"). - Str("token", token). - Msg("validate successfully") - return &dto.TokenPayloadAuth{ - UserId: response.UserId, - Role: response.Role, - }, nil + credential, err := s.tokenService.CreateCredential(user.ID.String(), user.Role, createAuthSession.ID.String()) + if err != nil { + log.Error(). + Err(err). + Str("service", "auth"). + Str("module", "signin"). + Msg("Error creating credential") + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } + + return credential, nil } -func (s *serviceImpl) RefreshToken(request *dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() +func (s *serviceImpl) SignOut(accessToken string) (*dto.SignOutResponse, *dto.ResponseErr) { + userCredential, err := s.tokenService.Validate(accessToken) + if err != nil { + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } - response, err := s.client.RefreshToken(ctx, &authProto.RefreshTokenRequest{ - RefreshToken: request.RefreshToken, - }) + err = s.tokenService.RemoveRefreshTokenCache(userCredential.RefreshToken) if err != nil { - st, ok := status.FromError(err) - log.Error(). - Str("service", "auth"). - Str("action", "RefreshToken"). - Str("token", request.RefreshToken). - Msg(st.Message()) - if !ok { - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } - switch st.Code() { - case codes.InvalidArgument: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidTokenMessage, - Data: nil, - } - case codes.Internal: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - } + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } + err = s.tokenService.RemoveAccessTokenCache(userCredential.AuthSessionID) + if err != nil { + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) } - log.Info(). - Str("service", "auth"). - Str("action", "RefreshToken"). - Str("token", request.RefreshToken). - Msg("Refresh token successfully") - return &dto.Credential{ - AccessToken: response.Credential.AccessToken, - RefreshToken: response.Credential.RefreshToken, - ExpiresIn: int(response.Credential.ExpiresIn), - }, nil + err = s.authRepo.Delete(userCredential.AuthSessionID) + if err != nil { + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } + + return &dto.SignOutResponse{IsSuccess: true}, nil } func (s *serviceImpl) ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() + user := &model.User{} + err := s.userRepo.FindByEmail(request.Email, user) + if err != nil { + return nil, dto.NotFoundError(constant.UserNotFoundErrorMessage) + } - _, err := s.client.ForgotPassword(ctx, &authProto.ForgotPasswordRequest{ - Email: request.Email, - }) + resetPasswordToken, err := s.tokenService.CreateResetPasswordToken(user.ID.String()) if err != nil { - st, ok := status.FromError(err) - log.Error(). - Str("service", "auth"). - Str("action", "ForgotPassword"). - Str("email", request.Email). - Msg(st.Message()) - if !ok { - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } - switch st.Code() { - case codes.NotFound: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.UserNotFoundMessage, - Data: nil, - } - case codes.Internal: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - } + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } + + resetPasswordURL := fmt.Sprintf("%s/admin/reset-password/%s", s.config.ClientURL, resetPasswordToken) + emailSubject := constant.ResetPasswordSubject + emailContent := fmt.Sprintf("Please click the following url to reset password %s", resetPasswordURL) + if err := s.emailService.SendEmail(emailSubject, user.Firstname, user.Email, emailContent); err != nil { + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) } - log.Info(). - Str("service", "auth"). - Str("action", "ForgotPassword"). - Str("email", request.Email). - Msg("Forgot password successfully") return &dto.ForgotPasswordResponse{ IsSuccess: true, }, nil } func (s *serviceImpl) ResetPassword(request *dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - response, err := s.client.ResetPassword(ctx, &authProto.ResetPasswordRequest{ - Token: request.Token, - Password: request.Password, - }) + resetTokenCache, err := s.tokenService.FindResetPasswordToken(request.Token) if err != nil { - st, ok := status.FromError(err) - log.Error(). - Str("service", "auth"). - Str("action", "ResetPassword"). - Str("token", request.Token). - Msg(st.Message()) - if !ok { - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } - switch st.Code() { - case codes.InvalidArgument: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.ForbiddenSamePasswordMessage, - Data: nil, - } - case codes.Internal: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } + + userDb := &model.User{} + if err := s.userRepo.FindById(resetTokenCache.UserID, userDb); err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, dto.NotFoundError(constant.UserNotFoundErrorMessage) } + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } + + err = s.bcryptUtil.CompareHashedPassword(userDb.Password, request.Password) + if err == nil { + return nil, dto.BadRequestError(constant.IncorrectPasswordErrorMessage) + } + + hashPassword, err := s.bcryptUtil.GenerateHashedPassword(request.Password) + if err != nil { + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } + + userDb.Password = hashPassword + if err := s.userRepo.Update(resetTokenCache.UserID, userDb); err != nil { + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) + } + + if err := s.tokenService.RemoveResetPasswordToken(request.Token); err != nil { + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) } - log.Info(). - Str("service", "auth"). - Str("action", "ResetPassword"). - Str("token", request.Token). - Msg("Reset password successfully") return &dto.ResetPasswordResponse{ - IsSuccess: response.IsSuccess, + IsSuccess: true, }, nil } diff --git a/internal/auth/jwt/jwt.strategy.go b/internal/auth/jwt/jwt.strategy.go new file mode 100644 index 0000000..1638e9d --- /dev/null +++ b/internal/auth/jwt/jwt.strategy.go @@ -0,0 +1,29 @@ +package jwt + +import ( + "fmt" + + "github.com/golang-jwt/jwt/v4" + "github.com/isd-sgcu/johnjud-gateway/internal/auth/token/strategy" + "github.com/pkg/errors" +) + +type JwtStrategy interface { + AuthDecode(token *jwt.Token) (interface{}, error) +} + +type jwtStrategyImpl struct { + secret string +} + +func NewJwtStrategy(secret string) strategy.JwtStrategy { + return &jwtStrategyImpl{secret: secret} +} + +func (s *jwtStrategyImpl) AuthDecode(token *jwt.Token) (interface{}, error) { + if _, isValid := token.Method.(*jwt.SigningMethodHMAC); !isValid { + return nil, errors.New(fmt.Sprintf("invalid token %v\n", token.Header["alg"])) + } + + return []byte(s.secret), nil +} diff --git a/internal/auth/test/auth.service_test.go b/internal/auth/test/auth.service_test.go deleted file mode 100644 index 3633086..0000000 --- a/internal/auth/test/auth.service_test.go +++ /dev/null @@ -1,839 +0,0 @@ -package test - -import ( - "errors" - "net/http" - "testing" - - "github.com/go-faker/faker/v4" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/auth" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - mockAuth "github.com/isd-sgcu/johnjud-gateway/mocks/client/auth" - authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -type AuthServiceTest struct { - suite.Suite - signupRequestDto *dto.SignupRequest - signInDto *dto.SignInRequest - token string - refreshTokenRequest *dto.RefreshTokenRequest - forgotPasswordRequest *dto.ForgotPasswordRequest - resetPasswordRequest *dto.ResetPasswordRequest -} - -func TestAuthService(t *testing.T) { - suite.Run(t, new(AuthServiceTest)) -} - -func (t *AuthServiceTest) SetupTest() { - signupRequestDto := &dto.SignupRequest{ - Email: faker.Email(), - Password: faker.Password(), - Firstname: faker.FirstName(), - Lastname: faker.LastName(), - } - signInDto := &dto.SignInRequest{ - Email: faker.Email(), - Password: faker.Password(), - } - token := faker.Word() - refreshTokenRequest := &dto.RefreshTokenRequest{ - RefreshToken: faker.UUIDDigit(), - } - forgotPasswordRequest := &dto.ForgotPasswordRequest{ - Email: faker.Email(), - } - resetPasswordRequest := &dto.ResetPasswordRequest{ - Token: faker.Word(), - Password: faker.Password(), - } - - t.signupRequestDto = signupRequestDto - t.signInDto = signInDto - t.token = token - t.refreshTokenRequest = refreshTokenRequest - t.forgotPasswordRequest = forgotPasswordRequest - t.resetPasswordRequest = resetPasswordRequest -} - -func (t *AuthServiceTest) TestSignupSuccess() { - protoReq := &authProto.SignUpRequest{ - FirstName: t.signupRequestDto.Firstname, - LastName: t.signupRequestDto.Lastname, - Email: t.signupRequestDto.Email, - Password: t.signupRequestDto.Password, - } - protoResp := &authProto.SignUpResponse{ - Id: faker.UUIDDigit(), - FirstName: t.signupRequestDto.Firstname, - LastName: t.signupRequestDto.Lastname, - Email: t.signupRequestDto.Email, - } - - expected := &dto.SignupResponse{ - Id: protoResp.Id, - Email: t.signupRequestDto.Email, - Firstname: t.signupRequestDto.Firstname, - Lastname: t.signupRequestDto.Lastname, - } - - client := mockAuth.AuthClientMock{} - - client.On("SignUp", protoReq).Return(protoResp, nil) - - svc := auth.NewService(&client) - actual, err := svc.Signup(t.signupRequestDto) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected.Id, actual.Id) - assert.Equal(t.T(), expected.Firstname, actual.Firstname) - assert.Equal(t.T(), expected.Lastname, actual.Lastname) - assert.Equal(t.T(), expected.Email, actual.Email) -} - -func (t *AuthServiceTest) TestSignupConflict() { - protoReq := &authProto.SignUpRequest{ - FirstName: t.signupRequestDto.Firstname, - LastName: t.signupRequestDto.Lastname, - Email: t.signupRequestDto.Email, - Password: t.signupRequestDto.Password, - } - clientErr := status.Error(codes.AlreadyExists, "Duplicate email") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusConflict, - Message: constant.DuplicateEmailMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("SignUp", protoReq).Return(nil, clientErr) - - svc := auth.NewService(&client) - actual, err := svc.Signup(t.signupRequestDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestSignupInternalError() { - protoReq := &authProto.SignUpRequest{ - FirstName: t.signupRequestDto.Firstname, - LastName: t.signupRequestDto.Lastname, - Email: t.signupRequestDto.Email, - Password: t.signupRequestDto.Password, - } - clientErr := status.Error(codes.Internal, "Internal error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("SignUp", protoReq).Return(nil, clientErr) - - svc := auth.NewService(&client) - actual, err := svc.Signup(t.signupRequestDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestSignupUnavailableService() { - protoReq := &authProto.SignUpRequest{ - FirstName: t.signupRequestDto.Firstname, - LastName: t.signupRequestDto.Lastname, - Email: t.signupRequestDto.Email, - Password: t.signupRequestDto.Password, - } - clientErr := status.Error(codes.Unavailable, "Connection lost") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("SignUp", protoReq).Return(nil, clientErr) - - svc := auth.NewService(&client) - actual, err := svc.Signup(t.signupRequestDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestSignupUnknownError() { - protoReq := &authProto.SignUpRequest{ - FirstName: t.signupRequestDto.Firstname, - LastName: t.signupRequestDto.Lastname, - Email: t.signupRequestDto.Email, - Password: t.signupRequestDto.Password, - } - clientErr := errors.New("Unknown error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("SignUp", protoReq).Return(nil, clientErr) - - svc := auth.NewService(&client) - actual, err := svc.Signup(t.signupRequestDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestSignInSuccess() { - protoReq := &authProto.SignInRequest{ - Email: t.signInDto.Email, - Password: t.signInDto.Password, - } - protoResp := &authProto.SignInResponse{ - Credential: &authProto.Credential{ - AccessToken: faker.Word(), - RefreshToken: faker.UUIDDigit(), - ExpiresIn: 3600, - }, - } - - expected := &dto.Credential{ - AccessToken: protoResp.Credential.AccessToken, - RefreshToken: protoResp.Credential.RefreshToken, - ExpiresIn: int(protoResp.Credential.ExpiresIn), - } - - client := mockAuth.AuthClientMock{} - - client.On("SignIn", protoReq).Return(protoResp, nil) - - svc := auth.NewService(&client) - actual, err := svc.SignIn(t.signInDto) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) -} - -func (t *AuthServiceTest) TestSignInForbidden() { - protoReq := &authProto.SignInRequest{ - Email: t.signInDto.Email, - Password: t.signInDto.Password, - } - protoErr := status.Error(codes.PermissionDenied, "Incorrect email or password") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusForbidden, - Message: constant.IncorrectEmailPasswordMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - - client.On("SignIn", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.SignIn(t.signInDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestSignInInternalError() { - protoReq := &authProto.SignInRequest{ - Email: t.signInDto.Email, - Password: t.signInDto.Password, - } - protoErr := status.Error(codes.Internal, "Internal error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - - client.On("SignIn", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.SignIn(t.signInDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestSignInUnavailableService() { - protoReq := &authProto.SignInRequest{ - Email: t.signInDto.Email, - Password: t.signInDto.Password, - } - protoErr := status.Error(codes.Unavailable, "Connection lost") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("SignIn", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.SignIn(t.signInDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestSignInUnknownError() { - protoReq := &authProto.SignInRequest{ - Email: t.signInDto.Email, - Password: t.signInDto.Password, - } - protoErr := errors.New("Unknown error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - - client.On("SignIn", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.SignIn(t.signInDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestSignOutSuccess() { - protoReq := &authProto.SignOutRequest{ - Token: t.token, - } - protoResp := &authProto.SignOutResponse{ - IsSuccess: true, - } - - expected := &dto.SignOutResponse{IsSuccess: true} - - client := mockAuth.AuthClientMock{} - client.On("SignOut", protoReq).Return(protoResp, nil) - - svc := auth.NewService(&client) - actual, err := svc.SignOut(t.token) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) -} - -func (t *AuthServiceTest) TestSignOutInternalError() { - protoReq := &authProto.SignOutRequest{ - Token: t.token, - } - protoErr := status.Error(codes.Internal, "Internal error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("SignOut", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.SignOut(t.token) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestSignOutUnavailableService() { - protoReq := &authProto.SignOutRequest{ - Token: t.token, - } - protoErr := status.Error(codes.Unavailable, "Connection lost") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("SignOut", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.SignOut(t.token) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestSignOutUnknownError() { - protoReq := &authProto.SignOutRequest{ - Token: t.token, - } - protoErr := errors.New("Unknown error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("SignOut", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.SignOut(t.token) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestValidateSuccess() { - protoReq := &authProto.ValidateRequest{ - Token: t.token, - } - protoResp := &authProto.ValidateResponse{ - UserId: faker.UUIDDigit(), - Role: "user", - } - - expected := &dto.TokenPayloadAuth{ - UserId: protoResp.UserId, - Role: protoResp.Role, - } - - client := mockAuth.AuthClientMock{} - client.On("Validate", protoReq).Return(protoResp, nil) - - svc := auth.NewService(&client) - actual, err := svc.Validate(t.token) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) -} - -func (t *AuthServiceTest) TestValidateUnauthorized() { - protoReq := &authProto.ValidateRequest{ - Token: t.token, - } - protoErr := status.Error(codes.Unauthenticated, "invalid token") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusUnauthorized, - Message: constant.UnauthorizedMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("Validate", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.Validate(t.token) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestValidateUnavailableService() { - protoReq := &authProto.ValidateRequest{ - Token: t.token, - } - protoErr := status.Error(codes.Unavailable, "connection lost") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("Validate", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.Validate(t.token) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestValidateUnknownError() { - protoReq := &authProto.ValidateRequest{ - Token: t.token, - } - protoErr := errors.New("Unknown error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("Validate", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.Validate(t.token) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestRefreshTokenSuccess() { - protoReq := &authProto.RefreshTokenRequest{ - RefreshToken: t.refreshTokenRequest.RefreshToken, - } - protoResp := &authProto.RefreshTokenResponse{ - Credential: &authProto.Credential{ - AccessToken: faker.Word(), - RefreshToken: faker.UUIDDigit(), - ExpiresIn: 3600, - }, - } - - expected := &dto.Credential{ - AccessToken: protoResp.Credential.AccessToken, - RefreshToken: protoResp.Credential.RefreshToken, - ExpiresIn: int(protoResp.Credential.ExpiresIn), - } - - client := mockAuth.AuthClientMock{} - client.On("RefreshToken", protoReq).Return(protoResp, nil) - - svc := auth.NewService(&client) - actual, err := svc.RefreshToken(t.refreshTokenRequest) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) -} - -func (t *AuthServiceTest) TestRefreshTokenInvalidToken() { - protoReq := &authProto.RefreshTokenRequest{ - RefreshToken: t.refreshTokenRequest.RefreshToken, - } - protoErr := status.Error(codes.InvalidArgument, "Invalid token") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidTokenMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("RefreshToken", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.RefreshToken(t.refreshTokenRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestRefreshTokenInternalError() { - protoReq := &authProto.RefreshTokenRequest{ - RefreshToken: t.refreshTokenRequest.RefreshToken, - } - protoErr := status.Error(codes.Internal, "Internal error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("RefreshToken", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.RefreshToken(t.refreshTokenRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestRefreshTokenUnavailableService() { - protoReq := &authProto.RefreshTokenRequest{ - RefreshToken: t.refreshTokenRequest.RefreshToken, - } - protoErr := status.Error(codes.Unavailable, "Connection lost") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("RefreshToken", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.RefreshToken(t.refreshTokenRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestRefreshTokenUnknownError() { - protoReq := &authProto.RefreshTokenRequest{ - RefreshToken: t.refreshTokenRequest.RefreshToken, - } - protoErr := errors.New("Unknown error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("RefreshToken", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.RefreshToken(t.refreshTokenRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestForgotPasswordSuccess() { - protoReq := &authProto.ForgotPasswordRequest{ - Email: t.forgotPasswordRequest.Email, - } - protoResp := &authProto.ForgotPasswordResponse{ - Url: faker.URL(), - } - expected := &dto.ForgotPasswordResponse{ - IsSuccess: true, - } - - client := mockAuth.AuthClientMock{} - client.On("ForgotPassword", protoReq).Return(protoResp, nil) - - svc := auth.NewService(&client) - actual, err := svc.ForgotPassword(t.forgotPasswordRequest) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) -} - -func (t *AuthServiceTest) TestForgotPasswordNotFound() { - protoReq := &authProto.ForgotPasswordRequest{ - Email: t.forgotPasswordRequest.Email, - } - protoErr := status.Error(codes.NotFound, "Not found") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.UserNotFoundMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("ForgotPassword", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.ForgotPassword(t.forgotPasswordRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestForgotPasswordInternalErr() { - protoReq := &authProto.ForgotPasswordRequest{ - Email: t.forgotPasswordRequest.Email, - } - protoErr := status.Error(codes.Internal, "Internal error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("ForgotPassword", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.ForgotPassword(t.forgotPasswordRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestForgotPasswordUnavailableService() { - protoReq := &authProto.ForgotPasswordRequest{ - Email: t.forgotPasswordRequest.Email, - } - protoErr := status.Error(codes.Unavailable, "Connection lost") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("ForgotPassword", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.ForgotPassword(t.forgotPasswordRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestForgotPasswordUnknownErr() { - protoReq := &authProto.ForgotPasswordRequest{ - Email: t.forgotPasswordRequest.Email, - } - protoErr := errors.New("Unknown Error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("ForgotPassword", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.ForgotPassword(t.forgotPasswordRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestResetPasswordSuccess() { - protoReq := &authProto.ResetPasswordRequest{ - Token: t.resetPasswordRequest.Token, - Password: t.resetPasswordRequest.Password, - } - protoResp := &authProto.ResetPasswordResponse{ - IsSuccess: true, - } - - expected := &dto.ResetPasswordResponse{ - IsSuccess: true, - } - - client := mockAuth.AuthClientMock{} - client.On("ResetPassword", protoReq).Return(protoResp, nil) - - svc := auth.NewService(&client) - actual, err := svc.ResetPassword(t.resetPasswordRequest) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) -} - -func (t *AuthServiceTest) TestResetPasswordInvalid() { - protoReq := &authProto.ResetPasswordRequest{ - Token: t.resetPasswordRequest.Token, - Password: t.resetPasswordRequest.Password, - } - protoErr := status.Error(codes.InvalidArgument, "Same password") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.ForbiddenSamePasswordMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("ResetPassword", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.ResetPassword(t.resetPasswordRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestResetPasswordInternalErr() { - protoReq := &authProto.ResetPasswordRequest{ - Token: t.resetPasswordRequest.Token, - Password: t.resetPasswordRequest.Password, - } - protoErr := status.Error(codes.Internal, "Internal error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("ResetPassword", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.ResetPassword(t.resetPasswordRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestResetPasswordUnavailableService() { - protoReq := &authProto.ResetPasswordRequest{ - Token: t.resetPasswordRequest.Token, - Password: t.resetPasswordRequest.Password, - } - protoErr := status.Error(codes.Unavailable, "Connection lost") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("ResetPassword", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.ResetPassword(t.resetPasswordRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *AuthServiceTest) TestResetPasswordUnknownErr() { - protoReq := &authProto.ResetPasswordRequest{ - Token: t.resetPasswordRequest.Token, - Password: t.resetPasswordRequest.Password, - } - protoErr := errors.New("Unknown Error") - - expected := &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - - client := mockAuth.AuthClientMock{} - client.On("ResetPassword", protoReq).Return(nil, protoErr) - - svc := auth.NewService(&client) - actual, err := svc.ResetPassword(t.resetPasswordRequest) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} diff --git a/internal/auth/token/test/token.service_test.go b/internal/auth/token/test/token.service_test.go index f3e8aae..9da850f 100644 --- a/internal/auth/token/test/token.service_test.go +++ b/internal/auth/token/test/token.service_test.go @@ -15,7 +15,6 @@ import ( mock_cache "github.com/isd-sgcu/johnjud-gateway/mocks/repository/cache" "github.com/isd-sgcu/johnjud-gateway/mocks/service/jwt" "github.com/isd-sgcu/johnjud-gateway/mocks/utils" - authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" "github.com/pkg/errors" "github.com/redis/go-redis/v9" "github.com/stretchr/testify/assert" @@ -75,10 +74,10 @@ func (t *TokenServiceTest) TestCreateCredentialSuccess() { Role: t.role, } - expected := authProto.Credential{ + expected := dto.Credential{ AccessToken: t.accessToken, RefreshToken: t.refreshToken.String(), - ExpiresIn: int32(t.jwtConfig.ExpiresIn), + ExpiresIn: int(t.jwtConfig.ExpiresIn), } controller := gomock.NewController(t.T()) diff --git a/internal/auth/token/token.service.go b/internal/auth/token/token.service.go index 4447c22..8c443a0 100644 --- a/internal/auth/token/token.service.go +++ b/internal/auth/token/token.service.go @@ -9,7 +9,6 @@ import ( "github.com/isd-sgcu/johnjud-gateway/internal/cache" "github.com/isd-sgcu/johnjud-gateway/internal/dto" "github.com/isd-sgcu/johnjud-gateway/internal/utils" - authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" "github.com/pkg/errors" "github.com/redis/go-redis/v9" "github.com/rs/zerolog/log" @@ -18,7 +17,7 @@ import ( ) type Service interface { - CreateCredential(userId string, role constant.Role, authSessionId string) (*authProto.Credential, error) + CreateCredential(userId string, role constant.Role, authSessionId string) (*dto.Credential, error) Validate(token string) (*dto.UserCredential, error) CreateRefreshToken() string RemoveAccessTokenCache(authSessionId string) error @@ -47,7 +46,7 @@ func NewService(jwtService jwt.Service, accessTokenCache cache.Repository, refre } } -func (s *serviceImpl) CreateCredential(userId string, role constant.Role, authSessionId string) (*authProto.Credential, error) { +func (s *serviceImpl) CreateCredential(userId string, role constant.Role, authSessionId string) (*dto.Credential, error) { accessToken, err := s.jwtService.SignAuth(userId, role, authSessionId) if err != nil { log.Error(). @@ -91,10 +90,10 @@ func (s *serviceImpl) CreateCredential(userId string, role constant.Role, authSe return nil, err } - credential := &authProto.Credential{ + credential := &dto.Credential{ AccessToken: accessToken, RefreshToken: refreshToken, - ExpiresIn: int32(jwtConf.ExpiresIn), + ExpiresIn: jwtConf.ExpiresIn, } return credential, nil diff --git a/internal/dto/common.dto.go b/internal/dto/common.dto.go index 611c90e..a169a6f 100644 --- a/internal/dto/common.dto.go +++ b/internal/dto/common.dto.go @@ -1,5 +1,7 @@ package dto +import "net/http" + type ResponseErr struct { StatusCode int `json:"status_code"` Message string `json:"message"` @@ -67,3 +69,31 @@ type ResponseGatewayTimeoutErr struct { Message string `json:"message" example:"Connection timeout"` Data interface{} `json:"data"` } + +func BadRequestError(message string) *ResponseErr { + return &ResponseErr{http.StatusBadRequest, message, nil} +} + +func UnauthorizedError(message string) *ResponseErr { + return &ResponseErr{http.StatusUnauthorized, message, nil} +} + +func ForbiddenError(message string) *ResponseErr { + return &ResponseErr{http.StatusForbidden, message, nil} +} + +func NotFoundError(message string) *ResponseErr { + return &ResponseErr{http.StatusNotFound, message, nil} +} + +func ConflictError(message string) *ResponseErr { + return &ResponseErr{http.StatusConflict, message, nil} +} + +func InternalServerError(message string) *ResponseErr { + return &ResponseErr{http.StatusInternalServerError, message, nil} +} + +func ServiceUnavailableError(message string) *ResponseErr { + return &ResponseErr{http.StatusServiceUnavailable, message, nil} +} diff --git a/internal/user/test/user.handler_test.go b/internal/user/test/user.handler_test.go deleted file mode 100644 index 198d469..0000000 --- a/internal/user/test/user.handler_test.go +++ /dev/null @@ -1,365 +0,0 @@ -package user - -import ( - "errors" - "net/http" - "strings" - "testing" - - "github.com/go-faker/faker/v4" - "github.com/golang/mock/gomock" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/user" - routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" - userMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/user" - validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" - - proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" - - "github.com/stretchr/testify/suite" -) - -type UserHandlerTest struct { - suite.Suite - User *proto.User - UserDto *dto.User - UpdateUserRequest *dto.UpdateUserRequest - BindErr *dto.ResponseErr - NotFoundErr *dto.ResponseErr - InvalidIDErr *dto.ResponseErr - ServiceDownErr *dto.ResponseErr - DuplicateEmailErr *dto.ResponseErr - InternalErr *dto.ResponseErr -} - -func TestUserHandler(t *testing.T) { - suite.Run(t, new(UserHandlerTest)) -} - -func (t *UserHandlerTest) SetupTest() { - t.User = &proto.User{ - Id: faker.UUIDDigit(), - Email: faker.Email(), - Password: faker.Password(), - Firstname: faker.FirstName(), - Lastname: faker.LastName(), - Role: "user", - } - t.UserDto = &dto.User{ - Id: t.User.Id, - Firstname: t.User.Firstname, - Lastname: t.User.Lastname, - Email: t.User.Email, - } - - t.UpdateUserRequest = &dto.UpdateUserRequest{} - - t.ServiceDownErr = &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: "Service is down", - Data: nil, - } - - t.NotFoundErr = &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.UserNotFoundMessage, - Data: nil, - } - - t.InvalidIDErr = &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidIDMessage, - Data: nil, - } - - t.BindErr = &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidIDMessage, - } - - t.DuplicateEmailErr = &dto.ResponseErr{ - StatusCode: http.StatusConflict, - Message: constant.DuplicateEmailMessage, - Data: nil, - } - - t.InternalErr = &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } -} - -func (t *UserHandlerTest) TestFindOneSuccess() { - svcResp := t.UserDto - expectedResp := t.UserDto - - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().ID().Return(t.User.Id, nil) - userSvc.EXPECT().FindOne(t.User.Id).Return(svcResp, nil) - context.EXPECT().JSON(http.StatusOK, expectedResp) - - handler := user.NewHandler(userSvc, validator) - handler.FindOne(context) -} - -func (t *UserHandlerTest) TestFindOneNotFoundErr() { - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().ID().Return(t.User.Id, nil) - userSvc.EXPECT().FindOne(t.User.Id).Return(nil, t.NotFoundErr) - context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) - - handler := user.NewHandler(userSvc, validator) - handler.FindOne(context) -} - -func (t *UserHandlerTest) TestFindOneInvalidIDErr() { - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().ID().Return("", errors.New("Invalid ID")) - context.EXPECT().JSON(http.StatusBadRequest, t.InvalidIDErr) - - handler := user.NewHandler(userSvc, validator) - handler.FindOne(context) -} - -func (t *UserHandlerTest) TestFindOneInternalErr() { - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().ID().Return(t.User.Id, nil) - userSvc.EXPECT().FindOne(t.User.Id).Return(nil, t.InternalErr) - context.EXPECT().JSON(http.StatusInternalServerError, t.InternalErr) - - handler := user.NewHandler(userSvc, validator) - handler.FindOne(context) -} - -func (t *UserHandlerTest) TestFindOneGrpcErr() { - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().ID().Return(t.User.Id, nil) - userSvc.EXPECT().FindOne(t.User.Id).Return(nil, t.ServiceDownErr) - context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - - handler := user.NewHandler(userSvc, validator) - handler.FindOne(context) -} - -func (t *UserHandlerTest) TestUpdateSuccess() { - svcResp := t.UserDto - expectedResp := t.UserDto - - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().UserID().Return(t.User.Id) - context.EXPECT().Bind(t.UpdateUserRequest).Return(nil) - validator.EXPECT().Validate(t.UpdateUserRequest).Return(nil) - userSvc.EXPECT().Update(t.User.Id, t.UpdateUserRequest).Return(svcResp, nil) - context.EXPECT().JSON(http.StatusOK, expectedResp) - - handler := user.NewHandler(userSvc, validator) - handler.Update(context) -} - -func (t *UserHandlerTest) TestUpdateBindErr() { - bindErr := errors.New("Bind err") - expectedResp := &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.BindingRequestErrorMessage + bindErr.Error(), - Data: nil, - } - - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().UserID().Return(t.User.Id) - context.EXPECT().Bind(t.UpdateUserRequest).Return(bindErr) - context.EXPECT().JSON(http.StatusBadRequest, expectedResp) - - handler := user.NewHandler(userSvc, validator) - handler.Update(context) -} - -func (t *UserHandlerTest) TestUpdateValidateErr() { - errorMessage := []string{"First name is required", "Last name is required"} - validateErr := []*dto.BadReqErrResponse{ - { - Message: errorMessage[0], - FailedField: "firstname", - }, - { - Message: errorMessage[1], - FailedField: "lastname", - }, - } - expectedResp := &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidRequestBodyMessage + strings.Join(errorMessage, ", "), - Data: nil, - } - - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().UserID().Return(t.User.Id) - context.EXPECT().Bind(t.UpdateUserRequest).Return(nil) - validator.EXPECT().Validate(t.UpdateUserRequest).Return(validateErr) - context.EXPECT().JSON(http.StatusBadRequest, expectedResp) - - handler := user.NewHandler(userSvc, validator) - handler.Update(context) -} - -func (t *UserHandlerTest) TestUpdateDuplicateEmailErr() { - expectedResp := &dto.ResponseErr{ - StatusCode: http.StatusConflict, - Message: constant.DuplicateEmailMessage, - Data: nil, - } - - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().UserID().Return(t.User.Id) - context.EXPECT().Bind(t.UpdateUserRequest).Return(nil) - validator.EXPECT().Validate(t.UpdateUserRequest).Return(nil) - userSvc.EXPECT().Update(t.User.Id, t.UpdateUserRequest).Return(nil, t.DuplicateEmailErr) - context.EXPECT().JSON(http.StatusConflict, expectedResp) - - handler := user.NewHandler(userSvc, validator) - handler.Update(context) -} - -func (t *UserHandlerTest) TestUpdateInternalErr() { - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().UserID().Return(t.User.Id) - context.EXPECT().Bind(t.UpdateUserRequest).Return(nil) - validator.EXPECT().Validate(t.UpdateUserRequest).Return(nil) - userSvc.EXPECT().Update(t.User.Id, t.UpdateUserRequest).Return(nil, t.InternalErr) - context.EXPECT().JSON(http.StatusInternalServerError, t.InternalErr) - - handler := user.NewHandler(userSvc, validator) - handler.Update(context) -} - -func (t *UserHandlerTest) TestUpdateGrpcErr() { - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().UserID().Return(t.User.Id) - context.EXPECT().Bind(t.UpdateUserRequest).Return(nil) - validator.EXPECT().Validate(t.UpdateUserRequest).Return(nil) - userSvc.EXPECT().Update(t.User.Id, t.UpdateUserRequest).Return(nil, t.ServiceDownErr) - context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - - handler := user.NewHandler(userSvc, validator) - handler.Update(context) -} - -func (t *UserHandlerTest) TestDeleteSuccess() { - deleteResp := &dto.DeleteUserResponse{ - Success: true, - } - expectedResp := deleteResp - - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().ID().Return(t.User.Id, nil) - userSvc.EXPECT().Delete(t.User.Id).Return(deleteResp, nil) - context.EXPECT().JSON(http.StatusOK, expectedResp) - - handler := user.NewHandler(userSvc, validator) - handler.Delete(context) -} - -func (t *UserHandlerTest) TestDeleteInvalidIDErr() { - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().ID().Return("", errors.New("Invalid ID")) - context.EXPECT().JSON(http.StatusBadRequest, t.InvalidIDErr) - - handler := user.NewHandler(userSvc, validator) - handler.Delete(context) -} - -func (t *UserHandlerTest) TestDeleteInternalErr() { - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().ID().Return(t.User.Id, nil) - userSvc.EXPECT().Delete(t.User.Id).Return(nil, t.InternalErr) - context.EXPECT().JSON(http.StatusInternalServerError, t.InternalErr) - - handler := user.NewHandler(userSvc, validator) - handler.Delete(context) -} - -func (t *UserHandlerTest) TestDeleteGrpcErr() { - controller := gomock.NewController(t.T()) - - userSvc := userMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().ID().Return(t.User.Id, nil) - userSvc.EXPECT().Delete(t.User.Id).Return(nil, t.ServiceDownErr) - context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - - handler := user.NewHandler(userSvc, validator) - handler.Delete(context) -} diff --git a/internal/user/test/user.service_test.go b/internal/user/test/user.service_test.go index 9b12076..31854f4 100644 --- a/internal/user/test/user.service_test.go +++ b/internal/user/test/user.service_test.go @@ -1,32 +1,32 @@ package user import ( + "errors" "net/http" "testing" + "time" - "github.com/go-faker/faker/v4" - "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-gateway/internal/model" "github.com/isd-sgcu/johnjud-gateway/internal/user" - mockUser "github.com/isd-sgcu/johnjud-gateway/mocks/client/user" - proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" + mock "github.com/isd-sgcu/johnjud-gateway/mocks/repository/user" + "github.com/isd-sgcu/johnjud-gateway/mocks/utils" + + "github.com/go-faker/faker/v4" + "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + "gorm.io/gorm" ) type UserServiceTest struct { suite.Suite - User *proto.User - FindOneUserReq *proto.FindOneUserRequest - UpdateUserReq *proto.UpdateUserRequest - UpdateUserDto *dto.UpdateUserRequest - DeleteUserReq *proto.DeleteUserRequest - NotFoundErr *dto.ResponseErr - UnavailableServiceErr *dto.ResponseErr - ConflictErr *dto.ResponseErr - InternalErr *dto.ResponseErr + User *model.User + UpdateUser *model.User + UserDto *dto.User + UserDtoNoPassword *dto.User + HashedPassword string + UpdateUserReqMock *dto.UpdateUserRequest } func TestUserService(t *testing.T) { @@ -34,246 +34,141 @@ func TestUserService(t *testing.T) { } func (t *UserServiceTest) SetupTest() { - t.User = &proto.User{ - Id: faker.UUIDDigit(), + t.User = &model.User{ + Base: model.Base{ + ID: uuid.New(), + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + DeletedAt: gorm.DeletedAt{}, + }, Email: faker.Email(), Password: faker.Password(), - Firstname: faker.FirstName(), - Lastname: faker.LastName(), + Firstname: faker.Username(), + Lastname: faker.Username(), Role: "user", } - t.FindOneUserReq = &proto.FindOneUserRequest{ - Id: t.User.Id, - } - - t.UpdateUserDto = &dto.UpdateUserRequest{ - Email: faker.Email(), - Password: faker.Password(), - Firstname: faker.FirstName(), - Lastname: faker.LastName(), - } - - t.UpdateUserReq = &proto.UpdateUserRequest{ - Id: t.User.Id, - Email: t.UpdateUserDto.Email, - Password: t.UpdateUserDto.Password, - Firstname: t.UpdateUserDto.Firstname, - Lastname: t.UpdateUserDto.Lastname, - } - - t.DeleteUserReq = &proto.DeleteUserRequest{ - Id: t.User.Id, - } - - t.UnavailableServiceErr = &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - - t.NotFoundErr = &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.UserNotFoundMessage, - Data: nil, + t.UserDto = &dto.User{ + Id: t.User.ID.String(), + Email: t.User.Email, + Firstname: t.User.Firstname, + Lastname: t.User.Lastname, } - t.ConflictErr = &dto.ResponseErr{ - StatusCode: http.StatusConflict, - Message: constant.DuplicateEmailMessage, - Data: nil, + t.UserDtoNoPassword = &dto.User{ + Id: t.User.ID.String(), + Email: t.User.Email, + Firstname: t.User.Firstname, + Lastname: t.User.Lastname, } - t.InternalErr = &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, + t.UpdateUserReqMock = &dto.UpdateUserRequest{ + Email: t.User.Email, + Password: t.User.Password, + Firstname: t.User.Firstname, + Lastname: t.User.Lastname, } -} -func (t *UserServiceTest) TestFindOneSuccess() { - protoResp := &proto.FindOneUserResponse{ - User: &proto.User{ - Id: t.User.Id, - Email: t.User.Email, - Firstname: t.User.Firstname, - Lastname: t.User.Lastname, - Role: t.User.Role, - }, - } + t.HashedPassword = faker.Password() - expected := &dto.User{ - Id: t.User.Id, + t.UpdateUser = &model.User{ Email: t.User.Email, + Password: t.HashedPassword, Firstname: t.User.Firstname, Lastname: t.User.Lastname, } - - client := mockUser.UserClientMock{} - client.On("FindOne", t.FindOneUserReq).Return(protoResp, nil) - - svc := user.NewService(&client) - actual, err := svc.FindOne(t.User.Id) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) } -func (t *UserServiceTest) TestFindOneNotFoundError() { - expected := t.NotFoundErr +func (t *UserServiceTest) TestFindOneSuccess() { + want := t.UserDtoNoPassword - client := mockUser.UserClientMock{} - clienErr := status.Error(codes.NotFound, constant.UserNotFoundMessage) - client.On("FindOne", t.FindOneUserReq).Return(nil, clienErr) + repo := &mock.UserRepositoryMock{} + repo.On("FindById", t.User.ID.String(), &model.User{}).Return(t.User, nil) - svc := user.NewService(&client) - actual, err := svc.FindOne(t.User.Id) + brcyptUtil := &utils.BcryptUtilMock{} + srv := user.NewService(repo, brcyptUtil) + actual, err := srv.FindOne(t.User.ID.String()) - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) + assert.Nil(t.T(), err) + assert.Equal(t.T(), want, actual) } -func (t *UserServiceTest) TestFindOneUnavailableServiceError() { - expected := t.UnavailableServiceErr +func (t *UserServiceTest) TestFindOneNotFoundErr() { + repo := &mock.UserRepositoryMock{} + repo.On("FindById", t.User.ID.String(), &model.User{}).Return(nil, gorm.ErrRecordNotFound) - client := mockUser.UserClientMock{} - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) - client.On("FindOne", t.FindOneUserReq).Return(nil, clientErr) - - svc := user.NewService(&client) - actual, err := svc.FindOne(t.User.Id) + brcyptUtil := &utils.BcryptUtilMock{} + srv := user.NewService(repo, brcyptUtil) + actual, err := srv.FindOne(t.User.ID.String()) assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) + assert.Equal(t.T(), http.StatusNotFound, err.StatusCode) } -func (t *UserServiceTest) TestFindOneInternalError() { - expected := t.InternalErr - - client := mockUser.UserClientMock{} - clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) - client.On("FindOne", t.FindOneUserReq).Return(nil, clientErr) +func (t *UserServiceTest) TestFindOneInternalErr() { + repo := &mock.UserRepositoryMock{} + repo.On("FindById", t.User.ID.String(), &model.User{}).Return(nil, errors.New("Not found user")) - svc := user.NewService(&client) - actual, err := svc.FindOne(t.User.Id) + brcyptUtil := &utils.BcryptUtilMock{} + srv := user.NewService(repo, brcyptUtil) + actual, err := srv.FindOne(t.User.ID.String()) assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) + assert.Equal(t.T(), http.StatusInternalServerError, err.StatusCode) } func (t *UserServiceTest) TestUpdateSuccess() { - protoResp := &proto.UpdateUserResponse{ - User: &proto.User{ - Id: t.User.Id, - Email: t.User.Email, - Firstname: t.User.Firstname, - Lastname: t.User.Lastname, - Role: t.User.Role, - }, - } + want := t.UserDtoNoPassword - expected := &dto.User{ - Id: t.User.Id, - Email: t.User.Email, - Firstname: t.User.Firstname, - Lastname: t.User.Lastname, - } + repo := &mock.UserRepositoryMock{} + repo.On("Update", t.User.ID.String(), t.UpdateUser).Return(t.User, nil) - client := mockUser.UserClientMock{} - client.On("Update", t.UpdateUserReq).Return(protoResp, nil) + brcyptUtil := &utils.BcryptUtilMock{} + brcyptUtil.On("GenerateHashedPassword", t.User.Password).Return(t.HashedPassword, nil) - svc := user.NewService(&client) - actual, err := svc.Update(t.User.Id, t.UpdateUserDto) + srv := user.NewService(repo, brcyptUtil) + actual, err := srv.Update(t.User.ID.String(), t.UpdateUserReqMock) assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) -} - -func (t *UserServiceTest) TestUpdateDuplicateEmail() { - expected := t.ConflictErr - - client := mockUser.UserClientMock{} - clientErr := status.Error(codes.AlreadyExists, constant.DuplicateEmailMessage) - client.On("Update", t.UpdateUserReq).Return(nil, clientErr) - - svc := user.NewService(&client) - actual, err := svc.Update(t.User.Id, t.UpdateUserDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) + assert.Equal(t.T(), want, actual) } -func (t *UserServiceTest) TestUpdateUnavailableServiceError() { - expected := t.UnavailableServiceErr +func (t *UserServiceTest) TestUpdateInternalErr() { + repo := &mock.UserRepositoryMock{} + repo.On("Update", t.User.ID.String(), t.UpdateUser).Return(nil, errors.New("Not found user")) - client := mockUser.UserClientMock{} - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) - client.On("Update", t.UpdateUserReq).Return(nil, clientErr) + brcyptUtil := &utils.BcryptUtilMock{} + brcyptUtil.On("GenerateHashedPassword", t.User.Password).Return(t.HashedPassword, nil) - svc := user.NewService(&client) - actual, err := svc.Update(t.User.Id, t.UpdateUserDto) + srv := user.NewService(repo, brcyptUtil) + actual, err := srv.Update(t.User.ID.String(), t.UpdateUserReqMock) assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *UserServiceTest) TestUpdateInternalError() { - expected := t.InternalErr - - client := mockUser.UserClientMock{} - clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) - client.On("Update", t.UpdateUserReq).Return(nil, clientErr) - - svc := user.NewService(&client) - actual, err := svc.Update(t.User.Id, t.UpdateUserDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) + assert.Equal(t.T(), http.StatusInternalServerError, err.StatusCode) } func (t *UserServiceTest) TestDeleteSuccess() { - protoResp := &proto.DeleteUserResponse{ - Success: true, - } - - expected := &dto.DeleteUserResponse{ - Success: true, - } + want := &dto.DeleteUserResponse{Success: true} - client := mockUser.UserClientMock{} - client.On("Delete", t.DeleteUserReq).Return(protoResp, nil) + repo := &mock.UserRepositoryMock{} + repo.On("Delete", t.User.ID.String()).Return(nil) - svc := user.NewService(&client) - actual, err := svc.Delete(t.User.Id) + brcyptUtil := &utils.BcryptUtilMock{} + srv := user.NewService(repo, brcyptUtil) + actual, err := srv.Delete(t.UserDto.Id) assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) -} - -func (t *UserServiceTest) TestDeleteUnavailableServiceError() { - expected := t.UnavailableServiceErr - - client := mockUser.UserClientMock{} - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) - client.On("Delete", t.DeleteUserReq).Return(nil, clientErr) - - svc := user.NewService(&client) - actual, err := svc.Delete(t.User.Id) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) + assert.Equal(t.T(), want, actual) } -func (t *UserServiceTest) TestDeleteInternalError() { - expected := t.InternalErr - - client := mockUser.UserClientMock{} - clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) - client.On("Delete", t.DeleteUserReq).Return(nil, clientErr) +func (t *UserServiceTest) TestDeleteInternalErr() { + repo := &mock.UserRepositoryMock{} + repo.On("Delete", t.User.ID.String()).Return(errors.New("Not found user")) - svc := user.NewService(&client) - actual, err := svc.Delete(t.User.Id) + brcyptUtil := &utils.BcryptUtilMock{} + srv := user.NewService(repo, brcyptUtil) + actual, err := srv.Delete(t.UserDto.Id) assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) + assert.Equal(t.T(), http.StatusInternalServerError, err.StatusCode) } diff --git a/internal/user/user.repository.go b/internal/user/user.repository.go new file mode 100644 index 0000000..4d0acda --- /dev/null +++ b/internal/user/user.repository.go @@ -0,0 +1,47 @@ +package user + +import ( + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "gorm.io/gorm" +) + +type Repository interface { + FindAll(user *[]*model.User) error + FindById(id string, user *model.User) error + FindByEmail(email string, user *model.User) error + Create(user *model.User) error + Update(id string, user *model.User) error + Delete(id string) error +} + +type repositoryImpl struct { + Db *gorm.DB +} + +func NewRepository(db *gorm.DB) Repository { + return &repositoryImpl{Db: db} +} + +func (r *repositoryImpl) FindAll(user *[]*model.User) error { + return r.Db.Find(user).Error +} + +func (r *repositoryImpl) FindById(id string, user *model.User) error { + return r.Db.First(user, "id = ?", id).Error +} + +func (r *repositoryImpl) FindByEmail(email string, user *model.User) error { + return r.Db.First(user, "email = ?", email).Error +} + +func (r *repositoryImpl) Create(user *model.User) error { + return r.Db.Create(user).Error +} + +func (r *repositoryImpl) Update(id string, user *model.User) error { + return r.Db.Where("id = ?", id).Updates(user).First(user, "id = ?", id).Error +} + +func (r *repositoryImpl) Delete(id string) error { + return r.Db.Delete(&model.User{}, "id = ?", id).Error +} diff --git a/internal/user/user.service.go b/internal/user/user.service.go index 0885530..d8b5390 100644 --- a/internal/user/user.service.go +++ b/internal/user/user.service.go @@ -1,159 +1,101 @@ package user import ( - "context" + "errors" "net/http" - "time" "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" - "github.com/rs/zerolog/log" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-gateway/internal/utils" + "gorm.io/gorm" ) type Service interface { - FindOne(string) (*dto.User, *dto.ResponseErr) - Update(string, *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) - Delete(string) (*dto.DeleteUserResponse, *dto.ResponseErr) + FindOne(id string) (*dto.User, *dto.ResponseErr) + Update(id string, request *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) + Delete(id string) (*dto.DeleteUserResponse, *dto.ResponseErr) } type serviceImpl struct { - client proto.UserServiceClient + repo Repository + bcryptUtil utils.IBcryptUtil } -func NewService(client proto.UserServiceClient) *serviceImpl { - return &serviceImpl{ - client: client, - } +func NewService(repo Repository, bcryptUtil utils.IBcryptUtil) Service { + return &serviceImpl{repo: repo, bcryptUtil: bcryptUtil} } func (s *serviceImpl) FindOne(id string) (*dto.User, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() + raw := model.User{} - response, err := s.client.FindOne(ctx, &proto.FindOneUserRequest{ - Id: id, - }) + err := s.repo.FindById(id, &raw) if err != nil { - st, _ := status.FromError(err) - log.Error(). - Err(err). - Str("service", "user"). - Str("module", "find one"). - Msg(st.Message()) - switch st.Code() { - case codes.NotFound: + if errors.Is(err, gorm.ErrRecordNotFound) { return nil, &dto.ResponseErr{ StatusCode: http.StatusNotFound, - Message: constant.UserNotFoundMessage, - Data: nil, - } - - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, + Message: constant.UserNotFoundErrorMessage, } } + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: "Find user failed", + } } - return &dto.User{ - Id: response.User.Id, - Firstname: response.User.Firstname, - Lastname: response.User.Lastname, - Email: response.User.Email, - }, nil + return RawToDto(&raw), nil } -func (s *serviceImpl) Update(id string, in *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() +func (s *serviceImpl) Update(id string, request *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) { + hashPassword, err := s.bcryptUtil.GenerateHashedPassword(request.Password) + if err != nil { + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalServerErrorMessage, + } + } + + updateUser := &model.User{ + Email: request.Email, + Password: hashPassword, + Firstname: request.Firstname, + Lastname: request.Lastname, + } - response, err := s.client.Update(ctx, &proto.UpdateUserRequest{ - Id: id, - Firstname: in.Firstname, - Lastname: in.Lastname, - Password: in.Password, - Email: in.Email, - }) + err = s.repo.Update(id, updateUser) if err != nil { - st, _ := status.FromError(err) - log.Error(). - Err(err). - Str("service", "user"). - Str("module", "update"). - Msg(st.Message()) - switch st.Code() { - case codes.AlreadyExists: + if errors.Is(err, gorm.ErrDuplicatedKey) { return nil, &dto.ResponseErr{ StatusCode: http.StatusConflict, - Message: constant.DuplicateEmailMessage, - Data: nil, - } - - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, + Message: constant.DuplicateEmailErrorMessage, } } + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: "Update user failed", + } } - return &dto.User{ - Id: response.User.Id, - Firstname: response.User.Firstname, - Lastname: response.User.Lastname, - Email: response.User.Email, - }, nil + return RawToDto(updateUser), nil } func (s *serviceImpl) Delete(id string) (*dto.DeleteUserResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - response, err := s.client.Delete(ctx, &proto.DeleteUserRequest{ - Id: id, - }) + err := s.repo.Delete(id) if err != nil { - st, _ := status.FromError(err) - log.Error(). - Err(err). - Str("service", "user"). - Str("module", "delete"). - Msg(st.Message()) - switch st.Code() { - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: "Delete user failed", } } - return &dto.DeleteUserResponse{ - Success: response.Success, - }, nil + return &dto.DeleteUserResponse{Success: true}, nil +} + +func RawToDto(in *model.User) *dto.User { + return &dto.User{ + Id: in.ID.String(), + Email: in.Email, + Firstname: in.Firstname, + Lastname: in.Lastname, + } } diff --git a/internal/utils/bcrypt.utils.go b/internal/utils/bcrypt.utils.go new file mode 100644 index 0000000..6d74c78 --- /dev/null +++ b/internal/utils/bcrypt.utils.go @@ -0,0 +1,23 @@ +package utils + +import "golang.org/x/crypto/bcrypt" + +type IBcryptUtil interface { + GenerateHashedPassword(password string) (string, error) + CompareHashedPassword(hashedPassword string, plainPassword string) error +} + +type bcryptUtil struct{} + +func NewBcryptUtil() IBcryptUtil { + return &bcryptUtil{} +} + +func (u *bcryptUtil) GenerateHashedPassword(password string) (string, error) { + hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + return string(hashedPassword), err +} + +func (u *bcryptUtil) CompareHashedPassword(hashedPassword string, plainPassword string) error { + return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(plainPassword)) +} diff --git a/internal/utils/common.utils.go b/internal/utils/common.utils.go index 7a9aa37..6562ab0 100644 --- a/internal/utils/common.utils.go +++ b/internal/utils/common.utils.go @@ -13,8 +13,5 @@ func TrimInList(word string, sep string, trimList map[string]struct{}) string { func IsExisted(e map[string]struct{}, key string) bool { _, ok := e[key] - if ok { - return true - } - return false + return ok } diff --git a/mocks/repository/auth/auth.mock.go b/mocks/repository/auth/auth.mock.go new file mode 100644 index 0000000..ef55d16 --- /dev/null +++ b/mocks/repository/auth/auth.mock.go @@ -0,0 +1,63 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./internal/auth/auth.repository.go + +// Package mock_auth is a generated GoMock package. +package mock_auth + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + model "github.com/isd-sgcu/johnjud-gateway/internal/model" +) + +// MockRepository is a mock of Repository interface. +type MockRepository struct { + ctrl *gomock.Controller + recorder *MockRepositoryMockRecorder +} + +// MockRepositoryMockRecorder is the mock recorder for MockRepository. +type MockRepositoryMockRecorder struct { + mock *MockRepository +} + +// NewMockRepository creates a new mock instance. +func NewMockRepository(ctrl *gomock.Controller) *MockRepository { + mock := &MockRepository{ctrl: ctrl} + mock.recorder = &MockRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { + return m.recorder +} + +// Create mocks base method. +func (m *MockRepository) Create(auth *model.AuthSession) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", auth) + ret0, _ := ret[0].(error) + return ret0 +} + +// Create indicates an expected call of Create. +func (mr *MockRepositoryMockRecorder) Create(auth interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockRepository)(nil).Create), auth) +} + +// Delete mocks base method. +func (m *MockRepository) Delete(id string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", id) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockRepositoryMockRecorder) Delete(id interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockRepository)(nil).Delete), id) +} diff --git a/mocks/repository/user/user.mock.go b/mocks/repository/user/user.mock.go new file mode 100644 index 0000000..ab6ee07 --- /dev/null +++ b/mocks/repository/user/user.mock.go @@ -0,0 +1,66 @@ +package user + +import ( + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/stretchr/testify/mock" +) + +type UserRepositoryMock struct { + mock.Mock +} + +func (m *UserRepositoryMock) FindAll(user *[]*model.User) error { + args := m.Called(user) + if args.Get(0) != nil { + *user = *args.Get(0).(*[]*model.User) + return nil + } + + return args.Error(1) +} + +func (m *UserRepositoryMock) FindById(id string, user *model.User) error { + args := m.Called(id, user) + if args.Get(0) != nil { + *user = *args.Get(0).(*model.User) + return nil + } + + return args.Error(1) +} + +func (m *UserRepositoryMock) FindByEmail(email string, user *model.User) error { + args := m.Called(email, user) + if args.Get(0) != nil { + *user = *args.Get(0).(*model.User) + return nil + } + + return args.Error(1) +} + +func (m *UserRepositoryMock) Create(user *model.User) error { + args := m.Called(user) + if args.Get(0) != nil { + *user = *args.Get(0).(*model.User) + return nil + } + + return args.Error(1) +} + +func (m *UserRepositoryMock) Update(id string, user *model.User) error { + args := m.Called(id, user) + if args.Get(0) != nil { + *user = *args.Get(0).(*model.User) + return nil + } + + return args.Error(1) +} + +func (m *UserRepositoryMock) Delete(id string) error { + args := m.Called(id) + + return args.Error(0) +} diff --git a/mocks/service/email/email.service.go b/mocks/service/email/email.service.go new file mode 100644 index 0000000..f09e612 --- /dev/null +++ b/mocks/service/email/email.service.go @@ -0,0 +1,5 @@ +package email + +type Service interface { + SendEmail(subject string, toName string, toAddress string, content string) error +} From ee61ada58238be9fcda50ceca082eb15d6853fad Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 23:02:12 +0700 Subject: [PATCH 087/104] env --- .env.template | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.env.template b/.env.template index afa9ce5..0f894b7 100644 --- a/.env.template +++ b/.env.template @@ -5,3 +5,22 @@ APP_MAX_FILE_SIZE=10 SERVICE_AUTH=localhost:3002 SERVICE_BACKEND=localhost:3003 SERVICE_FILE=localhost:3004 + +DB_URL=postgres://root:root@localhost:5432/johnjud_db + +JWT_SECRET=secret +JWT_EXPIRES_IN=3600 +JWT_REFRESH_TOKEN_TTL=604800 +JWT_ISSUER=issuer +JWT_RESET_TOKEN_TTL=900 + +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_PASSWORD= + +AUTH_CLIENT_URL=http://localhost:3000 + +SENDGRID_API_KEY=api_key +SENDGRID_NAME=johnjud +SENDGRID_ADDRESS=johnjud@gmail.com + From 228650c8b2798f6fe36fd6e1c96071c33545a775 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 23:03:10 +0700 Subject: [PATCH 088/104] fix conf --- config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index 28daf98..f5ba3c2 100644 --- a/config/config.go +++ b/config/config.go @@ -86,7 +86,7 @@ func LoadConfig() (*Config, error) { } database := Database{ - Url: os.Getenv("DATABASE_URL"), + Url: os.Getenv("DB_URL"), } redisPort, err := strconv.Atoi(os.Getenv("REDIS_PORT")) From 8a5c3a4765fce981df789f77b658ceb67b2b0ba6 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Wed, 21 Aug 2024 23:13:42 +0700 Subject: [PATCH 089/104] swagger --- Makefile | 2 +- {internal/docs => docs}/docs.go | 130 ++++++++++++++-------- {internal/docs => docs}/markdown/api.md | 0 {internal/docs => docs}/markdown/auth.md | 0 {internal/docs => docs}/markdown/image.md | 0 {internal/docs => docs}/markdown/pet.md | 0 {internal/docs => docs}/markdown/user.md | 0 {internal/docs => docs}/swagger.json | 130 ++++++++++++++-------- {internal/docs => docs}/swagger.yaml | 93 ++++++++++------ internal/router/like.router.go | 24 ---- internal/router/router.go | 6 +- 11 files changed, 230 insertions(+), 155 deletions(-) rename {internal/docs => docs}/docs.go (96%) rename {internal/docs => docs}/markdown/api.md (100%) rename {internal/docs => docs}/markdown/auth.md (100%) rename {internal/docs => docs}/markdown/image.md (100%) rename {internal/docs => docs}/markdown/pet.md (100%) rename {internal/docs => docs}/markdown/user.md (100%) rename {internal/docs => docs}/swagger.json (96%) rename {internal/docs => docs}/swagger.yaml (95%) delete mode 100644 internal/router/like.router.go diff --git a/Makefile b/Makefile index 5d2984c..6d68d1d 100644 --- a/Makefile +++ b/Makefile @@ -29,4 +29,4 @@ mock-gen: mockgen -source ./internal/router/context.go -destination ./mocks/router/context.mock.go create-doc: - swag init -d ./src -o ./src/docs -md ./src/docs/markdown \ No newline at end of file + swag init -d ./internal -g ../cmd/main.go -o ./docs -md ./docs/markdown --parseDependency --parseInternal \ No newline at end of file diff --git a/internal/docs/docs.go b/docs/docs.go similarity index 96% rename from internal/docs/docs.go rename to docs/docs.go index 93be1fb..698eefb 100644 --- a/internal/docs/docs.go +++ b/docs/docs.go @@ -471,6 +471,44 @@ const docTemplate = `{ } } }, + "/v1/pets/admin": { + "get": { + "description": "Returns the data of pets if successful", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pet" + ], + "summary": "finds all pets", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.PetResponse" + } + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, "/v1/pets/create": { "post": { "description": "Returns the data of pet if successful", @@ -948,6 +986,28 @@ const docTemplate = `{ } }, "definitions": { + "constant.Gender": { + "type": "string", + "enum": [ + "male", + "female" + ], + "x-enum-varnames": [ + "MALE", + "FEMALE" + ] + }, + "constant.Status": { + "type": "string", + "enum": [ + "adopted", + "findhome" + ], + "x-enum-varnames": [ + "ADOPTED", + "FINDHOME" + ] + }, "dto.AdoptByRequest": { "type": "object", "required": [ @@ -1012,12 +1072,6 @@ const docTemplate = `{ "type" ], "properties": { - "address": { - "type": "string" - }, - "adopt_by": { - "type": "string" - }, "birthdate": { "type": "string" }, @@ -1033,7 +1087,7 @@ const docTemplate = `{ "gender": { "allOf": [ { - "$ref": "#/definitions/pet.Gender" + "$ref": "#/definitions/constant.Gender" } ], "example": "male" @@ -1062,17 +1116,23 @@ const docTemplate = `{ "origin": { "type": "string" }, + "owner": { + "type": "string" + }, "pattern": { "type": "string" }, "status": { "allOf": [ { - "$ref": "#/definitions/pet.Status" + "$ref": "#/definitions/constant.Status" } ], "example": "findhome" }, + "tel": { + "type": "string" + }, "type": { "type": "string" } @@ -1150,12 +1210,6 @@ const docTemplate = `{ "dto.PetResponse": { "type": "object", "properties": { - "address": { - "type": "string" - }, - "adopt_by": { - "type": "string" - }, "birthdate": { "type": "string" }, @@ -1169,7 +1223,7 @@ const docTemplate = `{ "type": "string" }, "gender": { - "$ref": "#/definitions/pet.Gender" + "$ref": "#/definitions/constant.Gender" }, "habit": { "type": "string" @@ -1198,11 +1252,17 @@ const docTemplate = `{ "origin": { "type": "string" }, + "owner": { + "type": "string" + }, "pattern": { "type": "string" }, "status": { - "$ref": "#/definitions/pet.Status" + "$ref": "#/definitions/constant.Status" + }, + "tel": { + "type": "string" }, "type": { "type": "string" @@ -1404,12 +1464,6 @@ const docTemplate = `{ "dto.UpdatePetRequest": { "type": "object", "properties": { - "address": { - "type": "string" - }, - "adopt_by": { - "type": "string" - }, "birthdate": { "type": "string" }, @@ -1423,7 +1477,7 @@ const docTemplate = `{ "type": "string" }, "gender": { - "$ref": "#/definitions/pet.Gender" + "$ref": "#/definitions/constant.Gender" }, "habit": { "type": "string" @@ -1449,11 +1503,17 @@ const docTemplate = `{ "origin": { "type": "string" }, + "owner": { + "type": "string" + }, "pattern": { "type": "string" }, "status": { - "$ref": "#/definitions/pet.Status" + "$ref": "#/definitions/constant.Status" + }, + "tel": { + "type": "string" }, "type": { "type": "string" @@ -1522,28 +1582,6 @@ const docTemplate = `{ "type": "string" } } - }, - "pet.Gender": { - "type": "string", - "enum": [ - "male", - "female" - ], - "x-enum-varnames": [ - "MALE", - "FEMALE" - ] - }, - "pet.Status": { - "type": "string", - "enum": [ - "adopted", - "findhome" - ], - "x-enum-varnames": [ - "ADOPTED", - "FINDHOME" - ] } }, "securityDefinitions": { diff --git a/internal/docs/markdown/api.md b/docs/markdown/api.md similarity index 100% rename from internal/docs/markdown/api.md rename to docs/markdown/api.md diff --git a/internal/docs/markdown/auth.md b/docs/markdown/auth.md similarity index 100% rename from internal/docs/markdown/auth.md rename to docs/markdown/auth.md diff --git a/internal/docs/markdown/image.md b/docs/markdown/image.md similarity index 100% rename from internal/docs/markdown/image.md rename to docs/markdown/image.md diff --git a/internal/docs/markdown/pet.md b/docs/markdown/pet.md similarity index 100% rename from internal/docs/markdown/pet.md rename to docs/markdown/pet.md diff --git a/internal/docs/markdown/user.md b/docs/markdown/user.md similarity index 100% rename from internal/docs/markdown/user.md rename to docs/markdown/user.md diff --git a/internal/docs/swagger.json b/docs/swagger.json similarity index 96% rename from internal/docs/swagger.json rename to docs/swagger.json index 86894ef..48cdc08 100644 --- a/internal/docs/swagger.json +++ b/docs/swagger.json @@ -467,6 +467,44 @@ } } }, + "/v1/pets/admin": { + "get": { + "description": "Returns the data of pets if successful", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pet" + ], + "summary": "finds all pets", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.PetResponse" + } + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, "/v1/pets/create": { "post": { "description": "Returns the data of pet if successful", @@ -944,6 +982,28 @@ } }, "definitions": { + "constant.Gender": { + "type": "string", + "enum": [ + "male", + "female" + ], + "x-enum-varnames": [ + "MALE", + "FEMALE" + ] + }, + "constant.Status": { + "type": "string", + "enum": [ + "adopted", + "findhome" + ], + "x-enum-varnames": [ + "ADOPTED", + "FINDHOME" + ] + }, "dto.AdoptByRequest": { "type": "object", "required": [ @@ -1008,12 +1068,6 @@ "type" ], "properties": { - "address": { - "type": "string" - }, - "adopt_by": { - "type": "string" - }, "birthdate": { "type": "string" }, @@ -1029,7 +1083,7 @@ "gender": { "allOf": [ { - "$ref": "#/definitions/pet.Gender" + "$ref": "#/definitions/constant.Gender" } ], "example": "male" @@ -1058,17 +1112,23 @@ "origin": { "type": "string" }, + "owner": { + "type": "string" + }, "pattern": { "type": "string" }, "status": { "allOf": [ { - "$ref": "#/definitions/pet.Status" + "$ref": "#/definitions/constant.Status" } ], "example": "findhome" }, + "tel": { + "type": "string" + }, "type": { "type": "string" } @@ -1146,12 +1206,6 @@ "dto.PetResponse": { "type": "object", "properties": { - "address": { - "type": "string" - }, - "adopt_by": { - "type": "string" - }, "birthdate": { "type": "string" }, @@ -1165,7 +1219,7 @@ "type": "string" }, "gender": { - "$ref": "#/definitions/pet.Gender" + "$ref": "#/definitions/constant.Gender" }, "habit": { "type": "string" @@ -1194,11 +1248,17 @@ "origin": { "type": "string" }, + "owner": { + "type": "string" + }, "pattern": { "type": "string" }, "status": { - "$ref": "#/definitions/pet.Status" + "$ref": "#/definitions/constant.Status" + }, + "tel": { + "type": "string" }, "type": { "type": "string" @@ -1400,12 +1460,6 @@ "dto.UpdatePetRequest": { "type": "object", "properties": { - "address": { - "type": "string" - }, - "adopt_by": { - "type": "string" - }, "birthdate": { "type": "string" }, @@ -1419,7 +1473,7 @@ "type": "string" }, "gender": { - "$ref": "#/definitions/pet.Gender" + "$ref": "#/definitions/constant.Gender" }, "habit": { "type": "string" @@ -1445,11 +1499,17 @@ "origin": { "type": "string" }, + "owner": { + "type": "string" + }, "pattern": { "type": "string" }, "status": { - "$ref": "#/definitions/pet.Status" + "$ref": "#/definitions/constant.Status" + }, + "tel": { + "type": "string" }, "type": { "type": "string" @@ -1518,28 +1578,6 @@ "type": "string" } } - }, - "pet.Gender": { - "type": "string", - "enum": [ - "male", - "female" - ], - "x-enum-varnames": [ - "MALE", - "FEMALE" - ] - }, - "pet.Status": { - "type": "string", - "enum": [ - "adopted", - "findhome" - ], - "x-enum-varnames": [ - "ADOPTED", - "FINDHOME" - ] } }, "securityDefinitions": { diff --git a/internal/docs/swagger.yaml b/docs/swagger.yaml similarity index 95% rename from internal/docs/swagger.yaml rename to docs/swagger.yaml index 5b00a7d..d54f480 100644 --- a/internal/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,4 +1,20 @@ definitions: + constant.Gender: + enum: + - male + - female + type: string + x-enum-varnames: + - MALE + - FEMALE + constant.Status: + enum: + - adopted + - findhome + type: string + x-enum-varnames: + - ADOPTED + - FINDHOME dto.AdoptByRequest: properties: user_id: @@ -31,10 +47,6 @@ definitions: type: object dto.CreatePetRequest: properties: - address: - type: string - adopt_by: - type: string birthdate: type: string caption: @@ -45,7 +57,7 @@ definitions: type: string gender: allOf: - - $ref: '#/definitions/pet.Gender' + - $ref: '#/definitions/constant.Gender' example: male habit: type: string @@ -63,12 +75,16 @@ definitions: type: string origin: type: string + owner: + type: string pattern: type: string status: allOf: - - $ref: '#/definitions/pet.Status' + - $ref: '#/definitions/constant.Status' example: findhome + tel: + type: string type: type: string required: @@ -132,10 +148,6 @@ definitions: type: object dto.PetResponse: properties: - address: - type: string - adopt_by: - type: string birthdate: type: string caption: @@ -145,7 +157,7 @@ definitions: contact: type: string gender: - $ref: '#/definitions/pet.Gender' + $ref: '#/definitions/constant.Gender' habit: type: string id: @@ -164,10 +176,14 @@ definitions: type: string origin: type: string + owner: + type: string pattern: type: string status: - $ref: '#/definitions/pet.Status' + $ref: '#/definitions/constant.Status' + tel: + type: string type: type: string type: object @@ -306,10 +322,6 @@ definitions: type: object dto.UpdatePetRequest: properties: - address: - type: string - adopt_by: - type: string birthdate: type: string caption: @@ -319,7 +331,7 @@ definitions: contact: type: string gender: - $ref: '#/definitions/pet.Gender' + $ref: '#/definitions/constant.Gender' habit: type: string images: @@ -336,10 +348,14 @@ definitions: type: string origin: type: string + owner: + type: string pattern: type: string status: - $ref: '#/definitions/pet.Status' + $ref: '#/definitions/constant.Status' + tel: + type: string type: type: string type: object @@ -386,22 +402,6 @@ definitions: lastname: type: string type: object - pet.Gender: - enum: - - male - - female - type: string - x-enum-varnames: - - MALE - - FEMALE - pet.Status: - enum: - - adopted - - findhome - type: string - x-enum-varnames: - - ADOPTED - - FINDHOME info: contact: email: sd.team.sgcu@gmail.com @@ -890,6 +890,31 @@ paths: summary: changes pet's public visiblility tags: - pet + /v1/pets/admin: + get: + consumes: + - application/json + description: Returns the data of pets if successful + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/dto.PetResponse' + type: array + "500": + description: Internal service error + schema: + $ref: '#/definitions/dto.ResponseInternalErr' + "503": + description: Service is down + schema: + $ref: '#/definitions/dto.ResponseServiceDownErr' + summary: finds all pets + tags: + - pet /v1/pets/create: post: consumes: diff --git a/internal/router/like.router.go b/internal/router/like.router.go deleted file mode 100644 index 08395c4..0000000 --- a/internal/router/like.router.go +++ /dev/null @@ -1,24 +0,0 @@ -package router - -import "github.com/gofiber/fiber/v2" - -func (r *FiberRouter) GetLike(path string, h func(ctx IContext)) { - r.like.Get(path, func(c *fiber.Ctx) error { - h(NewFiberCtx(c)) - return nil - }) -} - -func (r *FiberRouter) PostLike(path string, h func(ctx IContext)) { - r.like.Post(path, func(c *fiber.Ctx) error { - h(NewFiberCtx(c)) - return nil - }) -} - -func (r *FiberRouter) DeleteLike(path string, h func(ctx IContext)) { - r.like.Delete(path, func(c *fiber.Ctx) error { - h(NewFiberCtx(c)) - return nil - }) -} diff --git a/internal/router/router.go b/internal/router/router.go index 8b2eecc..3e5c876 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -6,7 +6,7 @@ import ( "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/isd-sgcu/johnjud-gateway/config" - _ "github.com/isd-sgcu/johnjud-gateway/internal/docs" + _ "github.com/isd-sgcu/johnjud-gateway/docs" ) type FiberRouter struct { @@ -15,7 +15,6 @@ type FiberRouter struct { user fiber.Router pet fiber.Router image fiber.Router - like fiber.Router } type IGuard interface { @@ -55,9 +54,8 @@ func NewFiberRouter(authGuard IGuard, conf config.App) *FiberRouter { pet := GroupWithAuthMiddleware(r, "/pets", authGuard.Use) image := GroupWithAuthMiddleware(r, "/images", authGuard.Use) - like := GroupWithAuthMiddleware(r, "/likes", authGuard.Use) - return &FiberRouter{r, auth, user, pet, image, like} + return &FiberRouter{r, auth, user, pet, image} } func GroupWithAuthMiddleware(r *fiber.App, path string, middleware func(ctx IContext) error) fiber.Router { From bcfbf32d9ef304d530a5e720914834c6947c94a0 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Thu, 22 Aug 2024 22:08:18 +0700 Subject: [PATCH 090/104] add conf --- .env.template | 5 +++++ Makefile | 1 + config/config.go | 18 ++++++++++++++++ go.mod | 25 +++++++++++++++-------- go.sum | 53 +++++++++++++++++++++++++++++++----------------- 5 files changed, 74 insertions(+), 28 deletions(-) diff --git a/.env.template b/.env.template index 0f894b7..324bbd5 100644 --- a/.env.template +++ b/.env.template @@ -24,3 +24,8 @@ SENDGRID_API_KEY=api_key SENDGRID_NAME=johnjud SENDGRID_ADDRESS=johnjud@gmail.com +BUCKET_ENDPOINT=BUCKET_ENDPOINT +BUCKET_ACCESS_KEY=BUCKET_ACCESS_KEY +BUCKET_SECRET_KEY=BUCKET_SECRET_KEY +BUCKET_NAME=johnjud-pet-images +BUCKET_USE_SSL=true diff --git a/Makefile b/Makefile index 6d68d1d..0f0088b 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,7 @@ mock-gen: mockgen -source ./internal/auth/auth.service.go -destination ./mocks/service/auth/auth.mock.go mockgen -source ./internal/user/user.service.go -destination ./mocks/service/user/user.mock.go mockgen -source ./internal/pet/pet.service.go -destination ./mocks/service/pet/pet.mock.go + mockgen -source ./client/bucket/bucket.client.go -destination ./mocks/client/bucket/bucket.mock.go mockgen -source ./internal/image/image.service.go -destination ./mocks/service/image/image.mock.go mockgen -source ./internal/validator/validator.go -destination ./mocks/validator/validator.mock.go mockgen -source ./internal/router/context.go -destination ./mocks/router/context.mock.go diff --git a/config/config.go b/config/config.go index f5ba3c2..2214c8f 100644 --- a/config/config.go +++ b/config/config.go @@ -47,6 +47,14 @@ type Sendgrid struct { Address string } +type Bucket struct { + Endpoint string + AccessKeyID string + SecretAccessKey string + UseSSL bool + BucketName string +} + type Config struct { App App Service Service @@ -55,6 +63,7 @@ type Config struct { Jwt Jwt Auth Auth Sendgrid Sendgrid + Bucket Bucket } func LoadConfig() (*Config, error) { @@ -129,6 +138,14 @@ func LoadConfig() (*Config, error) { Address: os.Getenv("SENDGRID_ADDRESS"), } + bucket := Bucket{ + Endpoint: os.Getenv("BUCKET_ENDPOINT"), + AccessKeyID: os.Getenv("BUCKET_ACCESS_KEY_ID"), + SecretAccessKey: os.Getenv("BUCKET_SECRET_ACCESS_KEY"), + UseSSL: os.Getenv("BUCKET_USE_SSL") == "true", + BucketName: os.Getenv("BUCKET_NAME"), + } + return &Config{ App: app, Service: service, @@ -137,6 +154,7 @@ func LoadConfig() (*Config, error) { Jwt: jwt, Auth: auth, Sendgrid: sendgrid, + Bucket: bucket, }, nil } diff --git a/go.mod b/go.mod index d223bf8..cb58c20 100644 --- a/go.mod +++ b/go.mod @@ -15,13 +15,14 @@ require ( github.com/google/uuid v1.6.0 github.com/isd-sgcu/johnjud-go-proto v0.7.1 github.com/joho/godotenv v1.5.1 + github.com/minio/minio-go/v7 v7.0.75 github.com/pkg/errors v0.9.1 github.com/redis/go-redis/v9 v9.6.1 github.com/rs/zerolog v1.31.0 github.com/sendgrid/sendgrid-go v3.15.0+incompatible - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 github.com/swaggo/swag v1.16.2 - golang.org/x/crypto v0.19.0 + golang.org/x/crypto v0.24.0 google.golang.org/grpc v1.63.2 gorm.io/driver/postgres v1.5.9 gorm.io/gorm v1.25.11 @@ -33,11 +34,14 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/go-ini/ini v1.67.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/spec v0.20.13 // indirect github.com/go-openapi/swag v0.22.7 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgx/v5 v5.5.5 // indirect @@ -45,25 +49,28 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/minio/md5-simd v1.1.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.4.4 // indirect + github.com/rs/xid v1.5.0 // indirect github.com/sendgrid/rest v2.6.9+incompatible // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/swaggo/files v1.0.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.51.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 37e2548..e3cf50b 100644 --- a/go.sum +++ b/go.sum @@ -26,11 +26,15 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-faker/faker/v4 v4.2.0 h1:dGebOupKwssrODV51E0zbMrv5e2gO9VWSLNC1WDCpWg= github.com/go-faker/faker/v4 v4.2.0/go.mod h1:F/bBy8GH9NxOxMInug5Gx4WYeG6fHJZ8Ol/dhcpRub4= +github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= @@ -53,6 +57,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE= github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofiber/fiber/v2 v2.31.0/go.mod h1:1Ega6O199a3Y7yDGuM9FyXDPYQfv+7/y48wl6WCwUF4= github.com/gofiber/fiber/v2 v2.52.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/UE= @@ -86,8 +92,11 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm 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= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -110,6 +119,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= +github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= +github.com/minio/minio-go/v7 v7.0.75 h1:0uLrB6u6teY2Jt+cJUVi9cTvDRuBKWSRzSAcznRkwlE= +github.com/minio/minio-go/v7 v7.0.75/go.mod h1:qydcVzV8Hqtj1VtEocfxbmVFa2siu6HGa+LDEPogjD8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -128,6 +141,7 @@ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= @@ -141,16 +155,17 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 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 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= 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= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w= github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= @@ -172,12 +187,12 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -189,13 +204,13 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -213,8 +228,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -223,16 +238,16 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 5b35bc627c9f1ab6467e37fa910e36efc3e36fce Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Thu, 22 Aug 2024 22:08:34 +0700 Subject: [PATCH 091/104] model --- constant/error.constant.go | 11 +++++++++++ internal/model/image.model.go | 13 +++++++++++++ internal/model/pet.model.go | 24 ++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 internal/model/image.model.go create mode 100644 internal/model/pet.model.go diff --git a/constant/error.constant.go b/constant/error.constant.go index 61cdecd..01500c7 100644 --- a/constant/error.constant.go +++ b/constant/error.constant.go @@ -26,3 +26,14 @@ const DuplicateEmailErrorMessage = "Duplicate email" const InternalServerErrorMessage = "Internal server error" const UserNotFoundErrorMessage = "User not found" + +// file +const UploadToBucketErrorMessage = "Error uploading to bucket client" +const DeleteFromBucketErrorMessage = "Error deleting from bucket client" + +const ImageNotFoundErrorMessage = "Image not found" +const CreateImageErrorMessage = "Error creating image in db" +const DeleteImageErrorMessage = "Error deleting image from db" +const PrimaryKeyRequiredErrorMessage = "UUID Primary key (petId) required" +const PetIdNotUUIDErrorMessage = "Pet id is not uuid" +const PetIdNotFoundErrorMessage = "Pet id not found" diff --git a/internal/model/image.model.go b/internal/model/image.model.go new file mode 100644 index 0000000..6566507 --- /dev/null +++ b/internal/model/image.model.go @@ -0,0 +1,13 @@ +package model + +import ( + "github.com/google/uuid" +) + +type Image struct { + Base + PetID *uuid.UUID `json:"pet_id" gorm:"index:idx_name"` + Pet *Pet `json:"pet" gorm:"foreignKey:PetID;constraint:OnUpdate:CASCADE;OnDelete:SET NULL;"` + ImageUrl string `json:"image_url" gorm:"mediumtext"` + ObjectKey string `json:"object_key" gorm:"mediumtext"` +} diff --git a/internal/model/pet.model.go b/internal/model/pet.model.go new file mode 100644 index 0000000..d4c9ea3 --- /dev/null +++ b/internal/model/pet.model.go @@ -0,0 +1,24 @@ +package model + +import ( + "github.com/isd-sgcu/johnjud-gateway/constant" +) + +type Pet struct { + Base + Type string `json:"type" gorm:"tinytext"` + Name string `json:"name" gorm:"tinytext"` + Birthdate string `json:"birthdate" gorm:"tinytext"` + Gender constant.Gender `json:"gender" gorm:"tinytext" example:"male"` + Color string `json:"color" gorm:"tinytext"` + Habit string `json:"habit" gorm:"mediumtext"` + Caption string `json:"caption" gorm:"mediumtext"` + Status constant.Status `json:"status" gorm:"mediumtext" example:"findhome"` + IsSterile bool `json:"is_sterile"` + IsVaccinated bool `json:"is_vaccinated"` + IsVisible bool `json:"is_visible"` + Origin string `json:"origin" gorm:"tinytext"` + Owner string `json:"owner" gorm:"tinytext"` + Contact string `json:"contact" gorm:"tinytext"` + Tel string `json:"tel" gorm:"tinytext"` +} From 4a27414095b817c92297c7a9c82866347300a506 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Thu, 22 Aug 2024 22:08:50 +0700 Subject: [PATCH 092/104] utils, mock --- internal/utils/random.utils.go | 30 +++++++++++ mocks/client/bucket/bucket.mock.go | 78 ++++++++++++++++++++++++++++ mocks/repository/image/image.mock.go | 72 +++++++++++++++++++++++++ mocks/service/auth/auth.mock.go | 56 ++++++++++---------- mocks/service/image/image.mock.go | 40 +++++++------- mocks/service/user/user.mock.go | 24 ++++----- mocks/utils/random.mock.go | 16 ++++++ 7 files changed, 256 insertions(+), 60 deletions(-) create mode 100644 internal/utils/random.utils.go create mode 100644 mocks/client/bucket/bucket.mock.go create mode 100644 mocks/repository/image/image.mock.go create mode 100644 mocks/utils/random.mock.go diff --git a/internal/utils/random.utils.go b/internal/utils/random.utils.go new file mode 100644 index 0000000..1912acd --- /dev/null +++ b/internal/utils/random.utils.go @@ -0,0 +1,30 @@ +package utils + +import ( + "crypto/rand" + "encoding/base64" +) + +type RandomUtil interface { + GenerateRandomString(length int) (string, error) +} + +func NewRandomUtil() RandomUtil { + return &randomUtil{} +} + +type randomUtil struct{} + +func (u *randomUtil) GenerateRandomString(length int) (string, error) { + numBytes := (length * 6) / 8 + + randomBytes := make([]byte, numBytes) + _, err := rand.Read(randomBytes) + if err != nil { + return "", err + } + + randomString := base64.URLEncoding.EncodeToString(randomBytes) + + return randomString[:length], nil +} diff --git a/mocks/client/bucket/bucket.mock.go b/mocks/client/bucket/bucket.mock.go new file mode 100644 index 0000000..68390b6 --- /dev/null +++ b/mocks/client/bucket/bucket.mock.go @@ -0,0 +1,78 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./client/bucket/bucket.client.go + +// Package mock_bucket is a generated GoMock package. +package mock_bucket + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// 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 +} + +// Delete mocks base method. +func (m *MockClient) Delete(arg0 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockClientMockRecorder) Delete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockClient)(nil).Delete), arg0) +} + +// DeleteMany mocks base method. +func (m *MockClient) DeleteMany(arg0 []string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteMany", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteMany indicates an expected call of DeleteMany. +func (mr *MockClientMockRecorder) DeleteMany(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteMany", reflect.TypeOf((*MockClient)(nil).DeleteMany), arg0) +} + +// Upload mocks base method. +func (m *MockClient) Upload(arg0 []byte, arg1 string) (string, string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Upload", arg0, arg1) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(string) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// Upload indicates an expected call of Upload. +func (mr *MockClientMockRecorder) Upload(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upload", reflect.TypeOf((*MockClient)(nil).Upload), arg0, arg1) +} diff --git a/mocks/repository/image/image.mock.go b/mocks/repository/image/image.mock.go new file mode 100644 index 0000000..385b255 --- /dev/null +++ b/mocks/repository/image/image.mock.go @@ -0,0 +1,72 @@ +package image + +import ( + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/stretchr/testify/mock" +) + +type ImageRepositoryMock struct { + mock.Mock +} + +func (m *ImageRepositoryMock) FindAll(images *[]*model.Image) error { + args := m.Called(images) + if args.Get(0) != nil { + *images = *args.Get(0).(*[]*model.Image) + return nil + } + + return args.Error(1) +} + +func (m *ImageRepositoryMock) FindOne(id string, image *model.Image) error { + args := m.Called(id, image) + if args.Get(0) != nil { + *image = *args.Get(0).(*model.Image) + return nil + } + + return args.Error(1) +} + +func (m *ImageRepositoryMock) FindByPetId(id string, image *[]*model.Image) error { + args := m.Called(id, image) + if args.Get(0) != nil { + *image = *args.Get(0).(*[]*model.Image) + return nil + } + + return args.Error(1) +} + +func (m *ImageRepositoryMock) Create(image *model.Image) error { + args := m.Called(image) + if args.Get(0) != nil { + *image = *args.Get(0).(*model.Image) + return nil + } + + return args.Error(1) +} + +func (m *ImageRepositoryMock) Update(id string, image *model.Image) error { + args := m.Called(id, image) + if args.Get(0) != nil { + *image = *args.Get(0).(*model.Image) + return nil + } + + return args.Error(1) +} + +func (m *ImageRepositoryMock) Delete(id string) error { + args := m.Called(id) + + return args.Error(0) +} + +func (m *ImageRepositoryMock) DeleteMany(ids []string) error { + args := m.Called(ids) + + return args.Error(0) +} diff --git a/mocks/service/auth/auth.mock.go b/mocks/service/auth/auth.mock.go index 0a2236b..b3a5637 100644 --- a/mocks/service/auth/auth.mock.go +++ b/mocks/service/auth/auth.mock.go @@ -35,106 +35,106 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { } // ForgotPassword mocks base method. -func (m *MockService) ForgotPassword(arg0 *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) { +func (m *MockService) ForgotPassword(request *dto.ForgotPasswordRequest) (*dto.ForgotPasswordResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ForgotPassword", arg0) + ret := m.ctrl.Call(m, "ForgotPassword", request) ret0, _ := ret[0].(*dto.ForgotPasswordResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // ForgotPassword indicates an expected call of ForgotPassword. -func (mr *MockServiceMockRecorder) ForgotPassword(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) ForgotPassword(request interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForgotPassword", reflect.TypeOf((*MockService)(nil).ForgotPassword), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForgotPassword", reflect.TypeOf((*MockService)(nil).ForgotPassword), request) } // RefreshToken mocks base method. -func (m *MockService) RefreshToken(arg0 *dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) { +func (m *MockService) RefreshToken(request *dto.RefreshTokenRequest) (*dto.Credential, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RefreshToken", arg0) + ret := m.ctrl.Call(m, "RefreshToken", request) ret0, _ := ret[0].(*dto.Credential) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // RefreshToken indicates an expected call of RefreshToken. -func (mr *MockServiceMockRecorder) RefreshToken(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) RefreshToken(request interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RefreshToken", reflect.TypeOf((*MockService)(nil).RefreshToken), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RefreshToken", reflect.TypeOf((*MockService)(nil).RefreshToken), request) } // ResetPassword mocks base method. -func (m *MockService) ResetPassword(arg0 *dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) { +func (m *MockService) ResetPassword(request *dto.ResetPasswordRequest) (*dto.ResetPasswordResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ResetPassword", arg0) + ret := m.ctrl.Call(m, "ResetPassword", request) ret0, _ := ret[0].(*dto.ResetPasswordResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // ResetPassword indicates an expected call of ResetPassword. -func (mr *MockServiceMockRecorder) ResetPassword(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) ResetPassword(request interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetPassword", reflect.TypeOf((*MockService)(nil).ResetPassword), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetPassword", reflect.TypeOf((*MockService)(nil).ResetPassword), request) } // SignIn mocks base method. -func (m *MockService) SignIn(arg0 *dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) { +func (m *MockService) SignIn(request *dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SignIn", arg0) + ret := m.ctrl.Call(m, "SignIn", request) ret0, _ := ret[0].(*dto.Credential) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // SignIn indicates an expected call of SignIn. -func (mr *MockServiceMockRecorder) SignIn(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) SignIn(request interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignIn", reflect.TypeOf((*MockService)(nil).SignIn), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignIn", reflect.TypeOf((*MockService)(nil).SignIn), request) } // SignOut mocks base method. -func (m *MockService) SignOut(arg0 string) (*dto.SignOutResponse, *dto.ResponseErr) { +func (m *MockService) SignOut(accessToken string) (*dto.SignOutResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SignOut", arg0) + ret := m.ctrl.Call(m, "SignOut", accessToken) ret0, _ := ret[0].(*dto.SignOutResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // SignOut indicates an expected call of SignOut. -func (mr *MockServiceMockRecorder) SignOut(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) SignOut(accessToken interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignOut", reflect.TypeOf((*MockService)(nil).SignOut), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignOut", reflect.TypeOf((*MockService)(nil).SignOut), accessToken) } // Signup mocks base method. -func (m *MockService) Signup(arg0 *dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) { +func (m *MockService) Signup(request *dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Signup", arg0) + ret := m.ctrl.Call(m, "Signup", request) ret0, _ := ret[0].(*dto.SignupResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Signup indicates an expected call of Signup. -func (mr *MockServiceMockRecorder) Signup(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Signup(request interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Signup", reflect.TypeOf((*MockService)(nil).Signup), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Signup", reflect.TypeOf((*MockService)(nil).Signup), request) } // Validate mocks base method. -func (m *MockService) Validate(arg0 string) (*dto.TokenPayloadAuth, *dto.ResponseErr) { +func (m *MockService) Validate(refreshToken string) (*dto.TokenPayloadAuth, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Validate", arg0) + ret := m.ctrl.Call(m, "Validate", refreshToken) ret0, _ := ret[0].(*dto.TokenPayloadAuth) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Validate indicates an expected call of Validate. -func (mr *MockServiceMockRecorder) Validate(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Validate(refreshToken interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Validate", reflect.TypeOf((*MockService)(nil).Validate), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Validate", reflect.TypeOf((*MockService)(nil).Validate), refreshToken) } diff --git a/mocks/service/image/image.mock.go b/mocks/service/image/image.mock.go index cec33b2..ad8df35 100644 --- a/mocks/service/image/image.mock.go +++ b/mocks/service/image/image.mock.go @@ -35,48 +35,48 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { } // AssignPet mocks base method. -func (m *MockService) AssignPet(arg0 *dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) { +func (m *MockService) AssignPet(request *dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AssignPet", arg0) + ret := m.ctrl.Call(m, "AssignPet", request) ret0, _ := ret[0].(*dto.AssignPetResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // AssignPet indicates an expected call of AssignPet. -func (mr *MockServiceMockRecorder) AssignPet(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) AssignPet(request interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssignPet", reflect.TypeOf((*MockService)(nil).AssignPet), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssignPet", reflect.TypeOf((*MockService)(nil).AssignPet), request) } // Delete mocks base method. -func (m *MockService) Delete(arg0 string) (*dto.DeleteImageResponse, *dto.ResponseErr) { +func (m *MockService) Delete(id string) (*dto.DeleteImageResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", arg0) + ret := m.ctrl.Call(m, "Delete", id) ret0, _ := ret[0].(*dto.DeleteImageResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Delete indicates an expected call of Delete. -func (mr *MockServiceMockRecorder) Delete(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Delete(id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), id) } // DeleteByPetId mocks base method. -func (m *MockService) DeleteByPetId(arg0 string) (*dto.DeleteImageResponse, *dto.ResponseErr) { +func (m *MockService) DeleteByPetId(petID string) (*dto.DeleteImageResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteByPetId", arg0) + ret := m.ctrl.Call(m, "DeleteByPetId", petID) ret0, _ := ret[0].(*dto.DeleteImageResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // DeleteByPetId indicates an expected call of DeleteByPetId. -func (mr *MockServiceMockRecorder) DeleteByPetId(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) DeleteByPetId(petID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteByPetId", reflect.TypeOf((*MockService)(nil).DeleteByPetId), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteByPetId", reflect.TypeOf((*MockService)(nil).DeleteByPetId), petID) } // FindAll mocks base method. @@ -95,31 +95,31 @@ func (mr *MockServiceMockRecorder) FindAll() *gomock.Call { } // FindByPetId mocks base method. -func (m *MockService) FindByPetId(arg0 string) ([]*dto.ImageResponse, *dto.ResponseErr) { +func (m *MockService) FindByPetId(petID string) ([]*dto.ImageResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindByPetId", arg0) + ret := m.ctrl.Call(m, "FindByPetId", petID) ret0, _ := ret[0].([]*dto.ImageResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // FindByPetId indicates an expected call of FindByPetId. -func (mr *MockServiceMockRecorder) FindByPetId(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) FindByPetId(petID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByPetId", reflect.TypeOf((*MockService)(nil).FindByPetId), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByPetId", reflect.TypeOf((*MockService)(nil).FindByPetId), petID) } // Upload mocks base method. -func (m *MockService) Upload(arg0 *dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) { +func (m *MockService) Upload(request *dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Upload", arg0) + ret := m.ctrl.Call(m, "Upload", request) ret0, _ := ret[0].(*dto.ImageResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Upload indicates an expected call of Upload. -func (mr *MockServiceMockRecorder) Upload(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Upload(request interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upload", reflect.TypeOf((*MockService)(nil).Upload), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upload", reflect.TypeOf((*MockService)(nil).Upload), request) } diff --git a/mocks/service/user/user.mock.go b/mocks/service/user/user.mock.go index c329791..9a2cb22 100644 --- a/mocks/service/user/user.mock.go +++ b/mocks/service/user/user.mock.go @@ -35,46 +35,46 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { } // Delete mocks base method. -func (m *MockService) Delete(arg0 string) (*dto.DeleteUserResponse, *dto.ResponseErr) { +func (m *MockService) Delete(id string) (*dto.DeleteUserResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", arg0) + ret := m.ctrl.Call(m, "Delete", id) ret0, _ := ret[0].(*dto.DeleteUserResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Delete indicates an expected call of Delete. -func (mr *MockServiceMockRecorder) Delete(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Delete(id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), id) } // FindOne mocks base method. -func (m *MockService) FindOne(arg0 string) (*dto.User, *dto.ResponseErr) { +func (m *MockService) FindOne(id string) (*dto.User, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindOne", arg0) + ret := m.ctrl.Call(m, "FindOne", id) ret0, _ := ret[0].(*dto.User) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // FindOne indicates an expected call of FindOne. -func (mr *MockServiceMockRecorder) FindOne(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) FindOne(id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockService)(nil).FindOne), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockService)(nil).FindOne), id) } // Update mocks base method. -func (m *MockService) Update(arg0 string, arg1 *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) { +func (m *MockService) Update(id string, request *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Update", arg0, arg1) + ret := m.ctrl.Call(m, "Update", id, request) ret0, _ := ret[0].(*dto.User) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Update indicates an expected call of Update. -func (mr *MockServiceMockRecorder) Update(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Update(id, request interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockService)(nil).Update), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockService)(nil).Update), id, request) } diff --git a/mocks/utils/random.mock.go b/mocks/utils/random.mock.go new file mode 100644 index 0000000..347362e --- /dev/null +++ b/mocks/utils/random.mock.go @@ -0,0 +1,16 @@ +package utils + +import "github.com/stretchr/testify/mock" + +type RandomUtilMock struct { + mock.Mock +} + +func (m *RandomUtilMock) GenerateRandomString(length int) (string, error) { + args := m.Called(length) + if args.Get(0) != "" { + return args.Get(0).(string), nil + } + + return "", args.Error(1) +} From 480982941f3709e1c189fc4c263c2b71581d846e Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Thu, 22 Aug 2024 22:09:06 +0700 Subject: [PATCH 093/104] image repo, buc cli --- client/bucket/bucket.client.go | 99 ++++++++++++++++++++++++++++++ internal/image/image.repository.go | 54 ++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 client/bucket/bucket.client.go create mode 100644 internal/image/image.repository.go diff --git a/client/bucket/bucket.client.go b/client/bucket/bucket.client.go new file mode 100644 index 0000000..5d63781 --- /dev/null +++ b/client/bucket/bucket.client.go @@ -0,0 +1,99 @@ +package bucket + +import ( + "bytes" + "context" + "time" + + "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/minio/minio-go/v7" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" +) + +type Client interface { + Upload([]byte, string) (string, string, error) + Delete(string) error + DeleteMany([]string) error +} + +type clientImpl struct { + conf config.Bucket + minio *minio.Client +} + +func NewClient(conf config.Bucket, minioClient *minio.Client) Client { + return &clientImpl{conf: conf, minio: minioClient} +} + +func (c *clientImpl) Upload(file []byte, objectKey string) (string, string, error) { + ctx := context.Background() + _, cancel := context.WithTimeout(ctx, 50*time.Second) + defer cancel() + + buffer := bytes.NewReader(file) + + uploadOutput, err := c.minio.PutObject(context.Background(), c.conf.BucketName, objectKey, buffer, + buffer.Size(), minio.PutObjectOptions{ContentType: "application/octet-stream"}) + if err != nil { + log.Error(). + Err(err). + Str("service", "file"). + Str("module", "bucket client"). + Msgf("Couldn't upload object to %v:%v.", c.conf.BucketName, objectKey) + + return "", "", errors.Wrap(err, "Error while uploading the object") + } + + return c.getURL(objectKey), uploadOutput.Key, nil +} + +func (c *clientImpl) Delete(objectKey string) error { + ctx := context.Background() + _, cancel := context.WithTimeout(ctx, 50*time.Second) + defer cancel() + + opts := minio.RemoveObjectOptions{ + GovernanceBypass: true, + } + err := c.minio.RemoveObject(context.Background(), c.conf.BucketName, objectKey, opts) + if err != nil { + log.Error(). + Err(err). + Str("service", "file"). + Str("module", "bucket client"). + Msgf("Couldn't delete object from bucket %v:%v.", c.conf.BucketName, objectKey) + + return errors.Wrap(err, "Error while deleting the object") + } + + return nil +} + +func (c *clientImpl) DeleteMany(objectKeys []string) error { + ctx := context.Background() + _, cancel := context.WithTimeout(ctx, 50*time.Second) + defer cancel() + + opts := minio.RemoveObjectOptions{ + GovernanceBypass: true, + } + for _, objectKey := range objectKeys { + err := c.minio.RemoveObject(context.Background(), c.conf.BucketName, objectKey, opts) + if err != nil { + log.Error(). + Err(err). + Str("service", "file"). + Str("module", "bucket client"). + Msgf("Couldn't delete object from bucket %v:%v.", c.conf.BucketName, objectKey) + + return errors.Wrap(err, "Error while deleting the object") + } + } + + return nil +} + +func (c *clientImpl) getURL(objectKey string) string { + return "https://" + c.conf.Endpoint + "/" + c.conf.BucketName + "/" + objectKey +} diff --git a/internal/image/image.repository.go b/internal/image/image.repository.go new file mode 100644 index 0000000..95a6d3e --- /dev/null +++ b/internal/image/image.repository.go @@ -0,0 +1,54 @@ +package image + +import ( + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "gorm.io/gorm" +) + +type Repository interface { + FindAll(*[]*model.Image) error + FindOne(string, *model.Image) error + FindByPetId(string, *[]*model.Image) error + Create(*model.Image) error + Update(string, *model.Image) error + Delete(string) error + DeleteMany([]string) error +} + +type repositoryImpl struct { + db *gorm.DB +} + +func NewRepository(db *gorm.DB) Repository { + return &repositoryImpl{db: db} +} + +func (r *repositoryImpl) FindAll(result *[]*model.Image) error { + return r.db.Model(&model.Image{}).Find(result).Error +} + +func (r *repositoryImpl) FindOne(id string, result *model.Image) error { + return r.db.Model(&model.Image{}).First(result, "id = ?", id).Error +} + +func (r *repositoryImpl) FindByPetId(id string, result *[]*model.Image) error { + return r.db.Model(&model.Image{}).Find(&result, "pet_id = ?", id).Error +} + +func (r *repositoryImpl) Create(in *model.Image) error { + return r.db.Create(&in).Error +} + +func (r *repositoryImpl) Update(id string, in *model.Image) error { + return r.db.Where(id, "id = ?", id).Updates(&in).First(&in, "id = ?", id).Error +} + +func (r *repositoryImpl) Delete(id string) error { + return r.db.Where("id = ?", id).Delete(&model.Image{}).Error +} +func (r *repositoryImpl) DeleteMany(ids []string) error { + if len(ids) == 0 { + return nil + } + return r.db.Delete(&model.Image{}, ids).Error +} From 867e172e024a76ae252ef80fbed4063d369f16ae Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 23 Aug 2024 00:02:22 +0700 Subject: [PATCH 094/104] image svc --- constant/time.constant.go | 4 + go.mod | 2 +- go.sum | 4 +- internal/image/image.service.go | 473 ++++++++++++++++++-------------- 4 files changed, 279 insertions(+), 204 deletions(-) create mode 100644 constant/time.constant.go diff --git a/constant/time.constant.go b/constant/time.constant.go new file mode 100644 index 0000000..1ac27a3 --- /dev/null +++ b/constant/time.constant.go @@ -0,0 +1,4 @@ +package constant + +const DAY = 24 +const YEAR = 365 diff --git a/go.mod b/go.mod index cb58c20..8c6db2e 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21.3 require ( github.com/arsmn/fiber-swagger/v2 v2.31.1 - github.com/bxcodec/faker/v4 v4.0.0-beta.3 + github.com/bxcodec/faker/v3 v3.8.1 github.com/go-faker/faker/v4 v4.2.0 github.com/go-playground/locales v0.14.1 github.com/go-playground/universal-translator v0.18.1 diff --git a/go.sum b/go.sum index e3cf50b..a1d5ced 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,8 @@ github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/bxcodec/faker/v4 v4.0.0-beta.3 h1:gqYNBvN72QtzKkYohNDKQlm+pg+uwBDVMN28nWHS18k= -github.com/bxcodec/faker/v4 v4.0.0-beta.3/go.mod h1:m6+Ch1Lj3fqW/unZmvkXIdxWS5+XQWPWxcbbQW2X+Ho= +github.com/bxcodec/faker/v3 v3.8.1 h1:qO/Xq19V6uHt2xujwpaetgKhraGCapqY2CRWGD/SqcM= +github.com/bxcodec/faker/v3 v3.8.1/go.mod h1:DdSDccxF5msjFo5aO4vrobRQ8nIApg8kq3QWPEQD6+o= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= diff --git a/internal/image/image.service.go b/internal/image/image.service.go index 8fc97a7..d74f2ac 100644 --- a/internal/image/image.service.go +++ b/internal/image/image.service.go @@ -1,267 +1,338 @@ package image import ( - "context" - "net/http" + "strings" "time" + "github.com/google/uuid" + "github.com/isd-sgcu/johnjud-gateway/client/bucket" "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-gateway/internal/utils" "github.com/rs/zerolog/log" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + "gorm.io/gorm" ) type Service interface { FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) - FindByPetId(string) ([]*dto.ImageResponse, *dto.ResponseErr) - Upload(*dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) - Delete(string) (*dto.DeleteImageResponse, *dto.ResponseErr) - DeleteByPetId(string) (*dto.DeleteImageResponse, *dto.ResponseErr) - AssignPet(*dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) + FindByPetId(petID string) ([]*dto.ImageResponse, *dto.ResponseErr) + Upload(request *dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) + Delete(id string) (*dto.DeleteImageResponse, *dto.ResponseErr) + DeleteByPetId(petID string) (*dto.DeleteImageResponse, *dto.ResponseErr) + AssignPet(request *dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) } type serviceImpl struct { - client proto.ImageServiceClient + client bucket.Client + repository Repository + random utils.RandomUtil } -func NewService(client proto.ImageServiceClient) Service { +func NewService(client bucket.Client, repository Repository, random utils.RandomUtil) Service { return &serviceImpl{ - client: client, + client: client, + repository: repository, + random: random, } } func (s *serviceImpl) FindAll() ([]*dto.ImageResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() + var images []*model.Image - res, errRes := s.client.FindAll(ctx, &proto.FindAllImageRequest{}) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). + err := s.repository.FindAll(&images) + if err != nil { + log.Error().Err(err). Str("service", "image"). Str("module", "find all"). - Msg(st.Message()) - switch st.Code() { - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } + Msg("Error finding all images") + + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) } - return ProtoToDtoList(res.Images), nil + + return RawToDtoList(&images), nil } -func (s *serviceImpl) FindByPetId(petId string) ([]*dto.ImageResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() +func (s *serviceImpl) FindByPetId(petID string) ([]*dto.ImageResponse, *dto.ResponseErr) { + var images []*model.Image - res, errRes := s.client.FindByPetId(ctx, &proto.FindImageByPetIdRequest{PetId: petId}) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). + err := s.repository.FindByPetId(petID, &images) + if err != nil { + log.Error().Err(err). Str("service", "image"). - Str("module", "find by pet id"). - Msg(st.Message()) - switch st.Code() { - case codes.NotFound: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.PetNotFoundMessage, - Data: nil, - } - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } + Str("module", "find by petId"). + Str("petId", petID). + Msg("Error finding image by pet id from repo") + if err == gorm.ErrRecordNotFound { + return nil, dto.NotFoundError(constant.ImageNotFoundErrorMessage) } + + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) } - return ProtoToDtoList(res.Images), nil + + return RawToDtoList(&images), nil } -func (s *serviceImpl) Upload(in *dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() +func (s *serviceImpl) Upload(req *dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) { + if req.PetId != "" { + _, err := uuid.Parse(req.PetId) + if err != nil { + log.Error().Err(err). + Str("service", "image"). + Str("module", "upload"). + Str("petId", req.PetId). + Msg(constant.PetIdNotUUIDErrorMessage) + + return nil, dto.BadRequestError(constant.PetIdNotUUIDErrorMessage) + } + } + + randomString, err := s.random.GenerateRandomString(10) + if err != nil { + log.Error().Err(err). + Str("service", "image"). + Str("module", "upload"). + Str("petId", req.PetId). + Msg("Error while generating random string") + return nil, dto.InternalServerError("Error while generating random string") + } - request := CreateDtoToProto(in) - res, errRes := s.client.Upload(ctx, request) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). + imageUrl, objectKey, err := s.client.Upload(req.File, randomString+"_"+req.Filename) + if err != nil { + log.Error().Err(err). Str("service", "image"). Str("module", "upload"). - Msg(st.Message()) - switch st.Code() { - case codes.InvalidArgument: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidArgumentMessage, - Data: nil, - } - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } + Str("petId", req.PetId). + Msg(constant.UploadToBucketErrorMessage) + + // return nil, status.Error(codes.Internal, constant.UploadToBucketErrorMessage) + return nil, dto.InternalServerError(constant.UploadToBucketErrorMessage) + } + + raw, _ := DtoToRaw(&dto.ImageResponse{ + PetId: req.PetId, + Url: imageUrl, + ObjectKey: objectKey, + }) + + err = s.repository.Create(raw) + if err != nil { + log.Error().Err(err). + Str("service", "image"). + Str("module", "upload"). + Str("petId", req.PetId). + Msg(constant.CreateImageErrorMessage) + + return nil, dto.InternalServerError(constant.CreateImageErrorMessage) + } + + return RawToDto(raw), nil +} + +func (s *serviceImpl) AssignPet(req *dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) { + petId, err := uuid.Parse(req.PetId) + if err != nil { + log.Error().Err(err). + Str("service", "image"). + Str("module", "assign pet"). + Str("petId", req.PetId). + Msg(constant.PrimaryKeyRequiredErrorMessage) + + return nil, dto.BadRequestError(constant.PrimaryKeyRequiredErrorMessage) + } + + for _, id := range req.Ids { + err = s.repository.Update(id, &model.Image{ + PetID: &petId, + }) + if err == nil { + continue + } + + log.Error().Err(err). + Str("service", "image"). + Str("module", "assign pet"). + Str("petId", req.PetId). + Msg("Error updating image in repo") + + if strings.Contains(err.Error(), gorm.ErrForeignKeyViolated.Error()) { + return nil, dto.NotFoundError(constant.PetIdNotFoundErrorMessage) + } + switch err { + case gorm.ErrRecordNotFound: + return nil, dto.NotFoundError(constant.ImageNotFoundErrorMessage) default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) } } - return ProtoToDto(res.Image), nil + + return &dto.AssignPetResponse{Success: true}, nil } func (s *serviceImpl) Delete(id string) (*dto.DeleteImageResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() + var image model.Image + + err := s.repository.FindOne(id, &image) + if err != nil { + log.Error().Err(err). + Str("service", "image"). + Str("module", "delete"). + Str("id", id). + Msg("Error finding image from repo") + if err == gorm.ErrRecordNotFound { + return nil, dto.NotFoundError(constant.ImageNotFoundErrorMessage) + } - request := &proto.DeleteImageRequest{ - Id: id, + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) } - res, errRes := s.client.Delete(ctx, request) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). + err = s.client.Delete(image.ObjectKey) + if err != nil { + log.Error().Err(err). Str("service", "image"). Str("module", "delete"). - Msg(st.Message()) - switch st.Code() { - case codes.NotFound: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.ImageNotFoundMessage, - Data: nil, - } - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } + Str("id", id). + Msg(constant.DeleteFromBucketErrorMessage) + + return nil, dto.InternalServerError(constant.DeleteFromBucketErrorMessage) } - return &dto.DeleteImageResponse{ - Success: res.Success, - }, nil -} -func (s *serviceImpl) DeleteByPetId(petId string) (*dto.DeleteImageResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() + err = s.repository.Delete(id) + if err != nil { + log.Error().Err(err). + Str("service", "image"). + Str("module", "delete"). + Str("id", id). + Msg(constant.DeleteImageErrorMessage) - request := &proto.DeleteByPetIdRequest{ - PetId: petId, + return nil, dto.InternalServerError(constant.DeleteImageErrorMessage) } - res, errRes := s.client.DeleteByPetId(ctx, request) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). + return &dto.DeleteImageResponse{Success: true}, nil +} + +func (s *serviceImpl) DeleteByPetId(petID string) (*dto.DeleteImageResponse, *dto.ResponseErr) { + var images []*model.Image + + err := s.repository.FindByPetId(petID, &images) + if err != nil { + log.Error().Err(err). Str("service", "image"). Str("module", "delete by pet id"). - Msg(st.Message()) - switch st.Code() { - case codes.NotFound: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.ImageNotFoundMessage, - Data: nil, - } - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } + Str("pet id", petID). + Msg("Error finding image from repo") + if err == gorm.ErrRecordNotFound { + return nil, dto.NotFoundError(constant.ImageNotFoundErrorMessage) } + + return nil, dto.InternalServerError(constant.InternalServerErrorMessage) } - return &dto.DeleteImageResponse{ - Success: res.Success, - }, nil -} -func (s *serviceImpl) AssignPet(in *dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() + imageObjectKeys := ExtractImageObjectKeys(images) + err = s.client.DeleteMany(imageObjectKeys) + if err != nil { + log.Error().Err(err). + Str("service", "image"). + Str("module", "delete by pet id"). + Interface("image object keys", imageObjectKeys). + Msg(constant.DeleteFromBucketErrorMessage) - request := &proto.AssignPetRequest{ - Ids: in.Ids, - PetId: in.PetId, + return nil, dto.InternalServerError(constant.DeleteFromBucketErrorMessage) } - res, errRes := s.client.AssignPet(ctx, request) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). + imageIds := ExtractImageIds(images) + err = s.repository.DeleteMany(imageIds) + if err != nil { + log.Error().Err(err). Str("service", "image"). - Str("module", "assign pet"). - Msg(st.Message()) - switch st.Code() { - case codes.InvalidArgument: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidArgumentMessage, - Data: nil, - } - case codes.NotFound: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.PetNotFoundMessage, - Data: nil, - } - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } + Str("module", "delete by pet id"). + Interface("image ids", imageIds). + Msg(constant.DeleteImageErrorMessage) + + return nil, dto.InternalServerError(constant.DeleteImageErrorMessage) + } + + return &dto.DeleteImageResponse{Success: true}, nil +} + +func DtoToRaw(in *dto.ImageResponse) (result *model.Image, err error) { + var id uuid.UUID + if in.Id != "" { + id, err = uuid.Parse(in.Id) + if err != nil { + return nil, err } } - return &dto.AssignPetResponse{ - Success: res.Success, + + petId, err := uuid.Parse(in.PetId) + if err != nil { + return &model.Image{ + Base: model.Base{ + ID: id, + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + DeletedAt: gorm.DeletedAt{}, + }, + PetID: nil, + ImageUrl: in.Url, + ObjectKey: in.ObjectKey, + }, nil + } + + return &model.Image{ + Base: model.Base{ + ID: id, + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + DeletedAt: gorm.DeletedAt{}, + }, + PetID: &petId, + ImageUrl: in.Url, + ObjectKey: in.ObjectKey, }, nil } + +func RawToDtoList(in *[]*model.Image) []*dto.ImageResponse { + var result []*dto.ImageResponse + for _, b := range *in { + result = append(result, RawToDto(b)) + } + + return result +} + +func RawToDto(in *model.Image) *dto.ImageResponse { + var id string + var petId string + if in.ID != uuid.Nil { + id = in.ID.String() + } + if in.PetID != nil { + petId = in.PetID.String() + } + + return &dto.ImageResponse{ + Id: id, + PetId: petId, + Url: in.ImageUrl, + ObjectKey: in.ObjectKey, + } +} + +func ExtractImageIds(in []*model.Image) []string { + var imageIds []string + for _, image := range in { + imageIds = append(imageIds, image.ID.String()) + } + + return imageIds +} + +func ExtractImageObjectKeys(in []*model.Image) []string { + var imageObjectKeys []string + for _, image := range in { + imageObjectKeys = append(imageObjectKeys, image.ObjectKey) + } + + return imageObjectKeys +} From 7d66e0d52bbbb747685687ff75f8408632ae0035 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 23 Aug 2024 00:02:38 +0700 Subject: [PATCH 095/104] pet repo --- internal/pet/pet.repository.go | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 internal/pet/pet.repository.go diff --git a/internal/pet/pet.repository.go b/internal/pet/pet.repository.go new file mode 100644 index 0000000..1aeb8db --- /dev/null +++ b/internal/pet/pet.repository.go @@ -0,0 +1,48 @@ +package pet + +import ( + "errors" + + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "gorm.io/gorm" +) + +type Repository struct { + db *gorm.DB +} + +func NewRepository(db *gorm.DB) *Repository { + return &Repository{db: db} +} + +func (r *Repository) FindAll(result *[]*model.Pet, isAdmin bool) error { + if isAdmin { + return r.db.Model(&model.Pet{}).Find(result).Error + } + return r.db.Model(&model.Pet{}).Find(result, "is_visible = ?", true).Error +} + +func (r *Repository) FindOne(id string, result *model.Pet) error { + return r.db.Model(&model.Pet{}).First(result, "id = ?", id).Error +} + +func (r *Repository) Create(in *model.Pet) error { + return r.db.Create(&in).Error +} + +func (r *Repository) Update(id string, result *model.Pet) error { + updateMap := UpdateMap(result) + return r.db.Model(&result).Updates(updateMap).First(&result, "id = ?", id).Error +} + +func (r *Repository) Delete(id string) error { + var pet model.Pet + err := r.db.Where("id = ? AND deleted_at IS NULL", id).First(&pet).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return gorm.ErrRecordNotFound + } + return err + } + return r.db.Delete(&pet).Error +} From 1ce36664a0db7c8dc68344abee96c20261cecfd0 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 23 Aug 2024 15:00:49 +0700 Subject: [PATCH 096/104] merge backend, file monolith --- .env.template | 4 - cmd/main.go | 44 +- config/config.go | 14 - internal/pet/old/pet.service.go | 365 ++++++++ internal/pet/old/pet.utils.go | 269 ++++++ internal/pet/old/test/pet.service_test.go | 759 +++++++++++++++ internal/pet/pet.repository.go | 26 +- internal/pet/pet.service.go | 432 +++------ internal/pet/pet.utils.go | 414 +++++--- internal/pet/test/pet.handler_test.go | 1042 ++++++++++----------- internal/pet/test/pet.service_test.go | 948 ++++++++----------- mocks/repository/pet/pet.mock.go | 55 ++ mocks/service/image/image.mock_old.go | 70 ++ mocks/service/pet/pet.mock.go | 56 +- 14 files changed, 2875 insertions(+), 1623 deletions(-) create mode 100644 internal/pet/old/pet.service.go create mode 100644 internal/pet/old/pet.utils.go create mode 100644 internal/pet/old/test/pet.service_test.go create mode 100644 mocks/repository/pet/pet.mock.go create mode 100644 mocks/service/image/image.mock_old.go diff --git a/.env.template b/.env.template index 324bbd5..6849af4 100644 --- a/.env.template +++ b/.env.template @@ -2,10 +2,6 @@ APP_PORT=3001 APP_ENV=development APP_MAX_FILE_SIZE=10 -SERVICE_AUTH=localhost:3002 -SERVICE_BACKEND=localhost:3003 -SERVICE_FILE=localhost:3004 - DB_URL=postgres://root:root@localhost:5432/johnjud_db JWT_SECRET=secret diff --git a/cmd/main.go b/cmd/main.go index 5671043..705b7c9 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -10,6 +10,7 @@ import ( "syscall" "time" + "github.com/isd-sgcu/johnjud-gateway/client/bucket" "github.com/isd-sgcu/johnjud-gateway/config" "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/database" @@ -26,11 +27,9 @@ import ( "github.com/isd-sgcu/johnjud-gateway/internal/user" "github.com/isd-sgcu/johnjud-gateway/internal/utils" "github.com/isd-sgcu/johnjud-gateway/internal/validator" - petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" - imageProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" "github.com/rs/zerolog/log" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" ) // @title JohnJud API @@ -92,22 +91,6 @@ func main() { Msg("Failed to start service") } - backendConn, err := grpc.Dial(conf.Service.Backend, grpc.WithTransportCredentials(insecure.NewCredentials())) - if err != nil { - log.Fatal(). - Err(err). - Str("service", "johnjud-backend"). - Msg("Cannot connect to service") - } - - fileConn, err := grpc.Dial(conf.Service.File, grpc.WithTransportCredentials(insecure.NewCredentials())) - if err != nil { - log.Fatal(). - Err(err). - Str("service", "johnjud-file"). - Msg("Cannot connect to service") - } - hc := healthcheck.NewHandler() uuidUtil := utils.NewUuidUtil() @@ -133,12 +116,25 @@ func main() { authGuard := guard.NewAuthGuard(authSvc, constant.ExcludePath, constant.AdminPath, conf.App, constant.VersionList) - imageClient := imageProto.NewImageServiceClient(fileConn) - imageService := image.NewService(imageClient) + minioClient, err := minio.New(conf.Bucket.Endpoint, &minio.Options{ + Creds: credentials.NewStaticV4(conf.Bucket.AccessKeyID, conf.Bucket.SecretAccessKey, ""), + Secure: conf.Bucket.UseSSL, + }) + if err != nil { + log.Fatal(). + Err(err). + Str("service", "file"). + Msg("Failed to start Minio client") + return + } + imageClient := bucket.NewClient(conf.Bucket, minioClient) + randomUtils := utils.NewRandomUtil() + imageRepo := image.NewRepository(db) + imageService := image.NewService(imageClient, imageRepo, randomUtils) imageHandler := image.NewHandler(imageService, v, conf.App.MaxFileSize) - petClient := petProto.NewPetServiceClient(backendConn) - petService := pet.NewService(petClient, imageService) + petRepo := pet.NewRepository(db) + petService := pet.NewService(petRepo, imageService) petHandler := pet.NewHandler(petService, imageService, v) r := router.NewFiberRouter(&authGuard, conf.App) diff --git a/config/config.go b/config/config.go index 2214c8f..a267810 100644 --- a/config/config.go +++ b/config/config.go @@ -13,12 +13,6 @@ type App struct { MaxFileSize int64 } -type Service struct { - Auth string - Backend string - File string -} - type Database struct { Url string } @@ -57,7 +51,6 @@ type Bucket struct { type Config struct { App App - Service Service Database Database Redis Redis Jwt Jwt @@ -88,12 +81,6 @@ func LoadConfig() (*Config, error) { MaxFileSize: maxFileSize, } - service := Service{ - Auth: os.Getenv("SERVICE_AUTH"), - Backend: os.Getenv("SERVICE_BACKEND"), - File: os.Getenv("SERVICE_FILE"), - } - database := Database{ Url: os.Getenv("DB_URL"), } @@ -148,7 +135,6 @@ func LoadConfig() (*Config, error) { return &Config{ App: app, - Service: service, Database: database, Redis: redis, Jwt: jwt, diff --git a/internal/pet/old/pet.service.go b/internal/pet/old/pet.service.go new file mode 100644 index 0000000..f0f4dd2 --- /dev/null +++ b/internal/pet/old/pet.service.go @@ -0,0 +1,365 @@ +package pet + +// import ( +// "context" +// "net/http" +// "time" + +// "github.com/isd-sgcu/johnjud-gateway/constant" +// "github.com/isd-sgcu/johnjud-gateway/internal/dto" +// "github.com/isd-sgcu/johnjud-gateway/internal/image" + +// petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" +// "github.com/rs/zerolog/log" +// "google.golang.org/grpc/codes" +// "google.golang.org/grpc/status" +// ) + +// type Service interface { +// FindAll(*dto.FindAllPetRequest, bool) (*dto.FindAllPetResponse, *dto.ResponseErr) +// FindOne(string) (*dto.PetResponse, *dto.ResponseErr) +// Create(*dto.CreatePetRequest) (*dto.PetResponse, *dto.ResponseErr) +// Update(string, *dto.UpdatePetRequest) (*dto.PetResponse, *dto.ResponseErr) +// Delete(string) (*dto.DeleteResponse, *dto.ResponseErr) +// ChangeView(string, *dto.ChangeViewPetRequest) (*dto.ChangeViewPetResponse, *dto.ResponseErr) +// Adopt(string, *dto.AdoptByRequest) (*dto.AdoptByResponse, *dto.ResponseErr) +// } + +// type serviceImpl struct { +// petClient petproto.PetServiceClient +// imageService image.Service +// } + +// func NewService(petClient petproto.PetServiceClient, imageService image.Service) Service { +// return &serviceImpl{ +// petClient: petClient, +// imageService: imageService, +// } +// } + +// func (s *serviceImpl) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result *dto.FindAllPetResponse, err *dto.ResponseErr) { +// ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) +// defer cancel() + +// res, errRes := s.petClient.FindAll(ctx, FindAllDtoToProto(in, isAdmin)) +// if errRes != nil { +// st, _ := status.FromError(errRes) +// log.Error(). +// Err(errRes). +// Str("service", "pet"). +// Str("module", "find all"). +// Msg(st.Message()) +// switch st.Code() { +// case codes.Unavailable: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusServiceUnavailable, +// Message: constant.UnavailableServiceMessage, +// Data: nil, +// } +// } +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusInternalServerError, +// Message: constant.InternalErrorMessage, +// Data: nil, +// } +// } + +// images, errSvc := s.imageService.FindAll() +// if errSvc != nil { +// return nil, errSvc +// } + +// imagesList := ImageList(images) +// findAllDto := ProtoToDtoList(res.Pets, imagesList, isAdmin) +// metaData := MetadataProtoToDto(res.Metadata) + +// return &dto.FindAllPetResponse{ +// Pets: findAllDto, +// Metadata: metaData, +// }, nil +// } + +// func (s *serviceImpl) FindOne(id string) (result *dto.PetResponse, err *dto.ResponseErr) { +// ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) +// defer cancel() + +// res, errRes := s.petClient.FindOne(ctx, &petproto.FindOnePetRequest{Id: id}) +// if errRes != nil { +// st, _ := status.FromError(errRes) +// log.Error(). +// Err(errRes). +// Str("service", "pet"). +// Str("module", "find one"). +// Msg(st.Message()) +// switch st.Code() { +// case codes.NotFound: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusNotFound, +// Message: constant.PetNotFoundMessage, +// Data: nil, +// } + +// case codes.Unavailable: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusServiceUnavailable, +// Message: constant.UnavailableServiceMessage, +// Data: nil, +// } +// default: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusInternalServerError, +// Message: constant.InternalErrorMessage, +// Data: nil, +// } +// } +// } + +// imgRes, imgErrRes := s.imageService.FindByPetId(res.Pet.Id) +// if imgErrRes != nil { +// return nil, imgErrRes +// } + +// findOneResponse := ProtoToDto(res.Pet, imgRes) +// return findOneResponse, nil +// } + +// func (s *serviceImpl) Create(in *dto.CreatePetRequest) (result *dto.PetResponse, err *dto.ResponseErr) { +// ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) +// defer cancel() + +// request := CreateDtoToProto(in) + +// res, errRes := s.petClient.Create(ctx, request) +// if errRes != nil { +// st, _ := status.FromError(errRes) +// log.Error(). +// Err(errRes). +// Str("service", "pet"). +// Str("module", "create"). +// Msg(st.Message()) +// switch st.Code() { +// case codes.InvalidArgument: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusBadRequest, +// Message: constant.InvalidArgumentMessage, +// Data: nil, +// } +// case codes.Unavailable: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusServiceUnavailable, +// Message: constant.UnavailableServiceMessage, +// Data: nil, +// } +// default: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusInternalServerError, +// Message: constant.InternalErrorMessage, +// Data: nil, +// } +// } +// } + +// _, assignErr := s.imageService.AssignPet(&dto.AssignPetRequest{ +// Ids: in.Images, +// PetId: res.Pet.Id, +// }) +// if assignErr != nil { +// return nil, assignErr +// } + +// imgRes, imgErrRes := s.imageService.FindByPetId(res.Pet.Id) +// if imgErrRes != nil { +// return nil, imgErrRes +// } + +// createPetResponse := ProtoToDto(res.Pet, imgRes) +// return createPetResponse, nil +// } + +// func (s *serviceImpl) Update(id string, in *dto.UpdatePetRequest) (result *dto.PetResponse, err *dto.ResponseErr) { +// ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) +// defer cancel() + +// request := UpdateDtoToProto(id, in) + +// res, errRes := s.petClient.Update(ctx, request) +// if errRes != nil { +// st, _ := status.FromError(errRes) +// log.Error(). +// Err(errRes). +// Str("service", "pet"). +// Str("module", "update"). +// Msg(st.Message()) +// switch st.Code() { +// case codes.NotFound: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusNotFound, +// Message: constant.PetNotFoundMessage, +// Data: nil, +// } +// case codes.InvalidArgument: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusBadRequest, +// Message: constant.InvalidArgumentMessage, +// Data: nil, +// } +// case codes.Unavailable: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusServiceUnavailable, +// Message: constant.UnavailableServiceMessage, +// Data: nil, +// } +// default: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusInternalServerError, +// Message: constant.InternalErrorMessage, +// Data: nil, +// } +// } +// } + +// images, errSvc := s.imageService.FindByPetId(res.Pet.Id) +// if errSvc != nil { +// return nil, errSvc +// } + +// updatePetResponse := ProtoToDto(res.Pet, images) +// return updatePetResponse, nil +// } + +// func (s *serviceImpl) Delete(id string) (result *dto.DeleteResponse, err *dto.ResponseErr) { +// ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) +// defer cancel() + +// _, errSvc := s.imageService.DeleteByPetId(id) +// if errSvc != nil { +// return nil, errSvc +// } + +// res, errRes := s.petClient.Delete(ctx, &petproto.DeletePetRequest{ +// Id: id, +// }) +// if errRes != nil { +// st, _ := status.FromError(errRes) +// log.Error(). +// Err(errRes). +// Str("service", "pet"). +// Str("module", "delete"). +// Msg(st.Message()) +// switch st.Code() { +// case codes.NotFound: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusNotFound, +// Message: constant.PetNotFoundMessage, +// Data: nil, +// } +// case codes.Unavailable: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusServiceUnavailable, +// Message: constant.UnavailableServiceMessage, +// Data: nil, +// } +// default: +// return nil, &dto.ResponseErr{ +// StatusCode: http.StatusInternalServerError, +// Message: constant.InternalErrorMessage, +// Data: nil, +// } +// } +// } + +// return &dto.DeleteResponse{ +// Success: res.Success, +// }, nil +// } + +// func (s *serviceImpl) ChangeView(id string, in *dto.ChangeViewPetRequest) (result *dto.ChangeViewPetResponse, err *dto.ResponseErr) { +// ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) +// defer cancel() + +// res, errRes := s.petClient.ChangeView(ctx, &petproto.ChangeViewPetRequest{ +// Id: id, +// Visible: in.Visible, +// }) +// if errRes != nil { +// st, _ := status.FromError(errRes) +// log.Error(). +// Err(errRes). +// Str("service", "pet"). +// Str("module", "change view"). +// Msg(st.Message()) +// switch st.Code() { +// case codes.NotFound: +// return &dto.ChangeViewPetResponse{ +// Success: false, +// }, &dto.ResponseErr{ +// StatusCode: http.StatusNotFound, +// Message: constant.PetNotFoundMessage, +// Data: nil, +// } +// case codes.Unavailable: +// return &dto.ChangeViewPetResponse{ +// Success: false, +// }, &dto.ResponseErr{ +// StatusCode: http.StatusServiceUnavailable, +// Message: constant.UnavailableServiceMessage, +// Data: nil, +// } +// default: +// return &dto.ChangeViewPetResponse{ +// Success: false, +// }, &dto.ResponseErr{ +// StatusCode: http.StatusServiceUnavailable, +// Message: constant.InternalErrorMessage, +// Data: nil, +// } +// } +// } +// return &dto.ChangeViewPetResponse{ +// Success: res.Success, +// }, nil +// } + +// func (s *serviceImpl) Adopt(petId string, in *dto.AdoptByRequest) (result *dto.AdoptByResponse, err *dto.ResponseErr) { +// ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) +// defer cancel() + +// res, errRes := s.petClient.AdoptPet(ctx, &petproto.AdoptPetRequest{ +// UserId: in.UserID, +// PetId: petId, +// }) +// if errRes != nil { +// st, _ := status.FromError(errRes) +// log.Error(). +// Err(errRes). +// Str("service", "pet"). +// Str("module", "adopt"). +// Msg(st.Message()) +// switch st.Code() { +// case codes.NotFound: +// return nil, +// &dto.ResponseErr{ +// StatusCode: http.StatusNotFound, +// Message: constant.PetNotFoundMessage, +// Data: nil, +// } +// case codes.Unavailable: +// return nil, +// &dto.ResponseErr{ +// StatusCode: http.StatusServiceUnavailable, +// Message: constant.UnavailableServiceMessage, +// Data: nil, +// } +// default: +// return nil, +// &dto.ResponseErr{ +// StatusCode: http.StatusServiceUnavailable, +// Message: constant.InternalErrorMessage, +// Data: nil, +// } +// } +// } +// return &dto.AdoptByResponse{ +// Success: res.Success, +// }, nil +// } diff --git a/internal/pet/old/pet.utils.go b/internal/pet/old/pet.utils.go new file mode 100644 index 0000000..a2a7341 --- /dev/null +++ b/internal/pet/old/pet.utils.go @@ -0,0 +1,269 @@ +package pet + +// import ( +// "errors" +// "strconv" + +// "github.com/isd-sgcu/johnjud-gateway/constant" +// "github.com/isd-sgcu/johnjud-gateway/internal/dto" +// petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" +// imgproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" +// ) + +// func ImageList(in []*dto.ImageResponse) map[string][]*imgproto.Image { +// imagesList := make(map[string][]*imgproto.Image) +// for _, image := range in { +// img := &imgproto.Image{ +// Id: image.Id, +// PetId: image.PetId, +// ImageUrl: image.Url, +// ObjectKey: image.ObjectKey, +// } +// imagesList[image.PetId] = append(imagesList[image.PetId], img) +// } + +// return imagesList +// } + +// func ImageProtoToDto(images []*imgproto.Image) []*dto.ImageResponse { +// var imageDto []*dto.ImageResponse +// for _, image := range images { +// imageDto = append(imageDto, &dto.ImageResponse{ +// Id: image.Id, +// PetId: image.PetId, +// Url: image.ImageUrl, +// ObjectKey: image.ObjectKey, +// }) +// } +// return imageDto +// } + +// func ImageListProtoToDto(imagesList [][]*imgproto.Image) [][]*dto.ImageResponse { +// var imageListDto [][]*dto.ImageResponse +// for _, images := range imagesList { +// var imageDto []*dto.ImageResponse +// for _, image := range images { +// imageDto = append(imageDto, &dto.ImageResponse{ +// Id: image.Id, +// PetId: image.PetId, +// Url: image.ImageUrl, +// ObjectKey: image.ObjectKey, +// }) +// } +// imageListDto = append(imageListDto, imageDto) +// } +// return imageListDto +// } + +// func ProtoToDto(in *petproto.Pet, images []*dto.ImageResponse) *dto.PetResponse { +// pet := &dto.PetResponse{ +// Id: in.Id, +// Type: in.Type, +// Name: in.Name, +// Birthdate: in.Birthdate, +// Gender: constant.Gender(in.Gender), +// Color: in.Color, +// Pattern: in.Pattern, +// Habit: in.Habit, +// Caption: in.Caption, +// Status: constant.Status(in.Status), +// IsSterile: &in.IsSterile, +// IsVaccinated: &in.IsVaccinated, +// IsVisible: &in.IsVisible, +// Origin: in.Origin, +// Owner: in.Owner, +// Contact: in.Contact, +// Tel: in.Tel, +// Images: images, +// } +// return pet +// } + +// func CreateDtoToProto(in *dto.CreatePetRequest) *petproto.CreatePetRequest { +// return &petproto.CreatePetRequest{ +// Pet: &petproto.Pet{ +// Type: in.Type, +// Name: in.Name, +// Birthdate: in.Birthdate, +// Gender: string(in.Gender), +// Color: in.Color, +// Pattern: in.Pattern, +// Habit: in.Habit, +// Caption: in.Caption, +// Images: []*imgproto.Image{}, +// Status: string(in.Status), +// IsSterile: *in.IsSterile, +// IsVaccinated: *in.IsVaccinated, +// IsVisible: *in.IsVisible, +// Origin: in.Origin, +// Owner: in.Owner, +// Contact: in.Contact, +// Tel: in.Tel, +// }, +// } +// } + +// func UpdateDtoToProto(id string, in *dto.UpdatePetRequest) *petproto.UpdatePetRequest { +// isSterile := false +// if in.IsSterile != nil { +// isSterile = *in.IsSterile +// } +// isVaccinated := false +// if in.IsVaccinated != nil { +// isVaccinated = *in.IsVaccinated +// } +// isVisible := false +// if in.IsVisible != nil { +// isVisible = *in.IsVisible +// } + +// req := &petproto.UpdatePetRequest{ +// Pet: &petproto.Pet{ +// Id: id, +// Type: in.Type, +// Name: in.Name, +// Birthdate: in.Birthdate, +// Gender: string(in.Gender), +// Color: in.Color, +// Pattern: in.Pattern, +// Habit: in.Habit, +// Caption: in.Caption, +// Images: []*imgproto.Image{}, +// Status: string(in.Status), +// IsSterile: isSterile, +// IsVaccinated: isVaccinated, +// IsVisible: isVisible, +// Origin: in.Origin, +// Owner: in.Owner, +// Contact: in.Contact, +// Tel: in.Tel, +// }, +// } + +// return req +// } + +// func ProtoToDtoList(in []*petproto.Pet, imagesList map[string][]*imgproto.Image, isAdmin bool) []*dto.PetResponse { +// var resp []*dto.PetResponse +// for _, p := range in { +// if !isAdmin && !p.IsVisible { +// continue +// } +// pet := &dto.PetResponse{ +// Id: p.Id, +// Type: p.Type, +// Name: p.Name, +// Birthdate: p.Birthdate, +// Gender: constant.Gender(p.Gender), +// Color: p.Color, +// Pattern: p.Pattern, +// Habit: p.Habit, +// Caption: p.Caption, +// Status: constant.Status(p.Status), +// IsSterile: &p.IsSterile, +// IsVaccinated: &p.IsVaccinated, +// IsVisible: &p.IsVisible, +// Origin: p.Origin, +// Owner: p.Owner, +// Contact: p.Contact, +// Tel: p.Tel, +// Images: ImageProtoToDto(imagesList[p.Id]), +// } +// resp = append(resp, pet) +// } +// return resp +// } + +// func extractImages(images []*imgproto.Image) []dto.ImageResponse { +// var result []dto.ImageResponse +// for _, img := range images { +// result = append(result, dto.ImageResponse{ +// Id: img.Id, +// Url: img.ImageUrl, +// }) +// } +// return result +// } + +// func FindAllDtoToProto(in *dto.FindAllPetRequest, isAdmin bool) *petproto.FindAllPetRequest { +// return &petproto.FindAllPetRequest{ +// Search: in.Search, +// Type: in.Type, +// Gender: in.Gender, +// Color: in.Color, +// Pattern: in.Pattern, +// Origin: in.Origin, +// PageSize: int32(in.PageSize), +// Page: int32(in.Page), +// MaxAge: int32(in.MaxAge), +// MinAge: int32(in.MinAge), +// IsAdmin: isAdmin, +// } +// } + +// func MetadataProtoToDto(in *petproto.FindAllPetMetaData) *dto.FindAllMetadata { +// return &dto.FindAllMetadata{ +// Page: int(in.Page), +// TotalPages: int(in.TotalPages), +// PageSize: int(in.PageSize), +// Total: int(in.Total), +// } +// } + +// func QueriesToFindAllDto(queries map[string]string) (*dto.FindAllPetRequest, error) { +// request := &dto.FindAllPetRequest{ +// Search: "", +// Type: "", +// Gender: "", +// Color: "", +// Pattern: "", +// MinAge: 0, +// MaxAge: 0, +// Origin: "", +// PageSize: 0, +// Page: 0, +// } + +// for q, v := range queries { +// switch q { +// case "search": +// request.Search = v +// case "type": +// request.Type = v +// case "gender": +// request.Gender = v +// case "color": +// request.Color = v +// case "pattern": +// request.Pattern = v +// case "minAge": +// minAge, err := strconv.Atoi(v) +// if err != nil { +// return nil, errors.New("error parsing minAge") +// } +// request.MinAge = minAge +// case "maxAge": +// maxAge, err := strconv.Atoi(v) +// if err != nil { +// return nil, errors.New("error parsing maxAge") +// } +// request.MaxAge = maxAge +// case "origin": +// request.Origin = v +// case "pageSize": +// pageSize, err := strconv.Atoi(v) +// if err != nil { +// return nil, errors.New("error pasring pageSize") +// } +// request.PageSize = pageSize +// case "page": +// page, err := strconv.Atoi(v) +// if err != nil { +// return nil, errors.New("error pasring page") +// } +// request.Page = page +// } +// } + +// return request, nil +// } diff --git a/internal/pet/old/test/pet.service_test.go b/internal/pet/old/test/pet.service_test.go new file mode 100644 index 0000000..6668622 --- /dev/null +++ b/internal/pet/old/test/pet.service_test.go @@ -0,0 +1,759 @@ +package test + +// import ( +// "math/rand" +// "net/http" +// "testing" + +// "github.com/go-faker/faker/v4" +// "github.com/isd-sgcu/johnjud-gateway/constant" +// "github.com/isd-sgcu/johnjud-gateway/internal/dto" +// imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/image" +// "github.com/isd-sgcu/johnjud-gateway/internal/pet" +// imagemock "github.com/isd-sgcu/johnjud-gateway/mocks/client/image" +// petmock "github.com/isd-sgcu/johnjud-gateway/mocks/client/pet" +// petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" +// imgproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" +// "github.com/stretchr/testify/assert" +// "github.com/stretchr/testify/suite" +// "google.golang.org/grpc/codes" +// "google.golang.org/grpc/status" +// ) + +// type PetServiceTest struct { +// suite.Suite +// Pets []*petproto.Pet +// Pet *petproto.Pet +// MetadataDto *dto.FindAllMetadata +// MetadataProto *petproto.FindAllPetMetaData +// PetNotVisible *petproto.Pet +// FindAllPetReq *petproto.FindAllPetRequest +// FindAllImageReq *imgproto.FindAllImageRequest +// UpdatePetReq *petproto.UpdatePetRequest +// CreatePetReq *petproto.CreatePetRequest +// ChangeViewPetReq *petproto.ChangeViewPetRequest +// DeletePetReq *petproto.DeletePetRequest +// AdoptReq *petproto.AdoptPetRequest +// PetDto *dto.PetResponse +// FindAllPetDto *dto.FindAllPetRequest +// CreatePetDto *dto.CreatePetRequest +// UpdatePetDto *dto.UpdatePetRequest +// NotFoundErr *dto.ResponseErr +// UnavailableServiceErr *dto.ResponseErr +// InvalidArgumentErr *dto.ResponseErr +// InternalErr *dto.ResponseErr +// ChangeViewedPetDto *dto.ChangeViewPetRequest +// AdoptDto *dto.AdoptByRequest + +// Images []*imgproto.Image +// AllImages []*imgproto.Image +// ImagesList map[string][]*imgproto.Image + +// AssignPetReq *imgproto.AssignPetRequest +// AssignPetDto *dto.AssignPetRequest + +// FindByPetIdReq *imgproto.FindImageByPetIdRequest +// } + +// func TestPetService(t *testing.T) { +// suite.Run(t, new(PetServiceTest)) +// } + +// func (t *PetServiceTest) SetupTest() { +// petIds := []string{faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit()} +// t.AllImages = []*imgproto.Image{} +// imagesList := make(map[string][]*imgproto.Image) +// for i := 0; i <= 3; i++ { +// for j := 0; j <= 3; j++ { +// img := &imgproto.Image{ +// Id: faker.UUIDDigit(), +// PetId: petIds[i], +// ImageUrl: faker.URL(), +// ObjectKey: faker.Word(), +// } +// imagesList[petIds[i]] = append(imagesList[petIds[i]], img) +// t.AllImages = append(t.AllImages, img) +// } +// } +// t.ImagesList = imagesList +// t.Images = imagesList[petIds[0]] +// genders := []constant.Gender{constant.MALE, constant.FEMALE} +// statuses := []constant.Status{constant.ADOPTED, constant.FINDHOME} + +// var pets []*petproto.Pet +// for i := 0; i <= 3; i++ { +// pet := &petproto.Pet{ +// Id: petIds[i], +// Type: faker.Word(), +// Name: faker.Name(), +// Birthdate: faker.Word(), +// Gender: string(genders[rand.Intn(2)]), +// Color: faker.Word(), +// Pattern: faker.Word(), +// Habit: faker.Paragraph(), +// Caption: faker.Paragraph(), +// Images: imagesList[petIds[i]], +// Status: string(statuses[rand.Intn(2)]), +// IsSterile: true, +// IsVaccinated: true, +// IsVisible: true, +// Origin: faker.Paragraph(), +// Owner: faker.Paragraph(), +// Contact: faker.Paragraph(), +// Tel: faker.UUIDDigit(), +// } + +// pets = append(pets, pet) +// } + +// t.MetadataDto = &dto.FindAllMetadata{ +// Page: 1, +// TotalPages: 1, +// PageSize: len(t.Pets), +// Total: len(t.Pets), +// } + +// t.MetadataProto = &petproto.FindAllPetMetaData{ +// Page: 1, +// TotalPages: 1, +// PageSize: int32(len(t.Pets)), +// Total: int32(len(t.Pets)), +// } + +// t.Pets = pets +// t.Pet = t.Pets[0] + +// t.PetNotVisible = &petproto.Pet{ +// Id: t.Pet.Id, +// Type: t.Pet.Type, +// Name: t.Pet.Name, +// Birthdate: t.Pet.Birthdate, +// Gender: t.Pet.Gender, +// Color: t.Pet.Color, +// Pattern: t.Pet.Pattern, +// Habit: t.Pet.Habit, +// Caption: t.Pet.Caption, +// Images: t.Pet.Images, +// Status: t.Pet.Status, +// IsSterile: t.Pet.IsSterile, +// IsVaccinated: t.Pet.IsVaccinated, +// IsVisible: false, +// Origin: t.Pet.Origin, +// Owner: t.Pet.Owner, +// Contact: t.Pet.Contact, +// Tel: t.Pet.Tel, +// } + +// t.PetDto = pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) + +// t.FindAllPetDto = &dto.FindAllPetRequest{ +// Search: "", +// Type: "", +// Gender: "", +// Color: "", +// Pattern: "", +// Age: "", +// Origin: "", +// PageSize: len(t.Pets), +// Page: 1, +// } + +// t.CreatePetDto = &dto.CreatePetRequest{ +// Type: t.Pet.Type, +// Name: t.Pet.Name, +// Birthdate: t.Pet.Birthdate, +// Gender: constant.Gender(t.Pet.Gender), +// Color: t.Pet.Color, +// Pattern: t.Pet.Pattern, +// Habit: t.Pet.Habit, +// Caption: t.Pet.Caption, +// Images: []string{}, +// Status: constant.Status(t.Pet.Status), +// IsSterile: &t.Pet.IsSterile, +// IsVaccinated: &t.Pet.IsVaccinated, +// IsVisible: &t.Pet.IsVisible, +// Origin: t.Pet.Origin, +// Owner: t.Pet.Owner, +// Contact: t.Pet.Contact, +// Tel: t.Pet.Tel, +// } + +// t.UpdatePetDto = &dto.UpdatePetRequest{ +// Type: t.Pet.Type, +// Name: t.Pet.Name, +// Birthdate: t.Pet.Birthdate, +// Gender: constant.Gender(t.Pet.Gender), +// Color: t.Pet.Color, +// Pattern: t.Pet.Pattern, +// Habit: t.Pet.Habit, +// Caption: t.Pet.Caption, +// Images: []string{}, +// Status: constant.Status(t.Pet.Status), +// IsSterile: &t.Pet.IsSterile, +// IsVaccinated: &t.Pet.IsVaccinated, +// IsVisible: &t.Pet.IsVisible, +// Origin: t.Pet.Origin, +// Owner: t.Pet.Owner, +// Contact: t.Pet.Contact, +// Tel: t.Pet.Tel, +// } + +// t.FindAllPetReq = pet.FindAllDtoToProto(t.FindAllPetDto, true) +// t.CreatePetReq = pet.CreateDtoToProto(t.CreatePetDto) +// t.UpdatePetReq = pet.UpdateDtoToProto(t.Pet.Id, t.UpdatePetDto) + +// t.ChangeViewPetReq = &petproto.ChangeViewPetRequest{ +// Id: t.Pet.Id, +// Visible: false, +// } + +// t.ChangeViewedPetDto = &dto.ChangeViewPetRequest{ +// Visible: false, +// } + +// t.AdoptReq = &petproto.AdoptPetRequest{ +// PetId: t.Pet.Id, +// UserId: t.Pet.Owner, +// } + +// t.AdoptDto = &dto.AdoptByRequest{ +// UserID: t.Pet.Owner, +// } + +// t.FindAllImageReq = &imgproto.FindAllImageRequest{} + +// t.AssignPetReq = &imgproto.AssignPetRequest{ +// Ids: []string{}, +// PetId: t.Pet.Id, +// } + +// t.AssignPetDto = &dto.AssignPetRequest{ +// Ids: []string{}, +// PetId: t.Pet.Id, +// } + +// t.FindByPetIdReq = &imgproto.FindImageByPetIdRequest{ +// PetId: t.Pet.Id, +// } + +// t.UnavailableServiceErr = &dto.ResponseErr{ +// StatusCode: http.StatusServiceUnavailable, +// Message: constant.UnavailableServiceMessage, +// Data: nil, +// } + +// t.NotFoundErr = &dto.ResponseErr{ +// StatusCode: http.StatusNotFound, +// Message: constant.PetNotFoundMessage, +// Data: nil, +// } + +// t.InternalErr = &dto.ResponseErr{ +// StatusCode: http.StatusInternalServerError, +// Message: constant.InternalErrorMessage, +// Data: nil, +// } + +// t.InvalidArgumentErr = &dto.ResponseErr{ +// StatusCode: http.StatusBadRequest, +// Message: constant.InvalidArgumentMessage, +// Data: nil, +// } +// } + +// func (t *PetServiceTest) TestFindAllSuccess() { +// protoResp := &petproto.FindAllPetResponse{ +// Pets: t.Pets, +// Metadata: t.MetadataProto, +// } + +// findAllPPetsDto := pet.ProtoToDtoList(t.Pets, t.ImagesList, false) +// metadataDto := t.MetadataDto + +// expected := &dto.FindAllPetResponse{ +// Pets: findAllPPetsDto, +// Metadata: metadataDto, +// } + +// client := petmock.PetClientMock{} +// client.On("FindAll", t.FindAllPetReq).Return(protoResp, nil) + +// findAllImageResp := &imgproto.FindAllImageResponse{ +// Images: t.AllImages, +// } +// imageClient := imagemock.ImageClientMock{} +// imageClient.On("FindAll", t.FindAllImageReq).Return(findAllImageResp, nil) + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(&client, imageSvc) +// actual, err := svc.FindAll(t.FindAllPetDto, true) + +// assert.Nil(t.T(), err) +// assert.Equal(t.T(), expected, actual) +// } + +// func (t *PetServiceTest) TestFindAllUnavailableServiceError() { +// expected := t.UnavailableServiceErr + +// clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + +// client := petmock.PetClientMock{} +// client.On("FindAll", t.FindAllPetReq).Return(nil, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(&client, imageSvc) +// actual, err := svc.FindAll(t.FindAllPetDto, true) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestFindOneSuccess() { +// protoReq := &petproto.FindOnePetRequest{ +// Id: t.Pet.Id, +// } +// protoResp := &petproto.FindOnePetResponse{ +// Pet: t.Pet, +// } + +// findByPetIdReq := t.FindByPetIdReq +// findByPetIdResp := &imgproto.FindImageByPetIdResponse{ +// Images: t.Images, +// } + +// expected := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) + +// client := petmock.PetClientMock{} +// client.On("FindOne", protoReq).Return(protoResp, nil) + +// imageClient := imagemock.ImageClientMock{} +// imageClient.On("FindByPetId", findByPetIdReq).Return(findByPetIdResp, nil) + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(&client, imageSvc) +// actual, err := svc.FindOne(t.Pet.Id) + +// assert.Nil(t.T(), err) +// assert.Equal(t.T(), expected, actual) +// } + +// func (t *PetServiceTest) TestFindOneNotFoundError() { +// protoReq := &petproto.FindOnePetRequest{ +// Id: t.Pet.Id, +// } + +// clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) + +// expected := t.NotFoundErr + +// client := petmock.PetClientMock{} +// client.On("FindOne", protoReq).Return(nil, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(&client, imageSvc) +// actual, err := svc.FindOne(t.Pet.Id) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestFindOneUnavailableServiceError() { +// protoReq := &petproto.FindOnePetRequest{ +// Id: t.Pet.Id, +// } + +// clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + +// expected := t.UnavailableServiceErr + +// client := petmock.PetClientMock{} +// client.On("FindOne", protoReq).Return(nil, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) + +// svc := pet.NewService(&client, imageSvc) +// actual, err := svc.FindOne(t.Pet.Id) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestCreateSuccess() { +// protoReq := t.CreatePetReq +// protoResp := &petproto.CreatePetResponse{ +// Pet: t.Pet, +// } + +// assignPetReq := t.AssignPetReq +// assignPetResp := &imgproto.AssignPetResponse{ +// Success: true, +// } + +// findByPetIdReq := t.FindByPetIdReq +// findByPetIdResp := &imgproto.FindImageByPetIdResponse{ +// Images: t.Images, +// } + +// expected := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) + +// client := &petmock.PetClientMock{} +// client.On("Create", protoReq).Return(protoResp, nil) + +// imageClient := imagemock.ImageClientMock{} +// imageClient.On("AssignPet", assignPetReq).Return(assignPetResp, nil) +// imageClient.On("FindByPetId", findByPetIdReq).Return(findByPetIdResp, nil) + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Create(t.CreatePetDto) + +// assert.Nil(t.T(), err) +// assert.Equal(t.T(), expected, actual) +// } + +// func (t *PetServiceTest) TestCreateInvalidArgumentError() { +// protoReq := t.CreatePetReq + +// expected := t.InvalidArgumentErr + +// clientErr := status.Error(codes.InvalidArgument, constant.InvalidArgumentMessage) + +// client := &petmock.PetClientMock{} +// client.On("Create", protoReq).Return(nil, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Create(t.CreatePetDto) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestCreateInternalError() { +// protoReq := t.CreatePetReq + +// expected := t.InternalErr + +// clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) + +// client := &petmock.PetClientMock{} +// client.On("Create", protoReq).Return(nil, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Create(t.CreatePetDto) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestCreateUnavailableServiceError() { +// protoReq := t.CreatePetReq + +// clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + +// expected := t.UnavailableServiceErr + +// client := &petmock.PetClientMock{} +// client.On("Create", protoReq).Return(nil, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Create(t.CreatePetDto) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestUpdateSuccess() { +// protoReq := t.UpdatePetReq +// protoResp := &petproto.UpdatePetResponse{ +// Pet: t.Pet, +// } + +// expected := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) + +// client := &petmock.PetClientMock{} +// client.On("Update", protoReq).Return(protoResp, nil) + +// findByPetIdResp := &imgproto.FindImageByPetIdResponse{ +// Images: t.Images, +// } +// imageClient := imagemock.ImageClientMock{} +// imageClient.On("FindByPetId", t.FindByPetIdReq).Return(findByPetIdResp, nil) + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) + +// assert.Nil(t.T(), err) +// assert.Equal(t.T(), expected, actual) +// } + +// func (t *PetServiceTest) TestUpdateNotFound() { +// protoReq := t.UpdatePetReq +// clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) + +// expected := t.NotFoundErr + +// client := &petmock.PetClientMock{} +// client.On("Update", protoReq).Return(nil, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestUpdateUnavailableServiceError() { +// protoReq := t.UpdatePetReq +// clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + +// expected := t.UnavailableServiceErr + +// client := &petmock.PetClientMock{} +// client.On("Update", protoReq).Return(nil, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestDeleteSuccess() { +// petProtoReq := &petproto.DeletePetRequest{ +// Id: t.Pet.Id, +// } +// petProtoResp := &petproto.DeletePetResponse{ +// Success: true, +// } +// imageProtoReq := &imgproto.DeleteByPetIdRequest{ +// PetId: t.Pet.Id, +// } +// imageProtoResp := &imgproto.DeleteByPetIdResponse{ +// Success: true, +// } + +// expected := &dto.DeleteResponse{Success: true} + +// client := &petmock.PetClientMock{} +// client.On("Delete", petProtoReq).Return(petProtoResp, nil) + +// imageClient := imagemock.ImageClientMock{} +// imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Delete(t.Pet.Id) + +// assert.Nil(t.T(), err) +// assert.Equal(t.T(), expected, actual) +// } + +// func (t *PetServiceTest) TestDeleteNotFound() { +// protoReq := &petproto.DeletePetRequest{ +// Id: t.Pet.Id, +// } +// protoResp := &petproto.DeletePetResponse{ +// Success: false, +// } +// imageProtoReq := &imgproto.DeleteByPetIdRequest{ +// PetId: t.Pet.Id, +// } +// imageProtoResp := &imgproto.DeleteByPetIdResponse{ +// Success: true, +// } + +// clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) + +// expected := t.NotFoundErr + +// client := &petmock.PetClientMock{} +// client.On("Delete", protoReq).Return(protoResp, clientErr) + +// imageClient := imagemock.ImageClientMock{} +// imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Delete(t.Pet.Id) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestDeleteServiceUnavailableError() { +// protoReq := &petproto.DeletePetRequest{ +// Id: t.Pet.Id, +// } +// protoResp := &petproto.DeletePetResponse{ +// Success: false, +// } +// imageProtoReq := &imgproto.DeleteByPetIdRequest{ +// PetId: t.Pet.Id, +// } +// imageProtoResp := &imgproto.DeleteByPetIdResponse{ +// Success: true, +// } + +// clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + +// expected := t.UnavailableServiceErr + +// client := &petmock.PetClientMock{} +// client.On("Delete", protoReq).Return(protoResp, clientErr) + +// imageClient := imagemock.ImageClientMock{} +// imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Delete(t.Pet.Id) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestChangeViewSuccess() { +// protoReq := t.ChangeViewPetReq +// protoResp := &petproto.ChangeViewPetResponse{ +// Success: true, +// } + +// client := &petmock.PetClientMock{} +// client.On("ChangeView", protoReq).Return(protoResp, nil) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) + +// assert.Nil(t.T(), err) +// assert.Equal(t.T(), actual, &dto.ChangeViewPetResponse{Success: true}) +// } + +// func (t *PetServiceTest) TestChangeViewNotFoundError() { +// protoReq := t.ChangeViewPetReq +// protoResp := &petproto.ChangeViewPetResponse{ +// Success: false, +// } + +// clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) + +// expected := t.NotFoundErr + +// client := &petmock.PetClientMock{} +// client.On("ChangeView", protoReq).Return(protoResp, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) + +// assert.Equal(t.T(), &dto.ChangeViewPetResponse{Success: false}, actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestChangeViewUnavailableServiceError() { +// protoReq := t.ChangeViewPetReq +// protoResp := &petproto.ChangeViewPetResponse{ +// Success: false, +// } + +// clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + +// expected := t.UnavailableServiceErr + +// client := &petmock.PetClientMock{} +// client.On("ChangeView", protoReq).Return(protoResp, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) + +// assert.Equal(t.T(), &dto.ChangeViewPetResponse{Success: false}, actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestAdoptSuccess() { +// protoReq := t.AdoptReq +// protoResp := &petproto.AdoptPetResponse{ +// Success: true, +// } + +// client := &petmock.PetClientMock{} +// client.On("AdoptPet", protoReq).Return(protoResp, nil) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) + +// assert.Nil(t.T(), err) +// assert.Equal(t.T(), actual, &dto.AdoptByResponse{Success: true}) +// } + +// func (t *PetServiceTest) TestAdoptNotFoundError() { +// protoReq := t.AdoptReq + +// clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) + +// expected := t.NotFoundErr + +// client := &petmock.PetClientMock{} +// client.On("AdoptPet", protoReq).Return(nil, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } + +// func (t *PetServiceTest) TestAdoptUnavailableServiceError() { +// protoReq := t.AdoptReq + +// clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + +// expected := t.UnavailableServiceErr + +// client := &petmock.PetClientMock{} +// client.On("AdoptPet", protoReq).Return(nil, clientErr) + +// imageClient := imagemock.ImageClientMock{} + +// imageSvc := imageSvc.NewService(&imageClient) +// svc := pet.NewService(client, imageSvc) +// actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) + +// assert.Nil(t.T(), actual) +// assert.Equal(t.T(), expected, err) +// } diff --git a/internal/pet/pet.repository.go b/internal/pet/pet.repository.go index 1aeb8db..60c28c3 100644 --- a/internal/pet/pet.repository.go +++ b/internal/pet/pet.repository.go @@ -7,35 +7,43 @@ import ( "gorm.io/gorm" ) -type Repository struct { +type Repository interface { + FindAll(result *[]*model.Pet, isAdmin bool) error + FindOne(id string, result *model.Pet) error + Create(in *model.Pet) error + Update(id string, result *model.Pet) error + Delete(id string) error +} + +type repositoryImpl struct { db *gorm.DB } -func NewRepository(db *gorm.DB) *Repository { - return &Repository{db: db} +func NewRepository(db *gorm.DB) Repository { + return &repositoryImpl{db: db} } -func (r *Repository) FindAll(result *[]*model.Pet, isAdmin bool) error { +func (r *repositoryImpl) FindAll(result *[]*model.Pet, isAdmin bool) error { if isAdmin { return r.db.Model(&model.Pet{}).Find(result).Error } return r.db.Model(&model.Pet{}).Find(result, "is_visible = ?", true).Error } -func (r *Repository) FindOne(id string, result *model.Pet) error { +func (r *repositoryImpl) FindOne(id string, result *model.Pet) error { return r.db.Model(&model.Pet{}).First(result, "id = ?", id).Error } -func (r *Repository) Create(in *model.Pet) error { +func (r *repositoryImpl) Create(in *model.Pet) error { return r.db.Create(&in).Error } -func (r *Repository) Update(id string, result *model.Pet) error { +func (r *repositoryImpl) Update(id string, result *model.Pet) error { updateMap := UpdateMap(result) - return r.db.Model(&result).Updates(updateMap).First(&result, "id = ?", id).Error + return r.db.Model(&result).Where("id = ?", id).Updates(updateMap).First(&result, "id = ?", id).Error } -func (r *Repository) Delete(id string) error { +func (r *repositoryImpl) Delete(id string) error { var pet model.Pet err := r.db.Where("id = ? AND deleted_at IS NULL", id).First(&pet).Error if err != nil { diff --git a/internal/pet/pet.service.go b/internal/pet/pet.service.go index d4bcb1a..a991b3d 100644 --- a/internal/pet/pet.service.go +++ b/internal/pet/pet.service.go @@ -1,365 +1,179 @@ package pet import ( - "context" - "net/http" - "time" + "errors" + "fmt" - "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" "github.com/isd-sgcu/johnjud-gateway/internal/image" - - petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" + "github.com/isd-sgcu/johnjud-gateway/internal/model" "github.com/rs/zerolog/log" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + + "gorm.io/gorm" ) type Service interface { - FindAll(*dto.FindAllPetRequest, bool) (*dto.FindAllPetResponse, *dto.ResponseErr) - FindOne(string) (*dto.PetResponse, *dto.ResponseErr) - Create(*dto.CreatePetRequest) (*dto.PetResponse, *dto.ResponseErr) - Update(string, *dto.UpdatePetRequest) (*dto.PetResponse, *dto.ResponseErr) - Delete(string) (*dto.DeleteResponse, *dto.ResponseErr) - ChangeView(string, *dto.ChangeViewPetRequest) (*dto.ChangeViewPetResponse, *dto.ResponseErr) - Adopt(string, *dto.AdoptByRequest) (*dto.AdoptByResponse, *dto.ResponseErr) + FindAll(req *dto.FindAllPetRequest, isAdmin bool) (*dto.FindAllPetResponse, *dto.ResponseErr) + FindOne(id string) (*dto.PetResponse, *dto.ResponseErr) + Create(req *dto.CreatePetRequest) (*dto.PetResponse, *dto.ResponseErr) + Update(id string, req *dto.UpdatePetRequest) (*dto.PetResponse, *dto.ResponseErr) + Delete(id string) (*dto.DeleteResponse, *dto.ResponseErr) + ChangeView(id string, req *dto.ChangeViewPetRequest) (*dto.ChangeViewPetResponse, *dto.ResponseErr) + Adopt(id string, req *dto.AdoptByRequest) (*dto.AdoptByResponse, *dto.ResponseErr) } type serviceImpl struct { - petClient petproto.PetServiceClient + repository Repository imageService image.Service } -func NewService(petClient petproto.PetServiceClient, imageService image.Service) Service { - return &serviceImpl{ - petClient: petClient, - imageService: imageService, - } +func NewService(repository Repository, imageService image.Service) Service { + return &serviceImpl{repository: repository, imageService: imageService} } -func (s *serviceImpl) FindAll(in *dto.FindAllPetRequest, isAdmin bool) (result *dto.FindAllPetResponse, err *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - res, errRes := s.petClient.FindAll(ctx, FindAllDtoToProto(in, isAdmin)) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). - Str("service", "pet"). - Str("module", "find all"). - Msg(st.Message()) - switch st.Code() { - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - } - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, +func (s *serviceImpl) Delete(id string) (*dto.DeleteResponse, *dto.ResponseErr) { + err := s.repository.Delete(id) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, dto.NotFoundError("pet not found") } + return nil, dto.InternalServerError("internal error") } + return &dto.DeleteResponse{Success: true}, nil +} + +func (s *serviceImpl) Update(id string, req *dto.UpdatePetRequest) (*dto.PetResponse, *dto.ResponseErr) { + raw := UpdateDtoToModel(req) - images, errSvc := s.imageService.FindAll() - if errSvc != nil { - return nil, errSvc + err := s.repository.Update(id, raw) + if err != nil { + return nil, dto.NotFoundError("pet not found") } - imagesList := ImageList(images) - findAllDto := ProtoToDtoList(res.Pets, imagesList, isAdmin) - metaData := MetadataProtoToDto(res.Metadata) + images, apperr := s.imageService.FindByPetId(id) + if apperr != nil { + return nil, dto.InternalServerError("error querying image service") + } - return &dto.FindAllPetResponse{ - Pets: findAllDto, - Metadata: metaData, - }, nil + return RawToDto(raw, images), nil } -func (s *serviceImpl) FindOne(id string) (result *dto.PetResponse, err *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - res, errRes := s.petClient.FindOne(ctx, &petproto.FindOnePetRequest{Id: id}) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). - Str("service", "pet"). - Str("module", "find one"). - Msg(st.Message()) - switch st.Code() { - case codes.NotFound: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.PetNotFoundMessage, - Data: nil, - } - - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } +func (s *serviceImpl) ChangeView(id string, req *dto.ChangeViewPetRequest) (*dto.ChangeViewPetResponse, *dto.ResponseErr) { + petData, apperr := s.FindOne(id) + if apperr != nil { + return nil, apperr + } + pet, err := DtoToRaw(petData) + if err != nil { + return nil, dto.InternalServerError("error converting dto to raw") } + pet.IsVisible = req.Visible - imgRes, imgErrRes := s.imageService.FindByPetId(res.Pet.Id) - if imgErrRes != nil { - return nil, imgErrRes + err = s.repository.Update(id, pet) + if err != nil { + return nil, dto.NotFoundError("pet not found") } - findOneResponse := ProtoToDto(res.Pet, imgRes) - return findOneResponse, nil + return &dto.ChangeViewPetResponse{Success: true}, nil } -func (s *serviceImpl) Create(in *dto.CreatePetRequest) (result *dto.PetResponse, err *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - request := CreateDtoToProto(in) - - res, errRes := s.petClient.Create(ctx, request) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). - Str("service", "pet"). - Str("module", "create"). - Msg(st.Message()) - switch st.Code() { - case codes.InvalidArgument: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidArgumentMessage, - Data: nil, - } - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } - } +func (s *serviceImpl) FindAll(req *dto.FindAllPetRequest, isAdmin bool) (*dto.FindAllPetResponse, *dto.ResponseErr) { + var pets []*model.Pet + imagesList := make(map[string][]*dto.ImageResponse) + metaData := dto.FindAllMetadata{} - _, assignErr := s.imageService.AssignPet(&dto.AssignPetRequest{ - Ids: in.Images, - PetId: res.Pet.Id, - }) - if assignErr != nil { - return nil, assignErr + err := s.repository.FindAll(&pets, isAdmin) + if err != nil { + log.Error().Err(err).Str("service", "event").Str("module", "find all").Msg("Error while querying all events") + return nil, dto.InternalServerError("error querying all pets") } - imgRes, imgErrRes := s.imageService.FindByPetId(res.Pet.Id) - if imgErrRes != nil { - return nil, imgErrRes + FilterPet(&pets, req) + PaginatePets(&pets, req.Page, req.PageSize, &metaData) + + for _, pet := range pets { + images, err := s.imageService.FindByPetId(pet.ID.String()) + if err != nil { + return nil, dto.InternalServerError("error querying image service") + } + imagesList[pet.ID.String()] = images + } + petWithImages, err := RawToDtoList(&pets, imagesList, req) + if err != nil { + return nil, dto.InternalServerError(fmt.Sprintf("error converting raw to dto list: %v", err)) } - createPetResponse := ProtoToDto(res.Pet, imgRes) - return createPetResponse, nil + // images, errSvc := s.imageService.FindAll() + // if errSvc != nil { + // return nil, errSvc + // } + + // allImagesList := ImageList(images) + // findAllDto := ProtoToDtoList(res.Pets, allImagesList, isAdmin) + // metaData := MetadataProtoToDto(res.Metadata) + + return &dto.FindAllPetResponse{Pets: petWithImages, Metadata: &metaData}, nil } -func (s *serviceImpl) Update(id string, in *dto.UpdatePetRequest) (result *dto.PetResponse, err *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - request := UpdateDtoToProto(id, in) - - res, errRes := s.petClient.Update(ctx, request) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). - Str("service", "pet"). - Str("module", "update"). - Msg(st.Message()) - switch st.Code() { - case codes.NotFound: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.PetNotFoundMessage, - Data: nil, - } - case codes.InvalidArgument: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidArgumentMessage, - Data: nil, - } - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } +func (s *serviceImpl) FindOne(id string) (*dto.PetResponse, *dto.ResponseErr) { + var pet model.Pet + + err := s.repository.FindOne(id, &pet) + if err != nil { + log.Error().Err(err). + Str("service", "pet").Str("module", "find one").Str("id", id).Msg("Not found") + return nil, dto.NotFoundError("pet not found") } - images, errSvc := s.imageService.FindByPetId(res.Pet.Id) - if errSvc != nil { - return nil, errSvc + images, apperr := s.imageService.FindByPetId(id) + if apperr != nil { + return nil, apperr } - updatePetResponse := ProtoToDto(res.Pet, images) - return updatePetResponse, nil + return RawToDto(&pet, images), nil } -func (s *serviceImpl) Delete(id string) (result *dto.DeleteResponse, err *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() +func (s *serviceImpl) Create(req *dto.CreatePetRequest) (*dto.PetResponse, *dto.ResponseErr) { + raw := CreateDtoToModel(req) - _, errSvc := s.imageService.DeleteByPetId(id) - if errSvc != nil { - return nil, errSvc + err := s.repository.Create(raw) + if err != nil { + return nil, dto.InternalServerError("failed to create pet") } - res, errRes := s.petClient.Delete(ctx, &petproto.DeletePetRequest{ - Id: id, - }) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). - Str("service", "pet"). - Str("module", "delete"). - Msg(st.Message()) - switch st.Code() { - case codes.NotFound: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.PetNotFoundMessage, - Data: nil, - } - case codes.Unavailable: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } - } + assignReq := &dto.AssignPetRequest{ + PetId: raw.ID.String(), + Ids: req.Images, + } + _, apperr := s.imageService.AssignPet(assignReq) + if apperr != nil { + return nil, apperr + } + + images, apperr := s.imageService.FindByPetId(raw.ID.String()) + if apperr != nil { + return nil, apperr } - return &dto.DeleteResponse{ - Success: res.Success, - }, nil + return RawToDto(raw, images), nil } -func (s *serviceImpl) ChangeView(id string, in *dto.ChangeViewPetRequest) (result *dto.ChangeViewPetResponse, err *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - res, errRes := s.petClient.ChangeView(ctx, &petproto.ChangeViewPetRequest{ - Id: id, - Visible: in.Visible, - }) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). - Str("service", "pet"). - Str("module", "change view"). - Msg(st.Message()) - switch st.Code() { - case codes.NotFound: - return &dto.ChangeViewPetResponse{ - Success: false, - }, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.PetNotFoundMessage, - Data: nil, - } - case codes.Unavailable: - return &dto.ChangeViewPetResponse{ - Success: false, - }, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return &dto.ChangeViewPetResponse{ - Success: false, - }, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.InternalErrorMessage, - Data: nil, - } - } +func (s *serviceImpl) Adopt(id string, req *dto.AdoptByRequest) (*dto.AdoptByResponse, *dto.ResponseErr) { + dtoPet, apperr := s.FindOne(id) + if apperr != nil { + return nil, apperr } - return &dto.ChangeViewPetResponse{ - Success: res.Success, - }, nil -} -func (s *serviceImpl) Adopt(petId string, in *dto.AdoptByRequest) (result *dto.AdoptByResponse, err *dto.ResponseErr) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - res, errRes := s.petClient.AdoptPet(ctx, &petproto.AdoptPetRequest{ - UserId: in.UserID, - PetId: petId, - }) - if errRes != nil { - st, _ := status.FromError(errRes) - log.Error(). - Err(errRes). - Str("service", "pet"). - Str("module", "adopt"). - Msg(st.Message()) - switch st.Code() { - case codes.NotFound: - return nil, - &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.PetNotFoundMessage, - Data: nil, - } - case codes.Unavailable: - return nil, - &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - default: - return nil, - &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.InternalErrorMessage, - Data: nil, - } - } + pet, err := DtoToRaw(dtoPet) + if err != nil { + return nil, dto.InternalServerError("error converting dto to raw") } - return &dto.AdoptByResponse{ - Success: res.Success, - }, nil + pet.Owner = req.UserID + + err = s.repository.Update(id, pet) + if err != nil { + return nil, dto.NotFoundError("pet not found") + } + + return &dto.AdoptByResponse{Success: true}, nil } diff --git a/internal/pet/pet.utils.go b/internal/pet/pet.utils.go index 95f8865..79c4022 100644 --- a/internal/pet/pet.utils.go +++ b/internal/pet/pet.utils.go @@ -2,71 +2,110 @@ package pet import ( "errors" + "math" + "reflect" "strconv" + "strings" + "time" + "github.com/google/uuid" "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" - imgproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/rs/zerolog/log" + "gorm.io/gorm" ) -func ImageList(in []*dto.ImageResponse) map[string][]*imgproto.Image { - imagesList := make(map[string][]*imgproto.Image) - for _, image := range in { - img := &imgproto.Image{ - Id: image.Id, - PetId: image.PetId, - ImageUrl: image.Url, - ObjectKey: image.ObjectKey, - } - imagesList[image.PetId] = append(imagesList[image.PetId], img) +func FilterPet(in *[]*model.Pet, query *dto.FindAllPetRequest) error { + if query.MaxAge == 0 { + query.MaxAge = math.MaxInt32 } - return imagesList + var results []*model.Pet + for _, p := range *in { + res, err := filterAge(p, query.MinAge, query.MaxAge) + if err != nil { + return err + } + if !res { + continue + } + if query.Search != "" && !strings.Contains(p.Name, query.Search) { + continue + } + if query.Type != "" && p.Type != query.Type { + continue + } + if query.Gender != "" && p.Gender != constant.Gender(query.Gender) { + continue + } + if query.Color != "" && p.Color != query.Color { + continue + } + if query.Origin != "" && p.Origin != query.Origin { + continue + } + + results = append(results, p) + } + *in = results + return nil } -func ImageProtoToDto(images []*imgproto.Image) []*dto.ImageResponse { - var imageDto []*dto.ImageResponse - for _, image := range images { - imageDto = append(imageDto, &dto.ImageResponse{ - Id: image.Id, - PetId: image.PetId, - Url: image.ImageUrl, - ObjectKey: image.ObjectKey, - }) +func PaginatePets(pets *[]*model.Pet, page int, pageSize int, metadata *dto.FindAllMetadata) error { + totalsPets := int(len(*pets)) + if page <= 0 { + page = 1 + } + if pageSize <= 0 { + pageSize = totalsPets + } + start := (page - 1) * pageSize + end := start + pageSize + + if start > totalsPets { + *pets = []*model.Pet{} + return nil } - return imageDto + if end > totalsPets { + end = totalsPets + } + *pets = (*pets)[start:end] + + totalPages := int(math.Ceil(float64(totalsPets) / float64(pageSize))) + + metadata.Page = page + metadata.PageSize = pageSize + metadata.Total = totalsPets + metadata.TotalPages = totalPages + return nil } -func ImageListProtoToDto(imagesList [][]*imgproto.Image) [][]*dto.ImageResponse { - var imageListDto [][]*dto.ImageResponse - for _, images := range imagesList { - var imageDto []*dto.ImageResponse - for _, image := range images { - imageDto = append(imageDto, &dto.ImageResponse{ - Id: image.Id, - PetId: image.PetId, - Url: image.ImageUrl, - ObjectKey: image.ObjectKey, - }) - } - imageListDto = append(imageListDto, imageDto) +func RawToDtoList(in *[]*model.Pet, images map[string][]*dto.ImageResponse, query *dto.FindAllPetRequest) ([]*dto.PetResponse, error) { + var result []*dto.PetResponse + if len(*in) != len(images) { + return nil, errors.New("length of in and imageUrls have to be the same") } - return imageListDto + + for _, p := range *in { + // TODO: create new filter image function this wont work + result = append(result, RawToDto(p, images[p.ID.String()])) + } + return result, nil } -func ProtoToDto(in *petproto.Pet, images []*dto.ImageResponse) *dto.PetResponse { - pet := &dto.PetResponse{ - Id: in.Id, +func RawToDto(in *model.Pet, images []*dto.ImageResponse) *dto.PetResponse { + return &dto.PetResponse{ + Id: in.ID.String(), Type: in.Type, Name: in.Name, Birthdate: in.Birthdate, - Gender: constant.Gender(in.Gender), + Gender: in.Gender, Color: in.Color, - Pattern: in.Pattern, Habit: in.Habit, Caption: in.Caption, - Status: constant.Status(in.Status), + Status: in.Status, + Images: images, IsSterile: &in.IsSterile, IsVaccinated: &in.IsVaccinated, IsVisible: &in.IsVisible, @@ -74,140 +113,102 @@ func ProtoToDto(in *petproto.Pet, images []*dto.ImageResponse) *dto.PetResponse Owner: in.Owner, Contact: in.Contact, Tel: in.Tel, - Images: images, } - return pet } -func CreateDtoToProto(in *dto.CreatePetRequest) *petproto.CreatePetRequest { - return &petproto.CreatePetRequest{ - Pet: &petproto.Pet{ - Type: in.Type, - Name: in.Name, - Birthdate: in.Birthdate, - Gender: string(in.Gender), - Color: in.Color, - Pattern: in.Pattern, - Habit: in.Habit, - Caption: in.Caption, - Images: []*imgproto.Image{}, - Status: string(in.Status), - IsSterile: *in.IsSterile, - IsVaccinated: *in.IsVaccinated, - IsVisible: *in.IsVisible, - Origin: in.Origin, - Owner: in.Owner, - Contact: in.Contact, - Tel: in.Tel, - }, - } -} +func DtoToRaw(in *dto.PetResponse) (res *model.Pet, err error) { + var id uuid.UUID -func UpdateDtoToProto(id string, in *dto.UpdatePetRequest) *petproto.UpdatePetRequest { - isSterile := false - if in.IsSterile != nil { - isSterile = *in.IsSterile - } - isVaccinated := false - if in.IsVaccinated != nil { - isVaccinated = *in.IsVaccinated - } - isVisible := false - if in.IsVisible != nil { - isVisible = *in.IsVisible + if in.Id != "" { + id, err = uuid.Parse(in.Id) + if err != nil { + return nil, err + } } - req := &petproto.UpdatePetRequest{ - Pet: &petproto.Pet{ - Id: id, - Type: in.Type, - Name: in.Name, - Birthdate: in.Birthdate, - Gender: string(in.Gender), - Color: in.Color, - Pattern: in.Pattern, - Habit: in.Habit, - Caption: in.Caption, - Images: []*imgproto.Image{}, - Status: string(in.Status), - IsSterile: isSterile, - IsVaccinated: isVaccinated, - IsVisible: isVisible, - Origin: in.Origin, - Owner: in.Owner, - Contact: in.Contact, - Tel: in.Tel, + return &model.Pet{ + Base: model.Base{ + ID: id, + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + DeletedAt: gorm.DeletedAt{}, }, + Type: in.Type, + Name: in.Name, + Birthdate: in.Birthdate, + Gender: in.Gender, + Color: in.Color, + Habit: in.Habit, + Caption: in.Caption, + Status: in.Status, + IsSterile: *in.IsSterile, + IsVaccinated: *in.IsVaccinated, + IsVisible: *in.IsVisible, + Origin: in.Origin, + Owner: in.Owner, + Contact: in.Contact, + Tel: in.Tel, + }, nil +} + +func ExtractImageUrls(in []*dto.ImageResponse) []string { + var result []string + for _, e := range in { + result = append(result, e.Url) } + return result +} - return req +func ExtractImageIDs(in []*dto.ImageResponse) []string { + var result []string + for _, e := range in { + result = append(result, e.Id) + } + return result } -func ProtoToDtoList(in []*petproto.Pet, imagesList map[string][]*imgproto.Image, isAdmin bool) []*dto.PetResponse { - var resp []*dto.PetResponse - for _, p := range in { - if !isAdmin && !p.IsVisible { - continue +func UpdateMap(in *model.Pet) map[string]interface{} { + updateMap := make(map[string]interface{}) + t := reflect.TypeOf(*in) + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + typeName := field.Type.Name() + value := reflect.ValueOf(*in).Field(i).Interface() + if (typeName == "string" || typeName == "Gender" || typeName == "Status") && value != "" { + updateMap[field.Name] = value } - pet := &dto.PetResponse{ - Id: p.Id, - Type: p.Type, - Name: p.Name, - Birthdate: p.Birthdate, - Gender: constant.Gender(p.Gender), - Color: p.Color, - Pattern: p.Pattern, - Habit: p.Habit, - Caption: p.Caption, - Status: constant.Status(p.Status), - IsSterile: &p.IsSterile, - IsVaccinated: &p.IsVaccinated, - IsVisible: &p.IsVisible, - Origin: p.Origin, - Owner: p.Owner, - Contact: p.Contact, - Tel: p.Tel, - Images: ImageProtoToDto(imagesList[p.Id]), + if typeName == "bool" { + updateMap[field.Name] = value } - resp = append(resp, pet) } - return resp + return updateMap } -func extractImages(images []*imgproto.Image) []dto.ImageResponse { - var result []dto.ImageResponse - for _, img := range images { - result = append(result, dto.ImageResponse{ - Id: img.Id, - Url: img.ImageUrl, - }) +func parseDate(dateStr string) (time.Time, error) { + parsedTime, err := time.Parse(time.RFC3339, dateStr) + if err != nil { + return time.Time{}, err } - return result + return parsedTime, nil } -func FindAllDtoToProto(in *dto.FindAllPetRequest, isAdmin bool) *petproto.FindAllPetRequest { - return &petproto.FindAllPetRequest{ - Search: in.Search, - Type: in.Type, - Gender: in.Gender, - Color: in.Color, - Pattern: in.Pattern, - Origin: in.Origin, - PageSize: int32(in.PageSize), - Page: int32(in.Page), - MaxAge: int32(in.MaxAge), - MinAge: int32(in.MinAge), - IsAdmin: isAdmin, +func filterAge(pet *model.Pet, minAge, maxAge int) (bool, error) { + log.Info(). + Str("service", "filterAge"). + Str("module", "birth").Msgf("birthdate: %s", pet.Birthdate) + birthdate, err := parseDate(pet.Birthdate) + if err != nil { + return false, err } -} -func MetadataProtoToDto(in *petproto.FindAllPetMetaData) *dto.FindAllMetadata { - return &dto.FindAllMetadata{ - Page: int(in.Page), - TotalPages: int(in.TotalPages), - PageSize: int(in.PageSize), - Total: int(in.Total), - } + currYear := time.Now() + birthYear := birthdate + diff := currYear.Sub(birthYear).Hours() / constant.DAY / constant.YEAR + log.Info(). + Str("service", "filterAge"). + Str("module", "FilterAge").Msgf("diff: %f", diff) + + return diff >= float64(minAge) && diff <= float64(maxAge), nil } func QueriesToFindAllDto(queries map[string]string) (*dto.FindAllPetRequest, error) { @@ -267,3 +268,104 @@ func QueriesToFindAllDto(queries map[string]string) (*dto.FindAllPetRequest, err return request, nil } + +func UpdateDtoToModel(in *dto.UpdatePetRequest) *model.Pet { + isSterile := false + if in.IsSterile != nil { + isSterile = *in.IsSterile + } + isVaccinated := false + if in.IsVaccinated != nil { + isVaccinated = *in.IsVaccinated + } + isVisible := false + if in.IsVisible != nil { + isVisible = *in.IsVisible + } + + req := &model.Pet{ + Type: in.Type, + Name: in.Name, + Birthdate: in.Birthdate, + Gender: in.Gender, + Color: in.Color, + Habit: in.Habit, + Caption: in.Caption, + Status: in.Status, + IsSterile: isSterile, + IsVaccinated: isVaccinated, + IsVisible: isVisible, + Origin: in.Origin, + Owner: in.Owner, + Contact: in.Contact, + Tel: in.Tel, + } + + return req +} + +func CreateDtoToModel(in *dto.CreatePetRequest) *model.Pet { + return &model.Pet{ + Type: in.Type, + Name: in.Name, + Birthdate: in.Birthdate, + Gender: in.Gender, + Color: in.Color, + Habit: in.Habit, + Caption: in.Caption, + Status: in.Status, + IsSterile: *in.IsSterile, + IsVaccinated: *in.IsVaccinated, + IsVisible: *in.IsVisible, + Origin: in.Origin, + Owner: in.Owner, + Contact: in.Contact, + Tel: in.Tel, + } +} + +func ImageList(in []*dto.ImageResponse) map[string][]*dto.ImageResponse { + imagesList := make(map[string][]*dto.ImageResponse) + for _, image := range in { + img := &dto.ImageResponse{ + Id: image.Id, + PetId: image.PetId, + Url: image.Url, + ObjectKey: image.ObjectKey, + } + imagesList[image.PetId] = append(imagesList[image.PetId], img) + } + + return imagesList +} + +// func ProtoToDtoList(in []*petproto.Pet, imagesList map[string][]*imgproto.Image, isAdmin bool) []*dto.PetResponse { +// var resp []*dto.PetResponse +// for _, p := range in { +// if !isAdmin && !p.IsVisible { +// continue +// } +// pet := &dto.PetResponse{ +// Id: p.Id, +// Type: p.Type, +// Name: p.Name, +// Birthdate: p.Birthdate, +// Gender: constant.Gender(p.Gender), +// Color: p.Color, +// Pattern: p.Pattern, +// Habit: p.Habit, +// Caption: p.Caption, +// Status: constant.Status(p.Status), +// IsSterile: &p.IsSterile, +// IsVaccinated: &p.IsVaccinated, +// IsVisible: &p.IsVisible, +// Origin: p.Origin, +// Owner: p.Owner, +// Contact: p.Contact, +// Tel: p.Tel, +// Images: ImageProtoToDto(imagesList[p.Id]), +// } +// resp = append(resp, pet) +// } +// return resp +// } diff --git a/internal/pet/test/pet.handler_test.go b/internal/pet/test/pet.handler_test.go index 3632492..c4a371e 100644 --- a/internal/pet/test/pet.handler_test.go +++ b/internal/pet/test/pet.handler_test.go @@ -1,539 +1,539 @@ package test -import ( - "math/rand" - "net/http" - "testing" - - "github.com/bxcodec/faker/v4" - "github.com/golang/mock/gomock" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/pet" - routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" - imageMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/image" - petMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/pet" - validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" - - petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" - imgProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" - - "github.com/stretchr/testify/suite" -) - -type PetHandlerTest struct { - suite.Suite - Pet *petProto.Pet - Pets []*petProto.Pet - PetDto *dto.PetResponse - QueriesMock map[string]string - Metadata *dto.FindAllMetadata - FindAllPetRequest *dto.FindAllPetRequest - CreatePetRequest *dto.CreatePetRequest - ChangeViewPetRequest *dto.ChangeViewPetRequest - UpdatePetRequest *dto.UpdatePetRequest - AdoptByRequest *dto.AdoptByRequest - BindErr *dto.ResponseErr - NotFoundErr *dto.ResponseErr - ServiceDownErr *dto.ResponseErr - InternalErr *dto.ResponseErr - Images []*imgProto.Image - ImagesList map[string][]*imgProto.Image -} - -func TestPetHandler(t *testing.T) { - suite.Run(t, new(PetHandlerTest)) -} - -func (t *PetHandlerTest) SetupTest() { - petIds := []string{faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit()} - imagesList := make(map[string][]*imgProto.Image) - for i := 0; i <= 3; i++ { - for j := 0; j <= 3; j++ { - img := &imgProto.Image{ - Id: faker.UUIDDigit(), - PetId: petIds[i], - ImageUrl: faker.URL(), - ObjectKey: faker.Word(), - } - imagesList[petIds[i]] = append(imagesList[petIds[i]], img) - } - } - t.ImagesList = imagesList - t.Images = imagesList[petIds[0]] - var pets []*petProto.Pet - genders := []constant.Gender{constant.MALE, constant.FEMALE} - statuses := []constant.Status{constant.ADOPTED, constant.FINDHOME} - - for i := 0; i <= 3; i++ { - pet := &petProto.Pet{ - Id: faker.UUIDDigit(), - Type: faker.Word(), - Name: faker.Name(), - Birthdate: faker.Word(), - Gender: string(genders[rand.Intn(2)]), - Color: faker.Word(), - Pattern: faker.Word(), - Habit: faker.Paragraph(), - Caption: faker.Paragraph(), - Images: []*imgProto.Image{}, - Status: string(statuses[rand.Intn(2)]), - IsSterile: true, - IsVaccinated: true, - IsVisible: true, - Origin: faker.Paragraph(), - Owner: faker.Paragraph(), - Contact: faker.Paragraph(), - Tel: "", - } - - pets = append(pets, pet) - } - - t.Pets = pets - t.Pet = t.Pets[0] - - t.Metadata = &dto.FindAllMetadata{ - Page: 1, - TotalPages: 1, - PageSize: len(t.Pets), - Total: len(t.Pets), - } - - t.PetDto = &dto.PetResponse{ - Id: t.Pet.Id, - Type: t.Pet.Type, - Name: t.Pet.Name, - Birthdate: t.Pet.Birthdate, - Gender: constant.Gender(t.Pet.Gender), - Color: t.Pet.Color, - Pattern: t.Pet.Pattern, - Habit: t.Pet.Habit, - Caption: t.Pet.Caption, - Status: constant.Status(t.Pet.Status), - IsSterile: &t.Pet.IsSterile, - IsVaccinated: &t.Pet.IsVaccinated, - IsVisible: &t.Pet.IsVisible, - Origin: t.Pet.Origin, - Owner: t.Pet.Owner, - Contact: t.Pet.Contact, - Tel: t.Pet.Tel, - } - - t.QueriesMock = map[string]string{ - "search": "", - "type": "", - "gender": "", - "color": "", - "pattern": "", - "age": "", - "origin": "", - "pageSize": "0", - "page": "0", - } - - t.FindAllPetRequest = &dto.FindAllPetRequest{} - - t.CreatePetRequest = &dto.CreatePetRequest{} - - t.UpdatePetRequest = &dto.UpdatePetRequest{} - - t.ChangeViewPetRequest = &dto.ChangeViewPetRequest{} - - t.AdoptByRequest = &dto.AdoptByRequest{} - - t.ServiceDownErr = &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: "Service is down", - Data: nil, - } - - t.NotFoundErr = &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.PetNotFoundMessage, - Data: nil, - } - - t.BindErr = &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidIDMessage, - } - - t.InternalErr = &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, - } -} - -func (t *PetHandlerTest) TestFindAllSuccess() { - findAllResponse := pet.ProtoToDtoList(t.Pets, t.ImagesList, false) - metadataResponse := t.Metadata - expectedResponse := &dto.FindAllPetResponse{ - Pets: findAllResponse, - Metadata: metadataResponse, - } - - controller := gomock.NewController(t.T()) - - petSvc := petMock.NewMockService(controller) - imageSvc := imageMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Queries().Return(t.QueriesMock) - petSvc.EXPECT().FindAll(t.FindAllPetRequest, false).Return(expectedResponse, nil) - context.EXPECT().JSON(http.StatusOK, expectedResponse) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.FindAll(context) -} - -func (t *PetHandlerTest) TestFindOneSuccess() { - findOneResponse := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Images)) - expectedResponse := findOneResponse - - controller := gomock.NewController(t.T()) - - 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) - petSvc.EXPECT().FindOne(t.Pet.Id).Return(findOneResponse, nil) - context.EXPECT().JSON(http.StatusOK, expectedResponse) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.FindOne(context) -} - -func (t *PetHandlerTest) TestFindOneNotFoundErr() { - findOneResponse := t.NotFoundErr - - controller := gomock.NewController(t.T()) - - 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) - petSvc.EXPECT().FindOne(t.Pet.Id).Return(nil, findOneResponse) - context.EXPECT().JSON(http.StatusNotFound, findOneResponse) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.FindOne(context) -} +// import ( +// "math/rand" +// "net/http" +// "testing" + +// "github.com/bxcodec/faker/v4" +// "github.com/golang/mock/gomock" +// "github.com/isd-sgcu/johnjud-gateway/constant" +// "github.com/isd-sgcu/johnjud-gateway/internal/dto" +// "github.com/isd-sgcu/johnjud-gateway/internal/pet" +// routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" +// imageMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/image" +// petMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/pet" +// validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" + +// petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" +// imgProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" + +// "github.com/stretchr/testify/suite" +// ) + +// type PetHandlerTest struct { +// suite.Suite +// Pet *petProto.Pet +// Pets []*petProto.Pet +// PetDto *dto.PetResponse +// QueriesMock map[string]string +// Metadata *dto.FindAllMetadata +// FindAllPetRequest *dto.FindAllPetRequest +// CreatePetRequest *dto.CreatePetRequest +// ChangeViewPetRequest *dto.ChangeViewPetRequest +// UpdatePetRequest *dto.UpdatePetRequest +// AdoptByRequest *dto.AdoptByRequest +// BindErr *dto.ResponseErr +// NotFoundErr *dto.ResponseErr +// ServiceDownErr *dto.ResponseErr +// InternalErr *dto.ResponseErr +// Images []*imgProto.Image +// ImagesList map[string][]*imgProto.Image +// } + +// func TestPetHandler(t *testing.T) { +// suite.Run(t, new(PetHandlerTest)) +// } + +// func (t *PetHandlerTest) SetupTest() { +// petIds := []string{faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit()} +// imagesList := make(map[string][]*imgProto.Image) +// for i := 0; i <= 3; i++ { +// for j := 0; j <= 3; j++ { +// img := &imgProto.Image{ +// Id: faker.UUIDDigit(), +// PetId: petIds[i], +// ImageUrl: faker.URL(), +// ObjectKey: faker.Word(), +// } +// imagesList[petIds[i]] = append(imagesList[petIds[i]], img) +// } +// } +// t.ImagesList = imagesList +// t.Images = imagesList[petIds[0]] +// var pets []*petProto.Pet +// genders := []constant.Gender{constant.MALE, constant.FEMALE} +// statuses := []constant.Status{constant.ADOPTED, constant.FINDHOME} + +// for i := 0; i <= 3; i++ { +// pet := &petProto.Pet{ +// Id: faker.UUIDDigit(), +// Type: faker.Word(), +// Name: faker.Name(), +// Birthdate: faker.Word(), +// Gender: string(genders[rand.Intn(2)]), +// Color: faker.Word(), +// Pattern: faker.Word(), +// Habit: faker.Paragraph(), +// Caption: faker.Paragraph(), +// Images: []*imgProto.Image{}, +// Status: string(statuses[rand.Intn(2)]), +// IsSterile: true, +// IsVaccinated: true, +// IsVisible: true, +// Origin: faker.Paragraph(), +// Owner: faker.Paragraph(), +// Contact: faker.Paragraph(), +// Tel: "", +// } + +// pets = append(pets, pet) +// } + +// t.Pets = pets +// t.Pet = t.Pets[0] + +// t.Metadata = &dto.FindAllMetadata{ +// Page: 1, +// TotalPages: 1, +// PageSize: len(t.Pets), +// Total: len(t.Pets), +// } + +// t.PetDto = &dto.PetResponse{ +// Id: t.Pet.Id, +// Type: t.Pet.Type, +// Name: t.Pet.Name, +// Birthdate: t.Pet.Birthdate, +// Gender: constant.Gender(t.Pet.Gender), +// Color: t.Pet.Color, +// Pattern: t.Pet.Pattern, +// Habit: t.Pet.Habit, +// Caption: t.Pet.Caption, +// Status: constant.Status(t.Pet.Status), +// IsSterile: &t.Pet.IsSterile, +// IsVaccinated: &t.Pet.IsVaccinated, +// IsVisible: &t.Pet.IsVisible, +// Origin: t.Pet.Origin, +// Owner: t.Pet.Owner, +// Contact: t.Pet.Contact, +// Tel: t.Pet.Tel, +// } + +// t.QueriesMock = map[string]string{ +// "search": "", +// "type": "", +// "gender": "", +// "color": "", +// "pattern": "", +// "age": "", +// "origin": "", +// "pageSize": "0", +// "page": "0", +// } + +// t.FindAllPetRequest = &dto.FindAllPetRequest{} + +// t.CreatePetRequest = &dto.CreatePetRequest{} + +// t.UpdatePetRequest = &dto.UpdatePetRequest{} + +// t.ChangeViewPetRequest = &dto.ChangeViewPetRequest{} + +// t.AdoptByRequest = &dto.AdoptByRequest{} + +// t.ServiceDownErr = &dto.ResponseErr{ +// StatusCode: http.StatusServiceUnavailable, +// Message: "Service is down", +// Data: nil, +// } + +// t.NotFoundErr = &dto.ResponseErr{ +// StatusCode: http.StatusNotFound, +// Message: constant.PetNotFoundMessage, +// Data: nil, +// } + +// t.BindErr = &dto.ResponseErr{ +// StatusCode: http.StatusBadRequest, +// Message: constant.InvalidIDMessage, +// } + +// t.InternalErr = &dto.ResponseErr{ +// StatusCode: http.StatusInternalServerError, +// Message: constant.InternalErrorMessage, +// Data: nil, +// } +// } + +// func (t *PetHandlerTest) TestFindAllSuccess() { +// findAllResponse := pet.ProtoToDtoList(t.Pets, t.ImagesList, false) +// metadataResponse := t.Metadata +// expectedResponse := &dto.FindAllPetResponse{ +// Pets: findAllResponse, +// Metadata: metadataResponse, +// } + +// controller := gomock.NewController(t.T()) + +// petSvc := petMock.NewMockService(controller) +// imageSvc := imageMock.NewMockService(controller) +// validator := validatorMock.NewMockIDtoValidator(controller) +// context := routerMock.NewMockIContext(controller) + +// context.EXPECT().Queries().Return(t.QueriesMock) +// petSvc.EXPECT().FindAll(t.FindAllPetRequest, false).Return(expectedResponse, nil) +// context.EXPECT().JSON(http.StatusOK, expectedResponse) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.FindAll(context) +// } + +// func (t *PetHandlerTest) TestFindOneSuccess() { +// findOneResponse := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Images)) +// expectedResponse := findOneResponse + +// controller := gomock.NewController(t.T()) + +// 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) +// petSvc.EXPECT().FindOne(t.Pet.Id).Return(findOneResponse, nil) +// context.EXPECT().JSON(http.StatusOK, expectedResponse) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.FindOne(context) +// } + +// func (t *PetHandlerTest) TestFindOneNotFoundErr() { +// findOneResponse := t.NotFoundErr + +// controller := gomock.NewController(t.T()) + +// 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) +// petSvc.EXPECT().FindOne(t.Pet.Id).Return(nil, findOneResponse) +// context.EXPECT().JSON(http.StatusNotFound, findOneResponse) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.FindOne(context) +// } -func (t *PetHandlerTest) TestFindOneGrpcErr() { - findOneResponse := t.ServiceDownErr +// func (t *PetHandlerTest) TestFindOneGrpcErr() { +// findOneResponse := t.ServiceDownErr - controller := gomock.NewController(t.T()) +// controller := gomock.NewController(t.T()) - petSvc := petMock.NewMockService(controller) - imageSvc := imageMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.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) - petSvc.EXPECT().FindOne(t.Pet.Id).Return(nil, findOneResponse) - context.EXPECT().JSON(http.StatusServiceUnavailable, findOneResponse) +// context.EXPECT().Param("id").Return(t.Pet.Id, nil) +// petSvc.EXPECT().FindOne(t.Pet.Id).Return(nil, findOneResponse) +// context.EXPECT().JSON(http.StatusServiceUnavailable, findOneResponse) - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.FindOne(context) -} - -func (t *PetHandlerTest) TestCreateSuccess() { - createResponse := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Images)) - expectedResponse := createResponse - - controller := gomock.NewController(t.T()) - - petSvc := petMock.NewMockService(controller) - imageSvc := imageMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) - - context.EXPECT().Bind(t.CreatePetRequest).Return(nil) - validator.EXPECT().Validate(t.CreatePetRequest).Return(nil) - petSvc.EXPECT().Create(t.CreatePetRequest).Return(createResponse, nil) - context.EXPECT().JSON(http.StatusCreated, expectedResponse) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.Create(context) -} +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.FindOne(context) +// } + +// func (t *PetHandlerTest) TestCreateSuccess() { +// createResponse := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Images)) +// expectedResponse := createResponse + +// controller := gomock.NewController(t.T()) + +// petSvc := petMock.NewMockService(controller) +// imageSvc := imageMock.NewMockService(controller) +// validator := validatorMock.NewMockIDtoValidator(controller) +// context := routerMock.NewMockIContext(controller) + +// context.EXPECT().Bind(t.CreatePetRequest).Return(nil) +// validator.EXPECT().Validate(t.CreatePetRequest).Return(nil) +// petSvc.EXPECT().Create(t.CreatePetRequest).Return(createResponse, nil) +// context.EXPECT().JSON(http.StatusCreated, expectedResponse) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.Create(context) +// } -func (t *PetHandlerTest) TestCreateGrpcErr() { - createErrorResponse := t.ServiceDownErr - - controller := gomock.NewController(t.T()) +// func (t *PetHandlerTest) TestCreateGrpcErr() { +// createErrorResponse := t.ServiceDownErr + +// controller := gomock.NewController(t.T()) - petSvc := petMock.NewMockService(controller) - imageSvc := imageMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.NewMockIContext(controller) +// petSvc := petMock.NewMockService(controller) +// imageSvc := imageMock.NewMockService(controller) +// validator := validatorMock.NewMockIDtoValidator(controller) +// context := routerMock.NewMockIContext(controller) - context.EXPECT().Bind(t.CreatePetRequest).Return(nil) - validator.EXPECT().Validate(t.CreatePetRequest).Return(nil) - petSvc.EXPECT().Create(t.CreatePetRequest).Return(nil, createErrorResponse) - context.EXPECT().JSON(http.StatusServiceUnavailable, createErrorResponse) +// context.EXPECT().Bind(t.CreatePetRequest).Return(nil) +// validator.EXPECT().Validate(t.CreatePetRequest).Return(nil) +// petSvc.EXPECT().Create(t.CreatePetRequest).Return(nil, createErrorResponse) +// context.EXPECT().JSON(http.StatusServiceUnavailable, createErrorResponse) - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.Create(context) -} +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.Create(context) +// } -func (t *PetHandlerTest) TestUpdateSuccess() { - updateResponse := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Images)) - expectedResponse := updateResponse +// func (t *PetHandlerTest) TestUpdateSuccess() { +// updateResponse := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Images)) +// expectedResponse := updateResponse - controller := gomock.NewController(t.T()) +// controller := gomock.NewController(t.T()) - petSvc := petMock.NewMockService(controller) - imageSvc := imageMock.NewMockService(controller) - validator := validatorMock.NewMockIDtoValidator(controller) - context := routerMock.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.UpdatePetRequest).Return(nil) - validator.EXPECT().Validate(t.UpdatePetRequest).Return(nil) - petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(updateResponse, nil) - context.EXPECT().JSON(http.StatusOK, expectedResponse) +// context.EXPECT().Param("id").Return(t.Pet.Id, nil) +// context.EXPECT().Bind(t.UpdatePetRequest).Return(nil) +// validator.EXPECT().Validate(t.UpdatePetRequest).Return(nil) +// petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(updateResponse, nil) +// context.EXPECT().JSON(http.StatusOK, expectedResponse) - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.Update(context) -} +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.Update(context) +// } -func (t *PetHandlerTest) TestUpdateNotFound() { - updateResponse := t.NotFoundErr +// func (t *PetHandlerTest) TestUpdateNotFound() { +// updateResponse := t.NotFoundErr - controller := gomock.NewController(t.T()) - - 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.UpdatePetRequest).Return(nil) - validator.EXPECT().Validate(t.UpdatePetRequest).Return(nil) - petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(nil, updateResponse) - context.EXPECT().JSON(http.StatusNotFound, updateResponse) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.Update(context) -} - -func (t *PetHandlerTest) TestUpdateGrpcErr() { - updateResponse := t.ServiceDownErr - - controller := gomock.NewController(t.T()) - - 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.UpdatePetRequest).Return(nil) - validator.EXPECT().Validate(t.UpdatePetRequest).Return(nil) - petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(nil, updateResponse) - context.EXPECT().JSON(http.StatusServiceUnavailable, updateResponse) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.Update(context) -} - -func (t *PetHandlerTest) TestDeleteSuccess() { - deleteResponse := &dto.DeleteResponse{ - Success: true, - } - expectedResponse := deleteResponse - - controller := gomock.NewController(t.T()) - - 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) - petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, nil) - context.EXPECT().JSON(http.StatusOK, expectedResponse) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.Delete(context) -} -func (t *PetHandlerTest) TestDeleteNotFound() { - deleteResponse := &dto.DeleteResponse{ - Success: false, - } - - controller := gomock.NewController(t.T()) - - 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) - petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, t.NotFoundErr) - context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.Delete(context) -} - -func (t *PetHandlerTest) TestDeleteGrpcErr() { - deleteResponse := &dto.DeleteResponse{ - Success: false, - } - - controller := gomock.NewController(t.T()) - - 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) - petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, t.ServiceDownErr) - context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.Delete(context) -} - -func (t *PetHandlerTest) TestChangeViewSuccess() { - changeViewResponse := &dto.ChangeViewPetResponse{ - Success: true, - } - expectedResponse := changeViewResponse - - controller := gomock.NewController(t.T()) - - 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.ChangeViewPetRequest).Return(nil) - validator.EXPECT().Validate(t.ChangeViewPetRequest).Return(nil) - petSvc.EXPECT().ChangeView(t.Pet.Id, t.ChangeViewPetRequest).Return(changeViewResponse, nil) - context.EXPECT().JSON(http.StatusOK, expectedResponse) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.ChangeView(context) -} - -func (t *PetHandlerTest) TestChangeViewNotFound() { - changeViewResponse := &dto.ChangeViewPetResponse{ - Success: false, - } - - controller := gomock.NewController(t.T()) - - 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.ChangeViewPetRequest).Return(nil) - validator.EXPECT().Validate(t.ChangeViewPetRequest).Return(nil) - petSvc.EXPECT().ChangeView(t.Pet.Id, t.ChangeViewPetRequest).Return(changeViewResponse, t.NotFoundErr) - context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.ChangeView(context) -} - -func (t *PetHandlerTest) TestChangeViewGrpcErr() { - changeViewResponse := &dto.ChangeViewPetResponse{ - Success: false, - } - - controller := gomock.NewController(t.T()) - - 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.ChangeViewPetRequest).Return(nil) - validator.EXPECT().Validate(t.ChangeViewPetRequest).Return(nil) - petSvc.EXPECT().ChangeView(t.Pet.Id, t.ChangeViewPetRequest).Return(changeViewResponse, t.ServiceDownErr) - context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.ChangeView(context) -} - -func (t *PetHandlerTest) TestAdoptSuccess() { - adoptByResponse := &dto.AdoptByResponse{ - Success: true, - } - expectedResponse := adoptByResponse - - controller := gomock.NewController(t.T()) - - 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) - validator.EXPECT().Validate(t.AdoptByRequest).Return(nil) - petSvc.EXPECT().Adopt(t.Pet.Id, t.AdoptByRequest).Return(adoptByResponse, nil) - context.EXPECT().JSON(http.StatusOK, expectedResponse) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.Adopt(context) -} - -func (t *PetHandlerTest) TestAdoptNotFound() { - adoptByResponse := &dto.AdoptByResponse{ - Success: false, - } - - controller := gomock.NewController(t.T()) - - 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) - validator.EXPECT().Validate(t.AdoptByRequest).Return(nil) - petSvc.EXPECT().Adopt(t.Pet.Id, t.AdoptByRequest).Return(adoptByResponse, t.NotFoundErr) - context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.Adopt(context) -} - -func (t *PetHandlerTest) TestAdoptGrpcErr() { - adoptByResponse := &dto.AdoptByResponse{ - Success: false, - } - - controller := gomock.NewController(t.T()) - - 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) - validator.EXPECT().Validate(t.AdoptByRequest).Return(nil) - petSvc.EXPECT().Adopt(t.Pet.Id, t.AdoptByRequest).Return(adoptByResponse, t.ServiceDownErr) - context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) - - handler := pet.NewHandler(petSvc, imageSvc, validator) - handler.Adopt(context) -} +// controller := gomock.NewController(t.T()) + +// 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.UpdatePetRequest).Return(nil) +// validator.EXPECT().Validate(t.UpdatePetRequest).Return(nil) +// petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(nil, updateResponse) +// context.EXPECT().JSON(http.StatusNotFound, updateResponse) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.Update(context) +// } + +// func (t *PetHandlerTest) TestUpdateGrpcErr() { +// updateResponse := t.ServiceDownErr + +// controller := gomock.NewController(t.T()) + +// 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.UpdatePetRequest).Return(nil) +// validator.EXPECT().Validate(t.UpdatePetRequest).Return(nil) +// petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(nil, updateResponse) +// context.EXPECT().JSON(http.StatusServiceUnavailable, updateResponse) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.Update(context) +// } + +// func (t *PetHandlerTest) TestDeleteSuccess() { +// deleteResponse := &dto.DeleteResponse{ +// Success: true, +// } +// expectedResponse := deleteResponse + +// controller := gomock.NewController(t.T()) + +// 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) +// petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, nil) +// context.EXPECT().JSON(http.StatusOK, expectedResponse) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.Delete(context) +// } +// func (t *PetHandlerTest) TestDeleteNotFound() { +// deleteResponse := &dto.DeleteResponse{ +// Success: false, +// } + +// controller := gomock.NewController(t.T()) + +// 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) +// petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, t.NotFoundErr) +// context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.Delete(context) +// } + +// func (t *PetHandlerTest) TestDeleteGrpcErr() { +// deleteResponse := &dto.DeleteResponse{ +// Success: false, +// } + +// controller := gomock.NewController(t.T()) + +// 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) +// petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, t.ServiceDownErr) +// context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.Delete(context) +// } + +// func (t *PetHandlerTest) TestChangeViewSuccess() { +// changeViewResponse := &dto.ChangeViewPetResponse{ +// Success: true, +// } +// expectedResponse := changeViewResponse + +// controller := gomock.NewController(t.T()) + +// 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.ChangeViewPetRequest).Return(nil) +// validator.EXPECT().Validate(t.ChangeViewPetRequest).Return(nil) +// petSvc.EXPECT().ChangeView(t.Pet.Id, t.ChangeViewPetRequest).Return(changeViewResponse, nil) +// context.EXPECT().JSON(http.StatusOK, expectedResponse) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.ChangeView(context) +// } + +// func (t *PetHandlerTest) TestChangeViewNotFound() { +// changeViewResponse := &dto.ChangeViewPetResponse{ +// Success: false, +// } + +// controller := gomock.NewController(t.T()) + +// 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.ChangeViewPetRequest).Return(nil) +// validator.EXPECT().Validate(t.ChangeViewPetRequest).Return(nil) +// petSvc.EXPECT().ChangeView(t.Pet.Id, t.ChangeViewPetRequest).Return(changeViewResponse, t.NotFoundErr) +// context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.ChangeView(context) +// } + +// func (t *PetHandlerTest) TestChangeViewGrpcErr() { +// changeViewResponse := &dto.ChangeViewPetResponse{ +// Success: false, +// } + +// controller := gomock.NewController(t.T()) + +// 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.ChangeViewPetRequest).Return(nil) +// validator.EXPECT().Validate(t.ChangeViewPetRequest).Return(nil) +// petSvc.EXPECT().ChangeView(t.Pet.Id, t.ChangeViewPetRequest).Return(changeViewResponse, t.ServiceDownErr) +// context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.ChangeView(context) +// } + +// func (t *PetHandlerTest) TestAdoptSuccess() { +// adoptByResponse := &dto.AdoptByResponse{ +// Success: true, +// } +// expectedResponse := adoptByResponse + +// controller := gomock.NewController(t.T()) + +// 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) +// validator.EXPECT().Validate(t.AdoptByRequest).Return(nil) +// petSvc.EXPECT().Adopt(t.Pet.Id, t.AdoptByRequest).Return(adoptByResponse, nil) +// context.EXPECT().JSON(http.StatusOK, expectedResponse) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.Adopt(context) +// } + +// func (t *PetHandlerTest) TestAdoptNotFound() { +// adoptByResponse := &dto.AdoptByResponse{ +// Success: false, +// } + +// controller := gomock.NewController(t.T()) + +// 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) +// validator.EXPECT().Validate(t.AdoptByRequest).Return(nil) +// petSvc.EXPECT().Adopt(t.Pet.Id, t.AdoptByRequest).Return(adoptByResponse, t.NotFoundErr) +// context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.Adopt(context) +// } + +// func (t *PetHandlerTest) TestAdoptGrpcErr() { +// adoptByResponse := &dto.AdoptByResponse{ +// Success: false, +// } + +// controller := gomock.NewController(t.T()) + +// 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) +// validator.EXPECT().Validate(t.AdoptByRequest).Return(nil) +// petSvc.EXPECT().Adopt(t.Pet.Id, t.AdoptByRequest).Return(adoptByResponse, t.ServiceDownErr) +// context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) + +// handler := pet.NewHandler(petSvc, imageSvc, validator) +// handler.Adopt(context) +// } diff --git a/internal/pet/test/pet.service_test.go b/internal/pet/test/pet.service_test.go index d5f9df2..8f7f2b3 100644 --- a/internal/pet/test/pet.service_test.go +++ b/internal/pet/test/pet.service_test.go @@ -1,19 +1,22 @@ package test import ( + "errors" "math/rand" "net/http" "testing" + "time" - "github.com/go-faker/faker/v4" + "github.com/bxcodec/faker/v3" + "github.com/google/uuid" "github.com/isd-sgcu/johnjud-gateway/constant" "github.com/isd-sgcu/johnjud-gateway/internal/dto" - imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/image" + "github.com/isd-sgcu/johnjud-gateway/internal/model" "github.com/isd-sgcu/johnjud-gateway/internal/pet" - imagemock "github.com/isd-sgcu/johnjud-gateway/mocks/client/image" - petmock "github.com/isd-sgcu/johnjud-gateway/mocks/client/pet" - petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" - imgproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" + mock "github.com/isd-sgcu/johnjud-gateway/mocks/repository/pet" + img_mock "github.com/isd-sgcu/johnjud-gateway/mocks/service/image" + "gorm.io/gorm" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "google.golang.org/grpc/codes" @@ -22,37 +25,19 @@ import ( type PetServiceTest struct { suite.Suite - Pets []*petproto.Pet - Pet *petproto.Pet - MetadataDto *dto.FindAllMetadata - MetadataProto *petproto.FindAllPetMetaData - PetNotVisible *petproto.Pet - FindAllPetReq *petproto.FindAllPetRequest - FindAllImageReq *imgproto.FindAllImageRequest - UpdatePetReq *petproto.UpdatePetRequest - CreatePetReq *petproto.CreatePetRequest - ChangeViewPetReq *petproto.ChangeViewPetRequest - DeletePetReq *petproto.DeletePetRequest - AdoptReq *petproto.AdoptPetRequest - PetDto *dto.PetResponse - FindAllPetDto *dto.FindAllPetRequest - CreatePetDto *dto.CreatePetRequest - UpdatePetDto *dto.UpdatePetRequest - NotFoundErr *dto.ResponseErr - UnavailableServiceErr *dto.ResponseErr - InvalidArgumentErr *dto.ResponseErr - InternalErr *dto.ResponseErr - ChangeViewedPetDto *dto.ChangeViewPetRequest - AdoptDto *dto.AdoptByRequest - - Images []*imgproto.Image - AllImages []*imgproto.Image - ImagesList map[string][]*imgproto.Image - - AssignPetReq *imgproto.AssignPetRequest - AssignPetDto *dto.AssignPetRequest - - FindByPetIdReq *imgproto.FindImageByPetIdRequest + Pet *model.Pet + UpdatePet *model.Pet + ChangeViewPet *model.Pet + Pets []*model.Pet + PetDto *dto.PetResponse + CreatePetReqMock *dto.CreatePetRequest + UpdatePetReqMock *dto.UpdatePetRequest + ChangeViewPetReqMock *dto.ChangeViewPetRequest + Images []*dto.ImageResponse + ImageUrls []string + ImagesList [][]*dto.ImageResponse + ChangeAdoptBy *model.Pet + AdoptByReq *dto.AdoptByRequest } func TestPetService(t *testing.T) { @@ -60,700 +45,547 @@ func TestPetService(t *testing.T) { } func (t *PetServiceTest) SetupTest() { - petIds := []string{faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit(), faker.UUIDDigit()} - t.AllImages = []*imgproto.Image{} - imagesList := make(map[string][]*imgproto.Image) - for i := 0; i <= 3; i++ { - for j := 0; j <= 3; j++ { - img := &imgproto.Image{ - Id: faker.UUIDDigit(), - PetId: petIds[i], - ImageUrl: faker.URL(), - ObjectKey: faker.Word(), - } - imagesList[petIds[i]] = append(imagesList[petIds[i]], img) - t.AllImages = append(t.AllImages, img) - } - } - t.ImagesList = imagesList - t.Images = imagesList[petIds[0]] + var pets []*model.Pet + t.ImageUrls = []string{} genders := []constant.Gender{constant.MALE, constant.FEMALE} statuses := []constant.Status{constant.ADOPTED, constant.FINDHOME} - var pets []*petproto.Pet for i := 0; i <= 3; i++ { - pet := &petproto.Pet{ - Id: petIds[i], + pet := &model.Pet{ + Base: model.Base{ + ID: uuid.New(), + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + DeletedAt: gorm.DeletedAt{}, + }, Type: faker.Word(), Name: faker.Name(), Birthdate: faker.Word(), - Gender: string(genders[rand.Intn(2)]), + Gender: genders[rand.Intn(2)], Color: faker.Word(), - Pattern: faker.Word(), Habit: faker.Paragraph(), Caption: faker.Paragraph(), - Images: imagesList[petIds[i]], - Status: string(statuses[rand.Intn(2)]), + Status: statuses[rand.Intn(2)], IsSterile: true, IsVaccinated: true, IsVisible: true, Origin: faker.Paragraph(), Owner: faker.Paragraph(), Contact: faker.Paragraph(), - Tel: faker.UUIDDigit(), + Tel: "", } - + var images []*dto.ImageResponse + for i := 0; i < 3; i++ { + url := faker.URL() + images = append(images, &dto.ImageResponse{ + Id: faker.UUIDDigit(), + PetId: pet.ID.String(), + Url: url, + }) + t.ImageUrls = append(t.ImageUrls, url) + } + t.ImagesList = append(t.ImagesList, images) pets = append(pets, pet) } - t.MetadataDto = &dto.FindAllMetadata{ - Page: 1, - TotalPages: 1, - PageSize: len(t.Pets), - Total: len(t.Pets), - } + t.Pets = pets + t.Pet = pets[0] + t.Images = t.ImagesList[0] - t.MetadataProto = &petproto.FindAllPetMetaData{ - Page: 1, - TotalPages: 1, - PageSize: int32(len(t.Pets)), - Total: int32(len(t.Pets)), + t.PetDto = &dto.PetResponse{ + Id: t.Pet.ID.String(), + Type: t.Pet.Type, + Name: t.Pet.Name, + Birthdate: t.Pet.Birthdate, + Gender: t.Pet.Gender, + Color: t.Pet.Color, + Habit: t.Pet.Habit, + Caption: t.Pet.Caption, + Status: t.Pet.Status, + IsSterile: &t.Pet.IsSterile, + IsVaccinated: &t.Pet.IsVaccinated, + IsVisible: &t.Pet.IsVisible, + Origin: t.Pet.Origin, + Owner: t.Pet.Owner, + Contact: t.Pet.Contact, + Images: t.Images, } - t.Pets = pets - t.Pet = t.Pets[0] - - t.PetNotVisible = &petproto.Pet{ - Id: t.Pet.Id, + t.UpdatePet = &model.Pet{ + Base: model.Base{ + ID: t.Pet.Base.ID, + CreatedAt: t.Pet.Base.CreatedAt, + UpdatedAt: t.Pet.Base.UpdatedAt, + DeletedAt: t.Pet.Base.DeletedAt, + }, Type: t.Pet.Type, Name: t.Pet.Name, Birthdate: t.Pet.Birthdate, Gender: t.Pet.Gender, Color: t.Pet.Color, - Pattern: t.Pet.Pattern, Habit: t.Pet.Habit, Caption: t.Pet.Caption, - Images: t.Pet.Images, Status: t.Pet.Status, IsSterile: t.Pet.IsSterile, IsVaccinated: t.Pet.IsVaccinated, - IsVisible: false, + IsVisible: t.Pet.IsVisible, Origin: t.Pet.Origin, Owner: t.Pet.Owner, Contact: t.Pet.Contact, - Tel: t.Pet.Tel, } - t.PetDto = pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) - - t.FindAllPetDto = &dto.FindAllPetRequest{ - Search: "", - Type: "", - Gender: "", - Color: "", - Pattern: "", - Age: "", - Origin: "", - PageSize: len(t.Pets), - Page: 1, + t.ChangeViewPet = &model.Pet{ + Base: model.Base{ + ID: t.Pet.Base.ID, + CreatedAt: t.Pet.Base.CreatedAt, + UpdatedAt: t.Pet.Base.UpdatedAt, + DeletedAt: t.Pet.Base.DeletedAt, + }, + Type: t.Pet.Type, + Name: t.Pet.Name, + Birthdate: t.Pet.Birthdate, + Gender: t.Pet.Gender, + Color: t.Pet.Color, + + Habit: t.Pet.Habit, + Caption: t.Pet.Caption, + Status: t.Pet.Status, + IsSterile: t.Pet.IsSterile, + IsVaccinated: t.Pet.IsVaccinated, + IsVisible: false, + Origin: t.Pet.Origin, + Owner: t.Pet.Owner, + Contact: t.Pet.Contact, } - t.CreatePetDto = &dto.CreatePetRequest{ - Type: t.Pet.Type, - Name: t.Pet.Name, - Birthdate: t.Pet.Birthdate, - Gender: constant.Gender(t.Pet.Gender), - Color: t.Pet.Color, - Pattern: t.Pet.Pattern, + t.CreatePetReqMock = &dto.CreatePetRequest{ + Type: t.Pet.Type, + Name: t.Pet.Name, + Birthdate: t.Pet.Birthdate, + Gender: t.Pet.Gender, + Color: t.Pet.Color, + Habit: t.Pet.Habit, Caption: t.Pet.Caption, - Images: []string{}, - Status: constant.Status(t.Pet.Status), + Status: t.Pet.Status, + Images: t.ImageUrls, IsSterile: &t.Pet.IsSterile, IsVaccinated: &t.Pet.IsVaccinated, - IsVisible: &t.Pet.IsVisible, + IsVisible: &t.Pet.IsVaccinated, Origin: t.Pet.Origin, Owner: t.Pet.Owner, Contact: t.Pet.Contact, - Tel: t.Pet.Tel, } - t.UpdatePetDto = &dto.UpdatePetRequest{ - Type: t.Pet.Type, - Name: t.Pet.Name, - Birthdate: t.Pet.Birthdate, - Gender: constant.Gender(t.Pet.Gender), - Color: t.Pet.Color, - Pattern: t.Pet.Pattern, + t.UpdatePetReqMock = &dto.UpdatePetRequest{ + Type: t.Pet.Type, + Name: t.Pet.Name, + Birthdate: t.Pet.Birthdate, + Gender: t.Pet.Gender, + Color: t.Pet.Color, + Habit: t.Pet.Habit, Caption: t.Pet.Caption, - Images: []string{}, - Status: constant.Status(t.Pet.Status), + Status: t.Pet.Status, + Images: t.ImageUrls, IsSterile: &t.Pet.IsSterile, IsVaccinated: &t.Pet.IsVaccinated, IsVisible: &t.Pet.IsVisible, Origin: t.Pet.Origin, Owner: t.Pet.Owner, Contact: t.Pet.Contact, - Tel: t.Pet.Tel, } - t.FindAllPetReq = pet.FindAllDtoToProto(t.FindAllPetDto, true) - t.CreatePetReq = pet.CreateDtoToProto(t.CreatePetDto) - t.UpdatePetReq = pet.UpdateDtoToProto(t.Pet.Id, t.UpdatePetDto) - - t.ChangeViewPetReq = &petproto.ChangeViewPetRequest{ - Id: t.Pet.Id, - Visible: false, - } - - t.ChangeViewedPetDto = &dto.ChangeViewPetRequest{ + t.ChangeViewPetReqMock = &dto.ChangeViewPetRequest{ Visible: false, } - t.AdoptReq = &petproto.AdoptPetRequest{ - PetId: t.Pet.Id, - UserId: t.Pet.Owner, - } - - t.AdoptDto = &dto.AdoptByRequest{ - UserID: t.Pet.Owner, - } + t.ChangeAdoptBy = &model.Pet{ + Base: model.Base{ + ID: t.Pet.Base.ID, + CreatedAt: t.Pet.Base.CreatedAt, + UpdatedAt: t.Pet.Base.UpdatedAt, + DeletedAt: t.Pet.Base.DeletedAt, + }, + Type: t.Pet.Type, + Name: t.Pet.Name, + Birthdate: t.Pet.Birthdate, + Gender: t.Pet.Gender, + Color: t.Pet.Color, - t.FindAllImageReq = &imgproto.FindAllImageRequest{} - - t.AssignPetReq = &imgproto.AssignPetRequest{ - Ids: []string{}, - PetId: t.Pet.Id, - } - - t.AssignPetDto = &dto.AssignPetRequest{ - Ids: []string{}, - PetId: t.Pet.Id, - } - - t.FindByPetIdReq = &imgproto.FindImageByPetIdRequest{ - PetId: t.Pet.Id, - } - - t.UnavailableServiceErr = &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - - t.NotFoundErr = &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.PetNotFoundMessage, - Data: nil, + Habit: t.Pet.Habit, + Caption: t.Pet.Caption, + Status: t.Pet.Status, + IsSterile: t.Pet.IsSterile, + IsVaccinated: t.Pet.IsVaccinated, + IsVisible: t.Pet.IsVisible, + Origin: t.Pet.Origin, + Owner: t.Pet.Owner, + Contact: t.Pet.Contact, + Tel: t.Pet.Tel, } - t.InternalErr = &dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: constant.InternalErrorMessage, - Data: nil, + t.AdoptByReq = &dto.AdoptByRequest{ + UserID: t.ChangeAdoptBy.Owner, } - t.InvalidArgumentErr = &dto.ResponseErr{ - StatusCode: http.StatusBadRequest, - Message: constant.InvalidArgumentMessage, - Data: nil, - } } +func (t *PetServiceTest) TestDeleteSuccess() { + want := &dto.DeleteResponse{Success: true} -func (t *PetServiceTest) TestFindAllSuccess() { - protoResp := &petproto.FindAllPetResponse{ - Pets: t.Pets, - Metadata: t.MetadataProto, - } - - findAllPPetsDto := pet.ProtoToDtoList(t.Pets, t.ImagesList, false) - metadataDto := t.MetadataDto - - expected := &dto.FindAllPetResponse{ - Pets: findAllPPetsDto, - Metadata: metadataDto, - } - - client := petmock.PetClientMock{} - client.On("FindAll", t.FindAllPetReq).Return(protoResp, nil) + repo := new(mock.RepositoryMock) + repo.On("Delete", t.Pet.ID.String()).Return(nil) + imgSrv := new(img_mock.ServiceMock) - findAllImageResp := &imgproto.FindAllImageResponse{ - Images: t.AllImages, - } - imageClient := imagemock.ImageClientMock{} - imageClient.On("FindAll", t.FindAllImageReq).Return(findAllImageResp, nil) - - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(&client, imageSvc) - actual, err := svc.FindAll(t.FindAllPetDto, true) + srv := pet.NewService(repo, imgSrv) + actual, err := srv.Delete(t.Pet.ID.String()) assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) + assert.Equal(t.T(), want, actual) + repo.AssertExpectations(t.T()) } -func (t *PetServiceTest) TestFindAllUnavailableServiceError() { - expected := t.UnavailableServiceErr - - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) - - client := petmock.PetClientMock{} - client.On("FindAll", t.FindAllPetReq).Return(nil, clientErr) - - imageClient := imagemock.ImageClientMock{} - - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(&client, imageSvc) - actual, err := svc.FindAll(t.FindAllPetDto, true) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *PetServiceTest) TestFindOneSuccess() { - protoReq := &petproto.FindOnePetRequest{ - Id: t.Pet.Id, - } - protoResp := &petproto.FindOnePetResponse{ - Pet: t.Pet, - } - - findByPetIdReq := t.FindByPetIdReq - findByPetIdResp := &imgproto.FindImageByPetIdResponse{ - Images: t.Images, - } - - expected := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) - - client := petmock.PetClientMock{} - client.On("FindOne", protoReq).Return(protoResp, nil) - - imageClient := imagemock.ImageClientMock{} - imageClient.On("FindByPetId", findByPetIdReq).Return(findByPetIdResp, nil) +func (t *PetServiceTest) TestDeleteNotFound() { + repo := new(mock.RepositoryMock) + repo.On("Delete", t.Pet.ID.String()).Return(gorm.ErrRecordNotFound) + imgSrv := new(img_mock.ServiceMock) - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(&client, imageSvc) - actual, err := svc.FindOne(t.Pet.Id) + srv := pet.NewService(repo, imgSrv) + _, err := srv.Delete(t.Pet.ID.String()) - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) + assert.Equal(t.T(), http.StatusNotFound, err.StatusCode) + repo.AssertExpectations(t.T()) } -func (t *PetServiceTest) TestFindOneNotFoundError() { - protoReq := &petproto.FindOnePetRequest{ - Id: t.Pet.Id, - } - - clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) - - expected := t.NotFoundErr - - client := petmock.PetClientMock{} - client.On("FindOne", protoReq).Return(nil, clientErr) - - imageClient := imagemock.ImageClientMock{} +func (t *PetServiceTest) TestDeleteWithDatabaseError() { + repo := new(mock.RepositoryMock) + repo.On("Delete", t.Pet.ID.String()).Return(errors.New("internal server error")) + imgSrv := new(img_mock.ServiceMock) - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(&client, imageSvc) - actual, err := svc.FindOne(t.Pet.Id) + srv := pet.NewService(repo, imgSrv) + _, err := srv.Delete(t.Pet.ID.String()) - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) + assert.Equal(t.T(), http.StatusInternalServerError, err.StatusCode) + repo.AssertExpectations(t.T()) } -func (t *PetServiceTest) TestFindOneUnavailableServiceError() { - protoReq := &petproto.FindOnePetRequest{ - Id: t.Pet.Id, - } - - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) - - expected := t.UnavailableServiceErr - - client := petmock.PetClientMock{} - client.On("FindOne", protoReq).Return(nil, clientErr) - - imageClient := imagemock.ImageClientMock{} - - imageSvc := imageSvc.NewService(&imageClient) +func (t *PetServiceTest) TestDeleteWithUnexpectedError() { + repo := new(mock.RepositoryMock) + repo.On("Delete", t.Pet.ID.String()).Return(errors.New("unexpected error")) + imgSrv := new(img_mock.ServiceMock) - svc := pet.NewService(&client, imageSvc) - actual, err := svc.FindOne(t.Pet.Id) + srv := pet.NewService(repo, imgSrv) + _, err := srv.Delete(t.Pet.ID.String()) - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) + assert.NotNil(t.T(), err) + repo.AssertExpectations(t.T()) } -func (t *PetServiceTest) TestCreateSuccess() { - protoReq := t.CreatePetReq - protoResp := &petproto.CreatePetResponse{ - Pet: t.Pet, - } - - assignPetReq := t.AssignPetReq - assignPetResp := &imgproto.AssignPetResponse{ - Success: true, - } - - findByPetIdReq := t.FindByPetIdReq - findByPetIdResp := &imgproto.FindImageByPetIdResponse{ - Images: t.Images, - } - - expected := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) - - client := &petmock.PetClientMock{} - client.On("Create", protoReq).Return(protoResp, nil) +func (t *PetServiceTest) TestFindOneSuccess() { + want := t.PetDto - imageClient := imagemock.ImageClientMock{} - imageClient.On("AssignPet", assignPetReq).Return(assignPetResp, nil) - imageClient.On("FindByPetId", findByPetIdReq).Return(findByPetIdResp, nil) + repo := &mock.RepositoryMock{} + repo.On("FindOne", t.Pet.ID.String(), &model.Pet{}).Return(t.Pet, nil) + imgSrv := new(img_mock.ServiceMock) + imgSrv.On("FindByPetId", t.Pet.ID.String()).Return(t.Images, nil) - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Create(t.CreatePetDto) + srv := pet.NewService(repo, imgSrv) + actual, err := srv.FindOne(t.Pet.ID.String()) assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) + assert.Equal(t.T(), want, actual) } -func (t *PetServiceTest) TestCreateInvalidArgumentError() { - protoReq := t.CreatePetReq - - expected := t.InvalidArgumentErr - - clientErr := status.Error(codes.InvalidArgument, constant.InvalidArgumentMessage) +// func (t *PetServiceTest) TestFindAllSuccess() { - client := &petmock.PetClientMock{} - client.On("Create", protoReq).Return(nil, clientErr) +// want := &proto.FindAllPetResponse{ +// Pets: t.createPetsDto(t.Pets, t.ImagesList), +// Metadata: &proto.FindAllPetMetaData{ +// Page: 1, +// TotalPages: 1, +// PageSize: int32(len(t.Pets)), +// Total: int32(len(t.Pets)), +// }, +// } - imageClient := imagemock.ImageClientMock{} +// var petsIn []*model.Pet - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Create(t.CreatePetDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} +// repo := &mock.RepositoryMock{} +// repo.On("FindAll", petsIn).Return(&t.Pets, nil) -func (t *PetServiceTest) TestCreateInternalError() { - protoReq := t.CreatePetReq +// imgSrv := new(img_mock.ServiceMock) +// for i, pet := range t.Pets { +// imgSrv.On("FindByPetId", pet.ID.String()).Return(t.ImagesList[i], nil) +// } - expected := t.InternalErr +// srv := pet.NewService(repo, imgSrv) - clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) +// actual, err := srv.FindAll() +// assert.Nil(t.T(), err) +// assert.Equal(t.T(), want, actual) +// } - client := &petmock.PetClientMock{} - client.On("Create", protoReq).Return(nil, clientErr) +func (t *PetServiceTest) TestFindOneNotFound() { + repo := &mock.RepositoryMock{} + repo.On("FindOne", t.Pet.ID.String(), &model.Pet{}).Return(nil, errors.New("Not found pet")) + imgSrv := new(img_mock.ServiceMock) + imgSrv.On("FindByPetId", t.Pet.ID.String()).Return(nil, nil) - imageClient := imagemock.ImageClientMock{} - - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Create(t.CreatePetDto) - - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *PetServiceTest) TestCreateUnavailableServiceError() { - protoReq := t.CreatePetReq - - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) - - expected := t.UnavailableServiceErr - - client := &petmock.PetClientMock{} - client.On("Create", protoReq).Return(nil, clientErr) - - imageClient := imagemock.ImageClientMock{} - - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Create(t.CreatePetDto) + srv := pet.NewService(repo, imgSrv) + actual, err := srv.FindOne(t.Pet.ID.String()) + assert.Equal(t.T(), http.StatusNotFound, err.StatusCode) assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) } -func (t *PetServiceTest) TestUpdateSuccess() { - protoReq := t.UpdatePetReq - protoResp := &petproto.UpdatePetResponse{ - Pet: t.Pet, - } - - expected := pet.ProtoToDto(t.Pet, pet.ImageProtoToDto(t.Pet.Images)) - - client := &petmock.PetClientMock{} - client.On("Update", protoReq).Return(protoResp, nil) +func createPets() []*model.Pet { + var result []*model.Pet + genders := []constant.Gender{constant.MALE, constant.FEMALE} + statuses := []constant.Status{constant.ADOPTED, constant.FINDHOME} - findByPetIdResp := &imgproto.FindImageByPetIdResponse{ - Images: t.Images, + for i := 0; i < rand.Intn(4)+1; i++ { + r := &model.Pet{ + Base: model.Base{ + ID: uuid.New(), + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + DeletedAt: gorm.DeletedAt{}, + }, + Type: faker.Word(), + Name: faker.Name(), + Birthdate: faker.Word(), + Gender: genders[rand.Intn(2)], + Color: faker.Word(), + Habit: faker.Paragraph(), + Caption: faker.Paragraph(), + Status: statuses[rand.Intn(2)], + IsSterile: true, + IsVaccinated: true, + IsVisible: true, + Origin: faker.Paragraph(), + Owner: faker.Paragraph(), + Contact: faker.Paragraph(), + } + result = append(result, r) } - imageClient := imagemock.ImageClientMock{} - imageClient.On("FindByPetId", t.FindByPetIdReq).Return(findByPetIdResp, nil) - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) - - assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) + return result } -func (t *PetServiceTest) TestUpdateNotFound() { - protoReq := t.UpdatePetReq - clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) - - expected := t.NotFoundErr - - client := &petmock.PetClientMock{} - client.On("Update", protoReq).Return(nil, clientErr) - - imageClient := imagemock.ImageClientMock{} +func (t *PetServiceTest) createPetsDto(in []*model.Pet, imagesList [][]*dto.ImageResponse) []*dto.PetResponse { + var result []*dto.PetResponse + + for i, p := range in { + r := &dto.PetResponse{ + Id: p.ID.String(), + Type: p.Type, + Name: p.Name, + Birthdate: p.Birthdate, + Gender: p.Gender, + Color: p.Color, + + Habit: p.Habit, + Caption: p.Caption, + Status: p.Status, + Images: imagesList[i], + IsSterile: &p.IsSterile, + IsVaccinated: &p.IsVaccinated, + IsVisible: &p.IsVisible, + Origin: p.Origin, + Owner: p.Owner, + Contact: p.Contact, + } - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) + result = append(result, r) + } - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) + return result } -func (t *PetServiceTest) TestUpdateUnavailableServiceError() { - protoReq := t.UpdatePetReq - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) - - expected := t.UnavailableServiceErr - - client := &petmock.PetClientMock{} - client.On("Update", protoReq).Return(nil, clientErr) +func (t *PetServiceTest) TestCreateSuccess() { + want := t.PetDto + want.Images = t.Images - imageClient := imagemock.ImageClientMock{} + repo := &mock.RepositoryMock{} - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) + in := &model.Pet{ + Type: t.Pet.Type, + Name: t.Pet.Name, + Birthdate: t.Pet.Birthdate, + Gender: t.Pet.Gender, + Color: t.Pet.Color, - assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} - -func (t *PetServiceTest) TestDeleteSuccess() { - petProtoReq := &petproto.DeletePetRequest{ - Id: t.Pet.Id, - } - petProtoResp := &petproto.DeletePetResponse{ - Success: true, - } - imageProtoReq := &imgproto.DeleteByPetIdRequest{ - PetId: t.Pet.Id, - } - imageProtoResp := &imgproto.DeleteByPetIdResponse{ - Success: true, + Habit: t.Pet.Habit, + Caption: t.Pet.Caption, + Status: t.Pet.Status, + IsSterile: t.Pet.IsSterile, + IsVaccinated: t.Pet.IsVaccinated, + IsVisible: t.Pet.IsVisible, + Origin: t.Pet.Origin, + Owner: t.Pet.Owner, + Contact: t.Pet.Contact, } - expected := &dto.DeleteResponse{Success: true} + repo.On("Create", in).Return(t.Pet, nil) + imgSrv := new(img_mock.ServiceMock) + + // imageIds := []string{t.CreatePetReqMock.Images[0], t.CreatePetReqMock.Images[1], t.CreatePetReqMock.Images[2]} + imgSrv.On("AssignPet", &dto.AssignPetRequest{PetId: t.Pet.ID.String(), Ids: t.ImageUrls}).Return(&dto.AssignPetResponse{Success: true}) - client := &petmock.PetClientMock{} - client.On("Delete", petProtoReq).Return(petProtoResp, nil) + imgSrv.On("FindByPetId", t.Pet.ID.String()).Return(t.Images, nil) - imageClient := imagemock.ImageClientMock{} - imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) + srv := pet.NewService(repo, imgSrv) - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Delete(t.Pet.Id) + actual, err := srv.Create(t.CreatePetReqMock) assert.Nil(t.T(), err) - assert.Equal(t.T(), expected, actual) + assert.Equal(t.T(), want, actual) } -func (t *PetServiceTest) TestDeleteNotFound() { - protoReq := &petproto.DeletePetRequest{ - Id: t.Pet.Id, - } - protoResp := &petproto.DeletePetResponse{ - Success: false, - } - imageProtoReq := &imgproto.DeleteByPetIdRequest{ - PetId: t.Pet.Id, - } - imageProtoResp := &imgproto.DeleteByPetIdResponse{ - Success: true, - } +func (t *PetServiceTest) TestCreateInternalErr() { + repo := &mock.RepositoryMock{} - clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) + in := &model.Pet{ + Type: t.Pet.Type, + Name: t.Pet.Name, + Birthdate: t.Pet.Birthdate, + Gender: t.Pet.Gender, + Color: t.Pet.Color, - expected := t.NotFoundErr + Habit: t.Pet.Habit, + Caption: t.Pet.Caption, + Status: t.Pet.Status, + IsSterile: t.Pet.IsSterile, + IsVaccinated: t.Pet.IsVaccinated, + IsVisible: t.Pet.IsVisible, + Origin: t.Pet.Origin, + Owner: t.Pet.Owner, + Contact: t.Pet.Contact, + } - client := &petmock.PetClientMock{} - client.On("Delete", protoReq).Return(protoResp, clientErr) + repo.On("Create", in).Return(nil, errors.New("something wrong")) + imgSrv := new(img_mock.ServiceMock) - imageClient := imagemock.ImageClientMock{} - imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) + srv := pet.NewService(repo, imgSrv) - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Delete(t.Pet.Id) + actual, err := srv.Create(t.CreatePetReqMock) + assert.Equal(t.T(), http.StatusInternalServerError, err.StatusCode) assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) } -func (t *PetServiceTest) TestDeleteServiceUnavailableError() { - protoReq := &petproto.DeletePetRequest{ - Id: t.Pet.Id, - } - protoResp := &petproto.DeletePetResponse{ - Success: false, - } - imageProtoReq := &imgproto.DeleteByPetIdRequest{ - PetId: t.Pet.Id, - } - imageProtoResp := &imgproto.DeleteByPetIdResponse{ - Success: true, - } +func (t *PetServiceTest) TestUpdateSuccess() { + want := t.PetDto + updatePet := t.UpdatePet + updatePet.ID = uuid.Nil - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + repo := &mock.RepositoryMock{} + repo.On("Update", t.Pet.ID.String(), t.UpdatePet).Return(t.Pet, nil) + imgSrv := new(img_mock.ServiceMock) + imgSrv.On("FindByPetId", t.Pet.ID.String()).Return(t.Images, nil) - expected := t.UnavailableServiceErr + srv := pet.NewService(repo, imgSrv) + actual, err := srv.Update(t.Pet.ID.String(), t.UpdatePetReqMock) - client := &petmock.PetClientMock{} - client.On("Delete", protoReq).Return(protoResp, clientErr) + assert.Nil(t.T(), err) + assert.Equal(t.T(), want, actual) +} - imageClient := imagemock.ImageClientMock{} - imageClient.On("DeleteByPetId", imageProtoReq).Return(imageProtoResp, nil) +func (t *PetServiceTest) TestUpdateNotFound() { + updatePet := t.UpdatePet + updatePet.ID = uuid.Nil + repo := &mock.RepositoryMock{} + repo.On("Update", t.UpdatePet.ID.String(), t.UpdatePet).Return(nil, errors.New("Not found pet")) + imgSrv := new(img_mock.ServiceMock) + imgSrv.On("FindByPetId", t.UpdatePet.ID.String()).Return(t.Images, nil) - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Delete(t.Pet.Id) + srv := pet.NewService(repo, imgSrv) + actual, err := srv.Update(t.UpdatePet.ID.String(), t.UpdatePetReqMock) + assert.Equal(t.T(), http.StatusNotFound, err.StatusCode) assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) } func (t *PetServiceTest) TestChangeViewSuccess() { - protoReq := t.ChangeViewPetReq - protoResp := &petproto.ChangeViewPetResponse{ - Success: true, - } - - client := &petmock.PetClientMock{} - client.On("ChangeView", protoReq).Return(protoResp, nil) + want := &dto.ChangeViewPetResponse{Success: true} - imageClient := imagemock.ImageClientMock{} + repo := &mock.RepositoryMock{} + repo.On("FindOne", t.Pet.ID.String(), &model.Pet{}).Return(t.Pet, nil) + repo.On("Update", t.Pet.ID.String(), t.ChangeViewPet).Return(t.ChangeViewPet, nil) + imgSrv := new(img_mock.ServiceMock) + imgSrv.On("FindByPetId", t.Pet.ID.String()).Return(t.Images, nil) - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) + srv := pet.NewService(repo, imgSrv) + actual, err := srv.ChangeView(t.Pet.ID.String(), t.ChangeViewPetReqMock) assert.Nil(t.T(), err) - assert.Equal(t.T(), actual, &dto.ChangeViewPetResponse{Success: true}) + assert.Equal(t.T(), want, actual) } -func (t *PetServiceTest) TestChangeViewNotFoundError() { - protoReq := t.ChangeViewPetReq - protoResp := &petproto.ChangeViewPetResponse{ - Success: false, - } - - clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) - - expected := t.NotFoundErr - - client := &petmock.PetClientMock{} - client.On("ChangeView", protoReq).Return(protoResp, clientErr) - - imageClient := imagemock.ImageClientMock{} +func (t *PetServiceTest) TestChangeViewNotFound() { + repo := &mock.RepositoryMock{} + repo.On("FindOne", t.Pet.ID.String(), &model.Pet{}).Return(nil, errors.New("Not found pet")) + repo.On("Update", t.Pet.ID.String(), t.UpdatePet).Return(nil, errors.New("Not found pet")) + imgSrv := new(img_mock.ServiceMock) - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) + srv := pet.NewService(repo, imgSrv) + actual, err := srv.ChangeView(t.Pet.ID.String(), t.ChangeViewPetReqMock) - assert.Equal(t.T(), &dto.ChangeViewPetResponse{Success: false}, actual) - assert.Equal(t.T(), expected, err) + assert.Equal(t.T(), http.StatusNotFound, err.StatusCode) + assert.Nil(t.T(), actual) } -func (t *PetServiceTest) TestChangeViewUnavailableServiceError() { - protoReq := t.ChangeViewPetReq - protoResp := &petproto.ChangeViewPetResponse{ - Success: false, - } - - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) - - expected := t.UnavailableServiceErr - - client := &petmock.PetClientMock{} - client.On("ChangeView", protoReq).Return(protoResp, clientErr) - - imageClient := imagemock.ImageClientMock{} - - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) +func (t *PetServiceTest) TestAdoptBySuccess() { + want := &dto.AdoptByResponse{Success: true} + repo := &mock.RepositoryMock{} - assert.Equal(t.T(), &dto.ChangeViewPetResponse{Success: false}, actual) - assert.Equal(t.T(), expected, err) -} - -func (t *PetServiceTest) TestAdoptSuccess() { - protoReq := t.AdoptReq - protoResp := &petproto.AdoptPetResponse{ - Success: true, - } + repo.On("FindOne", t.Pet.ID.String(), &model.Pet{}).Return(t.Pet, nil) + repo.On("Update", t.Pet.ID.String(), t.ChangeAdoptBy).Return(t.ChangeAdoptBy, nil) - client := &petmock.PetClientMock{} - client.On("AdoptPet", protoReq).Return(protoResp, nil) + imgSrv := new(img_mock.ServiceMock) + imgSrv.On("FindByPetId", t.Pet.ID.String()).Return(t.Images, nil) - imageClient := imagemock.ImageClientMock{} + srv := pet.NewService(repo, imgSrv) - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) + actual, err := srv.Adopt(t.Pet.ID.String(), t.AdoptByReq) assert.Nil(t.T(), err) - assert.Equal(t.T(), actual, &dto.AdoptByResponse{Success: true}) + assert.Equal(t.T(), want, actual) } -func (t *PetServiceTest) TestAdoptNotFoundError() { - protoReq := t.AdoptReq - - clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) +func (t *PetServiceTest) TestAdoptByPetNotFound() { + wantError := status.Error(codes.NotFound, "pet not found") + repo := &mock.RepositoryMock{} - expected := t.NotFoundErr + repo.On("FindOne", t.Pet.ID.String(), &model.Pet{}).Return(nil, wantError) - client := &petmock.PetClientMock{} - client.On("AdoptPet", protoReq).Return(nil, clientErr) + imgSrv := new(img_mock.ServiceMock) + srv := pet.NewService(repo, imgSrv) - imageClient := imagemock.ImageClientMock{} - - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) + actual, err := srv.Adopt(t.Pet.ID.String(), t.AdoptByReq) + assert.NotNil(t.T(), err) + assert.Equal(t.T(), http.StatusNotFound, err.StatusCode) assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) -} -func (t *PetServiceTest) TestAdoptUnavailableServiceError() { - protoReq := t.AdoptReq + repo.AssertNotCalled(t.T(), "Update", t.Pet.ID.String(), t.ChangeAdoptBy) +} - clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) +func (t *PetServiceTest) TestAdoptByUpdateError() { + wantError := &dto.ResponseErr{StatusCode: http.StatusInternalServerError} + repo := &mock.RepositoryMock{} - expected := t.UnavailableServiceErr + repo.On("FindOne", t.Pet.ID.String(), &model.Pet{}).Return(t.Pet, nil) + repo.On("Update", t.Pet.ID.String(), t.ChangeAdoptBy).Return(nil, errors.New("update error")) - client := &petmock.PetClientMock{} - client.On("AdoptPet", protoReq).Return(nil, clientErr) + imgSrv := new(img_mock.ServiceMock) + imgSrv.On("FindByPetId", t.Pet.ID.String()).Return(nil, wantError) - imageClient := imagemock.ImageClientMock{} + srv := pet.NewService(repo, imgSrv) - imageSvc := imageSvc.NewService(&imageClient) - svc := pet.NewService(client, imageSvc) - actual, err := svc.Adopt(t.Pet.Id, t.AdoptDto) + actual, err := srv.Adopt(t.Pet.ID.String(), t.AdoptByReq) + assert.NotNil(t.T(), err) + assert.Equal(t.T(), http.StatusInternalServerError, err.StatusCode) assert.Nil(t.T(), actual) - assert.Equal(t.T(), expected, err) } diff --git a/mocks/repository/pet/pet.mock.go b/mocks/repository/pet/pet.mock.go new file mode 100644 index 0000000..aa2eced --- /dev/null +++ b/mocks/repository/pet/pet.mock.go @@ -0,0 +1,55 @@ +package pet + +import ( + "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/stretchr/testify/mock" +) + +type RepositoryMock struct { + mock.Mock +} + +func (r *RepositoryMock) FindOne(id string, result *model.Pet) error { + args := r.Called(id, result) + + if args.Get(0) != nil { + *result = *args.Get(0).(*model.Pet) + } + + return args.Error(1) +} + +func (r *RepositoryMock) Create(in *model.Pet) error { + args := r.Called(in) + + if args.Get(0) != nil { + *in = *args.Get(0).(*model.Pet) + } + + return args.Error(1) +} + +func (r *RepositoryMock) FindAll(result *[]*model.Pet, isAdmin bool) error { + args := r.Called(*result) + + if args.Get(0) != nil { + *result = *args.Get(0).(*[]*model.Pet) + } + + return args.Error(1) +} + +func (r *RepositoryMock) Update(id string, result *model.Pet) error { + args := r.Called(id, result) + + if args.Get(0) != nil { + *result = *args.Get(0).(*model.Pet) + } + + return args.Error(1) +} + +func (r *RepositoryMock) Delete(id string) error { + args := r.Called(id) + return args.Error(0) +} diff --git a/mocks/service/image/image.mock_old.go b/mocks/service/image/image.mock_old.go new file mode 100644 index 0000000..9816782 --- /dev/null +++ b/mocks/service/image/image.mock_old.go @@ -0,0 +1,70 @@ +package mock_image + +import ( + dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/stretchr/testify/mock" +) + +type ServiceMock struct { + mock.Mock +} + +func (c *ServiceMock) FindAll() (res []*dto.ImageResponse, err *dto.ResponseErr) { + args := c.Called() + + if args.Get(0) != nil { + res = args.Get(0).([]*dto.ImageResponse) + } + + return res, args.Get(1).(*dto.ResponseErr) +} + +func (c *ServiceMock) FindByPetId(petID string) ([]*dto.ImageResponse, *dto.ResponseErr) { + args := c.Called(petID) + + if args.Get(0) != nil { + res := args.Get(0).([]*dto.ImageResponse) + return res, nil + } + return nil, args.Get(1).(*dto.ResponseErr) +} + +func (c *ServiceMock) Upload(request *dto.UploadImageRequest) (*dto.ImageResponse, *dto.ResponseErr) { + args := c.Called(request) + + if args.Get(0) != nil { + res := args.Get(0).(*dto.ImageResponse) + return res, nil + } + return nil, args.Get(1).(*dto.ResponseErr) +} + +func (c *ServiceMock) Delete(id string) (*dto.DeleteImageResponse, *dto.ResponseErr) { + args := c.Called(id) + + if args.Get(0) != nil { + res := args.Get(0).(*dto.DeleteImageResponse) + return res, nil + } + return nil, args.Get(1).(*dto.ResponseErr) +} + +func (c *ServiceMock) DeleteByPetId(petID string) (*dto.DeleteImageResponse, *dto.ResponseErr) { + args := c.Called(petID) + + if args.Get(0) != nil { + res := args.Get(0).(*dto.DeleteImageResponse) + return res, nil + } + return nil, args.Get(1).(*dto.ResponseErr) +} + +func (c *ServiceMock) AssignPet(request *dto.AssignPetRequest) (*dto.AssignPetResponse, *dto.ResponseErr) { + args := c.Called(request) + + if args.Get(0) != nil { + res := args.Get(0).(*dto.AssignPetResponse) + return res, nil + } + return nil, args.Get(1).(*dto.ResponseErr) +} diff --git a/mocks/service/pet/pet.mock.go b/mocks/service/pet/pet.mock.go index 17563e0..0156dba 100644 --- a/mocks/service/pet/pet.mock.go +++ b/mocks/service/pet/pet.mock.go @@ -35,106 +35,106 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { } // Adopt mocks base method. -func (m *MockService) Adopt(arg0 string, arg1 *dto.AdoptByRequest) (*dto.AdoptByResponse, *dto.ResponseErr) { +func (m *MockService) Adopt(id string, req *dto.AdoptByRequest) (*dto.AdoptByResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Adopt", arg0, arg1) + ret := m.ctrl.Call(m, "Adopt", id, req) ret0, _ := ret[0].(*dto.AdoptByResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Adopt indicates an expected call of Adopt. -func (mr *MockServiceMockRecorder) Adopt(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Adopt(id, req interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Adopt", reflect.TypeOf((*MockService)(nil).Adopt), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Adopt", reflect.TypeOf((*MockService)(nil).Adopt), id, req) } // ChangeView mocks base method. -func (m *MockService) ChangeView(arg0 string, arg1 *dto.ChangeViewPetRequest) (*dto.ChangeViewPetResponse, *dto.ResponseErr) { +func (m *MockService) ChangeView(id string, req *dto.ChangeViewPetRequest) (*dto.ChangeViewPetResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ChangeView", arg0, arg1) + ret := m.ctrl.Call(m, "ChangeView", id, req) ret0, _ := ret[0].(*dto.ChangeViewPetResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // ChangeView indicates an expected call of ChangeView. -func (mr *MockServiceMockRecorder) ChangeView(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) ChangeView(id, req interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangeView", reflect.TypeOf((*MockService)(nil).ChangeView), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangeView", reflect.TypeOf((*MockService)(nil).ChangeView), id, req) } // Create mocks base method. -func (m *MockService) Create(arg0 *dto.CreatePetRequest) (*dto.PetResponse, *dto.ResponseErr) { +func (m *MockService) Create(req *dto.CreatePetRequest) (*dto.PetResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Create", arg0) + ret := m.ctrl.Call(m, "Create", req) ret0, _ := ret[0].(*dto.PetResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Create indicates an expected call of Create. -func (mr *MockServiceMockRecorder) Create(arg0 interface{}) *gomock.Call { +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), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockService)(nil).Create), req) } // Delete mocks base method. -func (m *MockService) Delete(arg0 string) (*dto.DeleteResponse, *dto.ResponseErr) { +func (m *MockService) Delete(id string) (*dto.DeleteResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", arg0) + ret := m.ctrl.Call(m, "Delete", id) ret0, _ := ret[0].(*dto.DeleteResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Delete indicates an expected call of Delete. -func (mr *MockServiceMockRecorder) Delete(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Delete(id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), id) } // FindAll mocks base method. -func (m *MockService) FindAll(arg0 *dto.FindAllPetRequest, arg1 bool) (*dto.FindAllPetResponse, *dto.ResponseErr) { +func (m *MockService) FindAll(req *dto.FindAllPetRequest, isAdmin bool) (*dto.FindAllPetResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindAll", arg0, arg1) + ret := m.ctrl.Call(m, "FindAll", req, isAdmin) ret0, _ := ret[0].(*dto.FindAllPetResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // FindAll indicates an expected call of FindAll. -func (mr *MockServiceMockRecorder) FindAll(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) FindAll(req, isAdmin interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAll", reflect.TypeOf((*MockService)(nil).FindAll), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAll", reflect.TypeOf((*MockService)(nil).FindAll), req, isAdmin) } // FindOne mocks base method. -func (m *MockService) FindOne(arg0 string) (*dto.PetResponse, *dto.ResponseErr) { +func (m *MockService) FindOne(id string) (*dto.PetResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindOne", arg0) + ret := m.ctrl.Call(m, "FindOne", id) ret0, _ := ret[0].(*dto.PetResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // FindOne indicates an expected call of FindOne. -func (mr *MockServiceMockRecorder) FindOne(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) FindOne(id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockService)(nil).FindOne), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockService)(nil).FindOne), id) } // Update mocks base method. -func (m *MockService) Update(arg0 string, arg1 *dto.UpdatePetRequest) (*dto.PetResponse, *dto.ResponseErr) { +func (m *MockService) Update(id string, req *dto.UpdatePetRequest) (*dto.PetResponse, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Update", arg0, arg1) + ret := m.ctrl.Call(m, "Update", id, req) ret0, _ := ret[0].(*dto.PetResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Update indicates an expected call of Update. -func (mr *MockServiceMockRecorder) Update(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Update(id, req interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockService)(nil).Update), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockService)(nil).Update), id, req) } From 5f8826cb19006970b450390b814b98fc6de3e9a9 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 23 Aug 2024 15:06:51 +0700 Subject: [PATCH 097/104] readme --- README.md | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9507431..ad46256 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Johnjud-gateway +# Johnjud-backend -Johnjud-gateway is a routing and request handling service for the Johnjud project. +Johnjud-backend is a routing and request handling service for the Johnjud project. ### What is Johnjud? Johnjud is a pet adoption web application of the [CUVET For Animal Welfare Club](https://www.facebook.com/CUVETforAnimalWelfareClub) @@ -8,7 +8,6 @@ Johnjud is a pet adoption web application of the [CUVET For Animal Welfare Club] ## Stack - golang -- gRPC - go-fiber ## Getting Started @@ -22,22 +21,16 @@ Johnjud is a pet adoption web application of the [CUVET For Animal Welfare Club] ### Installation 1. Clone this repo -2. Copy every `config.example.yaml` in `config` and paste it in the same directory with `.example` removed from its name. - +2. Copy `.env.template` in root directory and paste it in the same directory as `.env` with proper values. 3. Run `go mod download` to download all the dependencies. ### Running -1. Run `docker-compose up -d` -2. Run `make server` or `go run ./src/.` +1. Run `docker-compose -f docker-compose.example.yaml up` +2. Run `make server` or `go run ./cmd/.` ### Testing 1. Run `make test` or `go test -v -coverpkg ./... -coverprofile coverage.out -covermode count ./...` -## Other microservices/repositories of Johnjud -- [Johnjud-gateway](https://github.com/isd-sgcu/johnjud-gateway): Routing and request handling -- [Johnjud-auth](https://github.com/isd-sgcu/johnjud-auth): Authentication and authorization -- [Johnjud-backend](https://github.com/isd-sgcu/johnjud-backend): Main business logic -- [Johnjud-file](https://github.com/isd-sgcu/johnjud-file): File management service -- [Johnjud-proto](https://github.com/isd-sgcu/johnjud-proto): Protobuf files generator -- [Johnjud-go-proto](https://github.com/isd-sgcu/johnjud-go-proto): Generated protobuf files for golang -- [Johnjud-frontend](https://github.com/isd-sgcu/johnjud-frontend): Frontend web application +## Other repositories of Johnjud +- [Johnjud-backend](https://github.com/isd-sgcu/johnjud-backend) +- [Johnjud-frontend](https://github.com/isd-sgcu/johnjud-frontend) From 8477b80baa6595fb70695e712d306b21cef2165f Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 23 Aug 2024 15:07:20 +0700 Subject: [PATCH 098/104] wf no push gitops --- .github/workflows/build.yml | 40 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1c0c0db..8bcbd6a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,26 +54,26 @@ jobs: cache-from: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache cache-to: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache,mode=max - update-gitops: - name: Update gitops repository - runs-on: ubuntu-latest + # update-gitops: + # name: Update gitops repository + # runs-on: ubuntu-latest - steps: - - name: Checkout gitops repository - uses: actions/checkout@v4 - with: - repository: isd-sgcu/isd-gitops - token: ${{ secrets.GITOPS_TOKEN }} + # steps: + # - name: Checkout gitops repository + # uses: actions/checkout@v4 + # with: + # repository: isd-sgcu/isd-gitops + # token: ${{ secrets.GITOPS_TOKEN }} - - name: Update image tag - uses: mikefarah/yq@master - env: - NEW_TAG: ${{ github.ref_type == 'tag' && github.ref_name || env.IMAGE_TAG }} - with: - cmd: yq -i '.gateway.imageTag = strenv(NEW_TAG)' projects/johnjud/values/gateway-dev.values.yaml + # - name: Update image tag + # uses: mikefarah/yq@master + # env: + # NEW_TAG: ${{ github.ref_type == 'tag' && github.ref_name || env.IMAGE_TAG }} + # with: + # cmd: yq -i '.gateway.imageTag = strenv(NEW_TAG)' projects/johnjud/values/gateway-dev.values.yaml - - name: Commit & Push changes - uses: actions-js/push@v1.4 - with: - github_token: ${{ secrets.GITOPS_TOKEN }} - repository: isd-sgcu/isd-gitops \ No newline at end of file + # - name: Commit & Push changes + # uses: actions-js/push@v1.4 + # with: + # github_token: ${{ secrets.GITOPS_TOKEN }} + # repository: isd-sgcu/isd-gitops \ No newline at end of file From 871d3e2b7a333204f735d8bbaf2e8e0cc4e002bf Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 23 Aug 2024 15:09:30 +0700 Subject: [PATCH 099/104] github.com/isd-sgcu/johnjud-backend --- client/bucket/bucket.client.go | 2 +- cmd/main.go | 34 +++++++++---------- database/postgresql.connection.go | 4 +-- database/redis.connection.go | 2 +- go.mod | 2 +- internal/auth/auth.handler.go | 10 +++--- internal/auth/auth.repository.go | 2 +- internal/auth/auth.service.go | 16 ++++----- internal/auth/email/email.service.go | 2 +- internal/auth/jwt/jwt.service.go | 8 ++--- internal/auth/jwt/jwt.strategy.go | 2 +- internal/auth/jwt/test/jwt.service_test.go | 12 +++---- internal/auth/test/auth.handler_test.go | 14 ++++---- .../auth/token/test/token.service_test.go | 14 ++++---- internal/auth/token/token.service.go | 10 +++--- internal/cache/test/cache.repository_test.go | 4 +-- internal/dto/pet.dto.go | 2 +- internal/dto/token.dto.go | 2 +- internal/healthcheck/healthcheck.handler.go | 2 +- internal/image/image.handler.go | 8 ++--- internal/image/image.repository.go | 2 +- internal/image/image.service.go | 10 +++--- internal/image/image.utils.go | 2 +- internal/middleware/auth/auth.middleware.go | 12 +++---- internal/model/pet.model.go | 2 +- internal/model/user.model.go | 2 +- internal/pet/old/pet.service.go | 6 ++-- internal/pet/old/pet.utils.go | 4 +-- internal/pet/old/test/pet.service_test.go | 12 +++---- internal/pet/pet.handler.go | 10 +++--- internal/pet/pet.repository.go | 2 +- internal/pet/pet.service.go | 6 ++-- internal/pet/pet.utils.go | 6 ++-- internal/pet/test/pet.handler_test.go | 14 ++++---- internal/pet/test/pet.service_test.go | 12 +++---- internal/router/context.go | 4 +-- internal/router/router.go | 4 +-- internal/user/test/user.service_test.go | 10 +++--- internal/user/user.handler.go | 8 ++--- internal/user/user.repository.go | 2 +- internal/user/user.service.go | 8 ++--- internal/validator/validator.go | 2 +- mocks/repository/auth/auth.mock.go | 2 +- mocks/repository/image/image.mock.go | 2 +- mocks/repository/pet/pet.mock.go | 2 +- mocks/repository/user/user.mock.go | 2 +- mocks/router/context.mock.go | 2 +- mocks/service/auth/auth.mock.go | 2 +- mocks/service/image/image.mock.go | 2 +- mocks/service/image/image.mock_old.go | 2 +- mocks/service/jwt/jwt.mock.go | 4 +-- mocks/service/like/like.mock.go | 2 +- mocks/service/pet/pet.mock.go | 2 +- mocks/service/token/token.mock.go | 4 +-- mocks/service/user/user.mock.go | 2 +- mocks/validator/validator.mock.go | 2 +- 56 files changed, 162 insertions(+), 162 deletions(-) diff --git a/client/bucket/bucket.client.go b/client/bucket/bucket.client.go index 5d63781..d6aef4e 100644 --- a/client/bucket/bucket.client.go +++ b/client/bucket/bucket.client.go @@ -5,7 +5,7 @@ import ( "context" "time" - "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/isd-sgcu/johnjud-backend/config" "github.com/minio/minio-go/v7" "github.com/pkg/errors" "github.com/rs/zerolog/log" diff --git a/cmd/main.go b/cmd/main.go index 705b7c9..f2e56fc 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -10,23 +10,23 @@ import ( "syscall" "time" - "github.com/isd-sgcu/johnjud-gateway/client/bucket" - "github.com/isd-sgcu/johnjud-gateway/config" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/database" - "github.com/isd-sgcu/johnjud-gateway/internal/auth" - "github.com/isd-sgcu/johnjud-gateway/internal/auth/email" - "github.com/isd-sgcu/johnjud-gateway/internal/auth/jwt" - "github.com/isd-sgcu/johnjud-gateway/internal/auth/token" - "github.com/isd-sgcu/johnjud-gateway/internal/cache" - "github.com/isd-sgcu/johnjud-gateway/internal/healthcheck" - "github.com/isd-sgcu/johnjud-gateway/internal/image" - guard "github.com/isd-sgcu/johnjud-gateway/internal/middleware/auth" - "github.com/isd-sgcu/johnjud-gateway/internal/pet" - "github.com/isd-sgcu/johnjud-gateway/internal/router" - "github.com/isd-sgcu/johnjud-gateway/internal/user" - "github.com/isd-sgcu/johnjud-gateway/internal/utils" - "github.com/isd-sgcu/johnjud-gateway/internal/validator" + "github.com/isd-sgcu/johnjud-backend/client/bucket" + "github.com/isd-sgcu/johnjud-backend/config" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/database" + "github.com/isd-sgcu/johnjud-backend/internal/auth" + "github.com/isd-sgcu/johnjud-backend/internal/auth/email" + "github.com/isd-sgcu/johnjud-backend/internal/auth/jwt" + "github.com/isd-sgcu/johnjud-backend/internal/auth/token" + "github.com/isd-sgcu/johnjud-backend/internal/cache" + "github.com/isd-sgcu/johnjud-backend/internal/healthcheck" + "github.com/isd-sgcu/johnjud-backend/internal/image" + guard "github.com/isd-sgcu/johnjud-backend/internal/middleware/auth" + "github.com/isd-sgcu/johnjud-backend/internal/pet" + "github.com/isd-sgcu/johnjud-backend/internal/router" + "github.com/isd-sgcu/johnjud-backend/internal/user" + "github.com/isd-sgcu/johnjud-backend/internal/utils" + "github.com/isd-sgcu/johnjud-backend/internal/validator" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" "github.com/rs/zerolog/log" diff --git a/database/postgresql.connection.go b/database/postgresql.connection.go index 9d1135f..5c87268 100644 --- a/database/postgresql.connection.go +++ b/database/postgresql.connection.go @@ -1,8 +1,8 @@ package database import ( - "github.com/isd-sgcu/johnjud-gateway/config" - "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-backend/config" + "github.com/isd-sgcu/johnjud-backend/internal/model" "gorm.io/driver/postgres" "gorm.io/gorm" gormLogger "gorm.io/gorm/logger" diff --git a/database/redis.connection.go b/database/redis.connection.go index e7158bb..4535434 100644 --- a/database/redis.connection.go +++ b/database/redis.connection.go @@ -3,7 +3,7 @@ package database import ( "fmt" - "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/isd-sgcu/johnjud-backend/config" "github.com/pkg/errors" "github.com/redis/go-redis/v9" ) diff --git a/go.mod b/go.mod index 8c6db2e..db46ac2 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/isd-sgcu/johnjud-gateway +module github.com/isd-sgcu/johnjud-backend go 1.21.3 diff --git a/internal/auth/auth.handler.go b/internal/auth/auth.handler.go index 6494673..ffb40ea 100644 --- a/internal/auth/auth.handler.go +++ b/internal/auth/auth.handler.go @@ -4,11 +4,11 @@ import ( "net/http" "strings" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/router" - "github.com/isd-sgcu/johnjud-gateway/internal/user" - "github.com/isd-sgcu/johnjud-gateway/internal/validator" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/router" + "github.com/isd-sgcu/johnjud-backend/internal/user" + "github.com/isd-sgcu/johnjud-backend/internal/validator" ) type handlerImpl struct { diff --git a/internal/auth/auth.repository.go b/internal/auth/auth.repository.go index d62c331..8c91524 100644 --- a/internal/auth/auth.repository.go +++ b/internal/auth/auth.repository.go @@ -1,7 +1,7 @@ package auth import ( - "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/model" "gorm.io/gorm" ) diff --git a/internal/auth/auth.service.go b/internal/auth/auth.service.go index 248d081..ad22e08 100644 --- a/internal/auth/auth.service.go +++ b/internal/auth/auth.service.go @@ -4,14 +4,14 @@ import ( "fmt" "net/http" - "github.com/isd-sgcu/johnjud-gateway/config" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/auth/email" - "github.com/isd-sgcu/johnjud-gateway/internal/auth/token" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/model" - "github.com/isd-sgcu/johnjud-gateway/internal/user" - "github.com/isd-sgcu/johnjud-gateway/internal/utils" + "github.com/isd-sgcu/johnjud-backend/config" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/auth/email" + "github.com/isd-sgcu/johnjud-backend/internal/auth/token" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/user" + "github.com/isd-sgcu/johnjud-backend/internal/utils" "github.com/rs/zerolog/log" "github.com/pkg/errors" diff --git a/internal/auth/email/email.service.go b/internal/auth/email/email.service.go index 26d5b36..49cd8bb 100644 --- a/internal/auth/email/email.service.go +++ b/internal/auth/email/email.service.go @@ -4,7 +4,7 @@ import ( "fmt" "net/http" - "github.com/isd-sgcu/johnjud-gateway/config" + "github.com/isd-sgcu/johnjud-backend/config" "github.com/pkg/errors" "github.com/sendgrid/sendgrid-go" "github.com/sendgrid/sendgrid-go/helpers/mail" diff --git a/internal/auth/jwt/jwt.service.go b/internal/auth/jwt/jwt.service.go index 7a630b3..7f59111 100644 --- a/internal/auth/jwt/jwt.service.go +++ b/internal/auth/jwt/jwt.service.go @@ -6,10 +6,10 @@ import ( _jwt "github.com/golang-jwt/jwt/v4" - "github.com/isd-sgcu/johnjud-gateway/config" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/auth/token/strategy" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-backend/config" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/auth/token/strategy" + "github.com/isd-sgcu/johnjud-backend/internal/dto" "github.com/pkg/errors" ) diff --git a/internal/auth/jwt/jwt.strategy.go b/internal/auth/jwt/jwt.strategy.go index 1638e9d..33518e1 100644 --- a/internal/auth/jwt/jwt.strategy.go +++ b/internal/auth/jwt/jwt.strategy.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/golang-jwt/jwt/v4" - "github.com/isd-sgcu/johnjud-gateway/internal/auth/token/strategy" + "github.com/isd-sgcu/johnjud-backend/internal/auth/token/strategy" "github.com/pkg/errors" ) diff --git a/internal/auth/jwt/test/jwt.service_test.go b/internal/auth/jwt/test/jwt.service_test.go index c234aa7..c3bdf3d 100644 --- a/internal/auth/jwt/test/jwt.service_test.go +++ b/internal/auth/jwt/test/jwt.service_test.go @@ -7,12 +7,12 @@ import ( "github.com/go-faker/faker/v4" "github.com/golang-jwt/jwt/v4" - "github.com/isd-sgcu/johnjud-gateway/config" - "github.com/isd-sgcu/johnjud-gateway/constant" - _jwt "github.com/isd-sgcu/johnjud-gateway/internal/auth/jwt" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/mocks/strategy" - "github.com/isd-sgcu/johnjud-gateway/mocks/utils" + "github.com/isd-sgcu/johnjud-backend/config" + "github.com/isd-sgcu/johnjud-backend/constant" + _jwt "github.com/isd-sgcu/johnjud-backend/internal/auth/jwt" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/mocks/strategy" + "github.com/isd-sgcu/johnjud-backend/mocks/utils" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/internal/auth/test/auth.handler_test.go b/internal/auth/test/auth.handler_test.go index 08dd64b..60551ab 100644 --- a/internal/auth/test/auth.handler_test.go +++ b/internal/auth/test/auth.handler_test.go @@ -7,13 +7,13 @@ import ( "github.com/go-faker/faker/v4" "github.com/golang/mock/gomock" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/auth" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" - authMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/auth" - userMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/user" - validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/auth" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + routerMock "github.com/isd-sgcu/johnjud-backend/mocks/router" + authMock "github.com/isd-sgcu/johnjud-backend/mocks/service/auth" + userMock "github.com/isd-sgcu/johnjud-backend/mocks/service/user" + validatorMock "github.com/isd-sgcu/johnjud-backend/mocks/validator" "github.com/stretchr/testify/suite" ) diff --git a/internal/auth/token/test/token.service_test.go b/internal/auth/token/test/token.service_test.go index 9da850f..8db166f 100644 --- a/internal/auth/token/test/token.service_test.go +++ b/internal/auth/token/test/token.service_test.go @@ -8,13 +8,13 @@ import ( _jwt "github.com/golang-jwt/jwt/v4" "github.com/golang/mock/gomock" "github.com/google/uuid" - "github.com/isd-sgcu/johnjud-gateway/config" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/auth/token" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - mock_cache "github.com/isd-sgcu/johnjud-gateway/mocks/repository/cache" - "github.com/isd-sgcu/johnjud-gateway/mocks/service/jwt" - "github.com/isd-sgcu/johnjud-gateway/mocks/utils" + "github.com/isd-sgcu/johnjud-backend/config" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/auth/token" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + mock_cache "github.com/isd-sgcu/johnjud-backend/mocks/repository/cache" + "github.com/isd-sgcu/johnjud-backend/mocks/service/jwt" + "github.com/isd-sgcu/johnjud-backend/mocks/utils" "github.com/pkg/errors" "github.com/redis/go-redis/v9" "github.com/stretchr/testify/assert" diff --git a/internal/auth/token/token.service.go b/internal/auth/token/token.service.go index 8c443a0..cdc326e 100644 --- a/internal/auth/token/token.service.go +++ b/internal/auth/token/token.service.go @@ -4,11 +4,11 @@ import ( "time" _jwt "github.com/golang-jwt/jwt/v4" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/auth/jwt" - "github.com/isd-sgcu/johnjud-gateway/internal/cache" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/utils" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/auth/jwt" + "github.com/isd-sgcu/johnjud-backend/internal/cache" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/utils" "github.com/pkg/errors" "github.com/redis/go-redis/v9" "github.com/rs/zerolog/log" diff --git a/internal/cache/test/cache.repository_test.go b/internal/cache/test/cache.repository_test.go index 90f181e..7992356 100644 --- a/internal/cache/test/cache.repository_test.go +++ b/internal/cache/test/cache.repository_test.go @@ -7,8 +7,8 @@ import ( "time" "github.com/go-faker/faker/v4" - "github.com/isd-sgcu/johnjud-gateway/internal/cache" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/cache" + "github.com/isd-sgcu/johnjud-backend/internal/dto" "github.com/redis/go-redis/v9" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" diff --git a/internal/dto/pet.dto.go b/internal/dto/pet.dto.go index 2ccd682..db53bcf 100644 --- a/internal/dto/pet.dto.go +++ b/internal/dto/pet.dto.go @@ -1,7 +1,7 @@ package dto import ( - "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-backend/constant" ) type PetResponse struct { diff --git a/internal/dto/token.dto.go b/internal/dto/token.dto.go index 3aef3e7..4b42631 100644 --- a/internal/dto/token.dto.go +++ b/internal/dto/token.dto.go @@ -2,7 +2,7 @@ package dto import ( "github.com/golang-jwt/jwt/v4" - "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-backend/constant" ) type UserCredential struct { diff --git a/internal/healthcheck/healthcheck.handler.go b/internal/healthcheck/healthcheck.handler.go index 3935ded..5366e07 100644 --- a/internal/healthcheck/healthcheck.handler.go +++ b/internal/healthcheck/healthcheck.handler.go @@ -3,7 +3,7 @@ package healthcheck import ( "net/http" - "github.com/isd-sgcu/johnjud-gateway/internal/router" + "github.com/isd-sgcu/johnjud-backend/internal/router" ) type Handler struct { diff --git a/internal/image/image.handler.go b/internal/image/image.handler.go index d040b6c..1e98268 100644 --- a/internal/image/image.handler.go +++ b/internal/image/image.handler.go @@ -3,10 +3,10 @@ package image import ( "net/http" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/router" - "github.com/isd-sgcu/johnjud-gateway/internal/validator" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/router" + "github.com/isd-sgcu/johnjud-backend/internal/validator" "github.com/rs/zerolog/log" ) diff --git a/internal/image/image.repository.go b/internal/image/image.repository.go index 95a6d3e..5a925fc 100644 --- a/internal/image/image.repository.go +++ b/internal/image/image.repository.go @@ -1,7 +1,7 @@ package image import ( - "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/model" "gorm.io/gorm" ) diff --git a/internal/image/image.service.go b/internal/image/image.service.go index d74f2ac..38a6c76 100644 --- a/internal/image/image.service.go +++ b/internal/image/image.service.go @@ -5,11 +5,11 @@ import ( "time" "github.com/google/uuid" - "github.com/isd-sgcu/johnjud-gateway/client/bucket" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/model" - "github.com/isd-sgcu/johnjud-gateway/internal/utils" + "github.com/isd-sgcu/johnjud-backend/client/bucket" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/utils" "github.com/rs/zerolog/log" "gorm.io/gorm" ) diff --git a/internal/image/image.utils.go b/internal/image/image.utils.go index 1b45ee8..702474c 100644 --- a/internal/image/image.utils.go +++ b/internal/image/image.utils.go @@ -1,7 +1,7 @@ package image import ( - "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/dto" imageProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" ) diff --git a/internal/middleware/auth/auth.middleware.go b/internal/middleware/auth/auth.middleware.go index 956b681..11e5f1e 100644 --- a/internal/middleware/auth/auth.middleware.go +++ b/internal/middleware/auth/auth.middleware.go @@ -3,12 +3,12 @@ package auth import ( "net/http" - "github.com/isd-sgcu/johnjud-gateway/config" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/auth" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/router" - "github.com/isd-sgcu/johnjud-gateway/internal/utils" + "github.com/isd-sgcu/johnjud-backend/config" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/auth" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/router" + "github.com/isd-sgcu/johnjud-backend/internal/utils" ) type Guard struct { diff --git a/internal/model/pet.model.go b/internal/model/pet.model.go index d4c9ea3..9cd2e80 100644 --- a/internal/model/pet.model.go +++ b/internal/model/pet.model.go @@ -1,7 +1,7 @@ package model import ( - "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-backend/constant" ) type Pet struct { diff --git a/internal/model/user.model.go b/internal/model/user.model.go index 8f2cefb..b5c4dde 100644 --- a/internal/model/user.model.go +++ b/internal/model/user.model.go @@ -1,6 +1,6 @@ package model -import "github.com/isd-sgcu/johnjud-gateway/constant" +import "github.com/isd-sgcu/johnjud-backend/constant" type User struct { Base diff --git a/internal/pet/old/pet.service.go b/internal/pet/old/pet.service.go index f0f4dd2..d7f4a38 100644 --- a/internal/pet/old/pet.service.go +++ b/internal/pet/old/pet.service.go @@ -5,9 +5,9 @@ package pet // "net/http" // "time" -// "github.com/isd-sgcu/johnjud-gateway/constant" -// "github.com/isd-sgcu/johnjud-gateway/internal/dto" -// "github.com/isd-sgcu/johnjud-gateway/internal/image" +// "github.com/isd-sgcu/johnjud-backend/constant" +// "github.com/isd-sgcu/johnjud-backend/internal/dto" +// "github.com/isd-sgcu/johnjud-backend/internal/image" // petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" // "github.com/rs/zerolog/log" diff --git a/internal/pet/old/pet.utils.go b/internal/pet/old/pet.utils.go index a2a7341..3ed72b7 100644 --- a/internal/pet/old/pet.utils.go +++ b/internal/pet/old/pet.utils.go @@ -4,8 +4,8 @@ package pet // "errors" // "strconv" -// "github.com/isd-sgcu/johnjud-gateway/constant" -// "github.com/isd-sgcu/johnjud-gateway/internal/dto" +// "github.com/isd-sgcu/johnjud-backend/constant" +// "github.com/isd-sgcu/johnjud-backend/internal/dto" // petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" // imgproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" // ) diff --git a/internal/pet/old/test/pet.service_test.go b/internal/pet/old/test/pet.service_test.go index 6668622..f10a0df 100644 --- a/internal/pet/old/test/pet.service_test.go +++ b/internal/pet/old/test/pet.service_test.go @@ -6,12 +6,12 @@ package test // "testing" // "github.com/go-faker/faker/v4" -// "github.com/isd-sgcu/johnjud-gateway/constant" -// "github.com/isd-sgcu/johnjud-gateway/internal/dto" -// imageSvc "github.com/isd-sgcu/johnjud-gateway/internal/image" -// "github.com/isd-sgcu/johnjud-gateway/internal/pet" -// imagemock "github.com/isd-sgcu/johnjud-gateway/mocks/client/image" -// petmock "github.com/isd-sgcu/johnjud-gateway/mocks/client/pet" +// "github.com/isd-sgcu/johnjud-backend/constant" +// "github.com/isd-sgcu/johnjud-backend/internal/dto" +// imageSvc "github.com/isd-sgcu/johnjud-backend/internal/image" +// "github.com/isd-sgcu/johnjud-backend/internal/pet" +// imagemock "github.com/isd-sgcu/johnjud-backend/mocks/client/image" +// petmock "github.com/isd-sgcu/johnjud-backend/mocks/client/pet" // petproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" // imgproto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" // "github.com/stretchr/testify/assert" diff --git a/internal/pet/pet.handler.go b/internal/pet/pet.handler.go index f91e1bd..3d4c2e0 100644 --- a/internal/pet/pet.handler.go +++ b/internal/pet/pet.handler.go @@ -4,11 +4,11 @@ import ( "net/http" "strings" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/image" - "github.com/isd-sgcu/johnjud-gateway/internal/router" - "github.com/isd-sgcu/johnjud-gateway/internal/validator" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/image" + "github.com/isd-sgcu/johnjud-backend/internal/router" + "github.com/isd-sgcu/johnjud-backend/internal/validator" ) type handlerImpl struct { diff --git a/internal/pet/pet.repository.go b/internal/pet/pet.repository.go index 60c28c3..64cde15 100644 --- a/internal/pet/pet.repository.go +++ b/internal/pet/pet.repository.go @@ -3,7 +3,7 @@ package pet import ( "errors" - "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/model" "gorm.io/gorm" ) diff --git a/internal/pet/pet.service.go b/internal/pet/pet.service.go index a991b3d..f344e59 100644 --- a/internal/pet/pet.service.go +++ b/internal/pet/pet.service.go @@ -4,9 +4,9 @@ import ( "errors" "fmt" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/image" - "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/image" + "github.com/isd-sgcu/johnjud-backend/internal/model" "github.com/rs/zerolog/log" "gorm.io/gorm" diff --git a/internal/pet/pet.utils.go b/internal/pet/pet.utils.go index 79c4022..d55c358 100644 --- a/internal/pet/pet.utils.go +++ b/internal/pet/pet.utils.go @@ -9,9 +9,9 @@ import ( "time" "github.com/google/uuid" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/model" "github.com/rs/zerolog/log" "gorm.io/gorm" ) diff --git a/internal/pet/test/pet.handler_test.go b/internal/pet/test/pet.handler_test.go index c4a371e..201b4a4 100644 --- a/internal/pet/test/pet.handler_test.go +++ b/internal/pet/test/pet.handler_test.go @@ -7,13 +7,13 @@ package test // "github.com/bxcodec/faker/v4" // "github.com/golang/mock/gomock" -// "github.com/isd-sgcu/johnjud-gateway/constant" -// "github.com/isd-sgcu/johnjud-gateway/internal/dto" -// "github.com/isd-sgcu/johnjud-gateway/internal/pet" -// routerMock "github.com/isd-sgcu/johnjud-gateway/mocks/router" -// imageMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/image" -// petMock "github.com/isd-sgcu/johnjud-gateway/mocks/service/pet" -// validatorMock "github.com/isd-sgcu/johnjud-gateway/mocks/validator" +// "github.com/isd-sgcu/johnjud-backend/constant" +// "github.com/isd-sgcu/johnjud-backend/internal/dto" +// "github.com/isd-sgcu/johnjud-backend/internal/pet" +// routerMock "github.com/isd-sgcu/johnjud-backend/mocks/router" +// imageMock "github.com/isd-sgcu/johnjud-backend/mocks/service/image" +// petMock "github.com/isd-sgcu/johnjud-backend/mocks/service/pet" +// validatorMock "github.com/isd-sgcu/johnjud-backend/mocks/validator" // petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" // imgProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" diff --git a/internal/pet/test/pet.service_test.go b/internal/pet/test/pet.service_test.go index 8f7f2b3..566996a 100644 --- a/internal/pet/test/pet.service_test.go +++ b/internal/pet/test/pet.service_test.go @@ -9,12 +9,12 @@ import ( "github.com/bxcodec/faker/v3" "github.com/google/uuid" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/model" - "github.com/isd-sgcu/johnjud-gateway/internal/pet" - mock "github.com/isd-sgcu/johnjud-gateway/mocks/repository/pet" - img_mock "github.com/isd-sgcu/johnjud-gateway/mocks/service/image" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/pet" + mock "github.com/isd-sgcu/johnjud-backend/mocks/repository/pet" + img_mock "github.com/isd-sgcu/johnjud-backend/mocks/service/image" "gorm.io/gorm" "github.com/stretchr/testify/assert" diff --git a/internal/router/context.go b/internal/router/context.go index 9b43440..c8778a2 100644 --- a/internal/router/context.go +++ b/internal/router/context.go @@ -9,8 +9,8 @@ import ( "github.com/gofiber/fiber/v2" "github.com/google/uuid" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/utils" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/utils" ) type IContext interface { diff --git a/internal/router/router.go b/internal/router/router.go index 3e5c876..33e73c2 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -5,8 +5,8 @@ import ( "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/logger" - "github.com/isd-sgcu/johnjud-gateway/config" - _ "github.com/isd-sgcu/johnjud-gateway/docs" + "github.com/isd-sgcu/johnjud-backend/config" + _ "github.com/isd-sgcu/johnjud-backend/docs" ) type FiberRouter struct { diff --git a/internal/user/test/user.service_test.go b/internal/user/test/user.service_test.go index 31854f4..e7daf9a 100644 --- a/internal/user/test/user.service_test.go +++ b/internal/user/test/user.service_test.go @@ -6,11 +6,11 @@ import ( "testing" "time" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/model" - "github.com/isd-sgcu/johnjud-gateway/internal/user" - mock "github.com/isd-sgcu/johnjud-gateway/mocks/repository/user" - "github.com/isd-sgcu/johnjud-gateway/mocks/utils" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/user" + mock "github.com/isd-sgcu/johnjud-backend/mocks/repository/user" + "github.com/isd-sgcu/johnjud-backend/mocks/utils" "github.com/go-faker/faker/v4" "github.com/google/uuid" diff --git a/internal/user/user.handler.go b/internal/user/user.handler.go index ef28aea..556d008 100644 --- a/internal/user/user.handler.go +++ b/internal/user/user.handler.go @@ -4,10 +4,10 @@ import ( "net/http" "strings" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/router" - "github.com/isd-sgcu/johnjud-gateway/internal/validator" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/router" + "github.com/isd-sgcu/johnjud-backend/internal/validator" ) type Handler struct { diff --git a/internal/user/user.repository.go b/internal/user/user.repository.go index 4d0acda..a02c403 100644 --- a/internal/user/user.repository.go +++ b/internal/user/user.repository.go @@ -1,7 +1,7 @@ package user import ( - "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/model" "gorm.io/gorm" ) diff --git a/internal/user/user.service.go b/internal/user/user.service.go index d8b5390..b4d49db 100644 --- a/internal/user/user.service.go +++ b/internal/user/user.service.go @@ -4,10 +4,10 @@ import ( "errors" "net/http" - "github.com/isd-sgcu/johnjud-gateway/constant" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" - "github.com/isd-sgcu/johnjud-gateway/internal/model" - "github.com/isd-sgcu/johnjud-gateway/internal/utils" + "github.com/isd-sgcu/johnjud-backend/constant" + "github.com/isd-sgcu/johnjud-backend/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/utils" "gorm.io/gorm" ) diff --git a/internal/validator/validator.go b/internal/validator/validator.go index 6699018..d646d1d 100644 --- a/internal/validator/validator.go +++ b/internal/validator/validator.go @@ -8,7 +8,7 @@ import ( ut "github.com/go-playground/universal-translator" "github.com/go-playground/validator/v10" en_translations "github.com/go-playground/validator/v10/translations/en" - "github.com/isd-sgcu/johnjud-gateway/internal/dto" + "github.com/isd-sgcu/johnjud-backend/internal/dto" "github.com/rs/zerolog/log" ) diff --git a/mocks/repository/auth/auth.mock.go b/mocks/repository/auth/auth.mock.go index ef55d16..32e1139 100644 --- a/mocks/repository/auth/auth.mock.go +++ b/mocks/repository/auth/auth.mock.go @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - model "github.com/isd-sgcu/johnjud-gateway/internal/model" + model "github.com/isd-sgcu/johnjud-backend/internal/model" ) // MockRepository is a mock of Repository interface. diff --git a/mocks/repository/image/image.mock.go b/mocks/repository/image/image.mock.go index 385b255..2a0d7c4 100644 --- a/mocks/repository/image/image.mock.go +++ b/mocks/repository/image/image.mock.go @@ -1,7 +1,7 @@ package image import ( - "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/model" "github.com/stretchr/testify/mock" ) diff --git a/mocks/repository/pet/pet.mock.go b/mocks/repository/pet/pet.mock.go index aa2eced..f1724d3 100644 --- a/mocks/repository/pet/pet.mock.go +++ b/mocks/repository/pet/pet.mock.go @@ -1,7 +1,7 @@ package pet import ( - "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/model" "github.com/stretchr/testify/mock" ) diff --git a/mocks/repository/user/user.mock.go b/mocks/repository/user/user.mock.go index ab6ee07..5c97870 100644 --- a/mocks/repository/user/user.mock.go +++ b/mocks/repository/user/user.mock.go @@ -1,7 +1,7 @@ package user import ( - "github.com/isd-sgcu/johnjud-gateway/internal/model" + "github.com/isd-sgcu/johnjud-backend/internal/model" "github.com/stretchr/testify/mock" ) diff --git a/mocks/router/context.mock.go b/mocks/router/context.mock.go index 97487a1..5c2232f 100644 --- a/mocks/router/context.mock.go +++ b/mocks/router/context.mock.go @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" + dto "github.com/isd-sgcu/johnjud-backend/internal/dto" ) // MockIContext is a mock of IContext interface. diff --git a/mocks/service/auth/auth.mock.go b/mocks/service/auth/auth.mock.go index b3a5637..92eaf0f 100644 --- a/mocks/service/auth/auth.mock.go +++ b/mocks/service/auth/auth.mock.go @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" + dto "github.com/isd-sgcu/johnjud-backend/internal/dto" ) // MockService is a mock of Service interface. diff --git a/mocks/service/image/image.mock.go b/mocks/service/image/image.mock.go index ad8df35..6ffcb82 100644 --- a/mocks/service/image/image.mock.go +++ b/mocks/service/image/image.mock.go @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" + dto "github.com/isd-sgcu/johnjud-backend/internal/dto" ) // MockService is a mock of Service interface. diff --git a/mocks/service/image/image.mock_old.go b/mocks/service/image/image.mock_old.go index 9816782..2fc4414 100644 --- a/mocks/service/image/image.mock_old.go +++ b/mocks/service/image/image.mock_old.go @@ -1,7 +1,7 @@ package mock_image import ( - dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" + dto "github.com/isd-sgcu/johnjud-backend/internal/dto" "github.com/stretchr/testify/mock" ) diff --git a/mocks/service/jwt/jwt.mock.go b/mocks/service/jwt/jwt.mock.go index 458da93..4b70386 100644 --- a/mocks/service/jwt/jwt.mock.go +++ b/mocks/service/jwt/jwt.mock.go @@ -2,8 +2,8 @@ package jwt import ( "github.com/golang-jwt/jwt/v4" - "github.com/isd-sgcu/johnjud-gateway/config" - "github.com/isd-sgcu/johnjud-gateway/constant" + "github.com/isd-sgcu/johnjud-backend/config" + "github.com/isd-sgcu/johnjud-backend/constant" "github.com/stretchr/testify/mock" ) diff --git a/mocks/service/like/like.mock.go b/mocks/service/like/like.mock.go index 8ea1d1e..b1574f1 100644 --- a/mocks/service/like/like.mock.go +++ b/mocks/service/like/like.mock.go @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" + dto "github.com/isd-sgcu/johnjud-backend/internal/dto" ) // MockService is a mock of Service interface. diff --git a/mocks/service/pet/pet.mock.go b/mocks/service/pet/pet.mock.go index 0156dba..ec8b116 100644 --- a/mocks/service/pet/pet.mock.go +++ b/mocks/service/pet/pet.mock.go @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" + dto "github.com/isd-sgcu/johnjud-backend/internal/dto" ) // MockService is a mock of Service interface. diff --git a/mocks/service/token/token.mock.go b/mocks/service/token/token.mock.go index ee299f7..a43fc79 100644 --- a/mocks/service/token/token.mock.go +++ b/mocks/service/token/token.mock.go @@ -8,8 +8,8 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - constant "github.com/isd-sgcu/johnjud-gateway/constant" - dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" + constant "github.com/isd-sgcu/johnjud-backend/constant" + dto "github.com/isd-sgcu/johnjud-backend/internal/dto" v1 "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" ) diff --git a/mocks/service/user/user.mock.go b/mocks/service/user/user.mock.go index 9a2cb22..a30a696 100644 --- a/mocks/service/user/user.mock.go +++ b/mocks/service/user/user.mock.go @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" + dto "github.com/isd-sgcu/johnjud-backend/internal/dto" ) // MockService is a mock of Service interface. diff --git a/mocks/validator/validator.mock.go b/mocks/validator/validator.mock.go index eb2eb4b..151b559 100644 --- a/mocks/validator/validator.mock.go +++ b/mocks/validator/validator.mock.go @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - dto "github.com/isd-sgcu/johnjud-gateway/internal/dto" + dto "github.com/isd-sgcu/johnjud-backend/internal/dto" ) // MockIDtoValidator is a mock of IDtoValidator interface. From 915699b357b629dc8ddd4998321546bd37474989 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 23 Aug 2024 15:14:05 +0700 Subject: [PATCH 100/104] trigger From 2af3b05c947bef320ca8783b98077bd6c05ce833 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 23 Aug 2024 15:14:15 +0700 Subject: [PATCH 101/104] trigger From b2c3144addd59d3062fa64cf077eb784e7a39c5f Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 23 Aug 2024 15:16:12 +0700 Subject: [PATCH 102/104] fix dockerfiel --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 965add8..007a8be 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ RUN go mod download COPY . . # Build the application -RUN go build -o server ./src/. +RUN go build -o server ./cmd/main.go # Create master image FROM alpine AS master From c33630bf776729a5f4fe30de5d7942cdb05ea558 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 23 Aug 2024 15:18:21 +0700 Subject: [PATCH 103/104] fix wf test --- .github/workflows/run-unit-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-unit-test.yaml b/.github/workflows/run-unit-test.yaml index d14323e..50aefe4 100644 --- a/.github/workflows/run-unit-test.yaml +++ b/.github/workflows/run-unit-test.yaml @@ -34,5 +34,5 @@ jobs: - name: Test run: | - go test -v -coverpkg ./src/app/... -coverprofile coverage.out -covermode count ./src/app/... + go test -v -coverpkg ./internal/... -coverprofile coverage.out -covermode count ./internal/... go tool cover -func="./coverage.out" From 5f316ff97a76deb7f947b52b6f19f0a982d5b0b9 Mon Sep 17 00:00:00 2001 From: Idhibhat Pankam Date: Fri, 23 Aug 2024 15:22:45 +0700 Subject: [PATCH 104/104] remove cache repo test --- internal/cache/test/cache.repository_test.go | 78 -------------------- 1 file changed, 78 deletions(-) delete mode 100644 internal/cache/test/cache.repository_test.go diff --git a/internal/cache/test/cache.repository_test.go b/internal/cache/test/cache.repository_test.go deleted file mode 100644 index 7992356..0000000 --- a/internal/cache/test/cache.repository_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package test - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/go-faker/faker/v4" - "github.com/isd-sgcu/johnjud-backend/internal/cache" - "github.com/isd-sgcu/johnjud-backend/internal/dto" - "github.com/redis/go-redis/v9" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -type CacheRepositoryTest struct { - suite.Suite - cacheDb *redis.Client - cacheRepo cache.Repository - key string - value *dto.AccessTokenCache -} - -func TestCacheRepository(t *testing.T) { - suite.Run(t, new(CacheRepositoryTest)) -} - -func (t *CacheRepositoryTest) SetupTest() { - addr := fmt.Sprintf("%s:%d", "localhost", 6379) - cacheDb := redis.NewClient(&redis.Options{ - Addr: addr, - Password: "", - DB: 0, - }) - cacheRepo := cache.NewRepository(cacheDb) - key := faker.UUIDDigit() - value := &dto.AccessTokenCache{ - Token: faker.Word(), - RefreshToken: faker.UUIDDigit(), - } - - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - err := cacheDb.FlushDB(ctx).Err() - assert.Nil(t.T(), err) - - err = cacheRepo.SetValue(key, value, 60) - assert.Nil(t.T(), err) - - t.cacheDb = cacheDb - t.cacheRepo = cacheRepo - t.key = key - t.value = value -} - -func (t *CacheRepositoryTest) TestSetValueSuccess() { - key := faker.UUIDDigit() - value := &dto.AccessTokenCache{ - Token: faker.Word(), - RefreshToken: faker.UUIDDigit(), - } - err := t.cacheRepo.SetValue(key, value, 60) - assert.Nil(t.T(), err) -} - -func (t *CacheRepositoryTest) TestGetValueSuccess() { - value := &dto.AccessTokenCache{} - err := t.cacheRepo.GetValue(t.key, value) - assert.Nil(t.T(), err) - assert.Equal(t.T(), t.value, value) -} - -func (t *CacheRepositoryTest) TestDeleteValueSuccess() { - err := t.cacheRepo.DeleteValue(t.key) - assert.Nil(t.T(), err) -}