From 555662907ab9a98f2914366cd8e4b940ccf38610 Mon Sep 17 00:00:00 2001 From: uzma Date: Fri, 5 May 2023 11:07:33 +0100 Subject: [PATCH] [BAEL-6105] code for list to page article --- .../spring-data-jpa-query-3/pom.xml | 5 ++ .../spring/data/jpa/paging/Customer.java | 14 ++++ .../data/jpa/paging/CustomerRepository.java | 9 +++ .../jpa/paging/CustomerRestController.java | 31 +++++++ .../data/jpa/paging/CustomerService.java | 37 +++++++++ .../data/jpa/paging/PagingApplication.java | 12 +++ .../jpa/paging/CustomerControllerTest.java | 76 ++++++++++++++++++ .../data/jpa/paging/CustomerServiceTest.java | 80 +++++++++++++++++++ 8 files changed, 264 insertions(+) create mode 100644 persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/Customer.java create mode 100644 persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRepository.java create mode 100644 persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRestController.java create mode 100644 persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerService.java create mode 100644 persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/PagingApplication.java create mode 100644 persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerControllerTest.java create mode 100644 persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerServiceTest.java diff --git a/persistence-modules/spring-data-jpa-query-3/pom.xml b/persistence-modules/spring-data-jpa-query-3/pom.xml index 18df57fe14..1dff3024f6 100644 --- a/persistence-modules/spring-data-jpa-query-3/pom.xml +++ b/persistence-modules/spring-data-jpa-query-3/pom.xml @@ -30,6 +30,11 @@ javafaker ${javafaker.version} + + org.springframework.boot + spring-boot-starter-web + + org.springframework.boot spring-boot-starter-test diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/Customer.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/Customer.java new file mode 100644 index 0000000000..7ef4db808b --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/Customer.java @@ -0,0 +1,14 @@ +package com.baeldung.spring.data.jpa.paging; + +public class Customer { + + private String name; + + public Customer(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRepository.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRepository.java new file mode 100644 index 0000000000..ea418e7c55 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.spring.data.jpa.paging; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CustomerRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRestController.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRestController.java new file mode 100644 index 0000000000..4a3a38991c --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRestController.java @@ -0,0 +1,31 @@ +package com.baeldung.spring.data.jpa.paging; + +import org.springframework.data.domain.Page; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class CustomerRestController { + + private final CustomerService customerService; + + public CustomerRestController(CustomerService customerService) { + this.customerService = customerService; + } + + @GetMapping("/api/customers") + public ResponseEntity> getCustomers(@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) { + + Page customerPage = customerService.getCustomers(page, size); + HttpHeaders headers = new HttpHeaders(); + headers.add("X-Page-Number", String.valueOf(customerPage.getNumber())); + headers.add("X-Page-Size", String.valueOf(customerPage.getSize())); + + return ResponseEntity.ok() + .headers(headers) + .body(customerPage); + } +} diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerService.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerService.java new file mode 100644 index 0000000000..cb426084ca --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerService.java @@ -0,0 +1,37 @@ +package com.baeldung.spring.data.jpa.paging; + +import java.util.List; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +@Service +public class CustomerService { + + public CustomerService(CustomerRepository customerRepository) { + this.customerRepository = customerRepository; + } + + private final CustomerRepository customerRepository; + + public Page getCustomers(int page, int size) { + + Pageable pageRequest = createPageRequestUsing(page, size); + + List allCustomers = customerRepository.findAll(); + int start = (int) pageRequest.getOffset(); + int end = Math.min((start + pageRequest.getPageSize()), allCustomers.size()); + + + return new PageImpl<>(allCustomers.subList(start, end), pageRequest, allCustomers.size()); + + } + + private Pageable createPageRequestUsing(int page, int size) { + return PageRequest.of(page, size); + + } +} diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/PagingApplication.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/PagingApplication.java new file mode 100644 index 0000000000..58a6b43ff3 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/PagingApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.data.jpa.paging; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class PagingApplication { + + public static void main(String[] args) { + SpringApplication.run(PagingApplication.class, args); + } +} diff --git a/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerControllerTest.java b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerControllerTest.java new file mode 100644 index 0000000000..112ab545aa --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerControllerTest.java @@ -0,0 +1,76 @@ +package com.baeldung.spring.data.jpa.paging; + +import static org.assertj.core.api.Assertions.assertThat; +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.status; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; + +import org.assertj.core.api.Assertions; +import org.json.JSONObject; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; + + +@WebMvcTest(CustomerRestController.class) +public class CustomerControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private CustomerService customerService; + + @BeforeEach + void setup() { + List allCustomers = getAllCustomers(); + Page customerPage = new PageImpl<>(allCustomers, PageRequest.of(1, 5), allCustomers.size()); + + when(customerService.getCustomers(1, 5)).thenReturn(customerPage); + + } + + private static List getAllCustomers() { + List customers = new ArrayList<>(); + IntStream.range(0, 20) + .forEach(i -> { + Customer customer = new Customer((Integer.toString(i))); + customers.add(customer); + }); + return customers; + } + + @Test + void givenTotalCustomers20_whenGetRequestWithPageAndSize_thenPagedReponseIsReturnedFromDesiredPageAndSize() throws Exception { + + MvcResult result = mockMvc.perform(get("/api/customers?page=1&size=5")) + .andExpect(status().isOk()) + .andReturn(); + + MockHttpServletResponse response = result.getResponse(); + + JSONObject jsonObject = new JSONObject(response.getContentAsString()); + assertThat(jsonObject.get("totalPages")) + .isEqualTo(4); + assertThat(jsonObject.get("totalElements")) + .isEqualTo(20); + assertThat(jsonObject.get("number")) + .isEqualTo(1); + assertThat(jsonObject.get("size")) + .isEqualTo(5); + assertThat(jsonObject.get("content")) + .isNotNull(); + } +} diff --git a/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerServiceTest.java b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerServiceTest.java new file mode 100644 index 0000000000..0d5e4879db --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerServiceTest.java @@ -0,0 +1,80 @@ +package com.baeldung.spring.data.jpa.paging; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Page; + +@ExtendWith(MockitoExtension.class) +public class CustomerServiceTest { + + @Mock + private CustomerRepository customerRepository; + + @InjectMocks + private CustomerService customerService; + + private static final List ALL_CUSTOMERS = Arrays.asList( + new Customer("Ali"), new Customer("Brian"), new Customer("Coddy"), + new Customer("Di"), new Customer("Eve"), new Customer("Fin"), + new Customer("Grace"), new Customer("Harry"), + new Customer("Ivan"), new Customer("Judy"), + new Customer("Kasim"), new Customer("Liam"), + new Customer("Mike"),new Customer("Nick"), + new Customer("Omar"), new Customer("Penny"), + new Customer("Queen"),new Customer("Rob"), + new Customer("Sue"),new Customer("Tammy")); + + private static final List PAGE_1_CONTENTS = Arrays.asList("Ali", "Brian", "Coddy", "Di", "Eve"); + + private static final List PAGE_2_CONTENTS = Arrays.asList("Fin", "Grace", "Harry", "Ivan", "Judy"); + + private static final List PAGE_3_CONTENTS = Arrays.asList("Kasim", "Liam", "Mike", "Nick", "Omar"); + + private static final List PAGE_4_CONTENTS = Arrays.asList("Penny", "Queen", "Rob", "Sue", "Tammy"); + + private static final List EMPTY_PAGE = Arrays.asList(); + @BeforeEach + void setup() { + when(customerRepository.findAll()).thenReturn(ALL_CUSTOMERS); + } + + private static Collection testIO() { + return Arrays.asList( + new Object[][] { + { 0, 5, PAGE_1_CONTENTS, 20L, 4L }, + { 1, 5, PAGE_2_CONTENTS, 20L, 4L }, + { 2, 5, PAGE_3_CONTENTS, 20L, 4L }, + { 3, 5, PAGE_4_CONTENTS, 20L, 4L }, + { 4, 5, EMPTY_PAGE, 20L, 4L } } + ); + } + + @ParameterizedTest + @MethodSource("testIO") + void givenAListOfCustomers_whenGetCustomers_thenReturnsDesiredDataAlongWithPagingInformation(int page, int size, List expectedNames, long expectedTotalElements, long expectedTotalPages) { + Page customers = customerService.getCustomers(page, size); + List names = customers.getContent() + .stream() + .map(Customer::getName) + .collect(Collectors.toList()); + + assertEquals(expectedNames.size(), names.size()); + assertEquals(expectedNames, names); + assertEquals(expectedTotalElements, customers.getTotalElements()); + assertEquals(expectedTotalPages, customers.getTotalPages()); + } +}