From 420734ff8799be453f78bd89a5ba509869a88496 Mon Sep 17 00:00:00 2001 From: vladp Date: Wed, 10 Dec 2025 15:27:14 +0700 Subject: [PATCH] fix work controller code 20001,20002 --- .../no_copy/controller/ApiController.java | 32 +++++---------- .../ru/soune/no_copy/dto/AuthResponse.java | 10 ----- .../ru/soune/no_copy/dto/LogOutAnswer.java | 17 ++++++++ .../ru/soune/no_copy/dto/LoginAnswer.java | 17 ++++++++ .../ru/soune/no_copy/dto/LoginResponse.java | 14 ------- .../java/ru/soune/no_copy/dto/RegAnswer.java | 17 ++++++++ .../ru/soune/no_copy/dto/RegisterRequest.java | 40 ------------------ .../exception/NotValidFieldException.java | 13 ++---- .../handler/GlobalExceptionHandler.java | 5 +-- .../no_copy/handler/JwtTokenProvider.java | 7 ---- .../no_copy/handler/LoginRequestHandler.java | 30 +++++++------- .../no_copy/handler/RegRequestHandler.java | 37 +++++++++-------- .../soune/no_copy/handler/RequestHandler.java | 5 +-- .../{ => validator}/RegRequestValidator.java | 2 +- .../ru/soune/no_copy/service/AuthService.java | 13 +++--- .../no_copy/service/AuthServiceTest.java | 41 ------------------- 16 files changed, 111 insertions(+), 189 deletions(-) delete mode 100644 src/main/java/ru/soune/no_copy/dto/AuthResponse.java create mode 100644 src/main/java/ru/soune/no_copy/dto/LogOutAnswer.java create mode 100644 src/main/java/ru/soune/no_copy/dto/LoginAnswer.java delete mode 100644 src/main/java/ru/soune/no_copy/dto/LoginResponse.java create mode 100644 src/main/java/ru/soune/no_copy/dto/RegAnswer.java delete mode 100644 src/main/java/ru/soune/no_copy/dto/RegisterRequest.java delete mode 100644 src/main/java/ru/soune/no_copy/handler/JwtTokenProvider.java rename src/main/java/ru/soune/no_copy/handler/{ => validator}/RegRequestValidator.java (99%) diff --git a/src/main/java/ru/soune/no_copy/controller/ApiController.java b/src/main/java/ru/soune/no_copy/controller/ApiController.java index 174fcf7..8d6a646 100644 --- a/src/main/java/ru/soune/no_copy/controller/ApiController.java +++ b/src/main/java/ru/soune/no_copy/controller/ApiController.java @@ -9,7 +9,9 @@ import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.*; import ru.soune.no_copy.dto.BaseRequest; +import ru.soune.no_copy.dto.BaseResponse; import ru.soune.no_copy.dto.MessageCode; +import ru.soune.no_copy.dto.RegAnswer; import ru.soune.no_copy.exception.NotValidFieldException; import ru.soune.no_copy.exception.ValidationException; import ru.soune.no_copy.handler.LoginRequestHandler; @@ -48,15 +50,15 @@ public class ApiController { RequestHandler handler = handlers.get(msgId); if (handler == null) { - return ResponseEntity.ok().body(fillResponseInfo(msgId, + new BaseResponse(msgId, MessageCode.MSG_ID_NOT_FOUND.getCode(), - MessageCode.MSG_ID_NOT_FOUND.getDescription())); + MessageCode.MSG_ID_NOT_FOUND.getDescription(), + new HashMap<>()); } - Map response = handler.handle(request); + BaseResponse response = handler.handle(request); return ResponseEntity.ok().body(response); - } catch (ValidationException e) { return createValidationErrorResponse(e.getBindingResult(), e.getMsgId()); } catch (NotValidFieldException e) { @@ -67,20 +69,17 @@ public class ApiController { } } - private ResponseEntity> createValidationErrorResponse( - BindingResult bindingResult, Integer msgId) { - - Map response = fillResponseInfo(msgId, MessageCode.INVALID_FIELD.getCode(), - MessageCode.INVALID_FIELD.getDescription()); - + private ResponseEntity createValidationErrorResponse(BindingResult bindingResult, Integer msgId) { List> fieldErrors = bindingResult.getFieldErrors() .stream() .map(this::createErrorDetail) .collect(Collectors.toList()); - response.put("field_errors", fieldErrors); + RegAnswer regAnswer = new RegAnswer(); + regAnswer.setFieldErrors(fieldErrors); - return ResponseEntity.badRequest().body(response); + return ResponseEntity.ok().body(new BaseResponse(msgId, MessageCode.INVALID_FIELD.getCode(), + MessageCode.INVALID_FIELD.getDescription(), regAnswer)); } private Map createErrorDetail(FieldError fieldError) { @@ -96,13 +95,4 @@ public class ApiController { return errorDetail; } - - private Map fillResponseInfo(Integer msgId, Integer messageCode, String messageDesc) { - Map response = new HashMap<>(); - response.put("msg_id", msgId); - response.put("message_code", messageCode); - response.put("message_desc", messageDesc); - - return response; - } } \ No newline at end of file diff --git a/src/main/java/ru/soune/no_copy/dto/AuthResponse.java b/src/main/java/ru/soune/no_copy/dto/AuthResponse.java deleted file mode 100644 index c39301a..0000000 --- a/src/main/java/ru/soune/no_copy/dto/AuthResponse.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.soune.no_copy.dto; - -import java.time.LocalDateTime; - -public record AuthResponse ( - boolean success, - String message, - String token, - LocalDateTime expiresAt -) {} diff --git a/src/main/java/ru/soune/no_copy/dto/LogOutAnswer.java b/src/main/java/ru/soune/no_copy/dto/LogOutAnswer.java new file mode 100644 index 0000000..1174a5e --- /dev/null +++ b/src/main/java/ru/soune/no_copy/dto/LogOutAnswer.java @@ -0,0 +1,17 @@ +package ru.soune.no_copy.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Map; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LogOutAnswer { + private String Token; + + private List> fieldErrors; +} diff --git a/src/main/java/ru/soune/no_copy/dto/LoginAnswer.java b/src/main/java/ru/soune/no_copy/dto/LoginAnswer.java new file mode 100644 index 0000000..724c662 --- /dev/null +++ b/src/main/java/ru/soune/no_copy/dto/LoginAnswer.java @@ -0,0 +1,17 @@ +package ru.soune.no_copy.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Map; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LoginAnswer { + private String Token; + + private List> fieldErrors; +} diff --git a/src/main/java/ru/soune/no_copy/dto/LoginResponse.java b/src/main/java/ru/soune/no_copy/dto/LoginResponse.java deleted file mode 100644 index 5fe7d73..0000000 --- a/src/main/java/ru/soune/no_copy/dto/LoginResponse.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.soune.no_copy.dto; - -import lombok.AllArgsConstructor; -import lombok.Data; -import ru.soune.no_copy.entity.User; - -@Data -@AllArgsConstructor -public class LoginResponse { - private boolean success; - private String email; - private String token; - private String expiresAt; -} diff --git a/src/main/java/ru/soune/no_copy/dto/RegAnswer.java b/src/main/java/ru/soune/no_copy/dto/RegAnswer.java new file mode 100644 index 0000000..b79c14f --- /dev/null +++ b/src/main/java/ru/soune/no_copy/dto/RegAnswer.java @@ -0,0 +1,17 @@ +package ru.soune.no_copy.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Map; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RegAnswer { + private String Token; + + private List> fieldErrors; +} \ No newline at end of file diff --git a/src/main/java/ru/soune/no_copy/dto/RegisterRequest.java b/src/main/java/ru/soune/no_copy/dto/RegisterRequest.java deleted file mode 100644 index e08f39b..0000000 --- a/src/main/java/ru/soune/no_copy/dto/RegisterRequest.java +++ /dev/null @@ -1,40 +0,0 @@ -package ru.soune.no_copy.dto; - -import com.fasterxml.jackson.annotation.JsonFormat; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Past; -import jakarta.validation.constraints.Size; -import org.springframework.format.annotation.DateTimeFormat; -import ru.soune.no_copy.entity.GenderType; -import ru.soune.no_copy.entity.SubscriptionType; - -import java.time.LocalDate; - -public record RegisterRequest( - @NotBlank(message = "error.name.length") - String fullName, - - String companyName, - - @Size(min = 11, max = 14) - String phone, - - @NotBlank(message = "error.not.blank") - @Email(message = "error.not.email") - @Size(max = 128) - String email, - - @DateTimeFormat(pattern = "dd-MM-yyyy") - @JsonFormat(pattern = "dd-MM-yyyy") - @Past - LocalDate birthday, - - @NotBlank(message = "error.not.blank") - @Size(min = 8) - String password, - - SubscriptionType subscriptionType, - - GenderType genderType -) {} diff --git a/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java b/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java index 2181038..cbf2746 100644 --- a/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java +++ b/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java @@ -1,23 +1,18 @@ package ru.soune.no_copy.exception; import lombok.Getter; +import ru.soune.no_copy.dto.BaseResponse; @Getter public class NotValidFieldException extends RuntimeException { private final String message; - private final Integer messageId; + private final BaseResponse baseResponse; - private final Integer messageCode; - - private final String messageDescription; - - public NotValidFieldException(String message, Integer messageId, Integer messageCode, String messageDescription) { + public NotValidFieldException(String message, BaseResponse baseResponse) { super(message); this.message = message; - this.messageId = messageId; - this.messageCode = messageCode; - this.messageDescription = messageDescription; + this.baseResponse = baseResponse; } } diff --git a/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java b/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java index 7b78902..9e80dbb 100644 --- a/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java +++ b/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java @@ -35,10 +35,7 @@ public class GlobalExceptionHandler { return ResponseEntity .ok() - .body(Map.of( - "msg_id", ex.getMessageId(), - "message_code", ex.getMessageCode(), - "message_desc", ex.getMessageDescription())); + .body(ex.getBaseResponse()); } @ExceptionHandler(UserNotFoundException.class) diff --git a/src/main/java/ru/soune/no_copy/handler/JwtTokenProvider.java b/src/main/java/ru/soune/no_copy/handler/JwtTokenProvider.java deleted file mode 100644 index 721869c..0000000 --- a/src/main/java/ru/soune/no_copy/handler/JwtTokenProvider.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.soune.no_copy.handler; - -import org.springframework.stereotype.Component; - -@Component -public class JwtTokenProvider { -} diff --git a/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java b/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java index 0b2044a..91890e9 100644 --- a/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java +++ b/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java @@ -3,13 +3,13 @@ package ru.soune.no_copy.handler; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import ru.soune.no_copy.dto.BaseRequest; -import ru.soune.no_copy.dto.LoginRequest; -import ru.soune.no_copy.dto.MessageCode; +import ru.soune.no_copy.dto.*; +import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.exception.NotValidFieldException; import ru.soune.no_copy.repository.UserRepository; import ru.soune.no_copy.service.AuthService; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -22,26 +22,24 @@ public class LoginRequestHandler implements RequestHandler { private final ObjectMapper objectMapper; @Override - public Map handle(BaseRequest request) { + public BaseResponse handle(BaseRequest request) { LoginRequest loginRequest = objectMapper.convertValue(request.getMessageBody(), LoginRequest.class); if (!userRepository.existsByEmail(loginRequest.getEmail())) { + LoginAnswer loginAnswer = new LoginAnswer(); + loginAnswer.setFieldErrors(Arrays.asList(Map.of("email", loginRequest.getEmail()))); + throw new NotValidFieldException("User with email not found: " + loginRequest.getEmail(), - request.getMsgId(), MessageCode.AUTH_EMAIL_NOT_FOUND.getCode(), - MessageCode.AUTH_EMAIL_NOT_FOUND.getDescription()); + new BaseResponse(request.getMsgId(), MessageCode.AUTH_EMAIL_NOT_FOUND.getCode(), + MessageCode.AUTH_EMAIL_NOT_FOUND.getDescription(), loginAnswer)); } - authService.login(loginRequest); + AuthToken authToken = authService.login(loginRequest); - return fillResponseInfo(request.getMsgId(), MessageCode.SUCCESS.getCode(), - MessageCode.SUCCESS.getDescription()); - } + LoginAnswer loginAnswer = new LoginAnswer(); + loginAnswer.setToken(authToken.getToken()); - private Map fillResponseInfo(Integer msgId, Integer messageCode, String messageDesc) { - Map response = new HashMap<>(); - response.put("msg_id", msgId); - response.put("message_code", messageCode); - response.put("message_desc", messageDesc); - return response; + return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription(), loginAnswer); } } diff --git a/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java b/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java index c6a83ed..2c54dc2 100644 --- a/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java +++ b/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java @@ -6,35 +6,40 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; -import ru.soune.no_copy.dto.BaseRequest; -import ru.soune.no_copy.dto.MessageCode; -import ru.soune.no_copy.dto.RegRequest; +import ru.soune.no_copy.dto.*; +import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.exception.NotValidFieldException; import ru.soune.no_copy.exception.ValidationException; +import ru.soune.no_copy.handler.validator.RegRequestValidator; import ru.soune.no_copy.repository.UserRepository; import ru.soune.no_copy.service.AuthService; -import java.util.HashMap; +import java.util.Arrays; import java.util.Map; @Slf4j @Component @RequiredArgsConstructor public class RegRequestHandler implements RequestHandler { - private final UserRepository userRepository; + private final RegRequestValidator regRequestValidator; + private final AuthService authService; + private final ObjectMapper objectMapper; @Override - public Map handle(BaseRequest request) throws ValidationException { + public BaseResponse handle(BaseRequest request) throws ValidationException { RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class); if (userRepository.existsByEmail(regRequest.getEmail())) { + RegAnswer regAnswer = new RegAnswer(); + regAnswer.setFieldErrors(Arrays.asList(Map.of("email", regRequest.getEmail()))); + throw new NotValidFieldException("User already exists with email: " + regRequest.getEmail(), - request.getMsgId(), MessageCode.REG_EMAIL_EXISTS.getCode(), - MessageCode.REG_EMAIL_EXISTS.getDescription()); + new BaseResponse(request.getMsgId(), MessageCode.REG_EMAIL_EXISTS.getCode(), + MessageCode.REG_EMAIL_EXISTS.getDescription(), regAnswer)); } BindingResult bindingResult = new BeanPropertyBindingResult(regRequest, "regRequest"); @@ -44,16 +49,12 @@ public class RegRequestHandler implements RequestHandler { throw new ValidationException(bindingResult, request.getMsgId()); } - authService.register(regRequest); - return fillResponseInfo(request.getMsgId(), MessageCode.SUCCESS.getCode(), - MessageCode.SUCCESS.getDescription()); - } + AuthToken authToken = authService.register(regRequest); - private Map fillResponseInfo(Integer msgId, Integer messageCode, String messageDesc) { - Map response = new HashMap<>(); - response.put("msg_id", msgId); - response.put("message_code", messageCode); - response.put("message_desc", messageDesc); - return response; + RegAnswer regAnswer = new RegAnswer(); + regAnswer.setToken(authToken.getToken()); + + return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription(), regAnswer); } } \ No newline at end of file diff --git a/src/main/java/ru/soune/no_copy/handler/RequestHandler.java b/src/main/java/ru/soune/no_copy/handler/RequestHandler.java index d78e19b..c38848b 100644 --- a/src/main/java/ru/soune/no_copy/handler/RequestHandler.java +++ b/src/main/java/ru/soune/no_copy/handler/RequestHandler.java @@ -1,9 +1,8 @@ package ru.soune.no_copy.handler; import ru.soune.no_copy.dto.BaseRequest; - -import java.util.Map; +import ru.soune.no_copy.dto.BaseResponse; public interface RequestHandler { - Map handle(BaseRequest request) throws Exception; + BaseResponse handle(BaseRequest request) throws Exception; } diff --git a/src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java b/src/main/java/ru/soune/no_copy/handler/validator/RegRequestValidator.java similarity index 99% rename from src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java rename to src/main/java/ru/soune/no_copy/handler/validator/RegRequestValidator.java index f7ea83e..b25c2e0 100644 --- a/src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java +++ b/src/main/java/ru/soune/no_copy/handler/validator/RegRequestValidator.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.handler; +package ru.soune.no_copy.handler.validator; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; diff --git a/src/main/java/ru/soune/no_copy/service/AuthService.java b/src/main/java/ru/soune/no_copy/service/AuthService.java index 2a76f68..01ad0ea 100644 --- a/src/main/java/ru/soune/no_copy/service/AuthService.java +++ b/src/main/java/ru/soune/no_copy/service/AuthService.java @@ -5,9 +5,7 @@ import org.springframework.context.MessageSource; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import ru.soune.no_copy.dto.LoginRequest; -import ru.soune.no_copy.dto.MessageCode; -import ru.soune.no_copy.dto.RegRequest; +import ru.soune.no_copy.dto.*; import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.entity.User; import ru.soune.no_copy.exception.NotValidFieldException; @@ -18,7 +16,9 @@ import ru.soune.no_copy.repository.UserRepository; import java.security.SecureRandom; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.Base64; +import java.util.Map; import java.util.Optional; @Service @@ -65,9 +65,12 @@ public class AuthService { User user = userOpt.get(); if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) { - throw new NotValidFieldException("Invalid password", 20003, + LoginAnswer loginAnswer = new LoginAnswer(); + loginAnswer.setFieldErrors(Arrays.asList(Map.of("password", request.getPassword()))); + + throw new NotValidFieldException("Invalid password", new BaseResponse(20003, MessageCode.AUTH_PASSWORD_NOT_MATCHES.getCode(), - MessageCode.AUTH_PASSWORD_NOT_MATCHES.getDescription()); + MessageCode.AUTH_PASSWORD_NOT_MATCHES.getDescription(), loginAnswer)); } user.setLastLoginAt(LocalDateTime.now()); diff --git a/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java b/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java index c2a38a4..69b767e 100644 --- a/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java +++ b/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java @@ -9,21 +9,17 @@ import org.mockito.MockitoAnnotations; import org.springframework.context.MessageSource; import org.springframework.security.crypto.password.PasswordEncoder; import ru.soune.no_copy.dto.LoginRequest; -import ru.soune.no_copy.dto.RegisterRequest; import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.entity.User; import ru.soune.no_copy.exception.NotValidationPasswordException; -import ru.soune.no_copy.exception.NotValidFieldException; import ru.soune.no_copy.exception.UserNotFoundException; import ru.soune.no_copy.repository.AuthTokenRepository; import ru.soune.no_copy.repository.UserRepository; -import java.util.Locale; import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -49,43 +45,6 @@ public class AuthServiceTest { MockitoAnnotations.openMocks(this); } - @Test - void registerSuccess() { - RegisterRequest request = new RegisterRequest("John","A.","124124", - "john@example.com", null,"password123", null, null); - - when(userRepository.existsByEmail(request.email())).thenReturn(false); - when(passwordEncoder.encode(request.password())).thenReturn("hashed"); - when(userRepository.save(any(User.class))).thenAnswer(invocation -> invocation.getArgument(0)); - when(authTokenRepository.save(any(AuthToken.class))).thenAnswer(invocation -> invocation.getArgument(0)); - - AuthToken token = authService.register(request); - User user = token.getUser(); - String email = user.getEmail(); - - assertNotNull(token); - assertNotNull(token.getToken()); - assertNotNull(token.getUser()); - assertEquals("john@example.com", email); - assertNotNull(token.getExpiresAt()); - } - - @Test - void registerExistingEmailThrows() { - RegisterRequest request = new RegisterRequest("John","A.","124124", - "john@example.com", null,"password123", null, null); - - when(userRepository.existsByEmail(request.email())) - .thenReturn(true); - when(messageSource.getMessage(anyString(), any(), any(Locale.class))) - .thenReturn("User exists"); - - NotValidFieldException ex = assertThrows(NotValidFieldException.class, - () -> authService.register(request)); - - assertEquals("User exists", ex.getMessage()); - } - @Test void login_success() { LoginRequest request = new LoginRequest("test@mail.com", "password");