From 5475b9a0d9a669b121d0bc5b8c7963604232f6bc Mon Sep 17 00:00:00 2001 From: Rd4dev Date: Fri, 5 Jun 2026 19:14:09 +0530 Subject: [PATCH 1/5] Bad request handling of delete merchant When the merchant id is not present and given the id is a proper UUID, the default string to UUID is handled by the Spring itself --- .../com/mert/merchantservice/service/MerchantService.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java b/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java index 004c8e0..41935a7 100644 --- a/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java +++ b/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java @@ -74,6 +74,11 @@ public MerchantResponseDTO updateMerchant(UUID id, MerchantRequestDTO merchantRe } public void deleMerchant(UUID id) { - merchantRepository.deleteById(id); + Merchant merchant = merchantRepository.findById(id) + .orElseThrow(() -> + new MerchantNotFoundException( + "Merchant not found with ID: " + id + )); + merchantRepository.delete(merchant); } } From 40e9491011df6f68dd268e3e03bd7a251e939e1f Mon Sep 17 00:00:00 2001 From: Rd4dev Date: Fri, 5 Jun 2026 20:24:50 +0530 Subject: [PATCH 2/5] Phone number regex validation + error handling The phone number validation is just a regex for making sure it has 10 to 15 digits with no space after country code or inbetween. The error handlings are included for string to UUID inclusion errors where it doesn't accept non uuids on the merchant id and it is not evident on the response, same for the date format, though a regex is added it still doesn't verify the date within range. Few other fixes could be since registration date should be less than the current date, we should probably restrict any dates from today being provided. But for now let's leave to CodeRabbit and see what all suggestions it comes up with --- .../dto/MerchantRequestDTO.java | 14 +++++++++++++- .../exception/GlobalExceptionHandler.java | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/merchant-service/src/main/java/com/mert/merchantservice/dto/MerchantRequestDTO.java b/merchant-service/src/main/java/com/mert/merchantservice/dto/MerchantRequestDTO.java index 09da46e..256cf83 100644 --- a/merchant-service/src/main/java/com/mert/merchantservice/dto/MerchantRequestDTO.java +++ b/merchant-service/src/main/java/com/mert/merchantservice/dto/MerchantRequestDTO.java @@ -3,6 +3,7 @@ import com.mert.merchantservice.dto.validators.CreateMerchantValidationGroup; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; public class MerchantRequestDTO { @@ -17,13 +18,24 @@ public class MerchantRequestDTO { @Email(message = "Email should be valid") private String email; - @NotBlank(groups = CreateMerchantValidationGroup.class, message = "Registered date is required") + @NotBlank( + groups = CreateMerchantValidationGroup.class, + message = "Registered date is required" + ) + @Pattern( + regexp = "^\\d{4}-\\d{2}-\\d{2}$", + message = "Registered date must be in yyyy-MM-dd format" + ) private String registeredDate; @NotBlank(message = "Address is required") private String address; @NotBlank(message = "Phone Number is required") + @Pattern( + regexp = "^\\+?[0-9]{10,15}$", + message = "Phone number must contain 10 to 15 digits" + ) private String phoneNumber; public String getMerchantName() { diff --git a/merchant-service/src/main/java/com/mert/merchantservice/exception/GlobalExceptionHandler.java b/merchant-service/src/main/java/com/mert/merchantservice/exception/GlobalExceptionHandler.java index 340f04b..11c5043 100644 --- a/merchant-service/src/main/java/com/mert/merchantservice/exception/GlobalExceptionHandler.java +++ b/merchant-service/src/main/java/com/mert/merchantservice/exception/GlobalExceptionHandler.java @@ -6,7 +6,9 @@ import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; +import java.time.format.DateTimeParseException; import java.util.HashMap; import java.util.Map; @@ -15,6 +17,14 @@ public class GlobalExceptionHandler { private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public ResponseEntity> handleTypeMismatch(MethodArgumentTypeMismatchException ex) { + Map response = new HashMap<>(); + response.put("message", "Invalid merchant ID format. Expected UUID"); + + return ResponseEntity.badRequest().body(response); + } + @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity> handleValidationException(MethodArgumentNotValidException exception) { Map errors = new HashMap<>(); @@ -24,6 +34,14 @@ public ResponseEntity> handleValidationException(MethodArgum return ResponseEntity.badRequest().body(errors); } + @ExceptionHandler(DateTimeParseException.class) + public ResponseEntity> handleDateTimeParseException(DateTimeParseException ex) { + Map error = new HashMap<>(); + error.put("registeredDate", "Invalid date. Use a valid date in YYYY-MM-DD format"); + + return ResponseEntity.badRequest().body(error); + } + @ExceptionHandler(EmailAlreadyExistsException.class) public ResponseEntity> handleEmailAlreadyExistsException(EmailAlreadyExistsException exception) { log.warn("Email address already exists {}", exception.getMessage()); From 2fff38ad107894edd451fab95705e49223c8f967 Mon Sep 17 00:00:00 2001 From: Rd4dev Date: Tue, 9 Jun 2026 20:21:18 +0530 Subject: [PATCH 3/5] Trial coderabbit review 2 --- .../java/com/mert/merchantservice/service/MerchantService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java b/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java index 41935a7..11d5102 100644 --- a/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java +++ b/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java @@ -74,6 +74,7 @@ public MerchantResponseDTO updateMerchant(UUID id, MerchantRequestDTO merchantRe } public void deleMerchant(UUID id) { + if(id != null) throw new RuntimeException(); Merchant merchant = merchantRepository.findById(id) .orElseThrow(() -> new MerchantNotFoundException( From d2903c0e1e434e5bf144386d1fbe7dd89a879842 Mon Sep 17 00:00:00 2001 From: Rd4dev Date: Tue, 9 Jun 2026 21:07:44 +0530 Subject: [PATCH 4/5] Added tests for the service layer These are sample tests again to see what else coderabbit suggests and this for now includes tests only related to parts of changes made in this PR --- .../controller/MerchantController.java | 2 +- .../service/MerchantService.java | 2 +- .../service/MerchantServiceTest.java | 49 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 merchant-service/src/test/java/com/mert/merchantservice/service/MerchantServiceTest.java diff --git a/merchant-service/src/main/java/com/mert/merchantservice/controller/MerchantController.java b/merchant-service/src/main/java/com/mert/merchantservice/controller/MerchantController.java index eb4d038..dba3458 100644 --- a/merchant-service/src/main/java/com/mert/merchantservice/controller/MerchantController.java +++ b/merchant-service/src/main/java/com/mert/merchantservice/controller/MerchantController.java @@ -48,7 +48,7 @@ public ResponseEntity updateMerchant(@PathVariable UUID id, @DeleteMapping("/{id}") @Operation(summary = "Delete a Merchant") public ResponseEntity deleteMerchant(@PathVariable UUID id) { - merchantService.deleMerchant(id); + merchantService.deleteMerchant(id); return ResponseEntity.noContent().build(); } } diff --git a/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java b/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java index 11d5102..995f058 100644 --- a/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java +++ b/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java @@ -73,7 +73,7 @@ public MerchantResponseDTO updateMerchant(UUID id, MerchantRequestDTO merchantRe return MerchantMapper.toMerchantResponseDTO(updatedMerchant); } - public void deleMerchant(UUID id) { + public void deleteMerchant(UUID id) { if(id != null) throw new RuntimeException(); Merchant merchant = merchantRepository.findById(id) .orElseThrow(() -> diff --git a/merchant-service/src/test/java/com/mert/merchantservice/service/MerchantServiceTest.java b/merchant-service/src/test/java/com/mert/merchantservice/service/MerchantServiceTest.java new file mode 100644 index 0000000..8a81d2a --- /dev/null +++ b/merchant-service/src/test/java/com/mert/merchantservice/service/MerchantServiceTest.java @@ -0,0 +1,49 @@ +package com.mert.merchantservice.service; + +import com.mert.merchantservice.exception.MerchantNotFoundException; +import com.mert.merchantservice.model.Merchant; +import com.mert.merchantservice.repository.MerchantRepository; +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 java.util.Optional; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class MerchantServiceTest { + @Mock + private MerchantRepository merchantRepository; + + @InjectMocks + private MerchantService merchantService; + + @Test + void testMerchantService_validIdProvided_shouldDeleteMerchant() { + UUID id = UUID.randomUUID(); + + Merchant merchant = new Merchant(); + merchant.setId(id); + + when(merchantRepository.findById(id)).thenReturn(Optional.of(merchant)); + merchantService.deleteMerchant(id); + verify(merchantRepository).delete(merchant); + } + + @Test + void testMerchantService_invalidIdProvided_shouldThrowMerchantNotFoundException() { + UUID id = UUID.randomUUID(); + + when(merchantRepository.findById(id)).thenReturn(Optional.empty()); + assertThrows( + MerchantNotFoundException.class, + () -> merchantService.deleteMerchant(id) + ); + verify(merchantRepository, never()).delete(any()); + } +} From cea86419c2388ef84d6cd43bbd57bc86c6b99f2b Mon Sep 17 00:00:00 2001 From: Rd4dev Date: Tue, 9 Jun 2026 21:49:36 +0530 Subject: [PATCH 5/5] Spot right by CR The coderabbit rightly identified this but suggested a fix for this rather its just a sanity check so removing it and leaving the test case as well without any additional deps included that are not part of the PR --- .../java/com/mert/merchantservice/service/MerchantService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java b/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java index 995f058..39f66b0 100644 --- a/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java +++ b/merchant-service/src/main/java/com/mert/merchantservice/service/MerchantService.java @@ -74,7 +74,6 @@ public MerchantResponseDTO updateMerchant(UUID id, MerchantRequestDTO merchantRe } public void deleteMerchant(UUID id) { - if(id != null) throw new RuntimeException(); Merchant merchant = merchantRepository.findById(id) .orElseThrow(() -> new MerchantNotFoundException(