Skip to content
Snippets Groups Projects
Commit 6c47c16b authored by Karsch Lukas's avatar Karsch Lukas
Browse files

Merge branch 'plants-pagination' into 'main'

#29 Pagination for Plants endpoint w/ CustomPageDTO

See merge request !15
parents b5e9f8a6 aa840ae7
No related branches found
No related tags found
1 merge request!15#29 Pagination for Plants endpoint w/ CustomPageDTO
### Get all plants
GET http://localhost:8080/api/v1/plants
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsdWthcy5rYXJzY2hAZ214LmRlIiwiaWF0IjoxNzAwOTMzNjQ4LCJleHAiOjE3MDEwMjAwNDh9.IXoMuNecB7ARvZpEyx5SraMbdoZrHgADeHd7wAo0ddw
GET http://localhost:8080/api/v1/plants?page=0
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsdWthcy5rYXJzY2hAZ214LmRlIiwiaWF0IjoxNzAxMzcyNTIxLCJleHAiOjE3MDE0NTg5MjF9.8_rTh-5s4A6D1t_bdRdQFbM5RdNl2fpCLETpTQzInuc
### Get garden entries
GET http://localhost:8080/api/v1/garden
......
......@@ -25,6 +25,7 @@ public class Seeding {
return (args) -> {
if (plantRepository.count() > 0) {
log.info("Plants table is not empty, seeding will be skipped.");
log.info("If you wish to seed the database, manually clear the plants table and re-run the application.");
return;
}
......
package hdm.mi.growbros.controllers;
import hdm.mi.growbros.models.dto.CustomPageDto;
import hdm.mi.growbros.models.plant.Plant;
import hdm.mi.growbros.service.PlantsService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
@RestController
@CrossOrigin
@RequestMapping("/api/v1")
@RequiredArgsConstructor
public class PlantsController {
private final PlantsService plantsService;
public PlantsController(PlantsService plantsService) {
this.plantsService = plantsService;
@GetMapping("/plants")
public CustomPageDto<Plant> getAllPlants(
@RequestParam(value = "page", defaultValue = "0") int page,
@RequestParam(value = "pageSize", defaultValue = "25") int pageSize
) {
return plantsService.getPlants(page, pageSize);
}
@GetMapping("/api/v1/plants")
public Collection<Plant> getAllPlants() {
return plantsService.getPlants();
}
@GetMapping("api/v1/randomPlants/{numberOfPlants}")
@GetMapping("/randomPlants/{numberOfPlants}")
public Collection<Plant> getRandomPlants(@PathVariable Integer numberOfPlants) {return plantsService.getRandomPlants(numberOfPlants);}
@PostMapping("/api/v1/plants")
@PostMapping("/plants")
public void createPlant(@RequestBody @Valid Plant plant) {
plantsService.createPlant(plant);
}
......
package hdm.mi.growbros.models.dto;
import java.util.Collection;
public record CustomPageDto<T>(int currentPage, int pageSize, Collection<T> content) {
}
package hdm.mi.growbros.service;
import hdm.mi.growbros.models.dto.CustomPageDto;
import hdm.mi.growbros.models.plant.Plant;
import hdm.mi.growbros.repositories.PlantRepository;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
......@@ -16,11 +19,17 @@ import java.util.Random;
@RequiredArgsConstructor
public class PlantsService {
private final static Logger log = LoggerFactory.getLogger(PlantsService.class);
private final static int MAX_PAGE_SIZE = 100;
private final PlantRepository plantRepository;
public Collection<Plant> getPlants() {
return plantRepository.findAll();
public CustomPageDto<Plant> getPlants(int pageNumber, int pageSize) {
pageNumber = Math.max(0, pageNumber);
pageSize = Math.min(MAX_PAGE_SIZE, pageSize);
final Pageable page = PageRequest.of(pageNumber, pageSize);
List<Plant> pageContent = plantRepository.findAll(page).getContent();
return new CustomPageDto<>(pageNumber, pageContent.size(), pageContent);
}
public Collection<Plant> getRandomPlants(int numberOfPlants) {
......
package hdm.mi.growbros.service;
import hdm.mi.growbros.models.dto.CustomPageDto;
import hdm.mi.growbros.models.plant.Plant;
import hdm.mi.growbros.repositories.PlantRepository;
import org.junit.jupiter.api.Test;
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.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.context.ActiveProfiles;
import java.util.List;
import java.util.stream.IntStream;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@SpringBootTest
@ActiveProfiles("test")
class PlantsServiceTest {
@MockBean
private PlantRepository plantRepository;
@Autowired
private PlantsService plantsService;
@Test
void verify_repositoryCalled_withCorrectPageable() {
final PageRequest correctPageable = PageRequest.of(0, 10);
PageImpl<Plant> page = new PageImpl<>(List.of());
when(plantRepository.findAll(any(PageRequest.class)))
.thenReturn(page);
plantsService.getPlants(0, 10);
verify(plantRepository).findAll(correctPageable);
}
@Test
void getPlants_withPageEmpty() {
final PageRequest pageable = PageRequest.of(0, 10);
PageImpl<Plant> page = new PageImpl<>(List.of());
final CustomPageDto<Plant> expected = new CustomPageDto<>(0, 0, page.getContent());
when(plantRepository.findAll(pageable))
.thenReturn(page);
CustomPageDto<Plant> actual = plantsService.getPlants(0, 10);
assertAll(
() -> assertEquals(expected.currentPage(), actual.currentPage()),
() -> assertEquals(0, actual.pageSize()),
() -> assertEquals(expected.content(), actual.content())
);
}
@Test
void getPlants_correctPageSize() {
int plantAmount = 5;
var plants = getMockPlants(plantAmount);
final PageRequest pageable = PageRequest.of(0, 10);
PageImpl<Plant> page = new PageImpl<>(plants);
final CustomPageDto<Plant> expected = new CustomPageDto<>(0, plantAmount, page.getContent());
when(plantRepository.findAll(pageable))
.thenReturn(page);
CustomPageDto<Plant> actual = plantsService.getPlants(0, 10);
assertAll(
() -> assertEquals(expected.currentPage(), actual.currentPage()),
() -> assertEquals(plantAmount, actual.pageSize()),
() -> assertEquals(expected.content(), actual.content())
);
}
@Test
void getPlants_pageNumberNonNegative() {
int pageSize = 10;
final PageRequest correctPageRequest = PageRequest.of(0, pageSize);
when(plantRepository.findAll(any(PageRequest.class)))
.thenReturn(new PageImpl<>(List.of()));
plantsService.getPlants(-1, pageSize);
// calling the service with -1 as page number, and verifying that the repository is called
// with the correct page number
verify(plantRepository).findAll(correctPageRequest);
}
@Test
void pageSize_cappedAt_100() {
int pageNumber = 0;
final PageRequest correctPageRequest = PageRequest.of(pageNumber, 100);
when(plantRepository.findAll(any(PageRequest.class)))
.thenReturn(new PageImpl<>(List.of()));
plantsService.getPlants(pageNumber, 1000);
verify(plantRepository).findAll(correctPageRequest);
}
private List<Plant> getMockPlants(int amount) {
return IntStream
.range(0, amount)
.mapToObj(index -> Plant.builder().name(String.format("My generated plant %d", index)).build())
.toList();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment