diff --git a/go.mod b/go.mod index 665507e..92d5b76 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/go-playground/validator/v10 v10.16.0 github.com/gofiber/fiber/v2 v2.51.0 github.com/google/uuid v1.5.0 - github.com/isd-sgcu/johnjud-go-proto v0.0.8 + github.com/isd-sgcu/johnjud-go-proto v0.2.2 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.31.0 github.com/spf13/viper v1.18.2 @@ -68,7 +68,7 @@ require ( golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.16.1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index c210390..f31fc77 100644 --- a/go.sum +++ b/go.sum @@ -75,6 +75,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.0.8 h1:nIQBZgK2OFVrLjVtpeDgwows8poA7LhsIVE4hlbBC1o= github.com/isd-sgcu/johnjud-go-proto v0.0.8/go.mod h1:HP0w9gC30b5WNnqeFBM9JJZud+pvyikz0+pGFSI/Wjw= +github.com/isd-sgcu/johnjud-go-proto v0.2.2 h1:TOAmbwy/I+8/J5LPZH0ZN7lSLczBiZe1fs88gH8XrhY= +github.com/isd-sgcu/johnjud-go-proto v0.2.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= @@ -250,6 +252,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= diff --git a/src/app/dto/auth.dto.go b/src/app/dto/auth.dto.go index 1ca0eab..71252e2 100644 --- a/src/app/dto/auth.dto.go +++ b/src/app/dto/auth.dto.go @@ -30,3 +30,7 @@ type SignInRequest struct { Email string `json:"email" validate:"required,email"` Password string `json:"password" validate:"required,gte=6,lte=30"` } + +type SignOutResponse struct { + IsSuccess bool `json:"is_success"` +} diff --git a/src/app/handler/adopt/adopt.handler.go b/src/app/handler/adopt/adopt.handler.go deleted file mode 100644 index a082237..0000000 --- a/src/app/handler/adopt/adopt.handler.go +++ /dev/null @@ -1,35 +0,0 @@ -package auth - -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" - proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/adopt/v1" -) - -type Handler struct { - service Service - validate *validator.DtoValidator -} - -type Service interface { - FindAll() ([]*proto.Adopt, *dto.ResponseErr) - Create(*dto.AdoptDto) (*proto.Adopt, *dto.ResponseErr) - Delete(string) (bool, *dto.ResponseErr) -} - -func NewHandler(service Service, validate *validator.DtoValidator) *Handler { - return &Handler{service, validate} -} - -func (h *Handler) FindAll(c *router.FiberCtx) { - -} - -func (h *Handler) Create(c *router.FiberCtx) { - -} - -func (h *Handler) Delete(c *router.FiberCtx) { - -} diff --git a/src/app/handler/auth/auth.handler.go b/src/app/handler/auth/auth.handler.go index 92bfa5e..a9a2aaa 100644 --- a/src/app/handler/auth/auth.handler.go +++ b/src/app/handler/auth/auth.handler.go @@ -123,6 +123,24 @@ func (h *Handler) SignIn(c router.IContext) { c.JSON(http.StatusOK, response) } -func (h *Handler) Signout(c router.IContext) { +// SignOut is a function that remove token and auth session of user +// @Summary Sign out user +// @Description Return the bool value of success +// @Tags auth +// @Accept json +// @Produce json +// @Success 200 {object} dto.SignOutResponse +// @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) { + token := c.Token() + response, respErr := h.service.SignOut(token) + 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 31a081a..5a9b781 100644 --- a/src/app/handler/auth/auth.handler_test.go +++ b/src/app/handler/auth/auth.handler_test.go @@ -235,3 +235,49 @@ func (t *AuthHandlerTest) TestSignInServiceError() { handler.SignIn(context) } + +func (t *AuthHandlerTest) TestSignOutSuccess() { + token := faker.Word() + signOutResponse := &dto.SignOutResponse{ + IsSuccess: true, + } + + controller := gomock.NewController(t.T()) + + authSvc := mock_auth.NewMockService(controller) + userSvc := mock_user.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Token().Return(token) + authSvc.EXPECT().SignOut(token).Return(signOutResponse, nil) + context.EXPECT().JSON(http.StatusOK, signOutResponse) + + handler := NewHandler(authSvc, userSvc, validator) + + handler.SignOut(context) +} + +func (t *AuthHandlerTest) TestSignOutServiceError() { + token := faker.Word() + errResponse := &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + + controller := gomock.NewController(t.T()) + + authSvc := mock_auth.NewMockService(controller) + userSvc := mock_user.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + handler := NewHandler(authSvc, userSvc, validator) + + context.EXPECT().Token().Return(token) + authSvc.EXPECT().SignOut(token).Return(nil, errResponse) + context.EXPECT().JSON(http.StatusInternalServerError, errResponse) + + handler.SignOut(context) +} diff --git a/src/app/router/adopt.router.go b/src/app/router/adopt.router.go deleted file mode 100644 index 9619080..0000000 --- a/src/app/router/adopt.router.go +++ /dev/null @@ -1,24 +0,0 @@ -package router - -import "github.com/gofiber/fiber/v2" - -func (r *FiberRouter) GetAdopt(path string, h func(ctx *FiberCtx)) { - r.adopt.Get(path, func(c *fiber.Ctx) error { - h(NewFiberCtx(c)) - return nil - }) -} - -func (r *FiberRouter) PostAdopt(path string, h func(ctx *FiberCtx)) { - r.adopt.Post(path, func(c *fiber.Ctx) error { - h(NewFiberCtx(c)) - return nil - }) -} - -func (r *FiberRouter) DeleteAdopt(path string, h func(ctx *FiberCtx)) { - r.adopt.Delete(path, func(c *fiber.Ctx) error { - h(NewFiberCtx(c)) - return nil - }) -} diff --git a/src/app/router/router.go b/src/app/router/router.go index e41ef3d..ea19491 100644 --- a/src/app/router/router.go +++ b/src/app/router/router.go @@ -15,7 +15,6 @@ type FiberRouter struct { pet fiber.Router image fiber.Router like fiber.Router - adopt fiber.Router } type IGuard interface { @@ -53,9 +52,8 @@ func NewFiberRouter(authGuard IGuard, conf config.App) *FiberRouter { pet := GroupWithAuthMiddleware(r, "/pet", authGuard.Use) image := GroupWithAuthMiddleware(r, "/image", authGuard.Use) like := GroupWithAuthMiddleware(r, "/like", authGuard.Use) - adopt := GroupWithAuthMiddleware(r, "/adopt", authGuard.Use) - return &FiberRouter{r, auth, user, pet, image, adopt, like} + return &FiberRouter{r, auth, user, pet, image, like} } func GroupWithAuthMiddleware(r *fiber.App, path string, middleware func(ctx IContext) error) fiber.Router { diff --git a/src/app/service/adopt/adopt.service.go b/src/app/service/adopt/adopt.service.go deleted file mode 100644 index ff4609f..0000000 --- a/src/app/service/adopt/adopt.service.go +++ /dev/null @@ -1,28 +0,0 @@ -package adopt - -import ( - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/adopt/v1" -) - -type Service struct { - client proto.AdoptServiceClient -} - -func NewService(client proto.AdoptServiceClient) *Service { - return &Service{ - client: client, - } -} - -func (s *Service) FindAll() ([]*proto.Adopt, *dto.ResponseErr) { - return nil, nil -} - -func (s *Service) Create(in *dto.AdoptDto) (*proto.Adopt, *dto.ResponseErr) { - return nil, nil -} - -func (s *Service) Delete(id string) (bool, *dto.ResponseErr) { - return false, nil -} diff --git a/src/app/service/auth/auth.service.go b/src/app/service/auth/auth.service.go index e5ea5f0..c90aa09 100644 --- a/src/app/service/auth/auth.service.go +++ b/src/app/service/auth/auth.service.go @@ -5,6 +5,7 @@ import ( "github.com/isd-sgcu/johnjud-gateway/src/app/constant" "github.com/isd-sgcu/johnjud-gateway/src/app/dto" auth_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" + "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "net/http" @@ -25,36 +26,54 @@ func (s *Service) Signup(request *dto.SignupRequest) (*dto.SignupResponse, *dto. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - resp, err := s.client.Signup(ctx, &auth_proto.SignupRequest{ + resp, err := s.client.SignUp(ctx, &auth_proto.SignUpRequest{ FirstName: request.Firstname, LastName: request.Lastname, Email: request.Email, Password: request.Password, }) if err != nil { - st, _ := status.FromError(err) - 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, + st, ok := status.FromError(err) + log.Error(). + Str("service", "auth"). + Str("action", "SignUp"). + Str("email", request.Email). + Msg(st.Message()) + if ok { + 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.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } } + 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, @@ -63,38 +82,56 @@ func (s *Service) Signup(request *dto.SignupRequest) (*dto.SignupResponse, *dto. }, nil } -func (s *Service) SignIn(signIn *dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) { +func (s *Service) 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, &auth_proto.SignInRequest{ - Email: signIn.Email, - Password: signIn.Password, + Email: request.Email, + Password: request.Password, }) if err != 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.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, + st, ok := status.FromError(err) + log.Error(). + Str("service", "auth"). + Str("action", "SignIn"). + Str("email", request.Email). + Msg(st.Message()) + if ok { + 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, + } + default: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } } } + + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } } + 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, @@ -102,8 +139,52 @@ func (s *Service) SignIn(signIn *dto.SignInRequest) (*dto.Credential, *dto.Respo }, nil } -func (s *Service) SignOut(token string) (bool, *dto.ResponseErr) { - return false, nil +func (s *Service) SignOut(token string) (*dto.SignOutResponse, *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + response, err := s.client.SignOut(ctx, &auth_proto.SignOutRequest{ + Token: token, + }) + if err != nil { + st, ok := status.FromError(err) + log.Error(). + Str("service", "auth"). + Str("action", "SignOut"). + Str("token", token). + Msg(st.Message()) + if ok { + 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, + } + } + } + + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + + log.Info(). + Str("service", "auth"). + Str("action", "SignOut"). + Str("token", token). + Msg("sign out successfully") + return &dto.SignOutResponse{ + IsSuccess: response.IsSuccess, + }, nil } func (s *Service) Validate(token string) (*dto.TokenPayloadAuth, *dto.ResponseErr) { diff --git a/src/app/service/auth/auth.service_test.go b/src/app/service/auth/auth.service_test.go index eb964ad..91e82ac 100644 --- a/src/app/service/auth/auth.service_test.go +++ b/src/app/service/auth/auth.service_test.go @@ -1,6 +1,7 @@ package auth import ( + "errors" "github.com/go-faker/faker/v4" "github.com/isd-sgcu/johnjud-gateway/src/app/constant" "github.com/isd-sgcu/johnjud-gateway/src/app/dto" @@ -44,13 +45,13 @@ func (t *AuthServiceTest) SetupTest() { } func (t *AuthServiceTest) TestSignupSuccess() { - protoReq := &authProto.SignupRequest{ + protoReq := &authProto.SignUpRequest{ FirstName: t.signupRequestDto.Firstname, LastName: t.signupRequestDto.Lastname, Email: t.signupRequestDto.Email, Password: t.signupRequestDto.Password, } - protoResp := &authProto.SignupResponse{ + protoResp := &authProto.SignUpResponse{ Id: faker.UUIDDigit(), FirstName: t.signupRequestDto.Firstname, LastName: t.signupRequestDto.Lastname, @@ -66,7 +67,7 @@ func (t *AuthServiceTest) TestSignupSuccess() { client := auth.AuthClientMock{} - client.On("Signup", protoReq).Return(protoResp, nil) + client.On("SignUp", protoReq).Return(protoResp, nil) svc := NewService(&client) actual, err := svc.Signup(t.signupRequestDto) @@ -79,7 +80,7 @@ func (t *AuthServiceTest) TestSignupSuccess() { } func (t *AuthServiceTest) TestSignupConflict() { - protoReq := &authProto.SignupRequest{ + protoReq := &authProto.SignUpRequest{ FirstName: t.signupRequestDto.Firstname, LastName: t.signupRequestDto.Lastname, Email: t.signupRequestDto.Email, @@ -94,7 +95,7 @@ func (t *AuthServiceTest) TestSignupConflict() { } client := auth.AuthClientMock{} - client.On("Signup", protoReq).Return(nil, clientErr) + client.On("SignUp", protoReq).Return(nil, clientErr) svc := NewService(&client) actual, err := svc.Signup(t.signupRequestDto) @@ -104,7 +105,7 @@ func (t *AuthServiceTest) TestSignupConflict() { } func (t *AuthServiceTest) TestSignupInternalError() { - protoReq := &authProto.SignupRequest{ + protoReq := &authProto.SignUpRequest{ FirstName: t.signupRequestDto.Firstname, LastName: t.signupRequestDto.Lastname, Email: t.signupRequestDto.Email, @@ -119,7 +120,7 @@ func (t *AuthServiceTest) TestSignupInternalError() { } client := auth.AuthClientMock{} - client.On("Signup", protoReq).Return(nil, clientErr) + client.On("SignUp", protoReq).Return(nil, clientErr) svc := NewService(&client) actual, err := svc.Signup(t.signupRequestDto) @@ -129,7 +130,7 @@ func (t *AuthServiceTest) TestSignupInternalError() { } func (t *AuthServiceTest) TestSignupUnavailableService() { - protoReq := &authProto.SignupRequest{ + protoReq := &authProto.SignUpRequest{ FirstName: t.signupRequestDto.Firstname, LastName: t.signupRequestDto.Lastname, Email: t.signupRequestDto.Email, @@ -144,7 +145,32 @@ func (t *AuthServiceTest) TestSignupUnavailableService() { } client := auth.AuthClientMock{} - client.On("Signup", protoReq).Return(nil, clientErr) + client.On("SignUp", protoReq).Return(nil, clientErr) + + svc := 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 := auth.AuthClientMock{} + client.On("SignUp", protoReq).Return(nil, clientErr) svc := NewService(&client) actual, err := svc.Signup(t.signupRequestDto) @@ -254,6 +280,116 @@ func (t *AuthServiceTest) TestSignInUnavailableService() { 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 := auth.AuthClientMock{} + + client.On("SignIn", protoReq).Return(nil, protoErr) + + svc := 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 := auth.AuthClientMock{} + client.On("SignOut", protoReq).Return(protoResp, nil) + + svc := 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 := auth.AuthClientMock{} + client.On("SignOut", protoReq).Return(nil, protoErr) + + svc := 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 := auth.AuthClientMock{} + client.On("SignOut", protoReq).Return(nil, protoErr) + + svc := 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 := auth.AuthClientMock{} + client.On("SignOut", protoReq).Return(nil, protoErr) + + svc := NewService(&client) + actual, err := svc.SignOut(t.token) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + func (t *AuthServiceTest) TestValidateSuccess() {} func (t *AuthServiceTest) TestValidateUnauthorized() {} diff --git a/src/docs/docs.go b/src/docs/docs.go index 83c7f8d..844894b 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -76,6 +76,41 @@ const docTemplate = `{ } } }, + "/v1/auth/signout": { + "post": { + "description": "Return the bool value of success", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Sign out user", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.SignOutResponse" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, "/v1/auth/signup": { "post": { "description": "Return the data of user if successfully", @@ -257,6 +292,14 @@ const docTemplate = `{ } } }, + "dto.SignOutResponse": { + "type": "object", + "properties": { + "is_success": { + "type": "boolean" + } + } + }, "dto.SignupRequest": { "type": "object", "required": [ diff --git a/src/docs/swagger.json b/src/docs/swagger.json index 4fff186..df757f4 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -72,6 +72,41 @@ } } }, + "/v1/auth/signout": { + "post": { + "description": "Return the bool value of success", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Sign out user", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.SignOutResponse" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } + }, "/v1/auth/signup": { "post": { "description": "Return the data of user if successfully", @@ -253,6 +288,14 @@ } } }, + "dto.SignOutResponse": { + "type": "object", + "properties": { + "is_success": { + "type": "boolean" + } + } + }, "dto.SignupRequest": { "type": "object", "required": [ diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 41f5c09..e4b0423 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -84,6 +84,11 @@ definitions: - email - password type: object + dto.SignOutResponse: + properties: + is_success: + type: boolean + type: object dto.SignupRequest: properties: email: @@ -160,6 +165,29 @@ paths: summary: Sign in user tags: - auth + /v1/auth/signout: + post: + consumes: + - application/json + description: Return the bool value of success + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.SignOutResponse' + "500": + description: Internal service error + schema: + $ref: '#/definitions/dto.ResponseInternalErr' + "503": + description: Service is down + schema: + $ref: '#/definitions/dto.ResponseServiceDownErr' + summary: Sign out user + tags: + - auth /v1/auth/signup: post: consumes: diff --git a/src/main.go b/src/main.go index 50973fc..c0f0bc7 100644 --- a/src/main.go +++ b/src/main.go @@ -103,7 +103,7 @@ func main() { r.PostAuth("/signup", authHandler.Signup) r.PostAuth("/signin", authHandler.SignIn) - r.PostAuth("/signout", authHandler.Signout) + r.PostAuth("/signout", authHandler.SignOut) r.PostAuth("/me", authHandler.Validate) r.PostAuth("/refreshToken", authHandler.RefreshToken) diff --git a/src/mocks/client/auth/auth.mock.go b/src/mocks/client/auth/auth.mock.go index 21d848c..873ce2e 100644 --- a/src/mocks/client/auth/auth.mock.go +++ b/src/mocks/client/auth/auth.mock.go @@ -25,9 +25,9 @@ func (m *AuthClientMock) RefreshToken(_ context.Context, in *authProto.RefreshTo return resp, err } -func (m *AuthClientMock) Signup(_ context.Context, in *authProto.SignupRequest, _ ...grpc.CallOption) (*authProto.SignupResponse, error) { +func (m *AuthClientMock) SignUp(_ context.Context, in *authProto.SignUpRequest, _ ...grpc.CallOption) (*authProto.SignUpResponse, error) { args := m.Called(in) - resp, _ := args.Get(0).(*authProto.SignupResponse) + resp, _ := args.Get(0).(*authProto.SignUpResponse) err, _ := args.Get(1).(error) return resp, err } @@ -38,3 +38,10 @@ func (m *AuthClientMock) SignIn(_ context.Context, in *authProto.SignInRequest, err, _ := args.Get(1).(error) return resp, err } + +func (m *AuthClientMock) SignOut(_ context.Context, in *authProto.SignOutRequest, _ ...grpc.CallOption) (*authProto.SignOutResponse, error) { + args := m.Called(in) + resp, _ := args.Get(0).(*authProto.SignOutResponse) + err, _ := args.Get(1).(error) + return resp, err +} diff --git a/src/mocks/service/auth/auth.mock.go b/src/mocks/service/auth/auth.mock.go index 43dd28f..a1b9288 100644 --- a/src/mocks/service/auth/auth.mock.go +++ b/src/mocks/service/auth/auth.mock.go @@ -66,10 +66,10 @@ func (mr *MockServiceMockRecorder) SignIn(arg0 interface{}) *gomock.Call { } // SignOut mocks base method. -func (m *MockService) SignOut(arg0 string) (bool, *dto.ResponseErr) { +func (m *MockService) SignOut(arg0 string) (*dto.SignOutResponse, *dto.ResponseErr) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SignOut", arg0) - ret0, _ := ret[0].(bool) + ret0, _ := ret[0].(*dto.SignOutResponse) ret1, _ := ret[1].(*dto.ResponseErr) return ret0, ret1 } diff --git a/src/pkg/service/auth/auth.service.go b/src/pkg/service/auth/auth.service.go index 7c52aec..d3718b2 100644 --- a/src/pkg/service/auth/auth.service.go +++ b/src/pkg/service/auth/auth.service.go @@ -8,7 +8,7 @@ import ( type Service interface { Signup(*dto.SignupRequest) (*dto.SignupResponse, *dto.ResponseErr) SignIn(*dto.SignInRequest) (*dto.Credential, *dto.ResponseErr) - SignOut(string) (bool, *dto.ResponseErr) + SignOut(string) (*dto.SignOutResponse, *dto.ResponseErr) Validate(string) (*dto.TokenPayloadAuth, *dto.ResponseErr) RefreshToken(string) (*auth_proto.Credential, *dto.ResponseErr) }