From 62bd4ca0ffd6b01d258201f530f3a0985fbd09b7 Mon Sep 17 00:00:00 2001 From: nastiausenko Date: Sat, 20 Apr 2024 01:54:38 +0300 Subject: [PATCH 1/2] fix exception errors --- .../urlshortener/exception/ErrorResponse.java | 2 +- .../exception/GlobalExceptionHandler.java | 95 +++++++++++++------ .../link/DeletedLinkException.java | 4 - .../urlshortener/link/ForbiddenException.java | 12 --- .../link/InternalServerLinkException.java | 4 - .../urlshortener/link/LinkController.java | 1 + .../urlshortener/link/LinkService.java | 20 +--- .../link/LinkStatusException.java | 4 - .../link/NoLinkFoundByIdException.java | 4 - .../link/NoLinkFoundByShortLinkException.java | 4 - .../link/NullLinkPropertyException.java | 4 - .../security/ForbiddenException.java | 8 ++ .../user/NoSuchEmailFoundException.java | 4 - .../user/NoUserFoundByEmailException.java | 4 - .../user/NoUserFoundByIdException.java | 4 - .../urlshortener/user/NullEmailException.java | 4 - .../urlshortener/user/UserController.java | 1 + .../auth/AuthControllerIntegrationTest.java | 43 ++++----- .../urlshortener/auth/AuthControllerTest.java | 7 +- .../urlshortener/link/LinkServiceTest.java | 5 - .../user/UserControllerIntegrationTest.java | 6 +- 21 files changed, 109 insertions(+), 131 deletions(-) delete mode 100644 src/main/java/com/linkurlshorter/urlshortener/link/ForbiddenException.java create mode 100644 src/main/java/com/linkurlshorter/urlshortener/security/ForbiddenException.java diff --git a/src/main/java/com/linkurlshorter/urlshortener/exception/ErrorResponse.java b/src/main/java/com/linkurlshorter/urlshortener/exception/ErrorResponse.java index d61c002..fec4362 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/exception/ErrorResponse.java +++ b/src/main/java/com/linkurlshorter/urlshortener/exception/ErrorResponse.java @@ -11,5 +11,5 @@ public record ErrorResponse( LocalDateTime dateTime, int statusCode, String message, - String path + String exceptionMessage ) {} diff --git a/src/main/java/com/linkurlshorter/urlshortener/exception/GlobalExceptionHandler.java b/src/main/java/com/linkurlshorter/urlshortener/exception/GlobalExceptionHandler.java index c44821b..c46108e 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/linkurlshorter/urlshortener/exception/GlobalExceptionHandler.java @@ -1,13 +1,15 @@ package com.linkurlshorter.urlshortener.exception; import com.linkurlshorter.urlshortener.auth.exception.EmailAlreadyTakenException; +import com.linkurlshorter.urlshortener.security.ForbiddenException; import com.linkurlshorter.urlshortener.user.NoSuchEmailFoundException; import com.linkurlshorter.urlshortener.user.NoUserFoundByEmailException; import com.linkurlshorter.urlshortener.user.NoUserFoundByIdException; import com.linkurlshorter.urlshortener.user.NullEmailException; -import jakarta.servlet.http.HttpServletRequest; +import org.apache.coyote.BadRequestException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.AuthenticationException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; @@ -27,16 +29,13 @@ public class GlobalExceptionHandler { * Handles method argument validation errors and invalid request errors (400). * Returns a response with status 400 and the corresponding error message. * - * @param ex method argument validation error + * @param exception method argument validation error * @return {@link ResponseEntity} object with the appropriate status and error message */ - @ExceptionHandler(MethodArgumentNotValidException.class) - public ResponseEntity handleMethodArgumentNotValid( - MethodArgumentNotValidException ex, HttpServletRequest request) { - ErrorResponse errorResponse = buildErrorResponse( - HttpStatus.BAD_REQUEST, - Objects.requireNonNull(ex.getFieldError()).getDefaultMessage(), - request.getRequestURI()); + @ExceptionHandler({MethodArgumentNotValidException.class, BadRequestException.class}) + public ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotValidException exception) { + ErrorResponse errorResponse = buildErrorResponse(HttpStatus.BAD_REQUEST, "Validation failed!", + Objects.requireNonNull(exception.getFieldError()).getDefaultMessage()); return ResponseEntity.badRequest().body(errorResponse); } @@ -47,11 +46,11 @@ public ResponseEntity handleMethodArgumentNotValid( * @param ex null email error * @return {@link ResponseEntity} object with the corresponding status and error message */ + //TODO: write tests for this exception @ExceptionHandler(NullEmailException.class) - public ResponseEntity handleNullEmailException( - NullEmailException ex, HttpServletRequest request) { + public ResponseEntity handleNullEmailException(NullEmailException ex) { ErrorResponse errorResponse = buildErrorResponse(HttpStatus.BAD_REQUEST, - ex.getMessage(), request.getRequestURI()); + "Email provided is null, so request can not be processed!", ex.getMessage()); return ResponseEntity.badRequest().body(errorResponse); } @@ -62,10 +61,9 @@ public ResponseEntity handleNullEmailException( * @return {@link ResponseEntity} containing the error response for authentication failure */ @ExceptionHandler(AuthenticationException.class) - public ResponseEntity handleAuthenticationException( - AuthenticationException ex, HttpServletRequest request) { + public ResponseEntity handleAuthenticationException(AuthenticationException ex) { ErrorResponse errorResponse = buildErrorResponse(HttpStatus.UNAUTHORIZED, - ex.getMessage(), request.getRequestURI()); + "Authentication failed!", ex.getMessage()); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorResponse); } @@ -76,13 +74,40 @@ public ResponseEntity handleAuthenticationException( * @return {@link ResponseEntity} containing the error response for email already taken */ @ExceptionHandler(EmailAlreadyTakenException.class) - public ResponseEntity handleEmailAlreadyTakenException( - EmailAlreadyTakenException ex, HttpServletRequest request) { + public ResponseEntity handleEmailAlreadyTakenException(EmailAlreadyTakenException ex) { ErrorResponse errorResponse = buildErrorResponse(HttpStatus.BAD_REQUEST, - ex.getMessage(), request.getRequestURI()); + "Email already taken!", ex.getMessage()); return ResponseEntity.badRequest().body(errorResponse); } + /** + * Handles bad credentials (401) errors. + * Returns a response with a 401 status and the corresponding error message. + * + * @param ex bad credentials error + * @return {@link ResponseEntity} object with the corresponding status and error message + */ + @ExceptionHandler(BadCredentialsException.class) + public ResponseEntity handleBadCredentialsException(BadCredentialsException ex) { + ErrorResponse errorResponse = buildErrorResponse(HttpStatus.UNAUTHORIZED, + "Bad Credentials!", ex.getMessage()); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorResponse); + } + + /** + * Handles denied access (403) errors. + * Returns a response with a 403 status and the corresponding error message. + * + * @param ex denied access error + * @return {@link ResponseEntity} object with the corresponding status and error message + */ + @ExceptionHandler(ForbiddenException.class) + public ResponseEntity handleForbiddenException(ForbiddenException ex) { + ErrorResponse errorResponse = buildErrorResponse(HttpStatus.FORBIDDEN, + "Forbidden!", ex.getMessage()); + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(errorResponse); + } + /** * Handles no resource (404) exceptions for different types of requests. * Returns a response with a 404 status and the corresponding error message. @@ -90,25 +115,37 @@ public ResponseEntity handleEmailAlreadyTakenException( * @param ex missing resource exception * @return {@link ResponseEntity} object with the corresponding status and error message */ - @ExceptionHandler({NoSuchEmailFoundException.class, - NoUserFoundByEmailException.class, NoUserFoundByIdException.class}) - public ResponseEntity handleNotFoundExceptions( - RuntimeException ex, HttpServletRequest request) { - ErrorResponse errorResponse = buildErrorResponse(HttpStatus.NOT_FOUND, - ex.getMessage(), request.getRequestURI()); + @ExceptionHandler({NoSuchEmailFoundException.class, NoUserFoundByEmailException.class, NoUserFoundByIdException.class}) + public ResponseEntity handleNotFoundExceptions(Exception ex) { + ErrorResponse errorResponse = buildErrorResponse(HttpStatus.NOT_FOUND, "Email Not Found!", + ex.getMessage()); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); } + /** + * Handles general exceptions (500). + * Returns a response with status 500 and the corresponding error message. + * + * @param ex general exception + * @return {@link ResponseEntity} object with the appropriate status and error message + */ + @ExceptionHandler({Exception.class}) + public ResponseEntity handleInternalServerError(Exception ex) { + ErrorResponse errorResponse = buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, + "Internal Server Error!", ex.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse); + } + /** * Creates an error response object. * - * @param status status of the error - * @param message error message - * @param requestURI request URL + * @param status status of the error + * @param message error message + * @param exceptionMessage exception message * @return an {@link ErrorResponse} object with the appropriate data */ - private ErrorResponse buildErrorResponse(HttpStatus status, String message, String requestURI) { - return new ErrorResponse(LocalDateTime.now(), status.value(), message, requestURI); + private ErrorResponse buildErrorResponse(HttpStatus status, String message, String exceptionMessage) { + return new ErrorResponse(LocalDateTime.now(), status.value(), message, exceptionMessage); } } diff --git a/src/main/java/com/linkurlshorter/urlshortener/link/DeletedLinkException.java b/src/main/java/com/linkurlshorter/urlshortener/link/DeletedLinkException.java index b241f0d..2e7b046 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/link/DeletedLinkException.java +++ b/src/main/java/com/linkurlshorter/urlshortener/link/DeletedLinkException.java @@ -11,8 +11,4 @@ public class DeletedLinkException extends RuntimeException { public DeletedLinkException() { super(DEFAULT_MSG); } - - public DeletedLinkException(String msg) { - super(msg); - } } diff --git a/src/main/java/com/linkurlshorter/urlshortener/link/ForbiddenException.java b/src/main/java/com/linkurlshorter/urlshortener/link/ForbiddenException.java deleted file mode 100644 index 6cbd55b..0000000 --- a/src/main/java/com/linkurlshorter/urlshortener/link/ForbiddenException.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.linkurlshorter.urlshortener.link; - -public class ForbiddenException extends RuntimeException { - - public ForbiddenException(String message) { - super(message); - } - - public ForbiddenException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/main/java/com/linkurlshorter/urlshortener/link/InternalServerLinkException.java b/src/main/java/com/linkurlshorter/urlshortener/link/InternalServerLinkException.java index 87af4ed..9db6fd9 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/link/InternalServerLinkException.java +++ b/src/main/java/com/linkurlshorter/urlshortener/link/InternalServerLinkException.java @@ -12,8 +12,4 @@ public class InternalServerLinkException extends RuntimeException { public InternalServerLinkException() { super(DEFAULT_MSG); } - - public InternalServerLinkException(String msg) { - super(msg); - } } diff --git a/src/main/java/com/linkurlshorter/urlshortener/link/LinkController.java b/src/main/java/com/linkurlshorter/urlshortener/link/LinkController.java index a5f2132..2e4ebd3 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/link/LinkController.java +++ b/src/main/java/com/linkurlshorter/urlshortener/link/LinkController.java @@ -1,5 +1,6 @@ package com.linkurlshorter.urlshortener.link; +import com.linkurlshorter.urlshortener.security.ForbiddenException; import com.linkurlshorter.urlshortener.user.User; import com.linkurlshorter.urlshortener.user.UserService; import jakarta.validation.Valid; diff --git a/src/main/java/com/linkurlshorter/urlshortener/link/LinkService.java b/src/main/java/com/linkurlshorter/urlshortener/link/LinkService.java index e9e0f90..7226caa 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/link/LinkService.java +++ b/src/main/java/com/linkurlshorter/urlshortener/link/LinkService.java @@ -1,6 +1,5 @@ package com.linkurlshorter.urlshortener.link; -import com.linkurlshorter.urlshortener.user.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -42,8 +41,10 @@ public Link update(Link link) { if (Objects.isNull(link)) { throw new NullLinkPropertyException(); } - - throwIfDeleted(link); +//TODO:test for delete + if (findByShortLink(link.getShortLink()).getStatus() == LinkStatus.DELETED) { + throw new DeletedLinkException(); + } return linkRepository.save(link); } @@ -133,6 +134,7 @@ public void deleteById(UUID id) { * @throws NoLinkFoundByShortLinkException If no link was found by the short link. * @throws NullLinkPropertyException If the found link does not have the ACTIVE status. */ + //TODO: tests for this method public Link findByExistUniqueLink(String shortLink) { Link existingLink = linkRepository.findByShortLink(shortLink).orElseThrow(NoLinkFoundByShortLinkException::new); if (existingLink.getStatus() == LinkStatus.ACTIVE) { @@ -141,16 +143,4 @@ public Link findByExistUniqueLink(String shortLink) { throw new NullLinkPropertyException(); } } - - /** - * Throws a DeletedLinkException if the link has been marked as deleted. - * - * @param link The link entity to check. - * @throws DeletedLinkException If the link has been marked as deleted. - */ - private void throwIfDeleted(Link link) { - if (findByShortLink(link.getShortLink()).getStatus() == LinkStatus.DELETED) { - throw new DeletedLinkException(); - } - } } diff --git a/src/main/java/com/linkurlshorter/urlshortener/link/LinkStatusException.java b/src/main/java/com/linkurlshorter/urlshortener/link/LinkStatusException.java index 9776cba..cc17f5a 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/link/LinkStatusException.java +++ b/src/main/java/com/linkurlshorter/urlshortener/link/LinkStatusException.java @@ -16,8 +16,4 @@ public class LinkStatusException extends RuntimeException { public LinkStatusException() { super(MSG); } - - public LinkStatusException(String message) { - super(message); - } } diff --git a/src/main/java/com/linkurlshorter/urlshortener/link/NoLinkFoundByIdException.java b/src/main/java/com/linkurlshorter/urlshortener/link/NoLinkFoundByIdException.java index 11f05b0..c1040a8 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/link/NoLinkFoundByIdException.java +++ b/src/main/java/com/linkurlshorter/urlshortener/link/NoLinkFoundByIdException.java @@ -9,8 +9,4 @@ public class NoLinkFoundByIdException extends RuntimeException { public NoLinkFoundByIdException() { super(DEFAULT_MSG); } - - public NoLinkFoundByIdException(String msg) { - super(msg); - } } diff --git a/src/main/java/com/linkurlshorter/urlshortener/link/NoLinkFoundByShortLinkException.java b/src/main/java/com/linkurlshorter/urlshortener/link/NoLinkFoundByShortLinkException.java index 262c486..ff7fcda 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/link/NoLinkFoundByShortLinkException.java +++ b/src/main/java/com/linkurlshorter/urlshortener/link/NoLinkFoundByShortLinkException.java @@ -9,8 +9,4 @@ public class NoLinkFoundByShortLinkException extends RuntimeException { public NoLinkFoundByShortLinkException() { super(DEFAULT_MSG); } - - public NoLinkFoundByShortLinkException(String msg) { - super(msg); - } } diff --git a/src/main/java/com/linkurlshorter/urlshortener/link/NullLinkPropertyException.java b/src/main/java/com/linkurlshorter/urlshortener/link/NullLinkPropertyException.java index 78dae49..3619b7c 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/link/NullLinkPropertyException.java +++ b/src/main/java/com/linkurlshorter/urlshortener/link/NullLinkPropertyException.java @@ -15,8 +15,4 @@ public class NullLinkPropertyException extends RuntimeException { public NullLinkPropertyException() { super(DEFAULT_MSG); } - - public NullLinkPropertyException(String msg) { - super(msg); - } } diff --git a/src/main/java/com/linkurlshorter/urlshortener/security/ForbiddenException.java b/src/main/java/com/linkurlshorter/urlshortener/security/ForbiddenException.java new file mode 100644 index 0000000..6ca6d31 --- /dev/null +++ b/src/main/java/com/linkurlshorter/urlshortener/security/ForbiddenException.java @@ -0,0 +1,8 @@ +package com.linkurlshorter.urlshortener.security; + +public class ForbiddenException extends RuntimeException { + + public ForbiddenException(String message) { + super(message); + } +} diff --git a/src/main/java/com/linkurlshorter/urlshortener/user/NoSuchEmailFoundException.java b/src/main/java/com/linkurlshorter/urlshortener/user/NoSuchEmailFoundException.java index ee69ab0..564a890 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/user/NoSuchEmailFoundException.java +++ b/src/main/java/com/linkurlshorter/urlshortener/user/NoSuchEmailFoundException.java @@ -19,8 +19,4 @@ public class NoSuchEmailFoundException extends RuntimeException { public NoSuchEmailFoundException() { super(MSG); } - - public NoSuchEmailFoundException(String msg) { - super(msg); - } } diff --git a/src/main/java/com/linkurlshorter/urlshortener/user/NoUserFoundByEmailException.java b/src/main/java/com/linkurlshorter/urlshortener/user/NoUserFoundByEmailException.java index e9c8f75..d3a582e 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/user/NoUserFoundByEmailException.java +++ b/src/main/java/com/linkurlshorter/urlshortener/user/NoUserFoundByEmailException.java @@ -19,8 +19,4 @@ public class NoUserFoundByEmailException extends RuntimeException { public NoUserFoundByEmailException() { super(DEFAULT_MSG); } - - public NoUserFoundByEmailException(String msg) { - super(msg); - } } diff --git a/src/main/java/com/linkurlshorter/urlshortener/user/NoUserFoundByIdException.java b/src/main/java/com/linkurlshorter/urlshortener/user/NoUserFoundByIdException.java index 9751a97..518adb0 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/user/NoUserFoundByIdException.java +++ b/src/main/java/com/linkurlshorter/urlshortener/user/NoUserFoundByIdException.java @@ -19,8 +19,4 @@ public class NoUserFoundByIdException extends RuntimeException { public NoUserFoundByIdException() { super(DEFAULT_MSG); } - - public NoUserFoundByIdException(String msg) { - super(msg); - } } diff --git a/src/main/java/com/linkurlshorter/urlshortener/user/NullEmailException.java b/src/main/java/com/linkurlshorter/urlshortener/user/NullEmailException.java index 973ea22..bd8f2fd 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/user/NullEmailException.java +++ b/src/main/java/com/linkurlshorter/urlshortener/user/NullEmailException.java @@ -21,8 +21,4 @@ public class NullEmailException extends NullUserPropertyException { public NullEmailException() { super(MSG); } - - public NullEmailException(String msg) { - super(msg); - } } \ No newline at end of file diff --git a/src/main/java/com/linkurlshorter/urlshortener/user/UserController.java b/src/main/java/com/linkurlshorter/urlshortener/user/UserController.java index 16b1ca0..8f6b522 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/user/UserController.java +++ b/src/main/java/com/linkurlshorter/urlshortener/user/UserController.java @@ -78,6 +78,7 @@ public ResponseEntity changePassword(@RequestBody @Valid public ResponseEntity changeEmail(@RequestBody @Valid ChangeUserEmailRequest emailRequest) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String newEmail = emailRequest.getNewEmail(); + //TODO: test for this exception if (userService.existsByEmail(newEmail)) { throw new EmailAlreadyTakenException(newEmail); } diff --git a/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerIntegrationTest.java b/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerIntegrationTest.java index 3333374..dfe39f3 100644 --- a/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerIntegrationTest.java +++ b/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerIntegrationTest.java @@ -20,6 +20,7 @@ import org.testcontainers.junit.jupiter.Testcontainers; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** @@ -54,9 +55,9 @@ void loginSuccessfulTest() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders.post(baseUrl + "login") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(authRequest))) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("User logged in successfully!")) - .andExpect(MockMvcResultMatchers.jsonPath("$.jwtToken").exists()); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.message").value("User logged in successfully!")) + .andExpect(jsonPath("$.jwtToken").exists()); } /** @@ -66,13 +67,13 @@ void loginSuccessfulTest() throws Exception { */ @Test void loginFailedWhenUserDoesNotExistTest() throws Exception { - authRequest = new AuthRequest("user-not-found@example.com", "Pass1234"); - this.mockMvc.perform(MockMvcRequestBuilders.post(baseUrl + "login") + authRequest = new AuthRequest("userNotFound@example.com", "Pass1234"); + this.mockMvc.perform(post(baseUrl + "login") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(authRequest))) - .andExpect(MockMvcResultMatchers.status().is4xxClientError()) - .andExpect(MockMvcResultMatchers.jsonPath("$.statusCode").value(401)) - .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("No user by provided email found")); + .andExpect(status().is4xxClientError()) + .andExpect(jsonPath("$.statusCode").value(401)) + .andExpect(jsonPath("$.message").value("Authentication failed!")); } /** @@ -83,12 +84,12 @@ void loginFailedWhenUserDoesNotExistTest() throws Exception { @Test void loginFailedWhenPasswordDoesNotMatchTest() throws Exception { authRequest = new AuthRequest("user1@example.com", "Pass12345"); - this.mockMvc.perform(MockMvcRequestBuilders.post(baseUrl + "login") + this.mockMvc.perform(post(baseUrl + "login") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(authRequest))) .andExpect(MockMvcResultMatchers.status().is4xxClientError()) - .andExpect(MockMvcResultMatchers.jsonPath("$.statusCode").value(401)) - .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Bad credentials")); + .andExpect(jsonPath("$.statusCode").value(401)) + .andExpect(jsonPath("$.message").value("Bad Credentials!")); } /** @@ -105,10 +106,8 @@ void loginFailedWhenInvalidPasswordGivenTest(String password) throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(authRequest))) .andExpect(status().is4xxClientError()) - .andExpect(MockMvcResultMatchers.jsonPath("$.statusCode").value(400)) - .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Password " + - "must be at least 8 characters long and contain at least one digit, one uppercase letter, " + - "and one lowercase letter. No spaces are allowed.")); + .andExpect(jsonPath("$.statusCode").value(400)) + .andExpect(jsonPath("$.message").value("Validation failed!")); } /** @@ -130,8 +129,8 @@ void loginFailedWhenInvalidEmailGivenTest(String email) throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(authRequest))) .andExpect(status().is4xxClientError()) - .andExpect(MockMvcResultMatchers.jsonPath("$.statusCode").value(400)) - .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Email address entered incorrectly!")); + .andExpect(jsonPath("$.statusCode").value(400)) + .andExpect(jsonPath("$.message").value("Validation failed!")); } /** @@ -148,10 +147,8 @@ void registerFailedWhenInvalidPasswordGivenTest(String password) throws Exceptio .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(authRequest))) .andExpect(status().is4xxClientError()) - .andExpect(MockMvcResultMatchers.jsonPath("$.statusCode").value(400)) - .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Password " + - "must be at least 8 characters long and contain at least one digit, one uppercase letter, " + - "and one lowercase letter. No spaces are allowed.")); + .andExpect(jsonPath("$.statusCode").value(400)) + .andExpect(jsonPath("$.message").value("Validation failed!")); } /** @@ -173,7 +170,7 @@ void registerFailedWhenInvalidEmailGivenTest(String email) throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(authRequest))) .andExpect(status().is4xxClientError()) - .andExpect(MockMvcResultMatchers.jsonPath("$.statusCode").value(400)) - .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Email address entered incorrectly!")); + .andExpect(jsonPath("$.statusCode").value(400)) + .andExpect(jsonPath("$.message").value("Validation failed!")); } } diff --git a/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerTest.java b/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerTest.java index 5b260e1..a8347bb 100644 --- a/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerTest.java +++ b/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerTest.java @@ -1,11 +1,11 @@ package com.linkurlshorter.urlshortener.auth; import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.api.exception.UnauthorizedException; import com.linkurlshorter.urlshortener.auth.dto.AuthRequest; import com.linkurlshorter.urlshortener.auth.exception.EmailAlreadyTakenException; import com.linkurlshorter.urlshortener.TestConfig; import com.linkurlshorter.urlshortener.security.SecurityConfig; -import com.linkurlshorter.urlshortener.security.UnauthorizedException; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -13,6 +13,9 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; @@ -94,7 +97,7 @@ void loginSuccessfulTest() throws Exception { @Test void loginFailedTest() throws Exception { AuthRequest request = new AuthRequest("test3@email.com", "Password1"); - when(authService.loginUser(request)).thenThrow(UnauthorizedException.class); + when(authService.loginUser(request)).thenThrow(UsernameNotFoundException.class); ResultActions resultActions = mockMvc.perform(post("/api/V1/auth/login") .contentType(MediaType.APPLICATION_JSON) diff --git a/src/test/java/com/linkurlshorter/urlshortener/link/LinkServiceTest.java b/src/test/java/com/linkurlshorter/urlshortener/link/LinkServiceTest.java index 5fe16ea..774ba9e 100644 --- a/src/test/java/com/linkurlshorter/urlshortener/link/LinkServiceTest.java +++ b/src/test/java/com/linkurlshorter/urlshortener/link/LinkServiceTest.java @@ -2,17 +2,12 @@ import com.linkurlshorter.urlshortener.user.User; import com.linkurlshorter.urlshortener.user.UserRole; -import jakarta.persistence.EntityManager; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.boot.test.context.SpringBootTest; import java.time.LocalDateTime; import java.util.*; diff --git a/src/test/java/com/linkurlshorter/urlshortener/user/UserControllerIntegrationTest.java b/src/test/java/com/linkurlshorter/urlshortener/user/UserControllerIntegrationTest.java index b7ab16e..9394ad6 100644 --- a/src/test/java/com/linkurlshorter/urlshortener/user/UserControllerIntegrationTest.java +++ b/src/test/java/com/linkurlshorter/urlshortener/user/UserControllerIntegrationTest.java @@ -104,9 +104,7 @@ void changePasswordFailedWhenInvalidPasswordGivenTest(String password) throws Ex .content(objectMapper.writeValueAsString(request))) .andExpect(status().is4xxClientError()) .andExpect(MockMvcResultMatchers.jsonPath("$.statusCode").value(400)) - .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Password " + - "must be at least 8 characters long and contain at least one digit, one uppercase letter, " + - "and one lowercase letter. No spaces are allowed.")); + .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Validation failed!")); } /** @@ -156,6 +154,6 @@ void changeEmailFailedWhenInvalidEmailGivenTest(String email) throws Exception { .andExpect(status().is4xxClientError()) .andExpect(MockMvcResultMatchers.jsonPath("$.statusCode").value(400)) .andExpect(MockMvcResultMatchers.jsonPath("$.message") - .value("Email address entered incorrectly!")); + .value("Validation failed!")); } } From 36e9c675db2fdf65ecb01a90c0d635664f1ccb19 Mon Sep 17 00:00:00 2001 From: nastiausenko Date: Sun, 21 Apr 2024 00:08:41 +0300 Subject: [PATCH 2/2] fix errors --- .../exception/GlobalExceptionHandler.java | 20 +++++++------------ .../auth/AuthControllerIntegrationTest.java | 5 +++-- .../link/LinkControllerIntegrationTest.java | 10 +++++----- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/linkurlshorter/urlshortener/exception/GlobalExceptionHandler.java b/src/main/java/com/linkurlshorter/urlshortener/exception/GlobalExceptionHandler.java index 9f96b90..a97e194 100644 --- a/src/main/java/com/linkurlshorter/urlshortener/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/linkurlshorter/urlshortener/exception/GlobalExceptionHandler.java @@ -1,6 +1,7 @@ package com.linkurlshorter.urlshortener.exception; import com.linkurlshorter.urlshortener.auth.exception.EmailAlreadyTakenException; +import com.linkurlshorter.urlshortener.link.NoLinkFoundByIdException; import com.linkurlshorter.urlshortener.security.ForbiddenException; import com.linkurlshorter.urlshortener.user.NoSuchEmailFoundException; import com.linkurlshorter.urlshortener.user.NoUserFoundByEmailException; @@ -101,12 +102,6 @@ public ResponseEntity handleBadCredentialsException(BadCredentialsExcept * @param ex denied access error * @return {@link ResponseEntity} object with the corresponding status and error message */ - @ExceptionHandler(ForbiddenException.class) - public ResponseEntity handleForbiddenException(ForbiddenException ex) { - ErrorResponse errorResponse = buildErrorResponse(HttpStatus.FORBIDDEN, - "Forbidden!", ex.getMessage()); - return ResponseEntity.status(HttpStatus.FORBIDDEN).body(errorResponse); - } /** * Handles no resource (404) exceptions for different types of requests. @@ -152,21 +147,20 @@ private ErrorResponse buildErrorResponse(HttpStatus status, String message, Stri * Returns a response with a 403 status and the corresponding error message. * * @param ex forbidden exception - * @param request HttpServletRequest object representing the HTTP request * @return {@link ResponseEntity} object with the corresponding status and error message */ @ExceptionHandler(ForbiddenException.class) public ResponseEntity handleForbiddenException( - ForbiddenException ex, HttpServletRequest request) { - ErrorResponse errorResponse = buildErrorResponse(HttpStatus.FORBIDDEN, - ex.getMessage(), request.getRequestURI()); + ForbiddenException ex) { + ErrorResponse errorResponse = buildErrorResponse(HttpStatus.FORBIDDEN, "Operation forbidden!", + ex.getMessage()); return ResponseEntity.status(HttpStatus.FORBIDDEN).body(errorResponse); } @ExceptionHandler(NoLinkFoundByIdException.class) public ResponseEntity handleNoLinkFoundByIdException( - NoLinkFoundByIdException ex, HttpServletRequest request) { - ErrorResponse errorResponse = buildErrorResponse(HttpStatus.NOT_FOUND, - ex.getMessage(), request.getRequestURI()); + NoLinkFoundByIdException ex) { + ErrorResponse errorResponse = buildErrorResponse(HttpStatus.NOT_FOUND,"No link by provided id found", + ex.getMessage()); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); } } diff --git a/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerIntegrationTest.java b/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerIntegrationTest.java index af288c9..3b714fe 100644 --- a/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerIntegrationTest.java +++ b/src/test/java/com/linkurlshorter/urlshortener/auth/AuthControllerIntegrationTest.java @@ -77,7 +77,8 @@ void loginFailedWhenUserDoesNotExistTest() throws Exception { .content(objectMapper.writeValueAsString(authRequest))) .andExpect(status().is4xxClientError()) .andExpect(jsonPath("$.statusCode").value(401)) - .andExpect(jsonPath("$.message").value("Authentication failed!")) + .andExpect(jsonPath("$.message").value("Authentication failed!")); + } /** * Test case to verify login failure when password does not match. @@ -192,4 +193,4 @@ void registerFailedWhenInvalidEmailGivenTest(String email) throws Exception { .andExpect(jsonPath("$.statusCode").value(400)) .andExpect(jsonPath("$.message").value("Validation failed!")); } -} +} \ No newline at end of file diff --git a/src/test/java/com/linkurlshorter/urlshortener/link/LinkControllerIntegrationTest.java b/src/test/java/com/linkurlshorter/urlshortener/link/LinkControllerIntegrationTest.java index 9214ba5..545304b 100644 --- a/src/test/java/com/linkurlshorter/urlshortener/link/LinkControllerIntegrationTest.java +++ b/src/test/java/com/linkurlshorter/urlshortener/link/LinkControllerIntegrationTest.java @@ -96,8 +96,8 @@ void createShortLinkFailsWhenUrlIsInvalid(String url) throws Exception { .content(objectMapper.writeValueAsString(createLinkRequest))) .andExpect(status().is4xxClientError()) .andExpect(jsonPath("$.statusCode").value(400)) - .andExpect(jsonPath("$.message").value("Not valid format url!")) - .andExpect(jsonPath("$.path").value("/api/V1/link/create")); + .andExpect(jsonPath("$.message").value("Validation failed!")) + .andExpect(jsonPath("$.exceptionMessage").value("Not valid format url!")); } @Test @@ -118,14 +118,14 @@ void deleteLinkFailsWhenIdIsInvalid() throws Exception { .andExpect(status().is4xxClientError()) .andExpect(jsonPath("$.statusCode").value(404)) .andExpect(jsonPath("$.message").value("No link by provided id found")) - .andExpect(jsonPath("$.path").value("/api/V1/link/delete")); + .andExpect(jsonPath("$.exceptionMessage").value("No link by provided id found")); } @Test void deleteLinkFailsWhenIdIsNull() throws Exception { mockMvc.perform(post(baseUrl + "delete" + "?id=" + null) .contentType(MediaType.APPLICATION_JSON) .header("Authorization", token)) - .andExpect(status().is4xxClientError()); + .andExpect(status().isInternalServerError()); } @Test void deleteLinkFailsWhenUserHasNoRightsForThisLink() throws Exception { @@ -144,6 +144,6 @@ void deleteLinkFailsWhenUserHasNoRightsForThisLink() throws Exception { .andExpect(status().is4xxClientError()) .andExpect(jsonPath("$.statusCode").value(403)) .andExpect(jsonPath("$.message").value("Operation forbidden!")) - .andExpect(jsonPath("$.path").value("/api/V1/link/delete")); + .andExpect(jsonPath("$.exceptionMessage").value("Operation forbidden!")); } }