diff --git a/pom.xml b/pom.xml
index 5b31f78..99c40cf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,6 +16,15 @@
11
+ 1.4.2.Final
+ 30.1.1-jre
+ 5.7.2
+ 1.18.20
+ 1.3.1
+ 8.0.24
+ 1.5.4
+ 2.5.0
+ 2.5.0
@@ -32,7 +41,7 @@
com.google.guava
guava
- 30.1.1-jre
+ ${guava.version}
@@ -53,7 +62,7 @@
org.junit.jupiter
junit-jupiter-engine
- 5.7.2
+ ${junit.jupiter.version}
test
@@ -61,7 +70,7 @@
org.projectlombok
lombok
- 1.18.20
+ ${lombok.version}
provided
@@ -69,19 +78,19 @@
com.google.cloud.sql
mysql-socket-factory-connector-j-8
- 1.3.1
+ ${mysql.socket.factory.version}
mysql
mysql-connector-java
- 8.0.24
+ ${mysql.connector.version}
ma.glasnost.orika
orika-core
- 1.5.4
+ ${orika.core.version}
@@ -107,12 +116,19 @@
io.springfox
springfox-swagger2
- 2.5.0
+ ${springfox.swagger2.version}
io.springfox
springfox-swagger-ui
- 2.5.0
+ ${springfox.swagger.ui.version}
+
+
+
+
+ org.mapstruct
+ mapstruct
+ ${org.mapstruct.version}
@@ -124,6 +140,18 @@
11
11
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${org.mapstruct.version}
+
+
diff --git a/src/main/java/com/bravo/user/controller/PaymentController.java b/src/main/java/com/bravo/user/controller/PaymentController.java
new file mode 100644
index 0000000..1138fb9
--- /dev/null
+++ b/src/main/java/com/bravo/user/controller/PaymentController.java
@@ -0,0 +1,28 @@
+package com.bravo.user.controller;
+
+import com.bravo.user.annotation.SwaggerController;
+import com.bravo.user.model.dto.PaymentDto;
+import com.bravo.user.service.PaymentService;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+@SwaggerController
+@RequestMapping("/payments")
+@RequiredArgsConstructor
+@Slf4j
+public class PaymentController {
+
+ private final PaymentService paymentService;
+
+ @GetMapping
+ @ResponseBody
+ public List findPaymentByUserId(@RequestParam String userId) {
+ log.info("Starting to search payment for user with id {}", userId);
+ return paymentService.findPaymentByUserId(userId);
+ }
+}
diff --git a/src/main/java/com/bravo/user/controller/advice/ExceptionHandlerAdvice.java b/src/main/java/com/bravo/user/controller/advice/ExceptionHandlerAdvice.java
index 463658c..97d8a88 100644
--- a/src/main/java/com/bravo/user/controller/advice/ExceptionHandlerAdvice.java
+++ b/src/main/java/com/bravo/user/controller/advice/ExceptionHandlerAdvice.java
@@ -1,8 +1,10 @@
package com.bravo.user.controller.advice;
+import com.bravo.user.exception.PaymentNotFoundException;
import com.bravo.user.model.dto.ErrorDto;
import java.util.Set;
import java.util.stream.Collectors;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice;
@@ -11,6 +13,7 @@
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
+@Slf4j
public class ExceptionHandlerAdvice {
@ExceptionHandler(value = BindException.class)
@@ -31,4 +34,17 @@ public ErrorDto handleBindException(final BindException exception){
response.setStatusCode(400);
return response;
}
+
+ @ExceptionHandler(value = PaymentNotFoundException.class)
+ @ResponseBody
+ @ResponseStatus(value = HttpStatus.NOT_FOUND)
+ public ErrorDto handlePaymentNotFoundException(final PaymentNotFoundException exception){
+ log.info("Payments not found, details: {}", exception.getMessage());
+ var errorDto = new ErrorDto();
+ errorDto.setMessage(exception.getMessage());
+ errorDto.setStatusCode(HttpStatus.NOT_FOUND.value());
+
+ return errorDto;
+ }
+
}
diff --git a/src/main/java/com/bravo/user/dao/model/Payment.java b/src/main/java/com/bravo/user/dao/model/Payment.java
index 12eb7a5..736ac9b 100644
--- a/src/main/java/com/bravo/user/dao/model/Payment.java
+++ b/src/main/java/com/bravo/user/dao/model/Payment.java
@@ -1,12 +1,12 @@
package com.bravo.user.dao.model;
import java.time.LocalDateTime;
-import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
+import org.hibernate.annotations.GenericGenerator;
@Entity
@Data
@@ -15,6 +15,7 @@ public class Payment {
@Id
@Column(name = "id")
+ @GenericGenerator(name = "uuid", strategy = "uuid4")
private String id;
@Column(name = "user_id", nullable = false)
@@ -30,11 +31,6 @@ public class Payment {
private Integer expiryYear;
@Column(name = "updated", nullable = false)
- private LocalDateTime updated;
+ private LocalDateTime updated = LocalDateTime.now();
- public Payment(){
- super();
- this.id = UUID.randomUUID().toString();
- this.updated = LocalDateTime.now();
- }
}
diff --git a/src/main/java/com/bravo/user/dao/model/mapper/PaymentMapper.java b/src/main/java/com/bravo/user/dao/model/mapper/PaymentMapper.java
new file mode 100644
index 0000000..c3a8db6
--- /dev/null
+++ b/src/main/java/com/bravo/user/dao/model/mapper/PaymentMapper.java
@@ -0,0 +1,23 @@
+package com.bravo.user.dao.model.mapper;
+
+import com.bravo.user.dao.model.Payment;
+import com.bravo.user.model.dto.PaymentDto;
+import java.util.List;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Named;
+
+@Mapper(componentModel = "spring")
+public interface PaymentMapper {
+
+ @Mapping(source = "cardNumber", target = "cardNumber", qualifiedByName = "lastFourCardDigits")
+ PaymentDto toPaymentDto(Payment payment);
+
+ @Mapping(source = "cardNumber", target = "cardNumber", qualifiedByName = "lastFourCardDigits")
+ List toPaymentDtoList(List payments);
+
+ @Named("lastFourCardDigits")
+ static String lastFourCardDigits(String cardNumber) {
+ return cardNumber.replaceAll("\\w(?=\\w{4})", "*");
+ }
+}
diff --git a/src/main/java/com/bravo/user/dao/model/mapper/ResourceMapper.java b/src/main/java/com/bravo/user/dao/model/mapper/ResourceMapper.java
index 4a78188..d8e4553 100644
--- a/src/main/java/com/bravo/user/dao/model/mapper/ResourceMapper.java
+++ b/src/main/java/com/bravo/user/dao/model/mapper/ResourceMapper.java
@@ -1,11 +1,9 @@
package com.bravo.user.dao.model.mapper;
import com.bravo.user.dao.model.Address;
-import com.bravo.user.dao.model.Payment;
import com.bravo.user.dao.model.Profile;
import com.bravo.user.dao.model.User;
import com.bravo.user.model.dto.AddressDto;
-import com.bravo.user.model.dto.PaymentDto;
import com.bravo.user.model.dto.ProfileDto;
import com.bravo.user.model.dto.UserReadDto;
import java.util.Collection;
@@ -41,17 +39,6 @@ public AddressDto convertAddress(final Address address){
return dto;
}
- public > List convertPayments(final T payments){
- return payments.stream().map(this::convertPayment).collect(Collectors.toList());
- }
-
- public PaymentDto convertPayment(final Payment payment){
- final String cardNumber = payment.getCardNumber();
- final PaymentDto dto = mapperFacade.map(payment, PaymentDto.class);
- dto.setCardNumberLast4(cardNumber.substring(cardNumber.length() - 5));
- return dto;
- }
-
public ProfileDto convertProfile(final Profile profile){
return mapperFacade.map(profile, ProfileDto.class);
}
diff --git a/src/main/java/com/bravo/user/dao/repository/PaymentRepository.java b/src/main/java/com/bravo/user/dao/repository/PaymentRepository.java
new file mode 100644
index 0000000..5f48ac2
--- /dev/null
+++ b/src/main/java/com/bravo/user/dao/repository/PaymentRepository.java
@@ -0,0 +1,11 @@
+package com.bravo.user.dao.repository;
+
+import com.bravo.user.dao.model.Payment;
+import java.util.List;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface PaymentRepository extends JpaRepository {
+ List findByUserId(String userId);
+}
diff --git a/src/main/java/com/bravo/user/exception/PaymentNotFoundException.java b/src/main/java/com/bravo/user/exception/PaymentNotFoundException.java
new file mode 100644
index 0000000..bd152e6
--- /dev/null
+++ b/src/main/java/com/bravo/user/exception/PaymentNotFoundException.java
@@ -0,0 +1,12 @@
+package com.bravo.user.exception;
+
+import java.text.MessageFormat;
+
+public class PaymentNotFoundException extends RuntimeException {
+
+ private static final String MESSAGE = "Payment not found for user with id {0}";
+
+ public PaymentNotFoundException(String userId) {
+ super(MessageFormat.format(MESSAGE, userId));
+ }
+}
diff --git a/src/main/java/com/bravo/user/model/dto/ErrorDto.java b/src/main/java/com/bravo/user/model/dto/ErrorDto.java
index 93998d3..e9fa9c4 100644
--- a/src/main/java/com/bravo/user/model/dto/ErrorDto.java
+++ b/src/main/java/com/bravo/user/model/dto/ErrorDto.java
@@ -1,15 +1,19 @@
package com.bravo.user.model.dto;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
import java.util.Set;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
+@JsonInclude(Include.NON_NULL)
public class ErrorDto {
private Set errors;
private Class> exception;
private String message;
private Integer statusCode;
+
}
diff --git a/src/main/java/com/bravo/user/model/dto/PaymentDto.java b/src/main/java/com/bravo/user/model/dto/PaymentDto.java
index db32487..d70b9df 100644
--- a/src/main/java/com/bravo/user/model/dto/PaymentDto.java
+++ b/src/main/java/com/bravo/user/model/dto/PaymentDto.java
@@ -1,13 +1,18 @@
package com.bravo.user.model.dto;
import java.time.LocalDateTime;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
import lombok.Data;
+import lombok.NoArgsConstructor;
@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
public class PaymentDto {
-
private String id;
- private String cardNumberLast4;
+ private String cardNumber;
private Integer expiryMonth;
private Integer expiryYear;
private LocalDateTime updated;
diff --git a/src/main/java/com/bravo/user/service/PaymentService.java b/src/main/java/com/bravo/user/service/PaymentService.java
new file mode 100644
index 0000000..58eb132
--- /dev/null
+++ b/src/main/java/com/bravo/user/service/PaymentService.java
@@ -0,0 +1,30 @@
+package com.bravo.user.service;
+
+import com.bravo.user.dao.model.mapper.PaymentMapper;
+import com.bravo.user.dao.repository.PaymentRepository;
+import com.bravo.user.exception.PaymentNotFoundException;
+import com.bravo.user.model.dto.PaymentDto;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class PaymentService {
+
+ private final PaymentRepository paymentRepository;
+ private final PaymentMapper paymentMapper;
+
+ public List findPaymentByUserId(String userId) {
+ var payments = paymentRepository.findByUserId(userId);
+
+ if(payments.isEmpty()) {
+ throw new PaymentNotFoundException(userId);
+ }
+
+ return paymentMapper.toPaymentDtoList(payments);
+ }
+
+}
diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql
index da45720..e79ea1a 100644
--- a/src/main/resources/data.sql
+++ b/src/main/resources/data.sql
@@ -648,3 +648,10 @@ insert into address (id, user_id, line1, line2, city, state, zip) values
('42f33d30-f3f8-4743-a94e-4db11fdb747d', '008a4215-0b1d-445e-b655-a964039cbb5a', '412 Maple St', null, 'Dowagiac', 'Michigan', '49047'),
('579872ec-46f8-46b5-b809-d0724d965f0e', '00963d9b-f884-485e-9455-fcf30c6ac379', '237 Mountain Ter', 'Apt 10', 'Odenville', 'Alabama', '35120'),
('95a983d0-ba0e-4f30-afb6-667d4724b253', '00963d9b-f884-485e-9455-fcf30c6ac379', '107 Annettes Ct', null, 'Aydlett', 'North Carolina', '27916');
+
+insert into payment (id, user_id, card_number, expiry_month, expiry_year) values
+('45cb8ef20-5e39-472e-a967-06dee934b0f3', '008a4215-0b1d-445e-b655-a964039cbb5a', '288925317311943', '02', '2026'),
+('579872ec-46f8-46b5-b809-d0724d965f0e', '008a4215-0b1d-445e-b655-a964039cbb5a', '377925317620670', '01', '2031'),
+('95a983d0-ba0e-4f30-afb6-667d4724b253', '008a4215-0b1d-445e-b655-a964039cbb5a', '377925317621133', '02', '2021'),
+('ddabb1fa-0c94-451e-aa76-84c14a24c578', '00963d9b-f884-485e-9455-fcf30c6ac379', '374141394130819', '05', '2023'),
+('fa57433d-b7ed-4028-99d9-ce1919362de2', '00963d9b-f884-485e-9455-fcf30c6ac379', '372120757513243', '03', '2025');
\ No newline at end of file
diff --git a/src/test/java/com/bravo/user/TestUtils.java b/src/test/java/com/bravo/user/TestUtils.java
new file mode 100644
index 0000000..1be45fa
--- /dev/null
+++ b/src/test/java/com/bravo/user/TestUtils.java
@@ -0,0 +1,25 @@
+package com.bravo.user;
+
+import com.bravo.user.config.AppConfig;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import lombok.SneakyThrows;
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class TestUtils {
+ private static final ObjectMapper OBJECT_MAPPER = new AppConfig().objectMapperBuilder().build();
+
+ @SneakyThrows
+ public String readFromFile(String file) {
+ var url = TestUtils.class.getResource(file);
+ return Files.readString(Path.of(url.getPath()));
+ }
+
+ @SneakyThrows
+ public static T deserializeFromJson(String json, TypeReference clazz) {
+ return OBJECT_MAPPER.readValue(json, clazz);
+ }
+}
diff --git a/src/test/java/com/bravo/user/controller/PaymentControllerTest.java b/src/test/java/com/bravo/user/controller/PaymentControllerTest.java
new file mode 100644
index 0000000..5c966a7
--- /dev/null
+++ b/src/test/java/com/bravo/user/controller/PaymentControllerTest.java
@@ -0,0 +1,69 @@
+package com.bravo.user.controller;
+
+import com.bravo.user.TestUtils;
+import com.bravo.user.exception.PaymentNotFoundException;
+import com.bravo.user.model.dto.PaymentDto;
+import com.bravo.user.service.PaymentService;
+import com.fasterxml.jackson.core.type.TypeReference;
+import java.util.List;
+import lombok.SneakyThrows;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class PaymentControllerTest {
+
+ private static final String SUCCESS_PAYMENT_RESPONSE_PATH = "/response/paymentsResponse.json";
+ private static final String PAYMENTS_NOT_FOUND_RESPONSE_PATH = "/response/paymentsNotFoundResponse.json";
+
+ private static final String TEST_USER_ID = "testUserId";
+ private static final String PAYMENTS_ENDPOINT = "/payments";
+ private static final String USER_ID_PARAM_NAME = "userId";
+
+ @Autowired
+ private MockMvc mvc;
+
+ @MockBean
+ private PaymentService paymentService;
+
+ @Test
+ @SneakyThrows
+ public void successfullyFoundPaymentByUserIdTest() {
+ var successResponse = TestUtils.readFromFile(SUCCESS_PAYMENT_RESPONSE_PATH);
+ List payments = TestUtils.deserializeFromJson(successResponse, new TypeReference<>() {});
+
+ Mockito.when(paymentService.findPaymentByUserId(TEST_USER_ID)).thenReturn(payments);
+
+ mvc.perform(get(PAYMENTS_ENDPOINT)
+ .queryParam(USER_ID_PARAM_NAME, TEST_USER_ID)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().json(successResponse));
+ }
+
+ @Test
+ @SneakyThrows
+ public void paymentsNotFoundShouldReturnNotFoundWithMessageTest() {
+ var paymentsNotFoundResponse = TestUtils.readFromFile(PAYMENTS_NOT_FOUND_RESPONSE_PATH);
+
+ Mockito.when(paymentService.findPaymentByUserId(TEST_USER_ID)).thenThrow(new PaymentNotFoundException(TEST_USER_ID));
+
+ mvc.perform(get(PAYMENTS_ENDPOINT)
+ .queryParam(USER_ID_PARAM_NAME, TEST_USER_ID)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isNotFound())
+ .andExpect(content().json(paymentsNotFoundResponse));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/bravo/user/dao/model/mapper/PaymentMapperTest.java b/src/test/java/com/bravo/user/dao/model/mapper/PaymentMapperTest.java
new file mode 100644
index 0000000..f886927
--- /dev/null
+++ b/src/test/java/com/bravo/user/dao/model/mapper/PaymentMapperTest.java
@@ -0,0 +1,64 @@
+package com.bravo.user.dao.model.mapper;
+
+import com.bravo.user.dao.model.Payment;
+import com.bravo.user.model.dto.PaymentDto;
+import java.time.LocalDateTime;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@SpringBootTest(classes = PaymentMapperImpl.class)
+public class PaymentMapperTest {
+
+ private static final String TEST_CARD_NUMBER = "123456789";
+ private static final String MASKED_TEST_CARD_NUMBER = "*****6789";
+ private static final int TEST_EXPIRY_MONTH = 2;
+ private static final int TEST_EXPIRY_YEAR = 2022;
+ private static final LocalDateTime TEST_UPDATED = LocalDateTime.now();
+
+ @Autowired
+ private PaymentMapper paymentMapper;
+
+ @Test
+ public void shouldSuccessfullyMapPaymentToPaymentDtoTest() {
+ var paymentDto = paymentMapper.toPaymentDto(createTestPayment());
+ var expectedPaymentDto = createTestPaymentDto();
+ assertEquals(expectedPaymentDto, paymentDto);
+ }
+
+ @Test
+ public void shouldSuccessfullyMapPaymentListToPaymentDtoListTest() {
+ var paymentDtoList = paymentMapper.toPaymentDtoList(List.of(createTestPayment()));
+ var expectedPaymentDtoList = List.of(createTestPaymentDto());
+ assertEquals(expectedPaymentDtoList, paymentDtoList);
+ }
+
+ @Test
+ public void shouldSuccessfullyMaskCardNumberTest() {
+ var actualMaskedCard = PaymentMapper.lastFourCardDigits(TEST_CARD_NUMBER);
+
+ assertEquals(MASKED_TEST_CARD_NUMBER, actualMaskedCard);
+ }
+
+ private Payment createTestPayment() {
+ var payment = new Payment();
+ payment.setCardNumber(TEST_CARD_NUMBER);
+ payment.setExpiryMonth(TEST_EXPIRY_MONTH);
+ payment.setExpiryYear(TEST_EXPIRY_YEAR);
+ payment.setUpdated(TEST_UPDATED);
+
+ return payment;
+ }
+
+ private PaymentDto createTestPaymentDto() {
+ return PaymentDto.builder()
+ .expiryYear(TEST_EXPIRY_YEAR)
+ .expiryMonth(TEST_EXPIRY_MONTH)
+ .cardNumber(MASKED_TEST_CARD_NUMBER)
+ .updated(TEST_UPDATED)
+ .build();
+ }
+}
diff --git a/src/test/java/com/bravo/user/service/PaymentServiceTest.java b/src/test/java/com/bravo/user/service/PaymentServiceTest.java
new file mode 100644
index 0000000..ebc0787
--- /dev/null
+++ b/src/test/java/com/bravo/user/service/PaymentServiceTest.java
@@ -0,0 +1,77 @@
+package com.bravo.user.service;
+
+import com.bravo.user.dao.model.Payment;
+import com.bravo.user.dao.model.mapper.PaymentMapper;
+import com.bravo.user.dao.repository.PaymentRepository;
+import com.bravo.user.exception.PaymentNotFoundException;
+import com.bravo.user.model.dto.PaymentDto;
+import java.time.LocalDateTime;
+import java.util.Collections;
+import java.util.List;
+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 static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+public class PaymentServiceTest {
+
+ private static final String TEST_USER_ID = "testUserId";
+
+ @Mock
+ private PaymentRepository paymentRepository;
+ @Mock
+ private PaymentMapper paymentMapper;
+
+ @InjectMocks
+ private PaymentService paymentService;
+
+ @Test
+ public void paymentNotFoundShouldThrowExceptionTest() {
+ var expectedErrorMessage = "Payment not found for user with id " + TEST_USER_ID;
+
+ when(paymentRepository.findByUserId(TEST_USER_ID)).thenReturn(Collections.emptyList());
+
+ var exception = assertThrows(PaymentNotFoundException.class,
+ () -> paymentService.findPaymentByUserId(TEST_USER_ID));
+
+ assertEquals(expectedErrorMessage, exception.getMessage());
+ }
+
+ @Test
+ public void paymentsIsFoundShouldSuccessfullyReturnPaymentsTest() {
+ var testPayments = List.of(createTestPayment());
+ var expectedPayments = List.of(createTestPaymentDto());
+
+ when(paymentRepository.findByUserId(TEST_USER_ID)).thenReturn(testPayments);
+ when(paymentMapper.toPaymentDtoList(testPayments)).thenReturn(expectedPayments);
+
+ var actualPayments = paymentService.findPaymentByUserId(TEST_USER_ID);
+
+ assertEquals(expectedPayments, actualPayments);
+ }
+
+ private Payment createTestPayment() {
+ var payment = new Payment();
+ payment.setCardNumber("testCardNumber");
+ payment.setExpiryMonth(2);
+ payment.setExpiryYear(2022);
+ payment.setUpdated(LocalDateTime.now());
+
+ return payment;
+ }
+
+ private PaymentDto createTestPaymentDto() {
+ return PaymentDto.builder()
+ .cardNumber("testCardNumber")
+ .expiryMonth(2)
+ .expiryYear(2022)
+ .updated(LocalDateTime.now())
+ .build();
+ }
+}
diff --git a/src/test/resources/response/paymentsNotFoundResponse.json b/src/test/resources/response/paymentsNotFoundResponse.json
new file mode 100644
index 0000000..80b67a0
--- /dev/null
+++ b/src/test/resources/response/paymentsNotFoundResponse.json
@@ -0,0 +1,4 @@
+{
+ "message": "Payment not found for user with id testUserId",
+ "statusCode": 404
+}
\ No newline at end of file
diff --git a/src/test/resources/response/paymentsResponse.json b/src/test/resources/response/paymentsResponse.json
new file mode 100644
index 0000000..3a4666f
--- /dev/null
+++ b/src/test/resources/response/paymentsResponse.json
@@ -0,0 +1,23 @@
+[
+ {
+ "id": "45cb8ef20-5e39-472e-a967-06dee934b0f3",
+ "cardNumber": "***********1943",
+ "expiryMonth": 2,
+ "expiryYear": 2021,
+ "updated": "2022-03-17 21:09:29"
+ },
+ {
+ "id": "579872ec-46f8-46b5-b809-d0724d965f0e",
+ "cardNumber": "***********0670",
+ "expiryMonth": 2,
+ "expiryYear": 2021,
+ "updated": "2022-03-17 21:09:29"
+ },
+ {
+ "id": "95a983d0-ba0e-4f30-afb6-667d4724b253",
+ "cardNumber": "***********1133",
+ "expiryMonth": 2,
+ "expiryYear": 2021,
+ "updated": "2022-03-17 21:09:29"
+ }
+]
\ No newline at end of file