diff --git a/checkstyle.xml b/checkstyle.xml
index 9a6a928..416ea7e 100644
--- a/checkstyle.xml
+++ b/checkstyle.xml
@@ -26,6 +26,6 @@
-
+
diff --git a/payment-service-app/pom.xml b/payment-service-app/pom.xml
index 09edf3d..3d57ea1 100644
--- a/payment-service-app/pom.xml
+++ b/payment-service-app/pom.xml
@@ -17,6 +17,13 @@
21
+ 3.0.0
+ 1.18.36
+ 1.6.3
+ 1.6.3
+ 3.14.0
+ 3.3.0
+ 4.32.0
@@ -34,28 +41,27 @@
org.springdoc
springdoc-openapi-starter-webmvc-ui
- 3.0.0
+ ${springdoc.version}
org.postgresql
postgresql
-
org.mapstruct
mapstruct
- 1.6.3
+ ${mapstruct.version}
org.mapstruct
mapstruct-processor
- 1.6.3
+ ${mapstruct-processor.version}
provided
org.projectlombok
lombok
- 1.18.36
+ ${lombok.version}
com.h2database
@@ -86,20 +92,18 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.14.0
+ ${maven-compiler-plugin.version}
- 21
- 21
org.projectlombok
lombok
- 1.18.36
+ ${lombok.version}
org.mapstruct
mapstruct-processor
- 1.6.3
+ ${mapstruct-processor.version}
@@ -107,7 +111,7 @@
org.apache.maven.plugins
maven-checkstyle-plugin
- 3.3.0
+ ${maven-checkstyle-plugin.version}
verify
@@ -125,7 +129,7 @@
org.liquibase
liquibase-maven-plugin
- 4.32.0
+ ${liquibase-maven-plugin.version}
src/main/resources/liquibase.properties
src/main/resources/liquibase-outputChangeLog.xml
diff --git a/payment-service-app/src/main/java/com/iprody/controller/PaymentController.java b/payment-service-app/src/main/java/com/iprody/controller/PaymentController.java
index b029e4b..6d673f1 100644
--- a/payment-service-app/src/main/java/com/iprody/controller/PaymentController.java
+++ b/payment-service-app/src/main/java/com/iprody/controller/PaymentController.java
@@ -3,34 +3,28 @@
import com.iprody.model.PaymentDto;
import com.iprody.service.PaymentService;
import com.iprody.specification.PaymentFilter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
+import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
+import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
+import java.net.URI;
import java.util.List;
import java.util.UUID;
@RestController
+@RequiredArgsConstructor
@RequestMapping("/payments")
public class PaymentController {
private final PaymentService paymentService;
- /**
- * Use either "withMapper" or "withConverter"
- * @param paymentService
- */
- @Autowired
- public PaymentController(@Qualifier("withMapper") PaymentService paymentService) {
- this.paymentService = paymentService;
- }
-
@GetMapping("/search")
public Page searchPayments(
@ModelAttribute PaymentFilter filter,
@@ -49,17 +43,38 @@ public Page searchPayments(
@GetMapping
public ResponseEntity> fetchAll() {
- return ResponseEntity.ok().body(this.paymentService.fetchAllPayments());
+ return ResponseEntity.ok().body(this.paymentService.getPayments());
+ }
+
+ @PostMapping(path = "/add")
+ public ResponseEntity addPayment(@RequestBody PaymentDto paymentDto) {
+ final PaymentDto savedPayment = this.paymentService.create(paymentDto);
+ final URI location = ServletUriComponentsBuilder.fromCurrentRequest()
+ .path("/{id}")
+ .buildAndExpand(savedPayment.getGuid())
+ .toUri();
+ return ResponseEntity.created(location).body(savedPayment);
}
@GetMapping(path = "/{id}")
- public ResponseEntity fetchPayment(@PathVariable UUID id) {
- return ResponseEntity.ok().body(this.paymentService.fetchSinglePayment(id));
+ public ResponseEntity getPayment(@PathVariable UUID id) {
+ return ResponseEntity.ok().body(this.paymentService.get(id));
}
- @PostMapping(path = "/addPayment")
- public ResponseEntity addPayment(@RequestBody PaymentDto paymentDto) {
- return ResponseEntity.ok().body(this.paymentService.processPayment(paymentDto));
+ @PutMapping(path = "/update/{id}")
+ public ResponseEntity updatePayment(@PathVariable UUID id, @RequestBody PaymentDto paymentDto) {
+ return ResponseEntity.ok().body(this.paymentService.update(id, paymentDto));
+ }
+
+ @PutMapping(path = "/update/{id}/{note}")
+ public ResponseEntity updatePaymentNote(@PathVariable UUID id, @PathVariable String note) {
+ return ResponseEntity.ok().body(this.paymentService.updateNote(id, note));
+ }
+
+ @DeleteMapping(path = "/delete/{id}")
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ public void deletePayment(@PathVariable UUID id) {
+ this.paymentService.delete(id);
}
}
diff --git a/payment-service-app/src/main/java/com/iprody/exception/EntityNotFoundException.java b/payment-service-app/src/main/java/com/iprody/exception/EntityNotFoundException.java
new file mode 100644
index 0000000..a2f1ce1
--- /dev/null
+++ b/payment-service-app/src/main/java/com/iprody/exception/EntityNotFoundException.java
@@ -0,0 +1,22 @@
+package com.iprody.exception;
+
+import lombok.Getter;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+import java.util.UUID;
+
+@Getter
+@ResponseStatus(HttpStatus.NOT_FOUND)
+public class EntityNotFoundException extends RuntimeException {
+
+ private final String operation;
+ private final UUID entityId;
+
+ public EntityNotFoundException(String message, String operation, UUID entityId) {
+ super(message);
+ this.operation = operation;
+ this.entityId = entityId;
+ }
+
+}
diff --git a/payment-service-app/src/main/java/com/iprody/exception/ErrorResponse.java b/payment-service-app/src/main/java/com/iprody/exception/ErrorResponse.java
new file mode 100644
index 0000000..c6b7323
--- /dev/null
+++ b/payment-service-app/src/main/java/com/iprody/exception/ErrorResponse.java
@@ -0,0 +1,23 @@
+package com.iprody.exception;
+
+import lombok.Getter;
+
+import java.time.Instant;
+import java.util.UUID;
+
+@Getter
+public class ErrorResponse {
+
+ private final String error;
+ private final Instant timestamp;
+ private final String operation;
+ private final UUID entityId;
+
+ public ErrorResponse(String error, String operation, UUID entityId) {
+ this.error = error;
+ this.timestamp = Instant.now();
+ this.operation = operation;
+ this.entityId = entityId;
+ }
+
+}
\ No newline at end of file
diff --git a/payment-service-app/src/main/java/com/iprody/exception/GlobalExceptionHandler.java b/payment-service-app/src/main/java/com/iprody/exception/GlobalExceptionHandler.java
index 177c167..3b56215 100644
--- a/payment-service-app/src/main/java/com/iprody/exception/GlobalExceptionHandler.java
+++ b/payment-service-app/src/main/java/com/iprody/exception/GlobalExceptionHandler.java
@@ -1,10 +1,13 @@
package com.iprody.exception;
+import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
-@ControllerAdvice
+
+@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(AppException.class)
@@ -14,4 +17,16 @@ public ResponseEntity handleAppException(AppException ex) {
.body(ex.getMessage());
}
+ @ExceptionHandler(EntityNotFoundException.class)
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ public ErrorResponse handleNotFound(EntityNotFoundException ex) {
+ return new ErrorResponse(ex.getMessage(), ex.getOperation(), ex.getEntityId());
+ }
+
+ @ExceptionHandler(Exception.class)
+ @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+ public ErrorResponse handleOther(Exception ex) {
+ return new ErrorResponse(ex.getMessage(), null, null);
+ }
+
}
diff --git a/payment-service-app/src/main/java/com/iprody/service/PaymentService.java b/payment-service-app/src/main/java/com/iprody/service/PaymentService.java
index bc52b6b..282000d 100644
--- a/payment-service-app/src/main/java/com/iprody/service/PaymentService.java
+++ b/payment-service-app/src/main/java/com/iprody/service/PaymentService.java
@@ -9,9 +9,12 @@
import java.util.UUID;
public interface PaymentService {
- List fetchAllPayments();
- PaymentDto fetchSinglePayment(UUID id);
- PaymentDto processPayment(PaymentDto paymentDto);
+ PaymentDto create(PaymentDto paymentDto);
+ PaymentDto get(UUID id);
List search(PaymentFilter filter);
Page searchPaged(PaymentFilter filter, Pageable pageable);
+ List getPayments();
+ PaymentDto update(UUID id, PaymentDto dto);
+ PaymentDto updateNote(UUID id, String updatedNote);
+ void delete(UUID id);
}
diff --git a/payment-service-app/src/main/java/com/iprody/service/PaymentServiceImpl_withMapper.java b/payment-service-app/src/main/java/com/iprody/service/PaymentServiceImpl.java
similarity index 54%
rename from payment-service-app/src/main/java/com/iprody/service/PaymentServiceImpl_withMapper.java
rename to payment-service-app/src/main/java/com/iprody/service/PaymentServiceImpl.java
index cb557dc..10c27e3 100644
--- a/payment-service-app/src/main/java/com/iprody/service/PaymentServiceImpl_withMapper.java
+++ b/payment-service-app/src/main/java/com/iprody/service/PaymentServiceImpl.java
@@ -1,6 +1,7 @@
package com.iprody.service;
import com.iprody.exception.AppException;
+import com.iprody.exception.EntityNotFoundException;
import com.iprody.mapper.PaymentMapper;
import com.iprody.model.PaymentDto;
import com.iprody.persistence.PaymentEntity;
@@ -14,13 +15,14 @@
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
+import java.time.OffsetDateTime;
import java.util.List;
import java.util.UUID;
-@Service("withMapper")
+@Service
@RequiredArgsConstructor
-public class PaymentServiceImpl_withMapper implements PaymentService {
+public class PaymentServiceImpl implements PaymentService {
private final PaymentMapper paymentMapper;
private final PaymentRepository paymentRepository;
@@ -43,22 +45,22 @@ public Page searchPaged(PaymentFilter filter, Pageable pageable) {
}
@Override
- public List fetchAllPayments() {
- return paymentRepository.findAll().stream()
+ public List getPayments() {
+ return paymentRepository
+ .findAll().stream()
.map(paymentMapper::toPaymentDto)
.toList();
}
@Override
- public PaymentDto fetchSinglePayment(UUID id) {
+ public PaymentDto get(UUID id) {
return paymentRepository.findById(id)
.map(paymentMapper::toPaymentDto)
- .orElseThrow(() -> new AppException(
- HttpStatus.NOT_FOUND.value(), "Payment with the id '" + id + "' was not found"));
+ .orElseThrow(() -> new EntityNotFoundException("Платеж не найден", "get", id));
}
@Override
- public PaymentDto processPayment(PaymentDto paymentDto) {
+ public PaymentDto create(PaymentDto paymentDto) {
if (paymentDto.getAmount().doubleValue() <= 0) {
throw new AppException(HttpStatus.BAD_REQUEST.value(), "Payment is not valid");
}
@@ -66,4 +68,34 @@ public PaymentDto processPayment(PaymentDto paymentDto) {
return paymentMapper.toPaymentDto(paymentRepository.save(paymentEntity));
}
+ @Override
+ public PaymentDto update(UUID id, PaymentDto dto) {
+ paymentRepository.findById(id)
+ .orElseThrow(() -> new EntityNotFoundException("Платеж не найден", "update", id));
+ final PaymentEntity updated = paymentMapper.toPaymentEntity(dto);
+ updated.setGuid(id);
+ return paymentMapper.toPaymentDto(paymentRepository.save(updated));
+ }
+
+ @Override
+ public PaymentDto updateNote(UUID id, String updatedNote) {
+ return paymentRepository.findById(id)
+ .map(p -> {
+ p.setNote(updatedNote);
+ p.setUpdatedAt(OffsetDateTime.now());
+ return paymentMapper.toPaymentDto(paymentRepository.save(p));
+ })
+ .orElseThrow(() -> new EntityNotFoundException("Платеж не найден", "updateNote", id));
+ }
+
+ @Override
+ public void delete(UUID id) {
+ paymentRepository.findById(id)
+ .map(p -> {
+ paymentRepository.delete(p);
+ return id;
+ })
+ .orElseThrow(() -> new EntityNotFoundException("Платеж не найден", "delete", id));
+ }
+
}
diff --git a/payment-service-app/src/main/java/com/iprody/service/PaymentServiceImpl_withConverter.java b/payment-service-app/src/main/java/com/iprody/service/PaymentServiceImpl_withConverter.java
deleted file mode 100644
index 2593af8..0000000
--- a/payment-service-app/src/main/java/com/iprody/service/PaymentServiceImpl_withConverter.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.iprody.service;
-
-import com.iprody.converter.PaymentConverter;
-import com.iprody.exception.AppException;
-import com.iprody.model.PaymentDto;
-import com.iprody.persistence.PaymentEntity;
-import com.iprody.persistence.PaymentRepository;
-import com.iprody.specification.PaymentFilter;
-import com.iprody.specification.PaymentFilterFactory;
-import lombok.RequiredArgsConstructor;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.http.HttpStatus;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.UUID;
-
-
-@Service("withConverter")
-@RequiredArgsConstructor
-public class PaymentServiceImpl_withConverter implements PaymentService {
-
- private final PaymentConverter paymentConverter;
- private final PaymentRepository paymentRepository;
-
- @Override
- public List search(PaymentFilter filter) {
- final Specification spec = PaymentFilterFactory.fromFilter(filter);
- return paymentRepository
- .findAll(spec).stream()
- .map(paymentConverter::toPaymentDto)
- .toList();
- }
-
- @Override
- public Page searchPaged(PaymentFilter filter, Pageable pageable) {
- final Specification spec = PaymentFilterFactory.fromFilter(filter);
- return paymentRepository
- .findAll(spec, pageable)
- .map(paymentConverter::toPaymentDto);
- }
-
- @Override
- public List fetchAllPayments() {
- return paymentRepository.findAll().stream()
- .map(paymentConverter::toPaymentDto)
- .toList();
- }
-
- @Override
- public PaymentDto fetchSinglePayment(UUID id) {
- return paymentRepository.findById(id)
- .map(paymentConverter::toPaymentDto)
- .orElseThrow(() -> new AppException(
- HttpStatus.NOT_FOUND.value(), "Payment with the id '" + id + "' was not found"));
- }
-
- @Override
- public PaymentDto processPayment(PaymentDto paymentDto) {
- if (paymentDto.getAmount().doubleValue() <= 0) {
- throw new AppException(HttpStatus.BAD_REQUEST.value(), "Payment is not valid");
- }
- final var paymentEntity = paymentConverter.toPaymentEntity(paymentDto);
- return paymentConverter.toPaymentDto(paymentRepository.save(paymentEntity));
- }
-
-}
diff --git a/payment-service-app/src/main/resources/curl/add.json b/payment-service-app/src/main/resources/curl/add.json
new file mode 100644
index 0000000..824a1b7
--- /dev/null
+++ b/payment-service-app/src/main/resources/curl/add.json
@@ -0,0 +1,11 @@
+{
+ "guid": "01deac78-8673-4062-bc33-bdec273b553b",
+ "inquiryRefId": "01deac78-8673-4062-bc33-bdec273b553b",
+ "amount": "123",
+ "currency": "RUB",
+ "transactionRefId": "01deac78-8673-4062-bc33-bdec273b553b",
+ "status": "RECEIVED",
+ "note": "remark",
+ "createdAt": "2025-12-20T10:07:21.841Z",
+ "updatedAt": "2025-12-20T10:07:21.841Z"
+}
diff --git a/payment-service-app/src/main/resources/curl/endpoint_requests b/payment-service-app/src/main/resources/curl/endpoint_requests
new file mode 100644
index 0000000..b95e4d1
--- /dev/null
+++ b/payment-service-app/src/main/resources/curl/endpoint_requests
@@ -0,0 +1,15 @@
+/* Get all payments */
+curl http://localhost:8099/payments
+
+/* Get payment by id */
+curl -v http://localhost:8099/payments/ac328a1a-1e60-4dd3-bee5-ed573d74c841
+
+/* Add new payment */
+curl -v -H "Content-Type: application/json" -X POST --data @add.json http://localhost:8099/payments/add
+
+/* Update payment */
+curl -v -H "Content-Type: application/json" -X PUT --data @put.json \
+ http://localhost:8099/payments/update/ac328a1a-1e60-4dd3-bee5-ed573d74c841
+
+/* Delete payment */
+curl -v -X DELETE http://localhost:8099/payments/delete/ac328a1a-1e60-4dd3-bee5-ed573d74c841
diff --git a/payment-service-app/src/main/resources/curl/put.json b/payment-service-app/src/main/resources/curl/put.json
new file mode 100644
index 0000000..96e719b
--- /dev/null
+++ b/payment-service-app/src/main/resources/curl/put.json
@@ -0,0 +1,11 @@
+{
+ "guid": "01deac78-8673-4062-bc33-bdec273b553b",
+ "inquiryRefId": "01deac78-8673-4062-bc33-bdec273b553b",
+ "amount": "345",
+ "currency": "EUR",
+ "transactionRefId": "01deac78-8673-4062-bc33-bdec273b553b",
+ "status": "RECEIVED",
+ "note": "updated",
+ "createdAt": "2025-12-20T10:07:21.841Z",
+ "updatedAt": "2025-12-20T11:07:00.000Z"
+}
\ No newline at end of file
diff --git a/payment-service-app/src/test/java/com/iprody/service/PaymentControllerTest.java b/payment-service-app/src/test/java/com/iprody/service/PaymentControllerTest.java
index 3654e08..7b8c323 100644
--- a/payment-service-app/src/test/java/com/iprody/service/PaymentControllerTest.java
+++ b/payment-service-app/src/test/java/com/iprody/service/PaymentControllerTest.java
@@ -45,11 +45,37 @@ void setUp() {
initData();
}
+ private void initData() {
+ LocalDateTime now = LocalDateTime.now();
+ dto_1 = new PaymentDto(
+ UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa6"),
+ UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa7"),
+ BigDecimal.valueOf(100.89),
+ "EUR",
+ UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa8"),
+ PaymentStatus.RECEIVED,
+ "Some info 1",
+ OffsetDateTime.of(now, ZoneOffset.UTC),
+ OffsetDateTime.of(now, ZoneOffset.UTC)
+ );
+ dto_2 = new PaymentDto(
+ UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afb6"),
+ UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afb7"),
+ BigDecimal.valueOf(200.51),
+ "USD",
+ UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afb8"),
+ PaymentStatus.APPROVED,
+ "Some info 2",
+ OffsetDateTime.of(now, ZoneOffset.UTC),
+ OffsetDateTime.of(now, ZoneOffset.UTC)
+ );
+ }
+
@Test
@DisplayName("GET /payments should return list of two PaymentDto")
void findAll_ReturnsListOfTwoPayments() throws Exception {
// when
- when(paymentService.fetchAllPayments()).thenReturn(List.of(dto_1, dto_2));
+ when(paymentService.getPayments()).thenReturn(List.of(dto_1, dto_2));
// then
mockMvc.perform(get("/payments").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
@@ -67,7 +93,7 @@ void findAll_ReturnsListOfTwoPayments() throws Exception {
@DisplayName("GET /payments should return empty list when there is no payments")
void findAll_ReturnsEmptyList() throws Exception {
// when
- when(paymentService.fetchAllPayments()).thenReturn(List.of());
+ when(paymentService.getPayments()).thenReturn(List.of());
// then
mockMvc.perform(get("/payments")
.accept(MediaType.APPLICATION_JSON))
@@ -81,42 +107,15 @@ void findAll_ReturnsEmptyList() throws Exception {
void getById_ReturnsPayment_WhenFound() throws Exception {
// given
UUID id = dto_1.getGuid();
- String expectedUuid = "3fa85f64-5717-4562-b3fc-2c963f66afa6";
// when
- when(paymentService.fetchSinglePayment(id)).thenReturn(dto_1);
+ when(paymentService.get(id)).thenReturn(dto_1);
// then
mockMvc.perform(get("/payments/{id}", id).accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
- //.andExpect(jsonPath("$.guid").value(UUID.fromString(expectedUuid)))
+ .andExpect(jsonPath("$.guid").value("3fa85f64-5717-4562-b3fc-2c963f66afa6"))
.andExpect(jsonPath("$.amount").value(100.89))
.andExpect(jsonPath("$.note").value("Some info 1"));
}
- private void initData() {
- LocalDateTime now = LocalDateTime.now();
- dto_1 = new PaymentDto(
- UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa6"),
- UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa7"),
- BigDecimal.valueOf(100.89),
- "EUR",
- UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa8"),
- PaymentStatus.RECEIVED,
- "Some info 1",
- OffsetDateTime.of(now, ZoneOffset.UTC),
- OffsetDateTime.of(now, ZoneOffset.UTC)
- );
- dto_2 = new PaymentDto(
- UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afb6"),
- UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afb7"),
- BigDecimal.valueOf(200.51),
- "USD",
- UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afb8"),
- PaymentStatus.APPROVED,
- "Some info 2",
- OffsetDateTime.of(now, ZoneOffset.UTC),
- OffsetDateTime.of(now, ZoneOffset.UTC)
- );
- }
-
}
diff --git a/payment-service-app/src/test/java/com/iprody/service/PaymentServiceTest.java b/payment-service-app/src/test/java/com/iprody/service/PaymentServiceTest.java
index 5eafac4..894b430 100644
--- a/payment-service-app/src/test/java/com/iprody/service/PaymentServiceTest.java
+++ b/payment-service-app/src/test/java/com/iprody/service/PaymentServiceTest.java
@@ -1,7 +1,7 @@
package com.iprody.service;
-import com.iprody.converter.PaymentConverter;
-import com.iprody.exception.AppException;
+import com.iprody.exception.EntityNotFoundException;
+import com.iprody.mapper.PaymentMapper;
import com.iprody.model.PaymentDto;
import com.iprody.persistence.PaymentEntity;
import com.iprody.persistence.PaymentRepository;
@@ -34,13 +34,13 @@
class PaymentServiceTest {
@InjectMocks
- private PaymentServiceImpl_withConverter paymentService;
+ private PaymentServiceImpl paymentService;
@Mock
private PaymentRepository paymentRepository;
@Mock
- private PaymentConverter paymentConverter;
+ private PaymentMapper paymentMapper;
private PaymentEntity paymentEntity1;
private PaymentEntity paymentEntity2;
@@ -106,15 +106,15 @@ void setUp() {
}
@Test
- @DisplayName("fetchAllPayments should return list of payments when payments exist")
- void fetchAllPayments_shouldReturnListOfPayments_whenPaymentsExist() {
+ @DisplayName("getPayments should return list of payments when payments exist")
+ void getPayments_shouldReturnListOfPayments_whenPaymentsExist() {
// Given
List entities = Arrays.asList(paymentEntity1, paymentEntity2);
when(paymentRepository.findAll()).thenReturn(entities);
- when(paymentConverter.toPaymentDto(paymentEntity1)).thenReturn(paymentDto1);
- when(paymentConverter.toPaymentDto(paymentEntity2)).thenReturn(paymentDto2);
+ when(paymentMapper.toPaymentDto(paymentEntity1)).thenReturn(paymentDto1);
+ when(paymentMapper.toPaymentDto(paymentEntity2)).thenReturn(paymentDto2);
// When
- List result = paymentService.fetchAllPayments();
+ List result = paymentService.getPayments();
// Then
assertNotNull(result);
assertEquals(2, result.size());
@@ -126,47 +126,32 @@ void fetchAllPayments_shouldReturnListOfPayments_whenPaymentsExist() {
assertEquals("EUR", result.get(1).getCurrency());
verify(paymentRepository, times(1)).findAll();
- verify(paymentConverter, times(2)).toPaymentDto(any(PaymentEntity.class));
+ verify(paymentMapper, times(2)).toPaymentDto(any(PaymentEntity.class));
}
@Test
- @DisplayName("fetchAllPayments should return empty list when no payments exist")
- void fetchAllPayments_shouldReturnEmptyList_whenNoPaymentsExist() {
+ @DisplayName("getPayments should return empty list when no payments exist")
+ void getPayments_shouldReturnEmptyList_whenNoPaymentsExist() {
// Given
when(paymentRepository.findAll()).thenReturn(Collections.emptyList());
// When
- List result = paymentService.fetchAllPayments();
+ List result = paymentService.getPayments();
// Then
assertNotNull(result);
assertTrue(result.isEmpty());
verify(paymentRepository, times(1)).findAll();
- verify(paymentConverter, never()).toPaymentDto(any(PaymentEntity.class));
+ verify(paymentMapper, never()).toPaymentDto(any(PaymentEntity.class));
}
@Test
- @DisplayName("fetchAllPayments should handle multiple payments correctly")
- void fetchAllPayments_shouldHandleMultiplePayments() {
- // Given
- List entities = Arrays.asList(paymentEntity1, paymentEntity2);
- when(paymentRepository.findAll()).thenReturn(entities);
- when(paymentConverter.toPaymentDto(any(PaymentEntity.class)))
- .thenReturn(paymentDto1, paymentDto2);
- // When
- List result = paymentService.fetchAllPayments();
- // Then
- assertEquals(2, result.size());
- verify(paymentConverter, times(2)).toPaymentDto(any(PaymentEntity.class));
- }
-
- @Test
- @DisplayName("fetchSinglePayment should return payment when payment exists")
- void fetchSinglePayment_shouldReturnPayment_whenPaymentExists() {
+ @DisplayName("getPayment should return payment when payment exists")
+ void getPayment_shouldReturnPayment_whenExists() {
// Given
when(paymentRepository.findById(testUuid1)).thenReturn(Optional.of(paymentEntity1));
- when(paymentConverter.toPaymentDto(paymentEntity1)).thenReturn(paymentDto1);
+ when(paymentMapper.toPaymentDto(paymentEntity1)).thenReturn(paymentDto1);
// When
- PaymentDto result = paymentService.fetchSinglePayment(testUuid1);
+ PaymentDto result = paymentService.get(testUuid1);
// Then
assertNotNull(result);
assertEquals(testUuid1, result.getGuid());
@@ -176,54 +161,25 @@ void fetchSinglePayment_shouldReturnPayment_whenPaymentExists() {
assertEquals("Test payment 1", result.getNote());
verify(paymentRepository, times(1)).findById(testUuid1);
- verify(paymentConverter, times(1)).toPaymentDto(paymentEntity1);
+ verify(paymentMapper, times(1)).toPaymentDto(paymentEntity1);
}
@Test
- @DisplayName("fetchSinglePayment should throw NoSuchPaymentException when payment does not exist")
- void fetchSinglePayment_shouldThrowException_whenPaymentDoesNotExist() {
+ @DisplayName("getPayment should throw NoSuchPaymentException when payment does not exist")
+ void getPayment_shouldThrowException_whenDoesNotExist() {
// Given
UUID nonExistentId = UUID.randomUUID();
when(paymentRepository.findById(nonExistentId)).thenReturn(Optional.empty());
// When
- assertThrows(AppException.class, () -> paymentService.fetchSinglePayment(nonExistentId));
+ assertThrows(EntityNotFoundException.class, () -> paymentService.get(nonExistentId));
// Then
verify(paymentRepository, times(1)).findById(nonExistentId);
- verify(paymentConverter, never()).toPaymentDto(any(PaymentEntity.class));
- }
-
- @Test
- @DisplayName("fetchSinglePayment should handle different payment statuses")
- void fetchSinglePayment_shouldHandleDifferentStatuses() {
- // Given
- PaymentEntity pendingEntity = PaymentEntity.builder()
- .guid(testUuid1)
- .inquiryRefId(UUID.randomUUID())
- .amount(new BigDecimal("100.00"))
- .currency("USD")
- .status(PaymentStatus.PENDING)
- .createdAt(OffsetDateTime.now())
- .updatedAt(OffsetDateTime.now())
- .build();
-
- PaymentDto pendingDto = PaymentDto.builder()
- .guid(testUuid1)
- .status(PaymentStatus.PENDING)
- .build();
-
- when(paymentRepository.findById(testUuid1)).thenReturn(Optional.of(pendingEntity));
- when(paymentConverter.toPaymentDto(pendingEntity)).thenReturn(pendingDto);
-
- // When
- PaymentDto result = paymentService.fetchSinglePayment(testUuid1);
-
- // Then
- assertEquals(PaymentStatus.PENDING, result.getStatus());
+ verify(paymentMapper, never()).toPaymentDto(any(PaymentEntity.class));
}
@Test
- @DisplayName("processPayment should save and return payment")
- void processPayment_shouldSaveAndReturnPayment() {
+ @DisplayName("create should save and return payment")
+ void createPayment_shouldSaveAndReturnPayment() {
// Given
UUID newUuid = UUID.randomUUID();
PaymentDto inputDto = PaymentDto.builder()
@@ -266,12 +222,12 @@ void processPayment_shouldSaveAndReturnPayment() {
.updatedAt(savedEntity.getUpdatedAt())
.build();
- when(paymentConverter.toPaymentEntity(inputDto)).thenReturn(entityToSave);
+ when(paymentMapper.toPaymentEntity(inputDto)).thenReturn(entityToSave);
when(paymentRepository.save(entityToSave)).thenReturn(savedEntity);
- when(paymentConverter.toPaymentDto(savedEntity)).thenReturn(expectedDto);
+ when(paymentMapper.toPaymentDto(savedEntity)).thenReturn(expectedDto);
// When
- PaymentDto result = paymentService.processPayment(inputDto);
+ PaymentDto result = paymentService.create(inputDto);
// Then
assertNotNull(result);
@@ -280,118 +236,42 @@ void processPayment_shouldSaveAndReturnPayment() {
assertEquals("GBP", result.getCurrency());
assertEquals(PaymentStatus.RECEIVED, result.getStatus());
- verify(paymentConverter, times(1)).toPaymentEntity(inputDto);
+ verify(paymentMapper, times(1)).toPaymentEntity(inputDto);
verify(paymentRepository, times(1)).save(entityToSave);
- verify(paymentConverter, times(1)).toPaymentDto(savedEntity);
+ verify(paymentMapper, times(1)).toPaymentDto(savedEntity);
}
- @Test
- @DisplayName("processPayment should handle payment with all fields populated")
- void processPayment_shouldHandleCompletePayment() {
- // Given
- UUID guid = UUID.randomUUID();
- UUID inquiryRefId = UUID.randomUUID();
- UUID transactionRefId = UUID.randomUUID();
- OffsetDateTime now = OffsetDateTime.now();
-
- PaymentDto inputDto = PaymentDto.builder()
- .guid(guid)
- .inquiryRefId(inquiryRefId)
- .amount(new BigDecimal("500.50"))
- .currency("USD")
- .transactionRefId(transactionRefId)
- .status(PaymentStatus.APPROVED)
- .note("Complete payment with all fields")
- .createdAt(now)
- .updatedAt(now)
- .build();
-
- PaymentEntity entityToSave = PaymentEntity.builder()
- .guid(guid)
- .inquiryRefId(inquiryRefId)
- .amount(new BigDecimal("500.50"))
- .currency("USD")
- .transactionRefId(transactionRefId)
- .status(PaymentStatus.APPROVED)
- .note("Complete payment with all fields")
- .createdAt(now)
- .updatedAt(now)
- .build();
-
- when(paymentConverter.toPaymentEntity(inputDto)).thenReturn(entityToSave);
- when(paymentRepository.save(entityToSave)).thenReturn(entityToSave);
- when(paymentConverter.toPaymentDto(entityToSave)).thenReturn(inputDto);
-
- // When
- PaymentDto result = paymentService.processPayment(inputDto);
-
- // Then
- assertNotNull(result);
- assertEquals(guid, result.getGuid());
- assertEquals(inquiryRefId, result.getInquiryRefId());
- assertEquals(transactionRefId, result.getTransactionRefId());
- assertEquals(new BigDecimal("500.50"), result.getAmount());
- assertEquals("USD", result.getCurrency());
- assertEquals(PaymentStatus.APPROVED, result.getStatus());
- assertEquals("Complete payment with all fields", result.getNote());
- assertEquals(now, result.getCreatedAt());
- assertEquals(now, result.getUpdatedAt());
- }
-
- @Test
- @DisplayName("processPayment should handle payment with minimal fields")
- void processPayment_shouldHandleMinimalPayment() {
+ @ParameterizedTest
+ @MethodSource("statusProvider")
+ @DisplayName("get should handle different payment statuses")
+ void get_shouldHandleDifferentStatuses(PaymentStatus status) {
// Given
- PaymentDto inputDto = PaymentDto.builder()
+ PaymentEntity paymentEntity = PaymentEntity.builder()
+ .guid(testUuid1)
.inquiryRefId(UUID.randomUUID())
- .amount(new BigDecimal("10.00"))
- .currency("USD")
- .status(PaymentStatus.RECEIVED)
- .build();
-
- PaymentEntity entityToSave = PaymentEntity.builder()
- .inquiryRefId(inputDto.getInquiryRefId())
- .amount(new BigDecimal("10.00"))
- .currency("USD")
- .status(PaymentStatus.RECEIVED)
- .build();
-
- PaymentEntity savedEntity = PaymentEntity.builder()
- .guid(UUID.randomUUID())
- .inquiryRefId(inputDto.getInquiryRefId())
- .amount(new BigDecimal("10.00"))
+ .amount(new BigDecimal("100.00"))
.currency("USD")
- .status(PaymentStatus.RECEIVED)
+ .status(status)
.createdAt(OffsetDateTime.now())
.updatedAt(OffsetDateTime.now())
.build();
- PaymentDto savedDto = PaymentDto.builder()
- .guid(savedEntity.getGuid())
- .inquiryRefId(inputDto.getInquiryRefId())
- .amount(new BigDecimal("10.00"))
- .currency("USD")
- .status(PaymentStatus.RECEIVED)
- .createdAt(savedEntity.getCreatedAt())
- .updatedAt(savedEntity.getUpdatedAt())
+ PaymentDto paymentDto = PaymentDto.builder()
+ .guid(testUuid1)
+ .status(status)
.build();
- when(paymentConverter.toPaymentEntity(inputDto)).thenReturn(entityToSave);
- when(paymentRepository.save(entityToSave)).thenReturn(savedEntity);
- when(paymentConverter.toPaymentDto(savedEntity)).thenReturn(savedDto);
+ when(paymentRepository.findById(testUuid1)).thenReturn(Optional.of(paymentEntity));
+ when(paymentMapper.toPaymentDto(paymentEntity)).thenReturn(paymentDto);
// When
- PaymentDto result = paymentService.processPayment(inputDto);
+ PaymentDto result = paymentService.get(testUuid1);
// Then
- assertNotNull(result);
- assertNotNull(result.getGuid());
- assertEquals(new BigDecimal("10.00"), result.getAmount());
- assertEquals("USD", result.getCurrency());
- assertEquals(PaymentStatus.RECEIVED, result.getStatus());
+ assertEquals(status, result.getStatus());
}
- static Stream statusProvider() {
+ private static Stream statusProvider() {
return Stream.of(
PaymentStatus.RECEIVED,
PaymentStatus.PENDING,
@@ -401,34 +281,4 @@ static Stream statusProvider() {
);
}
- @ParameterizedTest
- @MethodSource("statusProvider")
- @DisplayName("fetchSinglePayment should handle different payment statuses")
- void fetchSinglePayment_shouldHandleDifferentStatuses_1(PaymentStatus status) {
- // Given
- PaymentEntity pendingEntity = PaymentEntity.builder()
- .guid(testUuid1)
- .inquiryRefId(UUID.randomUUID())
- .amount(new BigDecimal("100.00"))
- .currency("USD")
- .status(status)
- .createdAt(OffsetDateTime.now())
- .updatedAt(OffsetDateTime.now())
- .build();
-
- PaymentDto pendingDto = PaymentDto.builder()
- .guid(testUuid1)
- .status(status)
- .build();
-
- when(paymentRepository.findById(testUuid1)).thenReturn(Optional.of(pendingEntity));
- when(paymentConverter.toPaymentDto(pendingEntity)).thenReturn(pendingDto);
-
- // When
- PaymentDto result = paymentService.fetchSinglePayment(testUuid1);
-
- // Then
- assertEquals(status, result.getStatus());
- }
-
}