From bdeee57cc2991cafda29bddf89febaf2190076d1 Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Sun, 14 Jan 2024 15:42:46 +0700 Subject: [PATCH 1/3] feat: implement reset password rpc --- internal/constant/error.constant.go | 1 + internal/service/auth/auth.service.go | 36 ++- internal/service/auth/auth.service_test.go | 308 +++++++++++++++++++++ 3 files changed, 344 insertions(+), 1 deletion(-) diff --git a/internal/constant/error.constant.go b/internal/constant/error.constant.go index 61efcea..548055c 100644 --- a/internal/constant/error.constant.go +++ b/internal/constant/error.constant.go @@ -2,6 +2,7 @@ package constant const InvalidTokenErrorMessage = "Invalid token" const IncorrectEmailPasswordErrorMessage = "Incorrect email or password" +const IncorrectPasswordErrorMessage = "New password should not be the same as the previous one" const DuplicateEmailErrorMessage = "Duplicate email" const InternalServerErrorMessage = "Internal server error" diff --git a/internal/service/auth/auth.service.go b/internal/service/auth/auth.service.go index bd4d8ce..0a9344e 100644 --- a/internal/service/auth/auth.service.go +++ b/internal/service/auth/auth.service.go @@ -195,5 +195,39 @@ func (s *serviceImpl) ForgotPassword(_ context.Context, request *authProto.Forgo } func (s *serviceImpl) ResetPassword(_ context.Context, request *authProto.ResetPasswordRequest) (*authProto.ResetPasswordResponse, error) { - return nil, nil + resetTokenCache, err := s.tokenService.FindResetPasswordToken(request.Token) + if err != nil { + return nil, status.Error(codes.Internal, constant.InternalServerErrorMessage) + } + + userDb := &model.User{} + if err := s.userRepo.FindById(resetTokenCache.UserID, userDb); err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, status.Error(codes.NotFound, constant.UserNotFoundErrorMessage) + } + return nil, status.Error(codes.Internal, constant.InternalServerErrorMessage) + } + + err = s.bcryptUtil.CompareHashedPassword(userDb.Password, request.Password) + if err != nil { + return nil, status.Error(codes.InvalidArgument, constant.IncorrectPasswordErrorMessage) + } + + hashPassword, err := s.bcryptUtil.GenerateHashedPassword(request.Password) + if err != nil { + return nil, status.Error(codes.Internal, constant.InternalServerErrorMessage) + } + + userDb.Password = hashPassword + if err := s.userRepo.Update(resetTokenCache.UserID, userDb); err != nil { + return nil, status.Error(codes.Internal, constant.InternalServerErrorMessage) + } + + if err := s.tokenService.RemoveResetPasswordToken(request.Token); err != nil { + return nil, status.Error(codes.Internal, constant.InternalServerErrorMessage) + } + + return &authProto.ResetPasswordResponse{ + IsSuccess: true, + }, nil } diff --git a/internal/service/auth/auth.service_test.go b/internal/service/auth/auth.service_test.go index 6a06313..06e0d35 100644 --- a/internal/service/auth/auth.service_test.go +++ b/internal/service/auth/auth.service_test.go @@ -36,6 +36,7 @@ type AuthServiceTest struct { refreshTokenRequest *authProto.RefreshTokenRequest validateRequest *authProto.ValidateRequest forgotPasswordRequest *authProto.ForgotPasswordRequest + resetPasswordRequest *authProto.ResetPasswordRequest authConfig cfgldr.Auth } @@ -67,6 +68,10 @@ func (t *AuthServiceTest) SetupTest() { forgotPasswordRequest := &authProto.ForgotPasswordRequest{ Email: faker.Email(), } + resetPasswordRequest := &authProto.ResetPasswordRequest{ + Token: faker.Word(), + Password: faker.Password(), + } authConfig := cfgldr.Auth{ ClientURL: "localhost", } @@ -78,6 +83,7 @@ func (t *AuthServiceTest) SetupTest() { t.validateRequest = validateRequest t.refreshTokenRequest = refreshTokenRequest t.forgotPasswordRequest = forgotPasswordRequest + t.resetPasswordRequest = resetPasswordRequest t.authConfig = authConfig } @@ -897,3 +903,305 @@ func (t *AuthServiceTest) TestForgotPasswordSendEmailFailed() { assert.Nil(t.T(), actual) assert.Equal(t.T(), expected, err) } + +func (t *AuthServiceTest) ResetPasswordSuccess() { + resetTokenCache := &tokenDto.ResetPasswordTokenCache{ + UserID: faker.UUIDDigit(), + } + userDb := &model.User{ + Base: model.Base{ + ID: uuid.New(), + }, + Email: faker.Email(), + Password: faker.Password(), + Firstname: faker.FirstName(), + Lastname: faker.LastName(), + Role: constant.USER, + } + hashedPassword := faker.Word() + updateUserDb := &model.User{ + Base: model.Base{ + ID: userDb.ID, + }, + Email: userDb.Email, + Password: hashedPassword, + Firstname: userDb.Firstname, + Lastname: userDb.Lastname, + Role: userDb.Role, + } + + expected := &authProto.ResetPasswordResponse{ + IsSuccess: true, + } + + controller := gomock.NewController(t.T()) + + authRepo := mock_auth.NewMockRepository(controller) + userRepo := user.UserRepositoryMock{} + tokenService := token.TokenServiceMock{} + emailService := email.EmailServiceMock{} + bcryptUtil := utils.BcryptUtilMock{} + + tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) + userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(userDb, nil) + bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(nil) + bcryptUtil.On("GenerateHashedPassword", t.resetPasswordRequest.Password).Return(hashedPassword, nil) + userRepo.On("Update", resetTokenCache.UserID, updateUserDb).Return(updateUserDb, nil) + tokenService.On("RemoveResetPasswordToken", t.resetPasswordRequest.Token).Return(nil) + + authSvc := NewService(authRepo, &userRepo, &tokenService, &emailService, &bcryptUtil, t.authConfig) + actual, err := authSvc.ResetPassword(t.ctx, t.resetPasswordRequest) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *AuthServiceTest) ResetPasswordFindTokenFailed() { + findTokenErr := errors.New("Internal error") + + expected := status.Error(codes.Internal, constant.InternalServerErrorMessage) + + controller := gomock.NewController(t.T()) + + authRepo := mock_auth.NewMockRepository(controller) + userRepo := user.UserRepositoryMock{} + tokenService := token.TokenServiceMock{} + emailService := email.EmailServiceMock{} + bcryptUtil := utils.BcryptUtilMock{} + + tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(nil, findTokenErr) + + authSvc := NewService(authRepo, &userRepo, &tokenService, &emailService, &bcryptUtil, t.authConfig) + actual, err := authSvc.ResetPassword(t.ctx, t.resetPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) ResetPasswordFindUserNotFound() { + resetTokenCache := &tokenDto.ResetPasswordTokenCache{ + UserID: faker.UUIDDigit(), + } + findUserErr := gorm.ErrRecordNotFound + + expected := status.Error(codes.NotFound, constant.UserNotFoundErrorMessage) + + controller := gomock.NewController(t.T()) + + authRepo := mock_auth.NewMockRepository(controller) + userRepo := user.UserRepositoryMock{} + tokenService := token.TokenServiceMock{} + emailService := email.EmailServiceMock{} + bcryptUtil := utils.BcryptUtilMock{} + + tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) + userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(nil, findUserErr) + + authSvc := NewService(authRepo, &userRepo, &tokenService, &emailService, &bcryptUtil, t.authConfig) + actual, err := authSvc.ResetPassword(t.ctx, t.resetPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) ResetPasswordFindUserInternalError() { + resetTokenCache := &tokenDto.ResetPasswordTokenCache{ + UserID: faker.UUIDDigit(), + } + findUserErr := errors.New("Internal error") + + expected := status.Error(codes.Internal, constant.InternalServerErrorMessage) + + controller := gomock.NewController(t.T()) + + authRepo := mock_auth.NewMockRepository(controller) + userRepo := user.UserRepositoryMock{} + tokenService := token.TokenServiceMock{} + emailService := email.EmailServiceMock{} + bcryptUtil := utils.BcryptUtilMock{} + + tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) + userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(nil, findUserErr) + + authSvc := NewService(authRepo, &userRepo, &tokenService, &emailService, &bcryptUtil, t.authConfig) + actual, err := authSvc.ResetPassword(t.ctx, t.resetPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) ResetPasswordSamePassword() { + resetTokenCache := &tokenDto.ResetPasswordTokenCache{ + UserID: faker.UUIDDigit(), + } + userDb := &model.User{ + Base: model.Base{ + ID: uuid.New(), + }, + Email: faker.Email(), + Password: faker.Password(), + Firstname: faker.FirstName(), + Lastname: faker.LastName(), + Role: constant.USER, + } + comparePasswordFailed := errors.New("Internal error") + + expected := status.Error(codes.InvalidArgument, constant.IncorrectPasswordErrorMessage) + + controller := gomock.NewController(t.T()) + + authRepo := mock_auth.NewMockRepository(controller) + userRepo := user.UserRepositoryMock{} + tokenService := token.TokenServiceMock{} + emailService := email.EmailServiceMock{} + bcryptUtil := utils.BcryptUtilMock{} + + tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) + userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(userDb, nil) + bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(comparePasswordFailed) + + authSvc := NewService(authRepo, &userRepo, &tokenService, &emailService, &bcryptUtil, t.authConfig) + actual, err := authSvc.ResetPassword(t.ctx, t.resetPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) ResetPasswordGenerateHashedPasswordFailed() { + resetTokenCache := &tokenDto.ResetPasswordTokenCache{ + UserID: faker.UUIDDigit(), + } + userDb := &model.User{ + Base: model.Base{ + ID: uuid.New(), + }, + Email: faker.Email(), + Password: faker.Password(), + Firstname: faker.FirstName(), + Lastname: faker.LastName(), + Role: constant.USER, + } + generatePasswordErr := errors.New("Internal error") + + expected := status.Error(codes.Internal, constant.InternalServerErrorMessage) + + controller := gomock.NewController(t.T()) + + authRepo := mock_auth.NewMockRepository(controller) + userRepo := user.UserRepositoryMock{} + tokenService := token.TokenServiceMock{} + emailService := email.EmailServiceMock{} + bcryptUtil := utils.BcryptUtilMock{} + + tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) + userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(userDb, nil) + bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(nil) + bcryptUtil.On("GenerateHashedPassword", t.resetPasswordRequest.Password).Return("", generatePasswordErr) + + authSvc := NewService(authRepo, &userRepo, &tokenService, &emailService, &bcryptUtil, t.authConfig) + actual, err := authSvc.ResetPassword(t.ctx, t.resetPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) ResetPasswordUpdateUserFailed() { + resetTokenCache := &tokenDto.ResetPasswordTokenCache{ + UserID: faker.UUIDDigit(), + } + userDb := &model.User{ + Base: model.Base{ + ID: uuid.New(), + }, + Email: faker.Email(), + Password: faker.Password(), + Firstname: faker.FirstName(), + Lastname: faker.LastName(), + Role: constant.USER, + } + hashedPassword := faker.Word() + updateUserDb := &model.User{ + Base: model.Base{ + ID: userDb.ID, + }, + Email: userDb.Email, + Password: hashedPassword, + Firstname: userDb.Firstname, + Lastname: userDb.Lastname, + Role: userDb.Role, + } + updateUserErr := errors.New("Internal error") + + expected := status.Error(codes.Internal, constant.InternalServerErrorMessage) + + controller := gomock.NewController(t.T()) + + authRepo := mock_auth.NewMockRepository(controller) + userRepo := user.UserRepositoryMock{} + tokenService := token.TokenServiceMock{} + emailService := email.EmailServiceMock{} + bcryptUtil := utils.BcryptUtilMock{} + + tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) + userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(userDb, nil) + bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(nil) + bcryptUtil.On("GenerateHashedPassword", t.resetPasswordRequest.Password).Return(hashedPassword, nil) + userRepo.On("Update", resetTokenCache.UserID, updateUserDb).Return(nil, updateUserErr) + + authSvc := NewService(authRepo, &userRepo, &tokenService, &emailService, &bcryptUtil, t.authConfig) + actual, err := authSvc.ResetPassword(t.ctx, t.resetPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *AuthServiceTest) ResetPasswordRemoveTokenFailed() { + resetTokenCache := &tokenDto.ResetPasswordTokenCache{ + UserID: faker.UUIDDigit(), + } + userDb := &model.User{ + Base: model.Base{ + ID: uuid.New(), + }, + Email: faker.Email(), + Password: faker.Password(), + Firstname: faker.FirstName(), + Lastname: faker.LastName(), + Role: constant.USER, + } + hashedPassword := faker.Word() + updateUserDb := &model.User{ + Base: model.Base{ + ID: userDb.ID, + }, + Email: userDb.Email, + Password: hashedPassword, + Firstname: userDb.Firstname, + Lastname: userDb.Lastname, + Role: userDb.Role, + } + removeTokenErr := errors.New("Internal error") + + expected := status.Error(codes.Internal, constant.InternalServerErrorMessage) + + controller := gomock.NewController(t.T()) + + authRepo := mock_auth.NewMockRepository(controller) + userRepo := user.UserRepositoryMock{} + tokenService := token.TokenServiceMock{} + emailService := email.EmailServiceMock{} + bcryptUtil := utils.BcryptUtilMock{} + + tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) + userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(userDb, nil) + bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(nil) + bcryptUtil.On("GenerateHashedPassword", t.resetPasswordRequest.Password).Return(hashedPassword, nil) + userRepo.On("Update", resetTokenCache.UserID, updateUserDb).Return(updateUserDb, nil) + tokenService.On("RemoveResetPasswordToken", t.resetPasswordRequest.Token).Return(removeTokenErr) + + authSvc := NewService(authRepo, &userRepo, &tokenService, &emailService, &bcryptUtil, t.authConfig) + actual, err := authSvc.ResetPassword(t.ctx, t.resetPasswordRequest) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} From 3ede81f0bc60a4f48ee86681ca853eb32919267c Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Sun, 14 Jan 2024 16:07:00 +0700 Subject: [PATCH 2/3] fix: fix --- internal/service/auth/auth.service.go | 2 +- internal/service/auth/auth.service_test.go | 31 ++++++++++++---------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/internal/service/auth/auth.service.go b/internal/service/auth/auth.service.go index 0a9344e..fd4de82 100644 --- a/internal/service/auth/auth.service.go +++ b/internal/service/auth/auth.service.go @@ -209,7 +209,7 @@ func (s *serviceImpl) ResetPassword(_ context.Context, request *authProto.ResetP } err = s.bcryptUtil.CompareHashedPassword(userDb.Password, request.Password) - if err != nil { + if err == nil { return nil, status.Error(codes.InvalidArgument, constant.IncorrectPasswordErrorMessage) } diff --git a/internal/service/auth/auth.service_test.go b/internal/service/auth/auth.service_test.go index 06e0d35..317471b 100644 --- a/internal/service/auth/auth.service_test.go +++ b/internal/service/auth/auth.service_test.go @@ -904,7 +904,7 @@ func (t *AuthServiceTest) TestForgotPasswordSendEmailFailed() { assert.Equal(t.T(), expected, err) } -func (t *AuthServiceTest) ResetPasswordSuccess() { +func (t *AuthServiceTest) TestResetPasswordSuccess() { resetTokenCache := &tokenDto.ResetPasswordTokenCache{ UserID: faker.UUIDDigit(), } @@ -918,6 +918,7 @@ func (t *AuthServiceTest) ResetPasswordSuccess() { Lastname: faker.LastName(), Role: constant.USER, } + comparePasswordErr := errors.New("Internal error") hashedPassword := faker.Word() updateUserDb := &model.User{ Base: model.Base{ @@ -944,7 +945,7 @@ func (t *AuthServiceTest) ResetPasswordSuccess() { tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(userDb, nil) - bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(nil) + bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(comparePasswordErr) bcryptUtil.On("GenerateHashedPassword", t.resetPasswordRequest.Password).Return(hashedPassword, nil) userRepo.On("Update", resetTokenCache.UserID, updateUserDb).Return(updateUserDb, nil) tokenService.On("RemoveResetPasswordToken", t.resetPasswordRequest.Token).Return(nil) @@ -956,7 +957,7 @@ func (t *AuthServiceTest) ResetPasswordSuccess() { assert.Equal(t.T(), expected, actual) } -func (t *AuthServiceTest) ResetPasswordFindTokenFailed() { +func (t *AuthServiceTest) TestResetPasswordFindTokenFailed() { findTokenErr := errors.New("Internal error") expected := status.Error(codes.Internal, constant.InternalServerErrorMessage) @@ -978,7 +979,7 @@ func (t *AuthServiceTest) ResetPasswordFindTokenFailed() { assert.Equal(t.T(), expected, err) } -func (t *AuthServiceTest) ResetPasswordFindUserNotFound() { +func (t *AuthServiceTest) TestResetPasswordFindUserNotFound() { resetTokenCache := &tokenDto.ResetPasswordTokenCache{ UserID: faker.UUIDDigit(), } @@ -1004,7 +1005,7 @@ func (t *AuthServiceTest) ResetPasswordFindUserNotFound() { assert.Equal(t.T(), expected, err) } -func (t *AuthServiceTest) ResetPasswordFindUserInternalError() { +func (t *AuthServiceTest) TestResetPasswordFindUserInternalError() { resetTokenCache := &tokenDto.ResetPasswordTokenCache{ UserID: faker.UUIDDigit(), } @@ -1030,7 +1031,7 @@ func (t *AuthServiceTest) ResetPasswordFindUserInternalError() { assert.Equal(t.T(), expected, err) } -func (t *AuthServiceTest) ResetPasswordSamePassword() { +func (t *AuthServiceTest) TestResetPasswordSamePassword() { resetTokenCache := &tokenDto.ResetPasswordTokenCache{ UserID: faker.UUIDDigit(), } @@ -1044,7 +1045,6 @@ func (t *AuthServiceTest) ResetPasswordSamePassword() { Lastname: faker.LastName(), Role: constant.USER, } - comparePasswordFailed := errors.New("Internal error") expected := status.Error(codes.InvalidArgument, constant.IncorrectPasswordErrorMessage) @@ -1058,7 +1058,7 @@ func (t *AuthServiceTest) ResetPasswordSamePassword() { tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(userDb, nil) - bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(comparePasswordFailed) + bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(nil) authSvc := NewService(authRepo, &userRepo, &tokenService, &emailService, &bcryptUtil, t.authConfig) actual, err := authSvc.ResetPassword(t.ctx, t.resetPasswordRequest) @@ -1067,10 +1067,11 @@ func (t *AuthServiceTest) ResetPasswordSamePassword() { assert.Equal(t.T(), expected, err) } -func (t *AuthServiceTest) ResetPasswordGenerateHashedPasswordFailed() { +func (t *AuthServiceTest) TestResetPasswordGenerateHashedPasswordFailed() { resetTokenCache := &tokenDto.ResetPasswordTokenCache{ UserID: faker.UUIDDigit(), } + comparePasswordErr := errors.New("Internal error") userDb := &model.User{ Base: model.Base{ ID: uuid.New(), @@ -1095,7 +1096,7 @@ func (t *AuthServiceTest) ResetPasswordGenerateHashedPasswordFailed() { tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(userDb, nil) - bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(nil) + bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(comparePasswordErr) bcryptUtil.On("GenerateHashedPassword", t.resetPasswordRequest.Password).Return("", generatePasswordErr) authSvc := NewService(authRepo, &userRepo, &tokenService, &emailService, &bcryptUtil, t.authConfig) @@ -1105,7 +1106,7 @@ func (t *AuthServiceTest) ResetPasswordGenerateHashedPasswordFailed() { assert.Equal(t.T(), expected, err) } -func (t *AuthServiceTest) ResetPasswordUpdateUserFailed() { +func (t *AuthServiceTest) TestResetPasswordUpdateUserFailed() { resetTokenCache := &tokenDto.ResetPasswordTokenCache{ UserID: faker.UUIDDigit(), } @@ -1119,6 +1120,7 @@ func (t *AuthServiceTest) ResetPasswordUpdateUserFailed() { Lastname: faker.LastName(), Role: constant.USER, } + comparePasswordErr := errors.New("Internal error") hashedPassword := faker.Word() updateUserDb := &model.User{ Base: model.Base{ @@ -1144,7 +1146,7 @@ func (t *AuthServiceTest) ResetPasswordUpdateUserFailed() { tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(userDb, nil) - bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(nil) + bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(comparePasswordErr) bcryptUtil.On("GenerateHashedPassword", t.resetPasswordRequest.Password).Return(hashedPassword, nil) userRepo.On("Update", resetTokenCache.UserID, updateUserDb).Return(nil, updateUserErr) @@ -1155,7 +1157,7 @@ func (t *AuthServiceTest) ResetPasswordUpdateUserFailed() { assert.Equal(t.T(), expected, err) } -func (t *AuthServiceTest) ResetPasswordRemoveTokenFailed() { +func (t *AuthServiceTest) TestResetPasswordRemoveTokenFailed() { resetTokenCache := &tokenDto.ResetPasswordTokenCache{ UserID: faker.UUIDDigit(), } @@ -1169,6 +1171,7 @@ func (t *AuthServiceTest) ResetPasswordRemoveTokenFailed() { Lastname: faker.LastName(), Role: constant.USER, } + comparePasswordErr := errors.New("Internal error") hashedPassword := faker.Word() updateUserDb := &model.User{ Base: model.Base{ @@ -1194,7 +1197,7 @@ func (t *AuthServiceTest) ResetPasswordRemoveTokenFailed() { tokenService.On("FindResetPasswordToken", t.resetPasswordRequest.Token).Return(resetTokenCache, nil) userRepo.On("FindById", resetTokenCache.UserID, &model.User{}).Return(userDb, nil) - bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(nil) + bcryptUtil.On("CompareHashedPassword", userDb.Password, t.resetPasswordRequest.Password).Return(comparePasswordErr) bcryptUtil.On("GenerateHashedPassword", t.resetPasswordRequest.Password).Return(hashedPassword, nil) userRepo.On("Update", resetTokenCache.UserID, updateUserDb).Return(updateUserDb, nil) tokenService.On("RemoveResetPasswordToken", t.resetPasswordRequest.Token).Return(removeTokenErr) From c30c36c2d0e6faeaa1081419f658ddd75ac6f6bf Mon Sep 17 00:00:00 2001 From: NitiwatOwen Date: Sun, 14 Jan 2024 16:47:34 +0700 Subject: [PATCH 3/3] fix: handle error when send email --- internal/service/email/email.service.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/internal/service/email/email.service.go b/internal/service/email/email.service.go index 8ebdab2..5899819 100644 --- a/internal/service/email/email.service.go +++ b/internal/service/email/email.service.go @@ -1,10 +1,13 @@ package email import ( + "fmt" "github.com/isd-sgcu/johnjud-auth/cfgldr" "github.com/isd-sgcu/johnjud-auth/pkg/service/email" + "github.com/pkg/errors" "github.com/sendgrid/sendgrid-go" "github.com/sendgrid/sendgrid-go/helpers/mail" + "net/http" ) type serviceImpl struct { @@ -17,10 +20,14 @@ func (s *serviceImpl) SendEmail(subject string, toName string, toAddress string, to := mail.NewEmail(toName, toAddress) message := mail.NewSingleEmail(from, subject, to, content, content) - _, err := s.client.Send(message) + resp, err := s.client.Send(message) if err != nil { return err } + if resp.StatusCode != http.StatusAccepted { + return errors.New(fmt.Sprintf("%d status code", resp.StatusCode)) + } + return nil }