diff --git a/src/main/java/com/tenniscourts/guests/GuestController.java b/src/main/java/com/tenniscourts/guests/GuestController.java new file mode 100644 index 00000000..47c382ab --- /dev/null +++ b/src/main/java/com/tenniscourts/guests/GuestController.java @@ -0,0 +1,69 @@ +package com.tenniscourts.guests; + +import com.tenniscourts.config.BaseRestController; +import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import java.util.List; +import java.util.Optional; + +@RequestMapping("/guests") +@RestController +@AllArgsConstructor +public class GuestController extends BaseRestController { + + @Autowired + private GuestService guestService; + + @ApiOperation("Find Guests by Id") + @GetMapping("/{id}") + public ResponseEntity> findById(@PathVariable Long id) { + return ResponseEntity.ok(guestService.findById(id)); + } + + @ApiOperation("Retrieve Guests List, with support to filter by name") + @GetMapping("/") + public ResponseEntity> listGuests(@RequestParam(value = "name", required = false) String name) { + if (name == null) { + return ResponseEntity.ok(guestService.listAllGuests()); + } + return ResponseEntity.ok(guestService.findByName(name)); + } + + @ApiOperation("Create a new Guest") + @PostMapping("/") + public ResponseEntity createGuest(@RequestBody @Valid GuestDTO guestDTO) { + return new ResponseEntity(guestService.createGuest(guestDTO), HttpStatus.CREATED); + } + + @ApiOperation("Update a Guest") + @PutMapping("/{id}") + public ResponseEntity> putGuest(@RequestBody @Valid GuestDTO guestDTO, @PathVariable Long id) { + Optional guest = guestService.putGuest(guestDTO, id); + if (guest.isPresent()) { + return ResponseEntity.ok(guest); + } + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + @ApiOperation("Delete a Guest") + @DeleteMapping("/{id}") + public ResponseEntity deleteGuest(@PathVariable Long id) { + guestService.deleteGuest(id); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + +} diff --git a/src/main/java/com/tenniscourts/guests/GuestDTO.java b/src/main/java/com/tenniscourts/guests/GuestDTO.java new file mode 100644 index 00000000..a03418d1 --- /dev/null +++ b/src/main/java/com/tenniscourts/guests/GuestDTO.java @@ -0,0 +1,16 @@ +package com.tenniscourts.guests; + +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Getter +@Setter +public class GuestDTO { + + @NotNull + @NotEmpty + public String name; +} diff --git a/src/main/java/com/tenniscourts/guests/GuestMapper.java b/src/main/java/com/tenniscourts/guests/GuestMapper.java new file mode 100644 index 00000000..5bb4ceb8 --- /dev/null +++ b/src/main/java/com/tenniscourts/guests/GuestMapper.java @@ -0,0 +1,14 @@ +package com.tenniscourts.guests; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; + +@Mapper(componentModel = "spring") +public interface GuestMapper { + + Guest map(GuestDTO source); + + @InheritInverseConfiguration + GuestDTO map(Guest source); + +} diff --git a/src/main/java/com/tenniscourts/guests/GuestRepository.java b/src/main/java/com/tenniscourts/guests/GuestRepository.java new file mode 100644 index 00000000..a7b8997f --- /dev/null +++ b/src/main/java/com/tenniscourts/guests/GuestRepository.java @@ -0,0 +1,13 @@ +package com.tenniscourts.guests; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface GuestRepository extends JpaRepository { + List findAll(); + + List findByName(String name); +} diff --git a/src/main/java/com/tenniscourts/guests/GuestService.java b/src/main/java/com/tenniscourts/guests/GuestService.java new file mode 100644 index 00000000..4aaa7959 --- /dev/null +++ b/src/main/java/com/tenniscourts/guests/GuestService.java @@ -0,0 +1,50 @@ +package com.tenniscourts.guests; + +import lombok.AllArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +@AllArgsConstructor +public class GuestService { + + @Autowired + private GuestRepository guestRepository; + + @Autowired + private GuestMapper guestMapper; + + public Guest createGuest(GuestDTO guestDTO) { + + Guest guest = guestMapper.map(guestDTO); + return guestRepository.save(guest); + } + + public List listAllGuests() { + return guestRepository.findAll(); + } + + public List findByName(String name) { + return guestRepository.findByName(name); + } + + public Optional findById(Long id) { + return guestRepository.findById(id); + } + + public void deleteGuest(Long id){ + guestRepository.deleteById(id); + } + + public Optional putGuest(GuestDTO guestDTO, Long id) { + Optional guest = guestRepository.findById(id); + return guest.map(value -> { + Guest newGuest = guestMapper.map(guestDTO); + newGuest.setId(id); + return guestRepository.save(newGuest); + }); + } +} diff --git a/src/main/java/com/tenniscourts/reservations/ReservationController.java b/src/main/java/com/tenniscourts/reservations/ReservationController.java index 2b1297b2..f42a329d 100644 --- a/src/main/java/com/tenniscourts/reservations/ReservationController.java +++ b/src/main/java/com/tenniscourts/reservations/ReservationController.java @@ -1,26 +1,43 @@ package com.tenniscourts.reservations; import com.tenniscourts.config.BaseRestController; +import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; @AllArgsConstructor +@RequestMapping("/reservation") +@RestController public class ReservationController extends BaseRestController { private final ReservationService reservationService; + @ApiOperation("Create a book reservation") + @PostMapping("/") public ResponseEntity bookReservation(CreateReservationRequestDTO createReservationRequestDTO) { return ResponseEntity.created(locationByEntity(reservationService.bookReservation(createReservationRequestDTO).getId())).build(); } + @ApiOperation("Find a reservation") + @GetMapping("/{id}") public ResponseEntity findReservation(Long reservationId) { return ResponseEntity.ok(reservationService.findReservation(reservationId)); } + @ApiOperation("Cancel a reservation") + @DeleteMapping("/{id}") public ResponseEntity cancelReservation(Long reservationId) { return ResponseEntity.ok(reservationService.cancelReservation(reservationId)); } + @ApiOperation("Reschedule a reservation") + @PutMapping("/{id}") public ResponseEntity rescheduleReservation(Long reservationId, Long scheduleId) { return ResponseEntity.ok(reservationService.rescheduleReservation(reservationId, scheduleId)); } diff --git a/src/main/java/com/tenniscourts/reservations/ReservationService.java b/src/main/java/com/tenniscourts/reservations/ReservationService.java index 14aa4436..9445d6d4 100644 --- a/src/main/java/com/tenniscourts/reservations/ReservationService.java +++ b/src/main/java/com/tenniscourts/reservations/ReservationService.java @@ -71,12 +71,11 @@ public BigDecimal getRefundValue(Reservation reservation) { return BigDecimal.ZERO; } - /*TODO: This method actually not fully working, find a way to fix the issue when it's throwing the error: - "Cannot reschedule to the same slot.*/ public ReservationDTO rescheduleReservation(Long previousReservationId, Long scheduleId) { Reservation previousReservation = cancel(previousReservationId); - if (scheduleId.equals(previousReservation.getSchedule().getId())) { + if (scheduleId.equals(previousReservation.getSchedule().getId()) && + previousReservation.getReservationStatus().name().equals(ReservationStatus.READY_TO_PLAY.name())) { throw new IllegalArgumentException("Cannot reschedule to the same slot."); } diff --git a/src/main/java/com/tenniscourts/schedules/ScheduleController.java b/src/main/java/com/tenniscourts/schedules/ScheduleController.java index 7613e89d..4f0dce9c 100644 --- a/src/main/java/com/tenniscourts/schedules/ScheduleController.java +++ b/src/main/java/com/tenniscourts/schedules/ScheduleController.java @@ -1,32 +1,56 @@ package com.tenniscourts.schedules; import com.tenniscourts.config.BaseRestController; +import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import javax.validation.Valid; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.List; +import java.util.Optional; @AllArgsConstructor +@RequestMapping("/schedule") +@RestController public class ScheduleController extends BaseRestController { - private final ScheduleService scheduleService; + @Autowired + private ScheduleService scheduleService; - //TODO: implement rest and swagger - public ResponseEntity addScheduleTennisCourt(CreateScheduleRequestDTO createScheduleRequestDTO) { + @ApiOperation("Register a schedule") + @PostMapping("/") + public ResponseEntity addScheduleTennisCourt(@RequestBody @Valid CreateScheduleRequestDTO createScheduleRequestDTO) { return ResponseEntity.created(locationByEntity(scheduleService.addSchedule(createScheduleRequestDTO.getTennisCourtId(), createScheduleRequestDTO).getId())).build(); } - //TODO: implement rest and swagger - public ResponseEntity> findSchedulesByDates(LocalDate startDate, - LocalDate endDate) { + @ApiOperation("Find schedules by timestamp") + @GetMapping("/") + public ResponseEntity> findSchedulesByDates( + @RequestParam(value = "startDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate, + @RequestParam(value = "endDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) { return ResponseEntity.ok(scheduleService.findSchedulesByDates(LocalDateTime.of(startDate, LocalTime.of(0, 0)), LocalDateTime.of(endDate, LocalTime.of(23, 59)))); } - //TODO: implement rest and swagger - public ResponseEntity findByScheduleId(Long scheduleId) { - return ResponseEntity.ok(scheduleService.findSchedule(scheduleId)); + @ApiOperation("Retrieve schedule by given id") + @GetMapping("/{scheduleId}") + public ResponseEntity> findByScheduleId(@PathVariable Long scheduleId) { + Optional scheduleDTO = scheduleService.findSchedule(scheduleId); + if (scheduleDTO.isPresent()) { + return ResponseEntity.ok(scheduleDTO); + } + return new ResponseEntity<>(HttpStatus.NOT_FOUND); } } diff --git a/src/main/java/com/tenniscourts/schedules/ScheduleRepository.java b/src/main/java/com/tenniscourts/schedules/ScheduleRepository.java index 12a44c6d..45042a7c 100644 --- a/src/main/java/com/tenniscourts/schedules/ScheduleRepository.java +++ b/src/main/java/com/tenniscourts/schedules/ScheduleRepository.java @@ -2,9 +2,13 @@ import org.springframework.data.jpa.repository.JpaRepository; +import java.time.LocalDateTime; import java.util.List; public interface ScheduleRepository extends JpaRepository { List findByTennisCourt_IdOrderByStartDateTime(Long id); + + List findAllByStartDateTimeIsGreaterThanEqualAndEndDateTimeIsLessThanEqual( + LocalDateTime startDateTime, LocalDateTime endDateTime); } \ No newline at end of file diff --git a/src/main/java/com/tenniscourts/schedules/ScheduleService.java b/src/main/java/com/tenniscourts/schedules/ScheduleService.java index 5d94ee1a..5a1fe05d 100644 --- a/src/main/java/com/tenniscourts/schedules/ScheduleService.java +++ b/src/main/java/com/tenniscourts/schedules/ScheduleService.java @@ -1,32 +1,57 @@ package com.tenniscourts.schedules; +import com.tenniscourts.exceptions.AlreadyExistsEntityException; +import com.tenniscourts.tenniscourts.TennisCourt; +import com.tenniscourts.tenniscourts.TennisCourtRepository; import lombok.AllArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; @Service @AllArgsConstructor public class ScheduleService { - private final ScheduleRepository scheduleRepository; + @Autowired + private ScheduleRepository scheduleRepository; - private final ScheduleMapper scheduleMapper; + @Autowired + private TennisCourtRepository tennisCourtRepository; + + @Autowired + private ScheduleMapper scheduleMapper; public ScheduleDTO addSchedule(Long tennisCourtId, CreateScheduleRequestDTO createScheduleRequestDTO) { - //TODO: implement addSchedule - return null; + LocalDateTime startDateTime = createScheduleRequestDTO.getStartDateTime(); + LocalDateTime endDateTime = startDateTime.plusHours(1); + List scheduleDTOList = findSchedulesByTennisCourtId(tennisCourtId); + if(scheduleDTOList.stream().anyMatch(l -> l.getStartDateTime().isAfter(startDateTime) && l.getStartDateTime().isBefore(endDateTime))){ + throw new AlreadyExistsEntityException("The schedule already exist"); + } + + TennisCourt tennisCourt = tennisCourtRepository.getOne(tennisCourtId); + + Schedule schedule = Schedule.builder() + .tennisCourt(tennisCourt) + .startDateTime(startDateTime).endDateTime(endDateTime).build(); + + scheduleRepository.save(schedule); + + return scheduleMapper.map(schedule); } public List findSchedulesByDates(LocalDateTime startDate, LocalDateTime endDate) { - //TODO: implement - return null; + List scheduleList = scheduleRepository. + findAllByStartDateTimeIsGreaterThanEqualAndEndDateTimeIsLessThanEqual(startDate, endDate); + return scheduleMapper.map(scheduleList); } - public ScheduleDTO findSchedule(Long scheduleId) { - //TODO: implement - return null; + public Optional findSchedule(Long scheduleId) { + Optional schedule = scheduleRepository.findById(scheduleId); + return schedule.map(scheduleMapper::map); } public List findSchedulesByTennisCourtId(Long tennisCourtId) { diff --git a/src/main/java/com/tenniscourts/tenniscourts/TennisCourtController.java b/src/main/java/com/tenniscourts/tenniscourts/TennisCourtController.java index a014bdc6..bcc754b2 100644 --- a/src/main/java/com/tenniscourts/tenniscourts/TennisCourtController.java +++ b/src/main/java/com/tenniscourts/tenniscourts/TennisCourtController.java @@ -1,26 +1,40 @@ package com.tenniscourts.tenniscourts; import com.tenniscourts.config.BaseRestController; +import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; @AllArgsConstructor +@RequestMapping("/courts") +@RestController public class TennisCourtController extends BaseRestController { private final TennisCourtService tennisCourtService; - //TODO: implement rest and swagger - public ResponseEntity addTennisCourt(TennisCourtDTO tennisCourtDTO) { + @ApiOperation("Register a new tennis court") + @PostMapping("/") + public ResponseEntity addTennisCourt(@RequestBody @Valid TennisCourtDTO tennisCourtDTO) { return ResponseEntity.created(locationByEntity(tennisCourtService.addTennisCourt(tennisCourtDTO).getId())).build(); } - //TODO: implement rest and swagger - public ResponseEntity findTennisCourtById(Long tennisCourtId) { + @ApiOperation("Find court by id") + @GetMapping("/{tennisCourtId}") + public ResponseEntity findTennisCourtById(@PathVariable Long tennisCourtId) { return ResponseEntity.ok(tennisCourtService.findTennisCourtById(tennisCourtId)); } - //TODO: implement rest and swagger - public ResponseEntity findTennisCourtWithSchedulesById(Long tennisCourtId) { + @ApiOperation(value = "Finds a tennis court by id, retrieving its schedules") + @GetMapping(value = "/{tennisCourtId}/schedules") + public ResponseEntity findTennisCourtWithSchedulesById(@PathVariable Long tennisCourtId) { return ResponseEntity.ok(tennisCourtService.findTennisCourtWithSchedulesById(tennisCourtId)); } } diff --git a/src/test/java/com/tenniscourts/guests/GuestControllerTest.java b/src/test/java/com/tenniscourts/guests/GuestControllerTest.java new file mode 100644 index 00000000..c45e303d --- /dev/null +++ b/src/test/java/com/tenniscourts/guests/GuestControllerTest.java @@ -0,0 +1,112 @@ +package com.tenniscourts.guests; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import java.util.List; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.any; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@SpringBootTest +public class GuestControllerTest { + + private MockMvc mockMvc; + + @Mock + private GuestService guestService; + + @InjectMocks + private GuestController guestController; + + ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); + + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mockMvc = MockMvcBuilders.standaloneSetup(guestController).build(); + } + + @Test + public void functionListGuestsShouldReturnAllGuests() throws Exception { + List guestList = List.of(Guest.builder().name("Maria").build(), Guest.builder().name("Matheus").build()); + Mockito.when(guestService.listAllGuests()).thenReturn(guestList); + mockMvc.perform(get("/guests/").contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json(ow.writeValueAsString(guestList))); + } + + @Test + public void functionListGuestsShouldReturnAllGuestsWithGivenName() throws Exception { + Guest expectedGuest = Guest.builder().name("Laura").build(); + + Mockito.when(guestService.findByName("Matheus")).thenReturn(List.of(expectedGuest)); + mockMvc.perform(get("/guests/?name=Matheus").contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json(ow.writeValueAsString(List.of(expectedGuest)))); + } + + @Test + public void functionFindByIdShouldReturnGuestWithMatchedID() throws Exception { + Guest expectedGuest = Guest.builder().name("Laura").build(); + expectedGuest.setId(123L); + + Mockito.when(guestService.findById(123L)).thenReturn(Optional.of(expectedGuest)); + mockMvc.perform(get("/guests/123").contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json(ow.writeValueAsString(expectedGuest))); + } + + @Test + public void functionCreateGuestShouldAddANewGuest() throws Exception { + GuestDTO guestDTO = new GuestDTO(); + guestDTO.setName("Matheus"); + + Guest expectedGuest = Guest.builder().name("Matheus").build(); + Mockito.when(guestService.createGuest(guestDTO)).thenReturn(expectedGuest); + mockMvc.perform(post("/guests/") + .contentType(MediaType.APPLICATION_JSON) + .content(ow.writeValueAsString(guestDTO))) + .andExpect(status().isCreated()); + } + + @Test + public void functionPutGuestShouldUpdateGuestWithGivenId() throws Exception { + GuestDTO guestDTO = new GuestDTO(); + guestDTO.setName("Matheus"); + Guest expectedGuest = Guest.builder().name("Matheus").build(); + + Mockito.when(guestService.putGuest(any(), any())).thenReturn(Optional.of(expectedGuest)); + mockMvc.perform(put("/guests/1").contentType(MediaType.APPLICATION_JSON) + .content(ow.writeValueAsString(guestDTO))) + .andExpect(status().isOk()) + .andExpect(content().json(ow.writeValueAsString(expectedGuest))); + } + + @Test + public void functionDeleteGuestShouldDeleteGuestWithGivenId() throws Exception { + mockMvc.perform(delete("/guests/1")) + .andExpect(status().isNoContent()); + } + +} diff --git a/src/test/java/com/tenniscourts/guests/GuestServiceTest.java b/src/test/java/com/tenniscourts/guests/GuestServiceTest.java new file mode 100644 index 00000000..d3a09e27 --- /dev/null +++ b/src/test/java/com/tenniscourts/guests/GuestServiceTest.java @@ -0,0 +1,91 @@ +package com.tenniscourts.guests; + +import com.tenniscourts.reservations.ReservationService; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@SpringBootTest +@RunWith(MockitoJUnitRunner.class) +@ContextConfiguration(classes = ReservationService.class) +public class GuestServiceTest { + + @Mock + private GuestRepository guestRepository; + + @Mock + private GuestMapper guestMapper; + + @InjectMocks + private GuestService guestService; + + @Test + public void functionCreateGuestShouldAddANewGuest() { + GuestDTO guestDTO = new GuestDTO(); + guestDTO.setName("Matheus"); + Guest guest = Guest.builder().name("Matheus").build(); + when(guestRepository.save(any())).thenReturn(guest); + + assertEquals(guestService.createGuest(guestDTO), guest); + + } + + @Test + public void functionPutGuestShouldUpdateGuestByGivenId() { + Guest guest = Guest.builder().name("Matheus").build(); + guest.setId(1L); + GuestDTO guestDTO = new GuestDTO(); + guestDTO.setName("Ana"); + Guest expectedGuest = Guest.builder().name("Ana").build(); + when(guestRepository.findById(1L)).thenReturn(Optional.of(guest)); + when(guestMapper.map(guestDTO)).thenReturn(expectedGuest); + when(guestRepository.save(expectedGuest)).thenReturn(expectedGuest); + + assertEquals(guestService.putGuest(guestDTO, 1L), Optional.of(expectedGuest)); + } + + @Test + public void functionDeleteGuestShouldDeleteGuestByGivenId() { + assertDoesNotThrow(() -> guestService.deleteGuest(1L)); + } + + @Test + public void functionFindAllGuestShouldRetrieveAllGuests() { + List guestList = List.of(Guest.builder().name("Maria").build(), Guest.builder().name("Matheus").build()); + Mockito.when(guestRepository.findAll()).thenReturn(guestList); + + assertEquals(guestService.listAllGuests(), guestList); + } + + @Test + public void functionFindByIdGuestShouldRetrieveGuestWithGivenId() { + Guest expectedGuest = Guest.builder().name("Laura").build(); + Mockito.when(guestRepository.findById(1L)).thenReturn(Optional.of(expectedGuest)); + + assertEquals(guestService.findById(1L), Optional.of(expectedGuest)); + } + + @Test + public void functionFindByNameGuestShouldRetrieveGuestWithGivenName() { + Guest expectedGuest = Guest.builder().name("Laura").build(); + Mockito.when(guestRepository.findByName("Laura")).thenReturn(List.of(expectedGuest)); + + assertEquals(guestService.findByName("Laura"), List.of(expectedGuest)); + } +} diff --git a/src/test/java/com/tenniscourts/schedule/ScheduleControllerTest.java b/src/test/java/com/tenniscourts/schedule/ScheduleControllerTest.java new file mode 100644 index 00000000..f89a8513 --- /dev/null +++ b/src/test/java/com/tenniscourts/schedule/ScheduleControllerTest.java @@ -0,0 +1,97 @@ +package com.tenniscourts.schedule; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.tenniscourts.schedules.Schedule; +import com.tenniscourts.schedules.ScheduleController; +import com.tenniscourts.schedules.ScheduleDTO; +import com.tenniscourts.schedules.ScheduleMapper; +import com.tenniscourts.schedules.ScheduleMapperImpl; +import com.tenniscourts.schedules.ScheduleService; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.List; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.any; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {ScheduleMapperImpl.class}) +public class ScheduleControllerTest { + + private MockMvc mockMvc; + + @Mock + private ScheduleService scheduleService; + + @Autowired + private ScheduleMapper scheduleMapper; + + @InjectMocks + private ScheduleController scheduleController; + + ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); + + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mockMvc = MockMvcBuilders.standaloneSetup(scheduleController).build(); + } + + @Test + public void functionFindAllSchedulesByGivenTimestamp() throws Exception { + List scheduleList = List.of(Schedule.builder() + .startDateTime(LocalDateTime.of(LocalDate.of(2022, 3, 3), LocalTime.of(0, 0))).build()); + Mockito.when(scheduleService.findSchedulesByDates(any(), any())).thenReturn(scheduleMapper.map(scheduleList)); + mockMvc.perform(get("/schedule/?startDate=2022-03-03&endDate=2022-03-03")) + .andExpect(status().isOk()) + .andExpect(content().string("[{\"id\":null,\"tennisCourt\":null,\"tennisCourtId\":null,\"startDateTime\":\"2022-03-03T00:00\",\"endDateTime\":null}]")); + } + + @Test + public void functionFindScheduleByGivenId() throws Exception { + Optional scheduleDTO = Optional.of(new ScheduleDTO()); + scheduleDTO.get().setId(1L); + Mockito.when(scheduleService.findSchedule(any())).thenReturn(scheduleDTO); + mockMvc.perform(get("/schedule/1")) + .andExpect(status().isOk()) + .andExpect(content().json(ow.writeValueAsString(scheduleDTO.get()))); + } + + @Test + public void functionAddScheduleTennisCourtShouldCreateNewSchedule() throws Exception { + Schedule schedule = Schedule.builder() + .startDateTime(LocalDateTime.of(LocalDate.of(2022, 3, 3), + LocalTime.of(0, 0))).build(); + ScheduleDTO scheduleDTO = scheduleMapper.map(schedule); + Mockito.when(scheduleService.addSchedule(any(), any())).thenReturn(scheduleDTO); + mockMvc.perform(post("/schedule/") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"tennisCourtId\":1,\"startDateTime\":\"2022-03-10T12:00\"}")) + .andExpect(status().isCreated()); + } + +}