diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 0000000..7748e23 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,13 @@ +## Change made + +- [ ]  New features +- [ ]  Bug fixes +- [ ]  Breaking changes +## Describe what you have done +- +### New Features +- +### Fix +- +### Others +- \ No newline at end of file diff --git a/config/auth/config.example.yaml b/config/auth/config.example.yaml index ad75341..50d989a 100644 --- a/config/auth/config.example.yaml +++ b/config/auth/config.example.yaml @@ -4,7 +4,7 @@ app: secret: database: - host: localhost + host: local-db port: 5432 name: johnjud_db username: root @@ -17,7 +17,7 @@ jwt: issuer: redis: - host: localhost + host: local-cache port: 6379 password: "" dbnum: 0 \ No newline at end of file diff --git a/config/config.example.yaml b/config/config.example.yaml index f5e400a..1a12b6b 100644 --- a/config/config.example.yaml +++ b/config/config.example.yaml @@ -3,6 +3,10 @@ app: debug: true service: - auth: auth:3002 - backend: backend:3003 - file: file:3004 \ No newline at end of file + 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/src/app/dto/common.dto.go b/src/app/dto/common.dto.go index ba64d2d..611c90e 100644 --- a/src/app/dto/common.dto.go +++ b/src/app/dto/common.dto.go @@ -67,9 +67,3 @@ type ResponseGatewayTimeoutErr struct { Message string `json:"message" example:"Connection timeout"` Data interface{} `json:"data"` } - -type ResponseSuccess struct { - StatusCode int `json:"status_code" example:"200"` - Message string `json:"message" example:"success"` - Data interface{} `json:"data"` -} diff --git a/src/app/dto/pet.dto.go b/src/app/dto/pet.dto.go index 0d7c5b1..1e99090 100644 --- a/src/app/dto/pet.dto.go +++ b/src/app/dto/pet.dto.go @@ -55,7 +55,7 @@ type ChangeViewPetRequest struct { } type ChangeViewPetResponse struct { - Success bool `json:"success" validate:"required"` + Success bool `json:"success"` } type UpdatePetRequest struct { @@ -81,5 +81,5 @@ type DeleteRequest struct { Id string `json:"id" validate:"required"` } type DeleteResponse struct { - Success bool `json:"success" validate:"required"` + Success bool `json:"success"` } diff --git a/src/app/dto/user.dto.go b/src/app/dto/user.dto.go index 30d1320..8fc8b3a 100644 --- a/src/app/dto/user.dto.go +++ b/src/app/dto/user.dto.go @@ -1,14 +1,19 @@ package dto -type UserDto struct { +type User struct { + Id string `json:"id"` + Email string `json:"email"` + Firstname string `json:"firstname"` + Lastname string `json:"lastname"` +} + +type UpdateUserRequest struct { Email string `json:"email" validate:"required,email"` Password string `json:"password" validate:"required,gte=6,lte=30"` Firstname string `json:"firstname" validate:"required"` Lastname string `json:"lastname" validate:"required"` } -type UpdateUserDto struct { - Password string `json:"password" validate:"required,gte=6,lte=30"` - Firstname string `json:"firstname" validate:"required"` - Lastname string `json:"lastname" validate:"required"` +type DeleteUserResponse struct { + Success bool `json:"success"` } diff --git a/src/app/handler/like/like.handler.go b/src/app/handler/like/like.handler.go index ab57fd8..accafc0 100644 --- a/src/app/handler/like/like.handler.go +++ b/src/app/handler/like/like.handler.go @@ -8,7 +8,6 @@ import ( "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" - likeConst "github.com/isd-sgcu/johnjud-gateway/src/constant/like" likeSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/like" ) @@ -38,11 +37,7 @@ func (h *Handler) FindByUserId(c router.IContext) { return } - c.JSON(http.StatusOK, dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: likeConst.FindLikeSuccessMessage, - Data: response, - }) + c.JSON(http.StatusOK, response) return } @@ -77,11 +72,7 @@ func (h *Handler) Create(c router.IContext) { return } - c.JSON(http.StatusCreated, dto.ResponseSuccess{ - StatusCode: http.StatusCreated, - Message: likeConst.CreateLikeSuccessMessage, - Data: response, - }) + c.JSON(http.StatusCreated, response) return } @@ -102,10 +93,6 @@ func (h *Handler) Delete(c router.IContext) { return } - c.JSON(http.StatusOK, dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: likeConst.DelteLikeSuccessMessage, - Data: res, - }) + c.JSON(http.StatusOK, res) return } diff --git a/src/app/handler/like/like.handler_test.go b/src/app/handler/like/like.handler_test.go index db72655..ed7debe 100644 --- a/src/app/handler/like/like.handler_test.go +++ b/src/app/handler/like/like.handler_test.go @@ -9,7 +9,6 @@ import ( 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" - likeConst "github.com/isd-sgcu/johnjud-gateway/src/constant/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" @@ -74,11 +73,7 @@ func (t *LikeHandlerTest) SetupTest() { func (t *LikeHandlerTest) TestFindLikesSuccess() { findLikeResponse := utils.ProtoToDtoList(t.Likes) - expectedResponse := dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: likeConst.FindLikeSuccessMessage, - Data: findLikeResponse, - } + expectedResponse := findLikeResponse controller := gomock.NewController(t.T()) @@ -147,11 +142,7 @@ func (t *LikeHandlerTest) TestFindLikeInternalError() { func (t *LikeHandlerTest) TestCreateSuccess() { createLikeResponse := utils.ProtoToDto(t.Like) - expectedResponse := dto.ResponseSuccess{ - StatusCode: http.StatusCreated, - Message: likeConst.CreateLikeSuccessMessage, - Data: createLikeResponse, - } + expectedResponse := createLikeResponse controller := gomock.NewController(t.T()) @@ -208,11 +199,7 @@ func (t *LikeHandlerTest) TestDeleteSuccess() { deleteResponse := &dto.DeleteLikeResponse{ Success: true, } - expectedResponse := dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: likeConst.DelteLikeSuccessMessage, - Data: deleteResponse, - } + expectedResponse := deleteResponse controller := gomock.NewController(t.T()) diff --git a/src/app/handler/pet/pet.handler.go b/src/app/handler/pet/pet.handler.go index 7dae48c..b249905 100644 --- a/src/app/handler/pet/pet.handler.go +++ b/src/app/handler/pet/pet.handler.go @@ -8,7 +8,6 @@ import ( "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" - petconst "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" imageSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/image" petSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/pet" ) @@ -40,11 +39,7 @@ func (h *Handler) FindAll(c router.IContext) { return } - c.JSON(http.StatusOK, dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petconst.FindAllPetSuccessMessage, - Data: response, - }) + c.JSON(http.StatusOK, response) return } @@ -77,11 +72,7 @@ func (h *Handler) FindOne(c router.IContext) { return } - c.JSON(http.StatusOK, dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petconst.FindOnePetSuccessMessage, - Data: response, - }) + c.JSON(http.StatusOK, response) return } @@ -128,11 +119,7 @@ func (h *Handler) Create(c router.IContext) { return } - c.JSON(http.StatusCreated, dto.ResponseSuccess{ - StatusCode: http.StatusCreated, - Message: petconst.CreatePetSuccessMessage, - Data: response, - }) + c.JSON(http.StatusCreated, response) return } @@ -191,11 +178,7 @@ func (h *Handler) Update(c router.IContext) { return } - c.JSON(http.StatusOK, dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petconst.UpdatePetSuccessMessage, - Data: pet, - }) + c.JSON(http.StatusOK, pet) return } @@ -254,11 +237,7 @@ func (h *Handler) ChangeView(c router.IContext) { return } - c.JSON(http.StatusOK, dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petconst.ChangeViewPetSuccessMessage, - Data: res, - }) + c.JSON(http.StatusOK, res) return } @@ -291,11 +270,7 @@ func (h *Handler) Delete(c router.IContext) { return } - c.JSON(http.StatusOK, dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petconst.DeletePetSuccessMessage, - Data: res, - }) + c.JSON(http.StatusOK, res) return } @@ -354,10 +329,6 @@ func (h *Handler) Adopt(c router.IContext) { return } - c.JSON(http.StatusOK, dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petconst.AdoptPetSuccessMessage, - Data: res, - }) + c.JSON(http.StatusOK, res) return } diff --git a/src/app/handler/pet/pet.handler_test.go b/src/app/handler/pet/pet.handler_test.go index 659e221..fc96046 100644 --- a/src/app/handler/pet/pet.handler_test.go +++ b/src/app/handler/pet/pet.handler_test.go @@ -16,7 +16,6 @@ import ( 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" petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" imgProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" @@ -131,11 +130,7 @@ func (t *PetHandlerTest) SetupTest() { func (t *PetHandlerTest) TestFindAllSuccess() { findAllResponse := utils.ProtoToDtoList(t.Pets, t.ImagesList) - expectedResponse := dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petConst.FindAllPetSuccessMessage, - Data: findAllResponse, - } + expectedResponse := findAllResponse controller := gomock.NewController(t.T()) @@ -153,11 +148,7 @@ func (t *PetHandlerTest) TestFindAllSuccess() { func (t *PetHandlerTest) TestFindOneSuccess() { findOneResponse := utils.ProtoToDto(t.Pet, t.Images) - expectedResponse := dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petConst.FindOnePetSuccessMessage, - Data: findOneResponse, - } + expectedResponse := findOneResponse controller := gomock.NewController(t.T()) @@ -212,11 +203,7 @@ func (t *PetHandlerTest) TestFindOneGrpcErr() { func (t *PetHandlerTest) TestCreateSuccess() { createResponse := utils.ProtoToDto(t.Pet, t.Images) - expectedResponse := dto.ResponseSuccess{ - StatusCode: http.StatusCreated, - Message: petConst.CreatePetSuccessMessage, - Data: createResponse, - } + expectedResponse := createResponse controller := gomock.NewController(t.T()) @@ -255,11 +242,7 @@ func (t *PetHandlerTest) TestCreateGrpcErr() { func (t *PetHandlerTest) TestUpdateSuccess() { updateResponse := utils.ProtoToDto(t.Pet, t.Images) - expectedResponse := dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petConst.UpdatePetSuccessMessage, - Data: updateResponse, - } + expectedResponse := updateResponse controller := gomock.NewController(t.T()) @@ -322,11 +305,7 @@ func (t *PetHandlerTest) TestDeleteSuccess() { deleteResponse := &dto.DeleteResponse{ Success: true, } - expectedResponse := dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petConst.DeletePetSuccessMessage, - Data: deleteResponse, - } + expectedResponse := deleteResponse controller := gomock.NewController(t.T()) @@ -386,11 +365,7 @@ func (t *PetHandlerTest) TestChangeViewSuccess() { changeViewResponse := &dto.ChangeViewPetResponse{ Success: true, } - expectedResponse := dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petConst.ChangeViewPetSuccessMessage, - Data: changeViewResponse, - } + expectedResponse := changeViewResponse controller := gomock.NewController(t.T()) @@ -457,11 +432,7 @@ func (t *PetHandlerTest) TestAdoptSuccess() { adoptByResponse := &dto.AdoptByResponse{ Success: true, } - expectedResponse := dto.ResponseSuccess{ - StatusCode: http.StatusOK, - Message: petConst.AdoptPetSuccessMessage, - Data: adoptByResponse, - } + expectedResponse := adoptByResponse controller := gomock.NewController(t.T()) diff --git a/src/app/handler/user/user.handler.go b/src/app/handler/user/user.handler.go index 9e25ed6..4277361 100644 --- a/src/app/handler/user/user.handler.go +++ b/src/app/handler/user/user.handler.go @@ -1,11 +1,14 @@ package user 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" - "net/http" ) type Handler struct { @@ -17,12 +20,24 @@ func NewHandler(service user.Service, validate validator.IDtoValidator) *Handler return &Handler{service, validate} } -func (h *Handler) FindOne(c *router.FiberCtx) { +// FindOne is a function that returns a user by id from database +// @Summary finds one user +// @Description Returns the data of user if successful +// @Param id path string true "user id" +// @Tags user +// @Accept json +// @Produce json +// @Success 200 {object} dto.User +// @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/users/{id} [get] +func (h *Handler) FindOne(c router.IContext) { id, err := c.ID() if err != nil { - c.JSON(http.StatusInternalServerError, dto.ResponseErr{ - StatusCode: http.StatusInternalServerError, - Message: "Invalid ID", + c.JSON(http.StatusBadRequest, &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: err.Error(), Data: nil, }) return @@ -34,22 +49,51 @@ func (h *Handler) FindOne(c *router.FiberCtx) { return } - c.JSON(http.StatusCreated, user) + c.JSON(http.StatusOK, user) return } -func (h *Handler) Update(c *router.FiberCtx) { +// Update is a function that updates user in database +// @Summary updates user +// @Description Returns the data of user if successfully +// @Param update body dto.UpdateUserRequest true "update user dto" +// @Tags auth +// @Accept json +// @Produce json +// @Success 201 {object} dto.User +// @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/users [put] +func (h *Handler) Update(c router.IContext) { usrId := c.UserID() - usrDto := dto.UpdateUserDto{} + request := &dto.UpdateUserRequest{} - err := c.Bind(&usrDto) + err := c.Bind(request) if err != nil { - c.JSON(http.StatusBadRequest, err) + c.JSON(http.StatusBadRequest, &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.BindingRequestErrorMessage + err.Error(), + Data: nil, + }) return } - user, errRes := h.service.Update(usrId, &usrDto) + 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 + } + + user, errRes := h.service.Update(usrId, request) if errRes != nil { c.JSON(errRes.StatusCode, errRes) return @@ -58,3 +102,37 @@ func (h *Handler) Update(c *router.FiberCtx) { c.JSON(http.StatusOK, user) return } + +// Delete is a function that deletes user in database +// @Summary deletes user +// @Description Returns successful status if user is successfully deleted +// @Param id path string true "user id" +// @Tags user +// @Accept json +// @Produce json +// @Success 201 {object} bool +// @Success 201 {object} dto.DeleteUserResponse +// @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/users/{id} [delete] +func (h *Handler) Delete(c router.IContext) { + id, err := c.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/src/app/handler/user/user.handler_test.go b/src/app/handler/user/user.handler_test.go new file mode 100644 index 0000000..8757d2f --- /dev/null +++ b/src/app/handler/user/user.handler_test.go @@ -0,0 +1,365 @@ +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/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" + + errConst "github.com/isd-sgcu/johnjud-gateway/src/app/constant" + 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: errConst.UserNotFoundMessage, + Data: nil, + } + + t.InvalidIDErr = &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: errConst.InvalidIDMessage, + Data: nil, + } + + t.BindErr = &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: errConst.InvalidIDMessage, + } + + t.DuplicateEmailErr = &dto.ResponseErr{ + StatusCode: http.StatusConflict, + Message: errConst.DuplicateEmailMessage, + Data: nil, + } + + t.InternalErr = &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: errConst.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 := 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 := 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 := 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 := 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 := 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 := 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 := 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 := 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 := 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 := 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 := 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 := 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 := 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 := 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 := NewHandler(userSvc, validator) + handler.Delete(context) +} diff --git a/src/app/middleware/auth/auth.middleware.go b/src/app/middleware/auth/auth.middleware.go index 70db9b5..3660164 100644 --- a/src/app/middleware/auth/auth.middleware.go +++ b/src/app/middleware/auth/auth.middleware.go @@ -1,26 +1,30 @@ 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" - "net/http" ) type Guard struct { service authPkg.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{}, conf config.App, versionList map[string]struct{}) Guard { +func NewAuthGuard(s authPkg.Service, e map[string]struct{}, a map[string]struct{}, conf config.App, versionList map[string]struct{}) Guard { return Guard{ service: s, excludes: e, + adminpath: a, conf: conf, versionList: versionList, } @@ -29,8 +33,10 @@ func NewAuthGuard(s authPkg.Service, e map[string]struct{}, conf config.App, ver func (m *Guard) Use(ctx router.IContext) error { method := ctx.Method() path := ctx.Path() + path = utils.TrimInList(path, "/", m.versionList) - path = auth.FormatPath(method, path) + ids := auth.FindIDFromPath(path) + path = auth.FormatPath(method, path, ids) if utils.IsExisted(m.excludes, path) { return ctx.Next() } @@ -53,5 +59,14 @@ 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) { + ctx.JSON(http.StatusUnauthorized, dto.ResponseErr{ + StatusCode: http.StatusUnauthorized, + Message: "Limited access", + Data: nil, + }) + return nil + } + return ctx.Next() } diff --git a/src/app/router/context.go b/src/app/router/context.go index 4a1b00f..4d55e9d 100644 --- a/src/app/router/context.go +++ b/src/app/router/context.go @@ -9,6 +9,7 @@ import ( type IContext interface { UserID() string + Role() string Bind(interface{}) error JSON(int, interface{}) ID() (string, error) @@ -32,6 +33,10 @@ func (c *FiberCtx) UserID() string { return c.Ctx.Locals("UserId").(string) } +func (c *FiberCtx) Role() string { + return c.Ctx.Locals("Role").(string) +} + func (c *FiberCtx) Bind(v interface{}) error { return c.Ctx.BodyParser(v) } diff --git a/src/app/router/user.router.go b/src/app/router/user.router.go index f506484..f2da894 100644 --- a/src/app/router/user.router.go +++ b/src/app/router/user.router.go @@ -2,16 +2,23 @@ package router import "github.com/gofiber/fiber/v2" -func (r *FiberRouter) GetUser(path string, h func(ctx *FiberCtx)) { +func (r *FiberRouter) GetUser(path string, h func(ctx IContext)) { r.user.Get(path, func(c *fiber.Ctx) error { h(NewFiberCtx(c)) return nil }) } -func (r *FiberRouter) PutUser(path string, h func(ctx *FiberCtx)) { +func (r *FiberRouter) PutUser(path string, h func(ctx IContext)) { r.user.Put(path, func(c *fiber.Ctx) error { h(NewFiberCtx(c)) return nil }) } + +func (r *FiberRouter) DeleteUser(path string, h func(ctx IContext)) { + r.user.Delete(path, func(c *fiber.Ctx) error { + h(NewFiberCtx(c)) + return nil + }) +} diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index 4362e19..47a7c98 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -196,29 +196,24 @@ func (s *Service) Delete(id string) (result *dto.DeleteResponse, err *dto.Respon Msg(st.Message()) switch st.Code() { case codes.NotFound: - return &dto.DeleteResponse{ - Success: false, - }, &dto.ResponseErr{ - StatusCode: http.StatusNotFound, - Message: constant.PetNotFoundMessage, - Data: nil, - } + return nil, &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.PetNotFoundMessage, + Data: nil, + } case codes.Unavailable: - return &dto.DeleteResponse{ - Success: false, - }, &dto.ResponseErr{ - StatusCode: http.StatusServiceUnavailable, - Message: constant.UnavailableServiceMessage, - Data: nil, - } - } - return &dto.DeleteResponse{ - Success: false, - }, &dto.ResponseErr{ + 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, diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 5705c12..b6a2973 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -440,7 +440,7 @@ func (t *PetServiceTest) TestDeleteNotFound() { svc := NewService(client) actual, err := svc.Delete(t.Pet.Id) - assert.Equal(t.T(), &dto.DeleteResponse{Success: false}, actual) + assert.Nil(t.T(), actual) assert.Equal(t.T(), expected, err) } @@ -461,7 +461,7 @@ func (t *PetServiceTest) TestDeleteServiceUnavailableError() { svc := NewService(client) actual, err := svc.Delete(t.Pet.Id) - assert.Equal(t.T(), &dto.DeleteResponse{Success: false}, actual) + assert.Nil(t.T(), actual) assert.Equal(t.T(), expected, err) } diff --git a/src/app/service/user/user.service.go b/src/app/service/user/user.service.go index 382bb3f..d4186f2 100644 --- a/src/app/service/user/user.service.go +++ b/src/app/service/user/user.service.go @@ -1,8 +1,16 @@ package user import ( + "context" + "net/http" + "time" + + "github.com/isd-sgcu/johnjud-gateway/src/app/constant" "github.com/isd-sgcu/johnjud-gateway/src/app/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" ) type Service struct { @@ -15,10 +23,131 @@ func NewService(client proto.UserServiceClient) *Service { } } -func (s *Service) FindOne(id string) (*proto.User, *dto.ResponseErr) { - return nil, nil +func (s *Service) FindOne(id string) (*dto.User, *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + response, err := s.client.FindOne(ctx, &proto.FindOneUserRequest{ + Id: id, + }) + 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: + 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.User{ + Id: response.User.Id, + Firstname: response.User.Firstname, + Lastname: response.User.Lastname, + Email: response.User.Email, + }, nil +} + +func (s *Service) Update(id string, in *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + response, err := s.client.Update(ctx, &proto.UpdateUserRequest{ + Id: id, + Firstname: in.Firstname, + Lastname: in.Lastname, + Password: in.Password, + Email: in.Email, + }) + 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: + 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, + } + } + } + + return &dto.User{ + Id: response.User.Id, + Firstname: response.User.Firstname, + Lastname: response.User.Lastname, + Email: response.User.Email, + }, nil } -func (s *Service) Update(id string, in *dto.UpdateUserDto) (*proto.User, *dto.ResponseErr) { - return nil, nil +func (s *Service) 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, + }) + 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 &dto.DeleteUserResponse{ + Success: response.Success, + }, nil } diff --git a/src/app/service/user/user.service_test.go b/src/app/service/user/user.service_test.go new file mode 100644 index 0000000..9630508 --- /dev/null +++ b/src/app/service/user/user.service_test.go @@ -0,0 +1,278 @@ +package user + +import ( + "net/http" + "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" + proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +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 +} + +func TestUserService(t *testing.T) { + suite.Run(t, new(UserServiceTest)) +} + +func (t *UserServiceTest) SetupTest() { + t.User = &proto.User{ + Id: faker.UUIDDigit(), + Email: faker.Email(), + Password: faker.Password(), + Firstname: faker.FirstName(), + Lastname: faker.LastName(), + 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.ConflictErr = &dto.ResponseErr{ + StatusCode: http.StatusConflict, + Message: constant.DuplicateEmailMessage, + Data: nil, + } + + t.InternalErr = &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } +} + +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, + }, + } + + expected := &dto.User{ + Id: t.User.Id, + Email: t.User.Email, + Firstname: t.User.Firstname, + Lastname: t.User.Lastname, + } + + client := user.UserClientMock{} + client.On("FindOne", t.FindOneUserReq).Return(protoResp, nil) + + svc := 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 + + client := user.UserClientMock{} + clienErr := status.Error(codes.NotFound, constant.UserNotFoundMessage) + client.On("FindOne", t.FindOneUserReq).Return(nil, clienErr) + + svc := NewService(&client) + actual, err := svc.FindOne(t.User.Id) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *UserServiceTest) TestFindOneUnavailableServiceError() { + expected := t.UnavailableServiceErr + + client := user.UserClientMock{} + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + client.On("FindOne", t.FindOneUserReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.FindOne(t.User.Id) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *UserServiceTest) TestFindOneInternalError() { + expected := t.InternalErr + + client := user.UserClientMock{} + clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) + client.On("FindOne", t.FindOneUserReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.FindOne(t.User.Id) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +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, + }, + } + + expected := &dto.User{ + Id: t.User.Id, + Email: t.User.Email, + Firstname: t.User.Firstname, + Lastname: t.User.Lastname, + } + + client := user.UserClientMock{} + client.On("Update", t.UpdateUserReq).Return(protoResp, nil) + + svc := NewService(&client) + actual, err := svc.Update(t.User.Id, t.UpdateUserDto) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *UserServiceTest) TestUpdateDuplicateEmail() { + expected := t.ConflictErr + + client := user.UserClientMock{} + clientErr := status.Error(codes.AlreadyExists, constant.DuplicateEmailMessage) + client.On("Update", t.UpdateUserReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.Update(t.User.Id, t.UpdateUserDto) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *UserServiceTest) TestUpdateUnavailableServiceError() { + expected := t.UnavailableServiceErr + + client := user.UserClientMock{} + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + client.On("Update", t.UpdateUserReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.Update(t.User.Id, t.UpdateUserDto) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *UserServiceTest) TestUpdateInternalError() { + expected := t.InternalErr + + client := user.UserClientMock{} + clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) + client.On("Update", t.UpdateUserReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.Update(t.User.Id, t.UpdateUserDto) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *UserServiceTest) TestDeleteSuccess() { + protoResp := &proto.DeleteUserResponse{ + Success: true, + } + + expected := &dto.DeleteUserResponse{ + Success: true, + } + + client := user.UserClientMock{} + client.On("Delete", t.DeleteUserReq).Return(protoResp, nil) + + svc := NewService(&client) + actual, err := svc.Delete(t.User.Id) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *UserServiceTest) TestDeleteUnavailableServiceError() { + expected := t.UnavailableServiceErr + + client := user.UserClientMock{} + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + client.On("Delete", t.DeleteUserReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.Delete(t.User.Id) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *UserServiceTest) TestDeleteInternalError() { + expected := t.InternalErr + + client := user.UserClientMock{} + clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) + client.On("Delete", t.DeleteUserReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.Delete(t.User.Id) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} diff --git a/src/app/utils/auth/auth.utils.go b/src/app/utils/auth/auth.utils.go index 18de087..5a05f51 100644 --- a/src/app/utils/auth/auth.utils.go +++ b/src/app/utils/auth/auth.utils.go @@ -2,8 +2,65 @@ package auth import ( "fmt" + "strconv" + "strings" + + "github.com/google/uuid" ) -func FormatPath(method string, path string) string { +func IsExisted(e map[string]struct{}, key string) bool { + _, ok := e[key] + if ok { + return true + } + return false +} + +func FormatPath(method string, path string, keys []string) string { + for _, key := range keys { + path = strings.Replace(path, key, ":id", 1) + } + return fmt.Sprintf("%v %v", method, path) } + +func FindIntFromStr(s string, sep string) []string { + spliteds := strings.Split(s, sep) + + var result []string + + for _, splited := range spliteds { + _, err := strconv.Atoi(splited) + if err == nil { + result = append(result, splited) + } + } + + return result +} + +func FindUUIDFromStr(s string, sep string) []string { + spliteds := strings.Split(s, sep) + + var result []string + + for _, splited := range spliteds { + _, err := uuid.Parse(splited) + if err == nil { + result = append(result, splited) + } + } + + return result +} + +func MergeStringSlice(s1 []string, s2 []string) []string { + return append(s1, s2...) +} + +func FindIDFromPath(path string) []string { + uuids := FindUUIDFromStr(path, "/") + ids := FindIntFromStr(path, "/") + + return MergeStringSlice(ids, uuids) +} diff --git a/src/constant/auth/auth.constant.go b/src/constant/auth/auth.constant.go index 2273fbe..e25d157 100644 --- a/src/constant/auth/auth.constant.go +++ b/src/constant/auth/auth.constant.go @@ -4,8 +4,18 @@ var ExcludePath = map[string]struct{}{ "POST /auth/signup": {}, "POST /auth/signin": {}, "POST /auth/verify": {}, - "GET /pet/": {}, - "GET /adopt/": {}, + "GET /user/:id": {}, + "GET /pets": {}, + "GET /adopt": {}, +} + +var AdminPath = map[string]struct{}{ + "DELETE /user/:id": {}, + "POST /pets": {}, + "PUT /pets/:id": {}, + "PUT /pets/:id/visible": {}, + "DELETE /pets/:id": {}, + //need to add image upload, delete, assignpet } var VersionList = map[string]struct{}{ diff --git a/src/constant/user/user.constant.go b/src/constant/user/user.constant.go new file mode 100644 index 0000000..cf1991e --- /dev/null +++ b/src/constant/user/user.constant.go @@ -0,0 +1,12 @@ +package user + +const FindOneUserSuccessMessage = "find one user success" +const UpdateUserSuccessMessage = "update user success" +const DeleteUserSuccessMessage = "delete user success" + +type Role string + +const ( + USER Role = "user" + ADMIN Role = "admin" +) diff --git a/src/main.go b/src/main.go index 2d354c7..f180270 100644 --- a/src/main.go +++ b/src/main.go @@ -103,7 +103,7 @@ func main() { authService := authSvc.NewService(authClient) authHandler := authHdr.NewHandler(authService, userService, v) - authGuard := guard.NewAuthGuard(authService, auth.ExcludePath, conf.App, auth.VersionList) + authGuard := guard.NewAuthGuard(authService, auth.ExcludePath, auth.AdminPath, conf.App, auth.VersionList) imageClient := imageProto.NewImageServiceClient(fileConn) imageService := imageSvc.NewService(imageClient) @@ -119,7 +119,8 @@ func main() { r := router.NewFiberRouter(&authGuard, conf.App) r.GetUser("/:id", userHandler.FindOne) - r.PutUser("/", userHandler.Update) + r.PutUser("", userHandler.Update) + r.DeleteUser("/:id", userHandler.Delete) r.PostAuth("/signup", authHandler.Signup) r.PostAuth("/signin", authHandler.SignIn) @@ -127,18 +128,18 @@ func main() { //r.PostAuth("/me", authHandler.Validate) r.PostAuth("/refreshToken", authHandler.RefreshToken) - r.GetHealthCheck("/", hc.HealthCheck) + r.GetHealthCheck("", hc.HealthCheck) - r.GetPet("/", petHandler.FindAll) + r.GetPet("", petHandler.FindAll) r.GetPet("/:id", petHandler.FindOne) - r.PostPet("/create", petHandler.Create) + r.PostPet("", petHandler.Create) r.PutPet("/:id", petHandler.Update) r.PutPet("/:id/adopt", petHandler.Adopt) r.PutPet("/:id/visible", petHandler.ChangeView) r.DeletePet("/:id", petHandler.Delete) r.GetLike("/:id", likeHandler.FindByUserId) - r.PostLike("/", likeHandler.Create) + r.PostLike("", likeHandler.Create) r.DeleteLike("/:id", likeHandler.Delete) v1 := router.NewAPIv1(r, conf.App) diff --git a/src/mocks/client/user/user.mock.go b/src/mocks/client/user/user.mock.go new file mode 100644 index 0000000..7e54f5f --- /dev/null +++ b/src/mocks/client/user/user.mock.go @@ -0,0 +1,41 @@ +package user + +import ( + "context" + + proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" + "github.com/stretchr/testify/mock" + "google.golang.org/grpc" +) + +type UserClientMock struct { + mock.Mock +} + +func (c *UserClientMock) FindOne(_ context.Context, in *proto.FindOneUserRequest, _ ...grpc.CallOption) (res *proto.FindOneUserResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*proto.FindOneUserResponse) + } + return res, args.Error(1) +} +func (c *UserClientMock) Update(_ context.Context, in *proto.UpdateUserRequest, _ ...grpc.CallOption) (res *proto.UpdateUserResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*proto.UpdateUserResponse) + } + + return res, args.Error(1) +} + +func (c *UserClientMock) Delete(_ context.Context, in *proto.DeleteUserRequest, _ ...grpc.CallOption) (res *proto.DeleteUserResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*proto.DeleteUserResponse) + } + + return res, args.Error(1) +} diff --git a/src/mocks/router/context.mock.go b/src/mocks/router/context.mock.go index f2238b6..df02a3c 100644 --- a/src/mocks/router/context.mock.go +++ b/src/mocks/router/context.mock.go @@ -131,6 +131,20 @@ func (mr *MockIContextMockRecorder) Path() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Path", reflect.TypeOf((*MockIContext)(nil).Path)) } +// Role mocks base method. +func (m *MockIContext) Role() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Role") + ret0, _ := ret[0].(string) + return ret0 +} + +// Role indicates an expected call of Role. +func (mr *MockIContextMockRecorder) Role() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Role", reflect.TypeOf((*MockIContext)(nil).Role)) +} + // StoreValue mocks base method. func (m *MockIContext) StoreValue(arg0, arg1 string) { m.ctrl.T.Helper() diff --git a/src/mocks/service/image/image.mock.go b/src/mocks/service/image/image.mock.go index 09a1ae0..c09925a 100644 --- a/src/mocks/service/image/image.mock.go +++ b/src/mocks/service/image/image.mock.go @@ -36,46 +36,46 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { } // Delete mocks base method. -func (m *MockService) Delete(id string) (bool, *dto.ResponseErr) { +func (m *MockService) Delete(arg0 string) (bool, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", id) + ret := m.ctrl.Call(m, "Delete", arg0) ret0, _ := ret[0].(bool) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Delete indicates an expected call of Delete. -func (mr *MockServiceMockRecorder) Delete(id interface{}) *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), id) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), arg0) } // FindByPetId mocks base method. -func (m *MockService) FindByPetId(id string) ([]*v1.Image, *dto.ResponseErr) { +func (m *MockService) FindByPetId(arg0 string) ([]*v1.Image, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindByPetId", id) + ret := m.ctrl.Call(m, "FindByPetId", arg0) ret0, _ := ret[0].([]*v1.Image) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // FindByPetId indicates an expected call of FindByPetId. -func (mr *MockServiceMockRecorder) FindByPetId(id interface{}) *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), id) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByPetId", reflect.TypeOf((*MockService)(nil).FindByPetId), arg0) } // Upload mocks base method. -func (m *MockService) Upload(in *dto.ImageDto) (*v1.Image, *dto.ResponseErr) { +func (m *MockService) Upload(arg0 *dto.ImageDto) (*v1.Image, *dto.ResponseErr) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Upload", in) + ret := m.ctrl.Call(m, "Upload", arg0) ret0, _ := ret[0].(*v1.Image) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } // Upload indicates an expected call of Upload. -func (mr *MockServiceMockRecorder) Upload(in interface{}) *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), in) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upload", reflect.TypeOf((*MockService)(nil).Upload), arg0) } diff --git a/src/mocks/service/like/like.mock.go b/src/mocks/service/like/like.mock.go index a40c24a..1e05b67 100644 --- a/src/mocks/service/like/like.mock.go +++ b/src/mocks/service/like/like.mock.go @@ -1,10 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. // Source: ./src/pkg/service/like/like.service.go -// -// Generated by this command: -// -// mockgen -source ./src/pkg/service/like/like.service.go -destination ./src/mocks/service/like/like.mock.go -// // Package mock_like is a generated GoMock package. package mock_like @@ -12,8 +7,8 @@ package mock_like 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) Create(arg0 *dto.CreateLikeRequest) (*dto.LikeResponse, *d } // 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) } @@ -64,7 +59,7 @@ func (m *MockService) Delete(arg0 string) (*dto.DeleteLikeResponse, *dto.Respons } // 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) FindByUserId(arg0 string) ([]*dto.LikeResponse, *dto.Respo } // FindByUserId indicates an expected call of FindByUserId. -func (mr *MockServiceMockRecorder) FindByUserId(arg0 any) *gomock.Call { +func (mr *MockServiceMockRecorder) FindByUserId(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByUserId", reflect.TypeOf((*MockService)(nil).FindByUserId), arg0) } diff --git a/src/mocks/service/pet/pet.mock.go b/src/mocks/service/pet/pet.mock.go index 84ba13d..d1689f4 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) } @@ -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) } diff --git a/src/mocks/service/user/user.mock.go b/src/mocks/service/user/user.mock.go index daa4fdb..ba40d67 100644 --- a/src/mocks/service/user/user.mock.go +++ b/src/mocks/service/user/user.mock.go @@ -9,7 +9,6 @@ import ( gomock "github.com/golang/mock/gomock" dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - v1 "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" ) // MockService is a mock of Service interface. @@ -35,11 +34,26 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { return m.recorder } +// Delete mocks base method. +func (m *MockService) Delete(arg0 string) (*dto.DeleteUserResponse, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0) + 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 { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), arg0) +} + // FindOne mocks base method. -func (m *MockService) FindOne(arg0 string) (*v1.User, *dto.ResponseErr) { +func (m *MockService) FindOne(arg0 string) (*dto.User, *dto.ResponseErr) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FindOne", arg0) - ret0, _ := ret[0].(*v1.User) + ret0, _ := ret[0].(*dto.User) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } @@ -51,10 +65,10 @@ func (mr *MockServiceMockRecorder) FindOne(arg0 interface{}) *gomock.Call { } // Update mocks base method. -func (m *MockService) Update(arg0 string, arg1 *dto.UpdateUserDto) (*v1.User, *dto.ResponseErr) { +func (m *MockService) Update(arg0 string, arg1 *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Update", arg0, arg1) - ret0, _ := ret[0].(*v1.User) + ret0, _ := ret[0].(*dto.User) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } diff --git a/src/mocks/user/user.mock.go b/src/mocks/user/user.mock.go deleted file mode 100644 index 909dab8..0000000 --- a/src/mocks/user/user.mock.go +++ /dev/null @@ -1,76 +0,0 @@ -package user - -import ( - "context" - - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - user_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" - "github.com/stretchr/testify/mock" - "google.golang.org/grpc" -) - -type ServiceMock struct { - mock.Mock -} - -func (s *ServiceMock) FindOne(id string) (result *user_proto.User, err *dto.ResponseErr) { - args := s.Called(id) - - if args.Get(0) != nil { - result = args.Get(0).(*user_proto.User) - } - - if args.Get(1) != nil { - err = args.Get(1).(*dto.ResponseErr) - } - - return -} - -func (s *ServiceMock) Update(id string, in *dto.UpdateUserDto) (result *user_proto.User, err *dto.ResponseErr) { - args := s.Called(id, in) - - if args.Get(0) != nil { - result = args.Get(0).(*user_proto.User) - } - - if args.Get(1) != nil { - err = args.Get(1).(*dto.ResponseErr) - } - - return -} - -type ClientMock struct { - mock.Mock -} - -func (c *ClientMock) FindOne(_ context.Context, in *user_proto.FindOneUserRequest, _ ...grpc.CallOption) (res *user_proto.FindOneUserResponse, err error) { - args := c.Called(in) - - if args.Get(0) != nil { - res = args.Get(0).(*user_proto.FindOneUserResponse) - } - - return res, args.Error(1) -} - -func (c *ClientMock) Update(_ context.Context, in *user_proto.UpdateUserRequest, _ ...grpc.CallOption) (res *user_proto.UpdateUserResponse, err error) { - args := c.Called(in) - - if args.Get(0) != nil { - res = args.Get(0).(*user_proto.UpdateUserResponse) - } - - return res, args.Error(1) -} - -func (c *ClientMock) Delete(_ context.Context, in *user_proto.DeleteUserRequest, _ ...grpc.CallOption) (res *user_proto.DeleteUserResponse, err error) { - args := c.Called(in) - - if args.Get(0) != nil { - res = args.Get(0).(*user_proto.DeleteUserResponse) - } - - return res, args.Error(1) -} diff --git a/src/pkg/service/user/user.service.go b/src/pkg/service/user/user.service.go index 1002d1d..731063b 100644 --- a/src/pkg/service/user/user.service.go +++ b/src/pkg/service/user/user.service.go @@ -2,10 +2,10 @@ package user import ( "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - user_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" ) type Service interface { - FindOne(string) (*user_proto.User, *dto.ResponseErr) - Update(string, *dto.UpdateUserDto) (*user_proto.User, *dto.ResponseErr) + FindOne(string) (*dto.User, *dto.ResponseErr) + Update(string, *dto.UpdateUserRequest) (*dto.User, *dto.ResponseErr) + Delete(string) (*dto.DeleteUserResponse, *dto.ResponseErr) }