diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/api/project/data/ProjectResponse.java b/corn-backend/src/main/java/dev/corn/cornbackend/api/project/data/ProjectResponse.java index 4c3132a1..10d6af24 100644 --- a/corn-backend/src/main/java/dev/corn/cornbackend/api/project/data/ProjectResponse.java +++ b/corn-backend/src/main/java/dev/corn/cornbackend/api/project/data/ProjectResponse.java @@ -1,6 +1,6 @@ package dev.corn.cornbackend.api.project.data; -import dev.corn.cornbackend.entities.sprint.data.SprintResponse; +import dev.corn.cornbackend.api.sprint.data.SprintResponse; import lombok.Builder; import java.util.List; diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/SprintControllerImpl.java b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/SprintControllerImpl.java new file mode 100644 index 00000000..7a9519d4 --- /dev/null +++ b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/SprintControllerImpl.java @@ -0,0 +1,87 @@ +package dev.corn.cornbackend.api.sprint; + +import dev.corn.cornbackend.api.sprint.data.SprintRequest; +import dev.corn.cornbackend.api.sprint.data.SprintResponse; +import dev.corn.cornbackend.api.sprint.interfaces.SprintController; +import dev.corn.cornbackend.api.sprint.interfaces.SprintService; +import dev.corn.cornbackend.config.jwtprocessing.JwtAuthed; +import dev.corn.cornbackend.entities.user.User; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +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 java.time.LocalDate; +import java.util.List; + +import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.ADD_SPRINT; +import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.DELETE_SPRINT; +import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.GET_SPRINTS_ON_PAGE; +import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.GET_SPRINT_BY_ID; +import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.SPRINT_API_ENDPOINT; +import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.UPDATE_SPRINTS_DESCRIPTION; +import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.UPDATE_SPRINTS_END_DATE; +import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.UPDATE_SPRINTS_NAME; +import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.UPDATE_SPRINTS_START_DATE; + +@RestController +@RequiredArgsConstructor +@RequestMapping(value = SPRINT_API_ENDPOINT) +public class SprintControllerImpl implements SprintController { + + private final SprintService sprintService; + + @Override + @PostMapping(value = ADD_SPRINT) + public SprintResponse addNewSprint(@RequestBody SprintRequest sprintRequest, @JwtAuthed User user) { + return sprintService.addNewSprint(sprintRequest, user); + } + + @Override + @GetMapping(value = GET_SPRINT_BY_ID) + public SprintResponse getSprintById(@RequestParam long sprintId, @JwtAuthed User user) { + return sprintService.getSprintById(sprintId, user); + } + + @Override + @GetMapping(value = GET_SPRINTS_ON_PAGE) + public List getSprintsOnPage(@RequestParam int page, @RequestParam long projectId, @JwtAuthed User user) { + return sprintService.getSprintsOnPage(page, projectId, user); + } + + @Override + @PatchMapping(value = UPDATE_SPRINTS_NAME) + public SprintResponse updateSprintsName(@RequestParam String name, @RequestParam long sprintId, @JwtAuthed User user) { + return sprintService.updateSprintsName(name, sprintId, user); + } + + @Override + @PatchMapping(value = UPDATE_SPRINTS_DESCRIPTION) + public SprintResponse updateSprintsDescription(@RequestParam String description, @RequestParam long sprintId, @JwtAuthed User user) { + return sprintService.updateSprintsDescription(description, sprintId, user); + } + + @Override + @PatchMapping(value = UPDATE_SPRINTS_START_DATE) + public SprintResponse updateSprintsStartDate(@RequestParam LocalDate startDate, @RequestParam long sprintId, @JwtAuthed User user) { + return sprintService.updateSprintsStartDate(startDate, sprintId, user); + } + + @Override + @PatchMapping(value = UPDATE_SPRINTS_END_DATE) + public SprintResponse updateSprintsEndDate(@RequestParam LocalDate endDate, @RequestParam long sprintId, @JwtAuthed User user) { + return sprintService.updateSprintsEndDate(endDate, sprintId, user); + } + + @Override + @DeleteMapping(value = DELETE_SPRINT) + public SprintResponse deleteSprint(@RequestParam long sprintId, @JwtAuthed User user) { + return sprintService.deleteSprint(sprintId, user); + } + +} diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/SprintServiceImpl.java b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/SprintServiceImpl.java new file mode 100644 index 00000000..a43b366a --- /dev/null +++ b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/SprintServiceImpl.java @@ -0,0 +1,170 @@ +package dev.corn.cornbackend.api.sprint; + +import dev.corn.cornbackend.api.sprint.data.SprintRequest; +import dev.corn.cornbackend.api.sprint.data.SprintResponse; +import dev.corn.cornbackend.api.sprint.interfaces.SprintService; +import dev.corn.cornbackend.entities.sprint.Sprint; +import dev.corn.cornbackend.entities.sprint.interfaces.SprintMapper; +import dev.corn.cornbackend.entities.sprint.interfaces.SprintRepository; +import dev.corn.cornbackend.entities.user.User; +import dev.corn.cornbackend.utils.exceptions.sprint.SprintDoesNotExistException; +import dev.corn.cornbackend.utils.exceptions.sprint.SprintEndDateMustBeAfterStartDate; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class SprintServiceImpl implements SprintService { + public static final int SPRINTS_PER_PAGE = 20; + private final SprintRepository sprintRepository; + private final SprintMapper sprintMapper; + + @Override + public final SprintResponse addNewSprint(SprintRequest sprintRequest, User user) { + //auth user + + if (sprintRequest.endDate().isBefore(sprintRequest.startDate())) { + throw new SprintEndDateMustBeAfterStartDate(sprintRequest.startDate(), sprintRequest.endDate()); + } + Sprint sprint = Sprint + .builder() + .sprintName(sprintRequest.name()) + .sprintStartDate(sprintRequest.startDate()) + .sprintEndDate(sprintRequest.endDate()) + .sprintDescription(sprintRequest.description()) + .build(); + log.info("Instantiated sprint: {}", sprint); + + Sprint newSprint = sprintRepository.save(sprint); + log.info("Saved sprint: {}", sprint); + + return sprintMapper.toSprintResponse(newSprint); + } + + @Override + public final SprintResponse getSprintById(long sprintId, User user) { + log.info("Getting sprint with id: {} for user: {}", sprintId, user); + + //auth user + + Sprint sprint = sprintRepository.findById(sprintId) + .orElseThrow(() -> new SprintDoesNotExistException(sprintId)); + log.info("Sprint found : {}", sprint); + + return sprintMapper.toSprintResponse(sprint); + } + + @Override + public final List getSprintsOnPage(int page, long projectId, User user) { + log.info("Getting sprints in project {} on page: {} for user: {}", projectId, page, user); + + //auth user + + Pageable pageable = PageRequest.of(page, SPRINTS_PER_PAGE); + Page sprints = sprintRepository.findAllByProjectId(projectId, pageable); + log.info("Sprints found on page : {}", sprints.getTotalElements()); + + return sprints.map(sprintMapper::toSprintResponse).toList(); + } + + @Override + public final SprintResponse updateSprintsName(String name, long sprintId, User user) { + log.info("Updating sprint with id: {} name to: {}", sprintId, name); + + //auth user + + Sprint sprintToUpdate = sprintRepository.findById(sprintId) + .orElseThrow(() -> new SprintDoesNotExistException(sprintId)); + log.info("Found sprint to update: {}", sprintToUpdate); + + sprintToUpdate.setSprintName(name); + Sprint updatedSprint = sprintRepository.save(sprintToUpdate); + log.info("Updated sprint: {}", updatedSprint); + + return sprintMapper.toSprintResponse(updatedSprint); + } + + @Override + public final SprintResponse updateSprintsDescription(String description, long sprintId, User user) { + log.info("Updating sprint with id: {} description to: {}", sprintId, description); + + //auth user + + Sprint sprintToUpdate = sprintRepository.findById(sprintId) + .orElseThrow(() -> new SprintDoesNotExistException(sprintId)); + log.info("Found sprint to update: {}", sprintToUpdate); + + sprintToUpdate.setSprintDescription(description); + Sprint updatedSprint = sprintRepository.save(sprintToUpdate); + log.info("Updated sprint: {}", updatedSprint); + + return sprintMapper.toSprintResponse(updatedSprint); + } + + @Override + public final SprintResponse updateSprintsStartDate(LocalDate startDate, long sprintId, User user) { + log.info("Updating sprint with id: {} startDate to: {}", sprintId, startDate); + + //auth user + + Sprint sprintToUpdate = sprintRepository.findById(sprintId) + .orElseThrow(() -> new SprintDoesNotExistException(sprintId)); + log.info("Found sprint to update: {}", sprintToUpdate); + + if (sprintToUpdate.isEndBefore(startDate)) { + throw new SprintEndDateMustBeAfterStartDate(startDate, sprintToUpdate.getSprintEndDate()); + } + + sprintToUpdate.setSprintStartDate(startDate); + Sprint updatedSprint = sprintRepository.save(sprintToUpdate); + log.info("Updated sprint: {}", updatedSprint); + + return sprintMapper.toSprintResponse(updatedSprint); + } + + @Override + public final SprintResponse updateSprintsEndDate(LocalDate endDate, long sprintId, User user) { + log.info("Updating sprint with id: {} endDate to: {}", sprintId, endDate); + + //auth user + + Sprint sprintToUpdate = sprintRepository.findById(sprintId) + .orElseThrow(() -> new SprintDoesNotExistException(sprintId)); + log.info("Found sprint to update: {}", sprintToUpdate); + + if (sprintToUpdate.isStartAfter(endDate)) { + throw new SprintEndDateMustBeAfterStartDate(sprintToUpdate.getSprintStartDate(), endDate); + } + + sprintToUpdate.setSprintEndDate(endDate); + Sprint updatedSprint = sprintRepository.save(sprintToUpdate); + log.info("Updated sprint: {}", updatedSprint); + + return sprintMapper.toSprintResponse(sprintToUpdate); + } + + @Override + public final SprintResponse deleteSprint(long sprintId, User user) { + log.info("Deleting sprint with id: {}", sprintId); + + //auth user + + Sprint sprintToDelete = sprintRepository.findById(sprintId) + .orElseThrow(() -> new SprintDoesNotExistException(sprintId)); + log.info("Found sprint to delete: {}", sprintToDelete); + + sprintRepository.deleteById(sprintId); + log.info("Deleted sprint with id: {}", sprintToDelete); + + return sprintMapper.toSprintResponse(sprintToDelete); + } + +} diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/constants/SprintMappings.java b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/constants/SprintMappings.java new file mode 100644 index 00000000..7dceaa94 --- /dev/null +++ b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/constants/SprintMappings.java @@ -0,0 +1,22 @@ +package dev.corn.cornbackend.api.sprint.constants; + +public final class SprintMappings { + + private SprintMappings() { + } + + public static final String SPRINT_API_ENDPOINT = "/api/v1/sprint"; + + public static final String GET_SPRINTS_ON_PAGE = "/getSprintsOnPage"; + + public static final String GET_SPRINT_BY_ID = "/getSprintById"; + + public static final String ADD_SPRINT = "/addSprint"; + + public static final String UPDATE_SPRINTS_NAME = "/updateSprintsName"; + public static final String UPDATE_SPRINTS_DESCRIPTION = "/updateSprintsName"; + public static final String UPDATE_SPRINTS_START_DATE = "/updateSprintsName"; + public static final String UPDATE_SPRINTS_END_DATE = "/updateSprintsName"; + + public static final String DELETE_SPRINT = "/deleteSprint"; +} diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/data/SprintRequest.java b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/data/SprintRequest.java new file mode 100644 index 00000000..f26e68da --- /dev/null +++ b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/data/SprintRequest.java @@ -0,0 +1,9 @@ +package dev.corn.cornbackend.api.sprint.data; + +import lombok.Builder; + +import java.time.LocalDate; + +@Builder +public record SprintRequest(String name, LocalDate startDate, LocalDate endDate, String description) { +} diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/data/SprintResponse.java b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/data/SprintResponse.java new file mode 100644 index 00000000..4e127019 --- /dev/null +++ b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/data/SprintResponse.java @@ -0,0 +1,10 @@ +package dev.corn.cornbackend.api.sprint.data; + +import lombok.Builder; + +import java.time.LocalDate; + +@Builder +public record SprintResponse(long sprintId, long projectId, String sprintName, String sprintDescription, + LocalDate sprintStartDate, LocalDate sprintEndDate) { +} diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/interfaces/SprintController.java b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/interfaces/SprintController.java new file mode 100644 index 00000000..77920585 --- /dev/null +++ b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/interfaces/SprintController.java @@ -0,0 +1,29 @@ +package dev.corn.cornbackend.api.sprint.interfaces; + +import dev.corn.cornbackend.api.sprint.data.SprintRequest; +import dev.corn.cornbackend.api.sprint.data.SprintResponse; +import dev.corn.cornbackend.entities.project.Project; +import dev.corn.cornbackend.entities.user.User; + +import java.time.LocalDate; +import java.util.List; + +public interface SprintController { + + SprintResponse addNewSprint(SprintRequest sprintRequest, User user); + + SprintResponse getSprintById(long sprintId, User user); + + List getSprintsOnPage(int page, long projectId, User user); + + SprintResponse updateSprintsName(String name, long sprintId, User user); + + SprintResponse updateSprintsDescription(String description, long sprintId, User user); + + SprintResponse updateSprintsStartDate(LocalDate startDate, long sprintId, User user); + + SprintResponse updateSprintsEndDate(LocalDate endDate, long sprintId, User user); + + SprintResponse deleteSprint(long sprintId, User user); + +} diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/interfaces/SprintService.java b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/interfaces/SprintService.java new file mode 100644 index 00000000..2e333d4b --- /dev/null +++ b/corn-backend/src/main/java/dev/corn/cornbackend/api/sprint/interfaces/SprintService.java @@ -0,0 +1,29 @@ +package dev.corn.cornbackend.api.sprint.interfaces; + +import dev.corn.cornbackend.api.sprint.data.SprintRequest; +import dev.corn.cornbackend.api.sprint.data.SprintResponse; +import dev.corn.cornbackend.entities.project.Project; +import dev.corn.cornbackend.entities.user.User; + +import java.time.LocalDate; +import java.util.List; + +public interface SprintService { + + SprintResponse addNewSprint(SprintRequest sprintRequest, User user); + + SprintResponse getSprintById(long sprintId, User user); + + List getSprintsOnPage(int page, long projectId, User user); + + SprintResponse updateSprintsName(String name, long sprintId, User user); + + SprintResponse updateSprintsDescription(String description, long sprintId, User user); + + SprintResponse updateSprintsStartDate(LocalDate startDate, long sprintId, User user); + + SprintResponse updateSprintsEndDate(LocalDate endDate, long sprintId, User user); + + SprintResponse deleteSprint(long sprintId, User user); + +} diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/entities/project/interfaces/ProjectMapper.java b/corn-backend/src/main/java/dev/corn/cornbackend/entities/project/interfaces/ProjectMapper.java index 720cb2d1..27e91ee9 100644 --- a/corn-backend/src/main/java/dev/corn/cornbackend/entities/project/interfaces/ProjectMapper.java +++ b/corn-backend/src/main/java/dev/corn/cornbackend/entities/project/interfaces/ProjectMapper.java @@ -2,13 +2,10 @@ import dev.corn.cornbackend.api.project.data.ProjectResponse; import dev.corn.cornbackend.entities.project.Project; -import dev.corn.cornbackend.entities.sprint.Sprint; -import dev.corn.cornbackend.entities.sprint.data.SprintResponse; import org.mapstruct.Mapper; @Mapper(componentModel = "spring") public interface ProjectMapper { ProjectResponse toProjectResponse(Project project); - SprintResponse toSprintResponse(Sprint sprint); } diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/Sprint.java b/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/Sprint.java index 77af0710..6d17be83 100644 --- a/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/Sprint.java +++ b/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/Sprint.java @@ -94,6 +94,22 @@ public final int hashCode() { return result; } + public boolean isStartBefore(LocalDate date) { + return sprintStartDate.isBefore(date); + } + + public boolean isStartAfter(LocalDate date) { + return sprintStartDate.isAfter(date); + } + + public boolean isEndBefore(LocalDate date) { + return sprintEndDate.isBefore(date); + } + + public boolean isEndAfter(LocalDate date) { + return sprintEndDate.isAfter(date); + } + @Override public final String toJson() { return JsonMapper.toJson(this); diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/data/SprintResponse.java b/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/data/SprintResponse.java deleted file mode 100644 index b13f4ce3..00000000 --- a/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/data/SprintResponse.java +++ /dev/null @@ -1,4 +0,0 @@ -package dev.corn.cornbackend.entities.sprint.data; - -public record SprintResponse() { -} diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/interfaces/SprintMapper.java b/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/interfaces/SprintMapper.java index 979ab1ad..9d2be860 100644 --- a/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/interfaces/SprintMapper.java +++ b/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/interfaces/SprintMapper.java @@ -1,7 +1,7 @@ package dev.corn.cornbackend.entities.sprint.interfaces; import dev.corn.cornbackend.entities.sprint.Sprint; -import dev.corn.cornbackend.entities.sprint.data.SprintResponse; +import dev.corn.cornbackend.api.sprint.data.SprintResponse; import org.mapstruct.Mapper; @Mapper(componentModel = "spring") diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/interfaces/SprintRepository.java b/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/interfaces/SprintRepository.java new file mode 100644 index 00000000..7b1da662 --- /dev/null +++ b/corn-backend/src/main/java/dev/corn/cornbackend/entities/sprint/interfaces/SprintRepository.java @@ -0,0 +1,17 @@ +package dev.corn.cornbackend.entities.sprint.interfaces; + +import dev.corn.cornbackend.entities.sprint.Sprint; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +@Repository +public interface SprintRepository extends JpaRepository { + + + @Query("SELECT s FROM Sprint s WHERE s.project.projectId = ?1") + Page findAllByProjectId(long projectId, Pageable pageable); + +} \ No newline at end of file diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/utils/exceptions/sprint/SprintDoesNotExistException.java b/corn-backend/src/main/java/dev/corn/cornbackend/utils/exceptions/sprint/SprintDoesNotExistException.java new file mode 100644 index 00000000..f04ea154 --- /dev/null +++ b/corn-backend/src/main/java/dev/corn/cornbackend/utils/exceptions/sprint/SprintDoesNotExistException.java @@ -0,0 +1,14 @@ +package dev.corn.cornbackend.utils.exceptions.sprint; + +import dev.corn.cornbackend.utils.exceptions.AbstractException; +import org.springframework.http.HttpStatus; + +public class SprintDoesNotExistException extends AbstractException { + + public SprintDoesNotExistException(long id) { + super(HttpStatus.NOT_FOUND, String.format( + "Sprint with id %d does not exist", + id + )); + } +} diff --git a/corn-backend/src/main/java/dev/corn/cornbackend/utils/exceptions/sprint/SprintEndDateMustBeAfterStartDate.java b/corn-backend/src/main/java/dev/corn/cornbackend/utils/exceptions/sprint/SprintEndDateMustBeAfterStartDate.java new file mode 100644 index 00000000..d9df4f60 --- /dev/null +++ b/corn-backend/src/main/java/dev/corn/cornbackend/utils/exceptions/sprint/SprintEndDateMustBeAfterStartDate.java @@ -0,0 +1,16 @@ +package dev.corn.cornbackend.utils.exceptions.sprint; + +import dev.corn.cornbackend.utils.exceptions.AbstractException; +import org.springframework.http.HttpStatus; + +import java.time.LocalDate; + +public class SprintEndDateMustBeAfterStartDate extends AbstractException { + + public SprintEndDateMustBeAfterStartDate(LocalDate startDate, LocalDate endDate) { + super(HttpStatus.BAD_REQUEST, String.format( + "Sprint end date must be after start date: given start date '%s' is after end date '%s'", + startDate, endDate + )); + } +} diff --git a/corn-backend/src/test/java/dev/corn/cornbackend/api/sprint/SprintControllerTest.java b/corn-backend/src/test/java/dev/corn/cornbackend/api/sprint/SprintControllerTest.java new file mode 100644 index 00000000..a3ea43d2 --- /dev/null +++ b/corn-backend/src/test/java/dev/corn/cornbackend/api/sprint/SprintControllerTest.java @@ -0,0 +1,166 @@ +package dev.corn.cornbackend.api.sprint; + + +import dev.corn.cornbackend.api.sprint.data.SprintRequest; +import dev.corn.cornbackend.api.sprint.data.SprintResponse; +import dev.corn.cornbackend.api.sprint.interfaces.SprintService; +import dev.corn.cornbackend.entities.sprint.interfaces.SprintMapper; +import dev.corn.cornbackend.test.sprint.SprintTestDataBuilder; +import dev.corn.cornbackend.test.sprint.data.AddNewSprintData; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +import static dev.corn.cornbackend.api.sprint.SprintServiceTest.SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +@SpringBootTest(classes = SprintService.class) +class SprintControllerTest { + + @InjectMocks + private SprintControllerImpl sprintController; + + private static final AddNewSprintData ADD_SPRINT_DATA = SprintTestDataBuilder.addNewProjectData(); + + private final SprintMapper MAPPER = Mappers.getMapper(SprintMapper.class); + + @Mock + private SprintService sprintService; + + @Test + final void test_addNewSprint_shouldAddNewSprint() { + // given + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintService.addNewSprint(ADD_SPRINT_DATA.asSprintRequest(), ADD_SPRINT_DATA.project().getOwner())) + .thenReturn(expected); + + SprintResponse actual = sprintController.addNewSprint(ADD_SPRINT_DATA.asSprintRequest(), ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_getSprintById_shouldGetSprint() { + // given + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintService.getSprintById(ADD_SPRINT_DATA.asSprint().getSprintId(), ADD_SPRINT_DATA.project().getOwner())) + .thenReturn(expected); + + SprintResponse actual = sprintController.getSprintById(ADD_SPRINT_DATA.asSprint().getSprintId(), ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_getSprintsOnPage_shouldGetSprints() { + // given + List expected = List.of(MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint())); + int page = 0; + + // when + when(sprintService.getSprintsOnPage(page, ADD_SPRINT_DATA.project().getProjectId(), + ADD_SPRINT_DATA.project().getOwner())) + .thenReturn(expected); + + List actual = sprintController.getSprintsOnPage(page, ADD_SPRINT_DATA.project().getProjectId(), + ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_updateSprintsName_shouldUpdateName() { + // given + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintService.updateSprintsName(ADD_SPRINT_DATA.name(), + ADD_SPRINT_DATA.asSprint().getSprintId(), ADD_SPRINT_DATA.project().getOwner())) + .thenReturn(expected); + + SprintResponse actual = sprintController.updateSprintsName(ADD_SPRINT_DATA.name(), + ADD_SPRINT_DATA.asSprint().getSprintId(), ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_updateSprintsDescription_shouldUpdateDescription() { + // given + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintService.updateSprintsDescription(ADD_SPRINT_DATA.description(), + ADD_SPRINT_DATA.asSprint().getSprintId(), ADD_SPRINT_DATA.project().getOwner())) + .thenReturn(expected); + + SprintResponse actual = sprintController.updateSprintsDescription(ADD_SPRINT_DATA.description(), + ADD_SPRINT_DATA.asSprint().getSprintId(), ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_updateSprintsStartDate_shouldUpdateStartDate() { + // given + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintService.updateSprintsStartDate(ADD_SPRINT_DATA.startDate(), + ADD_SPRINT_DATA.asSprint().getSprintId(), ADD_SPRINT_DATA.project().getOwner())) + .thenReturn(expected); + + SprintResponse actual = sprintController.updateSprintsStartDate(ADD_SPRINT_DATA.startDate(), + ADD_SPRINT_DATA.asSprint().getSprintId(), ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_updateSprintsEndDate_shouldUpdateEndDate() { + // given + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintService.updateSprintsEndDate(ADD_SPRINT_DATA.endDate(), + ADD_SPRINT_DATA.asSprint().getSprintId(), ADD_SPRINT_DATA.project().getOwner())) + .thenReturn(expected); + + SprintResponse actual = sprintController.updateSprintsEndDate(ADD_SPRINT_DATA.endDate(), + ADD_SPRINT_DATA.asSprint().getSprintId(), ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_deleteSprint_shouldDeleteSprint() { + // given + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + long sprintId = ADD_SPRINT_DATA.asSprint().getSprintId(); + + // when + when(sprintService.deleteSprint(sprintId, ADD_SPRINT_DATA.project().getOwner())) + .thenReturn(expected); + + SprintResponse actual = sprintController.deleteSprint(sprintId, ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } +} \ No newline at end of file diff --git a/corn-backend/src/test/java/dev/corn/cornbackend/api/sprint/SprintServiceTest.java b/corn-backend/src/test/java/dev/corn/cornbackend/api/sprint/SprintServiceTest.java new file mode 100644 index 00000000..19d2853a --- /dev/null +++ b/corn-backend/src/test/java/dev/corn/cornbackend/api/sprint/SprintServiceTest.java @@ -0,0 +1,346 @@ +package dev.corn.cornbackend.api.sprint; + +import dev.corn.cornbackend.api.sprint.data.SprintRequest; +import dev.corn.cornbackend.api.sprint.data.SprintResponse; +import dev.corn.cornbackend.entities.sprint.Sprint; +import dev.corn.cornbackend.entities.sprint.interfaces.SprintMapper; +import dev.corn.cornbackend.entities.sprint.interfaces.SprintRepository; +import dev.corn.cornbackend.entities.user.User; +import dev.corn.cornbackend.test.sprint.SprintTestDataBuilder; +import dev.corn.cornbackend.test.sprint.data.AddNewSprintData; +import dev.corn.cornbackend.utils.exceptions.sprint.SprintDoesNotExistException; +import dev.corn.cornbackend.utils.exceptions.sprint.SprintEndDateMustBeAfterStartDate; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; + +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@SpringBootTest(classes = SprintRepository.class) +public class SprintServiceTest { + + static final String SHOULD_THROW_SPRINT_DOES_NOT_EXIST_EXCEPTION = "Should throw SprintDoesNotExistException"; + static final String SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED = "SprintResponse should be equal to expected"; + + @InjectMocks + private SprintServiceImpl sprintService; + + @Mock + private SprintRepository sprintRepository; + @Mock + private SprintMapper MAPPER; + + private static final AddNewSprintData ADD_SPRINT_DATA = SprintTestDataBuilder.addNewProjectData(); + + @Test + final void test_addNewSprint_shouldAddNewSprint() { + // given + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintRepository.save(ADD_SPRINT_DATA.asSprint())) + .thenReturn(ADD_SPRINT_DATA.asSprint()); + when(MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint())) + .thenReturn(expected); + + SprintResponse actual = sprintService.addNewSprint( + ADD_SPRINT_DATA.asSprintRequest(), + ADD_SPRINT_DATA.project().getOwner() + ); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + verify(sprintRepository).save(ADD_SPRINT_DATA.asSprint()); + } + + @Test + final void test_addNewSprint_shouldThrowWhenEndIsBeforeStart() { + // given + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintRepository.save(ADD_SPRINT_DATA.asSprint())) + .thenReturn(ADD_SPRINT_DATA.asSprint()); + when(MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint())) + .thenReturn(expected); + + // then + assertThrows(SprintEndDateMustBeAfterStartDate.class, () -> { + SprintRequest sprintRequest = ADD_SPRINT_DATA.asSprintRequest(); + sprintRequest = SprintRequest.builder() + .name(sprintRequest.name()) + .startDate(sprintRequest.endDate()) + .endDate(sprintRequest.startDate()) + .description(sprintRequest.description()) + .build(); + sprintService.addNewSprint( + sprintRequest, + ADD_SPRINT_DATA.project().getOwner() + ); + }, "Should throw SprintDoesNotExistException"); + } + + @Test + final void test_getSprintById_shouldGetSprintById() { + // given + final long sprintId = 1L; + User user = ADD_SPRINT_DATA.project().getOwner(); + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintRepository.findById(sprintId)) + .thenReturn(Optional.of(ADD_SPRINT_DATA.asSprint())); + when(MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint())) + .thenReturn(expected); + + SprintResponse actual = sprintService.getSprintById(sprintId, user); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_getSprintsOnPage_shouldGetSprintsOnPage() { + // given + final int page = 0; + User user = ADD_SPRINT_DATA.project().getOwner(); + Pageable pageable = PageRequest.of(page, SprintServiceImpl.SPRINTS_PER_PAGE); + + // when + when(sprintRepository.findAllByProjectId(ADD_SPRINT_DATA.project().getProjectId(), pageable)) + .thenReturn(new PageImpl<>(List.of(ADD_SPRINT_DATA.asSprint()))); + SprintResponse response = new SprintResponse(0, 0, null, null, null, null); + when(MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint())) + .thenReturn(response); + + List actual = sprintService.getSprintsOnPage(page, ADD_SPRINT_DATA.project().getProjectId(), + ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(List.of(response), actual, "List of SprintResponse should not be empty"); + } + + @Test + final void test_updateSprintsName_shouldThrowSprintDoesNotExistException() { + // given + final String newName = "newName"; + final long sprintId = 1L; + + // when + when(sprintRepository.findById(sprintId)) + .thenReturn(Optional.empty()); + + // then + assertThrows(SprintDoesNotExistException.class, + () -> sprintService.updateSprintsName(newName, sprintId, ADD_SPRINT_DATA.project().getOwner()), + SHOULD_THROW_SPRINT_DOES_NOT_EXIST_EXCEPTION); + } + + @Test + final void test_updateSprintsName_shouldUpdateSprintsName() { + // given + final String newName = "newName"; + final long sprintId = 1L; + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintRepository.findById(sprintId)) + .thenReturn(Optional.of(ADD_SPRINT_DATA.asSprint())); + when(sprintRepository.save(ADD_SPRINT_DATA.asSprint())) + .thenReturn(ADD_SPRINT_DATA.asSprint()); + when(MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint())) + .thenReturn(expected); + + SprintResponse actual = sprintService.updateSprintsName(newName, sprintId, ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_updateSprintsDescription_shouldThrowSprintDoesNotExistException() { + // given + final String newDescription = "newDescription"; + final long sprintId = 1L; + + // when + when(sprintRepository.findById(sprintId)) + .thenReturn(Optional.empty()); + + // then + assertThrows(SprintDoesNotExistException.class, + () -> sprintService.updateSprintsDescription(newDescription, sprintId, ADD_SPRINT_DATA.project().getOwner()), + SHOULD_THROW_SPRINT_DOES_NOT_EXIST_EXCEPTION); + } + + @Test + final void test_updateSprintsDescription_shouldUpdateSprintsDescription() { + // given + final String newDescription = "newDescription"; + final long sprintId = 1L; + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintRepository.findById(sprintId)) + .thenReturn(Optional.of(ADD_SPRINT_DATA.asSprint())); + when(sprintRepository.save(ADD_SPRINT_DATA.asSprint())) + .thenReturn(ADD_SPRINT_DATA.asSprint()); + when(MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint())) + .thenReturn(expected); + + SprintResponse actual = sprintService.updateSprintsDescription(newDescription, sprintId, ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_updateSprintsStartDate_shouldThrowSprintDoesNotExistException() { + // given + final LocalDate newStartDate = LocalDate.now(); + final long sprintId = 1L; + + // when + when(sprintRepository.findById(sprintId)) + .thenReturn(Optional.empty()); + + // then + assertThrows(SprintDoesNotExistException.class, + () -> sprintService.updateSprintsStartDate(newStartDate, sprintId, ADD_SPRINT_DATA.project().getOwner()), + SHOULD_THROW_SPRINT_DOES_NOT_EXIST_EXCEPTION); + } + + @Test + final void test_updateSprintsStartDate_shouldThrowWhenEndIsBeforeStart() { + // given + Sprint sprint = ADD_SPRINT_DATA.asSprint(); + LocalDate newStartDate = sprint.getSprintEndDate().plusDays(10); + + // when + when(sprintRepository.findById(sprint.getSprintId())) + .thenReturn(Optional.of(sprint)); + + // then + assertThrows(SprintEndDateMustBeAfterStartDate.class, + () -> sprintService.updateSprintsStartDate(newStartDate, sprint.getSprintId(), ADD_SPRINT_DATA.project().getOwner()), + SHOULD_THROW_SPRINT_DOES_NOT_EXIST_EXCEPTION); + } + + @Test + final void test_updateSprintsStartDate_shouldUpdateSprintsStartDate() { + // given + final LocalDate newStartDate = LocalDate.now(); + final long sprintId = 1L; + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintRepository.findById(sprintId)) + .thenReturn(Optional.of(ADD_SPRINT_DATA.asSprint())); + when(sprintRepository.save(ADD_SPRINT_DATA.asSprint())) + .thenReturn(ADD_SPRINT_DATA.asSprint()); + when(MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint())) + .thenReturn(expected); + + SprintResponse actual = sprintService.updateSprintsStartDate(newStartDate, sprintId, ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_updateSprintsEndDate_shouldThrowSprintDoesNotExistException() { + // given + final LocalDate newEndDate = LocalDate.now().plusDays(7); + final long sprintId = 1L; + + // when + when(sprintRepository.findById(sprintId)) + .thenReturn(Optional.empty()); + + // then + assertThrows(SprintDoesNotExistException.class, + () -> sprintService.updateSprintsEndDate(newEndDate, sprintId, ADD_SPRINT_DATA.project().getOwner()), + "Should throw SprintDoesNotExistException"); + } + + @Test + final void test_updateSprintsEndDate_shouldThrowWhenEndIsBeforeStart() { + // given + Sprint sprint = ADD_SPRINT_DATA.asSprint(); + LocalDate newEndDate = sprint.getSprintStartDate().minusDays(10); + + // when + when(sprintRepository.findById(sprint.getSprintId())) + .thenReturn(Optional.of(sprint)); + + // then + assertThrows(SprintEndDateMustBeAfterStartDate.class, + () -> sprintService.updateSprintsEndDate(newEndDate, sprint.getSprintId(), ADD_SPRINT_DATA.project().getOwner()), + "Should throw SprintDoesNotExistException"); + } + + @Test + final void test_updateSprintsEndDate_shouldUpdateSprintsEndDate() { + // given + final LocalDate newEndDate = LocalDate.now().plusDays(7); + final long sprintId = 1L; + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintRepository.findById(sprintId)) + .thenReturn(Optional.of(ADD_SPRINT_DATA.asSprint())); + when(sprintRepository.save(ADD_SPRINT_DATA.asSprint())) + .thenReturn(ADD_SPRINT_DATA.asSprint()); + when(MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint())) + .thenReturn(expected); + + SprintResponse actual = sprintService.updateSprintsEndDate(newEndDate, sprintId, ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } + + @Test + final void test_deleteSprint_shouldThrowSprintDoesNotExistException() { + // given + final long sprintId = 1L; + + // when + when(sprintRepository.findById(sprintId)) + .thenReturn(Optional.empty()); + + // then + assertThrows(SprintDoesNotExistException.class, + () -> sprintService.deleteSprint(sprintId, ADD_SPRINT_DATA.project().getOwner()), + SHOULD_THROW_SPRINT_DOES_NOT_EXIST_EXCEPTION); + } + + @Test + final void test_deleteSprint_shouldDeleteSprint() { + // given + final long sprintId = 1L; + SprintResponse expected = MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint()); + + // when + when(sprintRepository.findById(sprintId)) + .thenReturn(Optional.of(ADD_SPRINT_DATA.asSprint())); + when(MAPPER.toSprintResponse(ADD_SPRINT_DATA.asSprint())) + .thenReturn(expected); + + SprintResponse actual = sprintService.deleteSprint(sprintId, ADD_SPRINT_DATA.project().getOwner()); + + // then + assertEquals(expected, actual, SPRINT_RESPONSE_SHOULD_BE_EQUAL_TO_EXPECTED); + } +} diff --git a/corn-backend/src/test/java/dev/corn/cornbackend/entities/project/ProjectMapperTest.java b/corn-backend/src/test/java/dev/corn/cornbackend/entities/project/ProjectMapperTest.java index e9386e31..0eb6811d 100644 --- a/corn-backend/src/test/java/dev/corn/cornbackend/entities/project/ProjectMapperTest.java +++ b/corn-backend/src/test/java/dev/corn/cornbackend/entities/project/ProjectMapperTest.java @@ -4,7 +4,7 @@ import dev.corn.cornbackend.entities.project.interfaces.ProjectMapper; import dev.corn.cornbackend.entities.project.interfaces.ProjectMapperImpl; import dev.corn.cornbackend.entities.sprint.Sprint; -import dev.corn.cornbackend.entities.sprint.data.SprintResponse; +import dev.corn.cornbackend.api.sprint.data.SprintResponse; import org.junit.jupiter.api.Test; import java.util.List; @@ -25,18 +25,6 @@ final void test_toProjectResponse_shouldReturnNull() { assertNull(actual, "Should return null"); } - @Test - final void test_toSprintResponse_shouldReturnNull() { - // given - ProjectMapper projectMapper = new ProjectMapperImpl(); - - // when - SprintResponse actual = projectMapper.toSprintResponse(null); - - // then - assertNull(actual, "Should return null"); - } - @Test final void test_sprintListToSprintResponseList_shouldReturnListOfSprints() { // given diff --git a/corn-backend/src/test/java/dev/corn/cornbackend/entities/sprint/SprintMapperTest.java b/corn-backend/src/test/java/dev/corn/cornbackend/entities/sprint/SprintMapperTest.java new file mode 100644 index 00000000..d25f05af --- /dev/null +++ b/corn-backend/src/test/java/dev/corn/cornbackend/entities/sprint/SprintMapperTest.java @@ -0,0 +1,40 @@ +package dev.corn.cornbackend.entities.sprint; + +import dev.corn.cornbackend.api.sprint.data.SprintResponse; +import dev.corn.cornbackend.entities.project.Project; +import dev.corn.cornbackend.entities.sprint.interfaces.SprintMapper; +import dev.corn.cornbackend.entities.sprint.interfaces.SprintMapperImpl; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +class SprintMapperTest { + @Test + final void test_toSprintResponse_shouldReturnNull() { + // given + SprintMapper sprintMapper = new SprintMapperImpl(); + + // when + SprintResponse actual = sprintMapper.toSprintResponse(null); + + // then + assertNull(actual, "Should return null"); + } + + @Test + final void test_sprintListToSprintResponseList_shouldReturnListOfSprints() { + // given + SprintMapper sprintMapper = new SprintMapperImpl(); + Sprint sprint = new Sprint(); + + // when + SprintResponse actual = sprintMapper.toSprintResponse(sprint); + + // then + assertNotNull(actual, "Should return null"); + } + +} diff --git a/corn-backend/src/test/java/dev/corn/cornbackend/entities/sprint/SprintTest.java b/corn-backend/src/test/java/dev/corn/cornbackend/entities/sprint/SprintTest.java index 33924bba..8066233b 100644 --- a/corn-backend/src/test/java/dev/corn/cornbackend/entities/sprint/SprintTest.java +++ b/corn-backend/src/test/java/dev/corn/cornbackend/entities/sprint/SprintTest.java @@ -16,6 +16,7 @@ import java.util.Set; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -315,6 +316,91 @@ final void test_shouldReturnNoViolationOnCorrectSprint() { "Should return no violations"); } + @Test + void givenSprintWithStartDateInPast_whenIsStartBeforeFutureDate_thenReturnsTrue() { + // Given + Sprint sprint = Sprint.builder() + .sprintStartDate(LocalDate.now().minusDays(1)) + .build(); + + // When + boolean result = sprint.isStartBefore(LocalDate.now().plusDays(1)); + + // Then + assertTrue(result); + } + + @Test + void givenSprintWithStartDateInFuture_whenIsStartBeforePastDate_thenReturnsFalse() { + // Given + Sprint sprint = Sprint.builder() + .sprintStartDate(LocalDate.now().plusDays(1)) + .build(); + + // When + boolean result = sprint.isStartBefore(LocalDate.now().minusDays(1)); + + // Then + assertFalse(result); + } + + @Test + void givenSprintWithStartDateInPast_whenIsStartAfterFutureDate_thenReturnsFalse() { + // Given + Sprint sprint = Sprint.builder() + .sprintStartDate(LocalDate.now().minusDays(1)) + .build(); + + // When + boolean result = sprint.isStartAfter(LocalDate.now().plusDays(1)); + + // Then + assertFalse(result); + } + + @Test + void givenSprintWithStartDateInFuture_whenIsStartAfterPastDate_thenReturnsTrue() { + // Given + Sprint sprint = Sprint.builder() + .sprintStartDate(LocalDate.now().plusDays(1)) + .build(); + + // When + boolean result = sprint.isStartAfter(LocalDate.now().minusDays(1)); + + // Then + assertTrue(result); + } + + + @Test + void givenSprintWithEndDateInPast_whenIsEndAfterFutureDate_thenReturnsTrue() { + // Given + Sprint sprint = Sprint.builder() + .sprintEndDate(LocalDate.now().minusDays(1)) + .build(); + + // When + boolean result = sprint.isEndAfter(LocalDate.now().plusDays(1)); + + // Then + assertFalse(result); + } + + @Test + void givenSprintWithEndDateInFuture_whenIsEndAfterPastDate_thenReturnsFalse() { + // Given + Sprint sprint = Sprint.builder() + .sprintEndDate(LocalDate.now().plusDays(1)) + .build(); + + // When + boolean result = sprint.isEndAfter(LocalDate.now().minusDays(1)); + + // Then + assertTrue(result); + } + private Sprint createSampleSprint() { return Sprint.builder() .sprintId(1L) diff --git a/corn-backend/src/test/java/dev/corn/cornbackend/test/sprint/SprintTestDataBuilder.java b/corn-backend/src/test/java/dev/corn/cornbackend/test/sprint/SprintTestDataBuilder.java new file mode 100644 index 00000000..1eeb28bf --- /dev/null +++ b/corn-backend/src/test/java/dev/corn/cornbackend/test/sprint/SprintTestDataBuilder.java @@ -0,0 +1,28 @@ +package dev.corn.cornbackend.test.sprint; + +import dev.corn.cornbackend.entities.project.Project; +import dev.corn.cornbackend.entities.user.User; +import dev.corn.cornbackend.test.sprint.data.AddNewSprintData; + +import java.time.LocalDate; +import java.util.Collections; + +public final class SprintTestDataBuilder { + public static AddNewSprintData addNewProjectData() { + User user = User + .builder() + .username("example@gmail.com") + .name("example") + .build(); + Project project = Project + .builder() + .name("projectName") + .owner(user) + .sprints(Collections.emptyList()) + .build(); + return new AddNewSprintData(project, "nazwa sprintu", "opis sprintu", LocalDate.now().plusDays(7), LocalDate.now().plusDays(14)); + } + + private SprintTestDataBuilder() { + } +} diff --git a/corn-backend/src/test/java/dev/corn/cornbackend/test/sprint/data/AddNewSprintData.java b/corn-backend/src/test/java/dev/corn/cornbackend/test/sprint/data/AddNewSprintData.java new file mode 100644 index 00000000..6c4d2ca5 --- /dev/null +++ b/corn-backend/src/test/java/dev/corn/cornbackend/test/sprint/data/AddNewSprintData.java @@ -0,0 +1,23 @@ +package dev.corn.cornbackend.test.sprint.data; + +import dev.corn.cornbackend.api.sprint.data.SprintRequest; +import dev.corn.cornbackend.entities.project.Project; +import dev.corn.cornbackend.entities.sprint.Sprint; + +import java.time.LocalDate; + +public record AddNewSprintData(Project project, String name, String description, LocalDate startDate, LocalDate endDate) { + + public Sprint asSprint() { + return new Sprint(0, project, name, description, startDate, endDate); + } + public SprintRequest asSprintRequest() { + return SprintRequest.builder() + .name(name) + .description(description) + .startDate(startDate) + .endDate(endDate) + .build(); + } + +}