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..28859a9 --- /dev/null +++ b/src/main/java/com/bravo/user/controller/PaymentController.java @@ -0,0 +1,33 @@ +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 com.bravo.user.validator.UserValidator; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.List; + +@RequestMapping(value = "/payment") +@SwaggerController +public class PaymentController { + + private final UserValidator userValidator; + private final PaymentService paymentService; + + public PaymentController(UserValidator userValidator, PaymentService paymentService) { + this.userValidator = userValidator; + this.paymentService = paymentService; + } + @GetMapping(value = "/retrieve/{userId}") + @ResponseBody + public List retrieve(final @PathVariable String userId) { + userValidator.validateId(userId); + return paymentService.retrieveByUserId(userId); + } + + +} 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..c4ae5a8 --- /dev/null +++ b/src/main/java/com/bravo/user/dao/repository/PaymentRepository.java @@ -0,0 +1,14 @@ +package com.bravo.user.dao.repository; + +import com.bravo.user.dao.model.Payment; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface PaymentRepository extends JpaRepository, JpaSpecificationExecutor { + + List findByUserId(final String userId); +} 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..e0525ab --- /dev/null +++ b/src/main/java/com/bravo/user/service/PaymentService.java @@ -0,0 +1,32 @@ +package com.bravo.user.service; + +import com.bravo.user.dao.model.Payment; +import com.bravo.user.dao.model.mapper.ResourceMapper; +import com.bravo.user.dao.repository.PaymentRepository; +import com.bravo.user.model.dto.PaymentDto; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class PaymentService { + + private static final Logger LOGGER = LoggerFactory.getLogger(PaymentService.class); + + private final PaymentRepository paymentRepository; + private final ResourceMapper resourceMapper; + + public PaymentService(PaymentRepository paymentRepository, ResourceMapper resourceMapper) { + this.paymentRepository = paymentRepository; + this.resourceMapper = resourceMapper; + } + + public List retrieveByUserId(final String id) { + final List payments = paymentRepository.findByUserId(id); + + LOGGER.info("found {} payment(s)", payments.size()); + return resourceMapper.convertPayments(payments); + } +} diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index da45720..6d38323 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -648,3 +648,8 @@ 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 +('42f33d30-f3f8-4743-a94e-4db11fdb747d', '008a4215-0b1d-445e-b655-a964039cbb5a', '1234456789123456', '01', '24'), +('579872ec-46f8-46b5-b809-d0724d965f0e', '00963d9b-f884-485e-9455-fcf30c6ac379', '7891234567891234', '02', '25'), +('95a983d0-ba0e-4f30-afb6-667d4724b253', '00963d9b-f884-485e-9455-fcf30c6ac379', '5678912345678912', '03', '26'); 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..80d0b63 --- /dev/null +++ b/src/test/java/com/bravo/user/controller/PaymentControllerTest.java @@ -0,0 +1,82 @@ +package com.bravo.user.controller; + +import com.bravo.user.App; +import com.bravo.user.model.dto.PaymentDto; +import com.bravo.user.service.PaymentService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +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.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@ContextConfiguration(classes = {App.class}) +@ExtendWith(SpringExtension.class) +@SpringBootTest() +@AutoConfigureMockMvc +public class PaymentControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private PaymentService paymentService; + + private List payments; + + @BeforeEach + public void beforeEach() { + final List ids = IntStream.range(1, 10).boxed().collect(Collectors.toList()); + + this.payments = ids.stream().map(id -> createPaymentDto(Integer.toString(id))) + .collect(Collectors.toList()); + } + + private PaymentDto createPaymentDto(final String id) { + final PaymentDto payment = new PaymentDto(); + payment.setId(id); + return payment; + } + + @Test + void getRetrieveByUserId() throws Exception { + final String userId = "123a-456b"; + + when(paymentService.retrieveByUserId(anyString())).thenReturn(payments); + + final ResultActions result = this.mockMvc.perform(get("/payment/retrieve/".concat(userId))) + .andExpect(status().isOk()); + + for (int i = 0; i < payments.size(); i++) { + result.andExpect(jsonPath(String.format("$[%d].id", i)).value(payments.get(i).getId())); + } + + verify(paymentService).retrieveByUserId(userId); + } + + @Test + void getRetrieveByUserId_Space() throws Exception { + this.mockMvc.perform(get("/payment/retrieve/ /")).andExpect(status().isBadRequest()); + } + + @Test + void getRetrieveByUserId_Missing() throws Exception { + this.mockMvc.perform(get("/payment/retrieve")).andExpect(status().isNotFound()); + } +} 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..4de74ab --- /dev/null +++ b/src/test/java/com/bravo/user/service/PaymentServiceTest.java @@ -0,0 +1,86 @@ +package com.bravo.user.service; + +import com.bravo.user.App; +import com.bravo.user.dao.model.Payment; +import com.bravo.user.dao.model.mapper.ResourceMapper; +import com.bravo.user.dao.repository.PaymentRepository; +import com.bravo.user.model.dto.PaymentDto; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ContextConfiguration(classes = {App.class}) +@ExtendWith(SpringExtension.class) +@SpringBootTest +public class PaymentServiceTest { + + @Autowired + private PaymentService paymentService; + + @MockBean + private ResourceMapper resourceMapper; + + @MockBean + private PaymentRepository paymentRepository; + + private List dtoPayments; + + @BeforeEach + public void beforeEach() { + final List ids = IntStream.range(1, 10).boxed().collect(Collectors.toList()); + + final List daoPayments = ids.stream() + .map(id -> createPayment(Integer.toString(id))).collect(Collectors.toList()); + + when(paymentRepository.findByUserId("123a-456b")).thenReturn(daoPayments); + + this.dtoPayments = ids.stream().map(id -> createPaymentDto(Integer.toString(id))) + .collect(Collectors.toList()); + + when(resourceMapper.convertPayments(daoPayments)).thenReturn(dtoPayments); + } + + @Test + void retrieveByUserId() { + final String userId = "123a-456b"; + final List results = paymentService.retrieveByUserId(userId); + assertEquals(dtoPayments, results); + + verify(paymentRepository).findByUserId(userId); + } + + @Test + void retrieveByUserIdNoResults() { + final String userId = "456b-789c"; + final List results = paymentService.retrieveByUserId(userId); + assertTrue(results.isEmpty()); + + verify(paymentRepository).findByUserId(userId); + } + + private Payment createPayment(final String id) { + final Payment payment = new Payment(); + payment.setId(id); + return payment; + } + + private PaymentDto createPaymentDto(final String id) { + final PaymentDto payment = new PaymentDto(); + payment.setId(id); + return payment; + } +}