From 6b37fe7ae4acfc95f144d92d55299705f6baf686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20S=C3=A4ume?= Date: Wed, 23 Oct 2024 12:42:39 +0200 Subject: [PATCH] PMT-43: Implement Tests and Minor Tweaks --- api/pmt.yml | 12 +- src/main/java/de/hmmh/pmt/ApiController.java | 9 +- .../java/de/hmmh/pmt/IntegrationTest.java | 21 ++++ .../de/hmmh/pmt/project/CompleteTest.java | 31 ++++++ .../java/de/hmmh/pmt/project/EditTest.java | 103 ++++++++++++++++-- 5 files changed, 153 insertions(+), 23 deletions(-) create mode 100644 src/test/java/de/hmmh/pmt/project/CompleteTest.java diff --git a/api/pmt.yml b/api/pmt.yml index 25ec77c..0a6419a 100644 --- a/api/pmt.yml +++ b/api/pmt.yml @@ -289,11 +289,7 @@ paths: 401: $ref: "#/components/responses/Unauthorized" 404: - description: "Project not found" - content: - text/plain: - schema: - type: string + $ref: "#/components/responses/NotFound" 500: $ref: "#/components/responses/InternalError" /project/{id}/completed: @@ -313,11 +309,7 @@ paths: 401: $ref: "#/components/responses/Unauthorized" 404: - description: "Project not found" - content: - text/plain: - schema: - type: string + $ref: "#/components/responses/NotFound" 500: $ref: "#/components/responses/InternalError" diff --git a/src/main/java/de/hmmh/pmt/ApiController.java b/src/main/java/de/hmmh/pmt/ApiController.java index 495cd6f..c29c60b 100644 --- a/src/main/java/de/hmmh/pmt/ApiController.java +++ b/src/main/java/de/hmmh/pmt/ApiController.java @@ -5,7 +5,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import de.hmmh.pmt.db.*; import de.hmmh.pmt.dtos.*; import de.hmmh.pmt.employee.ApiClientFactory; -import de.hmmh.pmt.employee.api.EmployeeControllerApi; import de.hmmh.pmt.employee.dtos.EmployeeResponseDTO; import de.hmmh.pmt.oas.DefaultApi; import de.hmmh.pmt.util.ApiTools; @@ -17,11 +16,9 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestClientException; import java.time.LocalDateTime; -import java.time.ZoneOffset; import java.util.*; import java.util.stream.Collectors; @@ -83,7 +80,7 @@ public class ApiController implements DefaultApi { } Project project = optionalProject.get(); - if (project.getName().equals(body.getName()) && projectRepository.existsByName(body.getName())) { + if (!project.getName().equals(body.getName()) && projectRepository.existsByName(body.getName())) { return new ResponseEntity<>(HttpStatus.CONFLICT); } @@ -109,8 +106,8 @@ public class ApiController implements DefaultApi { .flatMap(employeeId -> allocationRepository.findAllByEmployeeId(employeeId).stream()) .filter(employeeAllocation -> employeeAllocation.getProjectId().equals(finalProject.getId())) .toList() - )){ - return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY); + )) { + return new ResponseEntity<>(HttpStatus.CONFLICT); } projectRepository.save(project); diff --git a/src/test/java/de/hmmh/pmt/IntegrationTest.java b/src/test/java/de/hmmh/pmt/IntegrationTest.java index 26ccee2..0d2656d 100644 --- a/src/test/java/de/hmmh/pmt/IntegrationTest.java +++ b/src/test/java/de/hmmh/pmt/IntegrationTest.java @@ -114,6 +114,15 @@ public abstract class IntegrationTest { medicalResearchProject.setPlannedEnd(LocalDateTime.of(2026, 8, 20, 9, 15)); projects.put("medical-research", medicalResearchProject); + Project futureResearchProject = new Project(); + futureResearchProject.setName("What is the Future?"); + futureResearchProject.setGoal("Develop new Future (possibly through Genocide)."); + futureResearchProject.setCustomerId(95L); + futureResearchProject.setAdministratorId(TEST_EMPLOYEE_A_ID); + futureResearchProject.setStart(LocalDateTime.of(2077, 1, 12, 2, 0)); + futureResearchProject.setPlannedEnd(LocalDateTime.of(3000, 6, 19, 4, 0)); + projects.put("future-research", futureResearchProject); + Project overlappingProjectA = new Project(); overlappingProjectA.setName("Overlap A"); overlappingProjectA.setGoal("A Project That Overlaps with another one for Testing"); @@ -177,6 +186,18 @@ public abstract class IntegrationTest { allocation1ToAiResearch.setRole(TEST_QUALIFICATION_A_ID); allocations.put("1>ai-research", allocation1ToAiResearch); + Allocation allocation1ToMedical = new Allocation(); + allocation1ToMedical.setProject(allProjects.get("medical-research")); + allocation1ToMedical.setEmployeeId(TEST_EMPLOYEE_A_ID); + allocation1ToMedical.setRole(TEST_QUALIFICATION_A_ID); + allocations.put("1>medical-research", allocation1ToMedical); + + Allocation allocation1ToFuture = new Allocation(); + allocation1ToFuture.setProject(allProjects.get("future-research")); + allocation1ToFuture.setEmployeeId(TEST_EMPLOYEE_A_ID); + allocation1ToFuture.setRole(TEST_QUALIFICATION_A_ID); + allocations.put("1>future-research", allocation1ToFuture); + allocationRepository.saveAllAndFlush(allocations.values()); return allocations; } diff --git a/src/test/java/de/hmmh/pmt/project/CompleteTest.java b/src/test/java/de/hmmh/pmt/project/CompleteTest.java new file mode 100644 index 0000000..6f212f1 --- /dev/null +++ b/src/test/java/de/hmmh/pmt/project/CompleteTest.java @@ -0,0 +1,31 @@ +package de.hmmh.pmt.project; + +import de.hmmh.pmt.IntegrationTest; +import de.hmmh.pmt.db.Project; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class CompleteTest extends IntegrationTest { + + @Test + void shouldReturnNotFoundWhenProjectDoesntExist() throws Exception { + this.mvc + .perform(post(baseUri + "/project/0/completed")) + .andExpect(status().isNotFound()); + } + + @Test + void successfullyComplete() throws Exception { + + Map allProjects = createTestProjectData(); + Project projectToComplete = allProjects.get("medical-research"); + + this.mvc + .perform(post(baseUri + "/project/" + projectToComplete.getId() + "/completed")) + .andExpect(status().isNoContent()); + } +} diff --git a/src/test/java/de/hmmh/pmt/project/EditTest.java b/src/test/java/de/hmmh/pmt/project/EditTest.java index 8542e9f..7aedbc9 100644 --- a/src/test/java/de/hmmh/pmt/project/EditTest.java +++ b/src/test/java/de/hmmh/pmt/project/EditTest.java @@ -1,16 +1,19 @@ package de.hmmh.pmt.project; import de.hmmh.pmt.IntegrationTest; +import de.hmmh.pmt.db.Allocation; import de.hmmh.pmt.db.Project; -import de.hmmh.pmt.dtos.CreateProjectDTO; import de.hmmh.pmt.dtos.UpdateProjectDTO; import de.hmmh.pmt.employee.dtos.EmployeeResponseDTO; import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.web.client.HttpClientErrorException; +import java.time.LocalDateTime; import java.util.Map; import static org.mockito.Mockito.when; @@ -26,19 +29,105 @@ public class EditTest extends IntegrationTest { Map allProjects = createTestProjectData(); Project projectToEdit = allProjects.get("medical-research"); - UpdateProjectDTO dto = new UpdateProjectDTO(); + UpdateProjectDTO dto = getDto(projectToEdit); dto.setName("Mafia Drug Ring"); - dto.setGoal(projectToEdit.getGoal()); - dto.setCustomerId(projectToEdit.getCustomerId()); - dto.setAdministratorId(projectToEdit.getAdministratorId()); - dto.setStart(projectToEdit.getStart()); - dto.setPlannedEnd(projectToEdit.getPlannedEnd()); this.mvc .perform(getRequest(projectToEdit.getId(), dto)) .andExpect(status().isNoContent()); } + @Test + void shouldReturnNotFoundWhenProjectDoesntExist() throws Exception { + when(this.mockEmployeeApi.findById(Mockito.anyLong())) + .thenReturn(new EmployeeResponseDTO()); + + Map allProjects = createTestProjectData(); + Project projectToEdit = allProjects.get("medical-research"); + + UpdateProjectDTO dto = getDto(projectToEdit); + + this.mvc + .perform(getRequest(0L, dto)) + .andExpect(status().isNotFound()); + } + + @Test + void shouldReturnNotFoundWhenNewAdministratorDoesntExist() throws Exception { + when(this.mockEmployeeApi.findById(Mockito.anyLong())) + .thenThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND)); + + Map allProjects = createTestProjectData(); + Project projectToEdit = allProjects.get("medical-research"); + + UpdateProjectDTO dto = getDto(projectToEdit); + + this.mvc + .perform(getRequest(projectToEdit.getId(), dto)) + .andExpect(status().isNotFound()); + } + + @Test + void shouldReturnUnprocessableWhenNewTimestampsAreInvalid() throws Exception { + when(this.mockEmployeeApi.findById(Mockito.anyLong())) + .thenReturn(new EmployeeResponseDTO()); + + Map allProjects = createTestProjectData(); + Project projectToEdit = allProjects.get("medical-research"); + + UpdateProjectDTO dto = getDto(projectToEdit); + dto.setPlannedEnd(dto.getStart().minusDays(1)); + + this.mvc + .perform(getRequest(projectToEdit.getId(), dto)) + .andExpect(status().isUnprocessableEntity()); + } + + @Test + void shouldReturnConflictWhenUpdateWouldCreateNameConflict() throws Exception { + when(this.mockEmployeeApi.findById(Mockito.anyLong())) + .thenReturn(new EmployeeResponseDTO()); + + Map allProjects = createTestProjectData(); + Project projectToEdit = allProjects.get("medical-research"); + + UpdateProjectDTO dto = getDto(projectToEdit); + dto.setName(allProjects.get("renewable-energy").getName()); + + this.mvc + .perform(getRequest(projectToEdit.getId(), dto)) + .andExpect(status().isConflict()); + } + + @Test + void shouldReturnConflictWhenAllocationsWouldConflictAfterUpdate() throws Exception { + when(this.mockEmployeeApi.findById(Mockito.anyLong())) + .thenReturn(new EmployeeResponseDTO()); + + Map allProjects = createTestProjectData(); + Map allAllocations = createTestAllocationData(allProjects); + Project projectToEdit = allAllocations.get("1>future-research").getProject(); + + UpdateProjectDTO dto = getDto(projectToEdit); + dto.setStart(LocalDateTime.of(1970, 1, 1, 0, 0)); + dto.setStart(LocalDateTime.of(3000, 1, 1, 0, 0)); + + this.mvc + .perform(getRequest(projectToEdit.getId(), dto)) + .andExpect(status().isConflict()); + } + + private UpdateProjectDTO getDto(Project project) { + UpdateProjectDTO dto = new UpdateProjectDTO(); + dto.setName(project.getName()); + dto.setGoal(project.getGoal()); + dto.setCustomerId(project.getCustomerId()); + dto.setAdministratorId(project.getAdministratorId()); + dto.setStart(project.getStart()); + dto.setPlannedEnd(project.getPlannedEnd()); + return dto; + } + private RequestBuilder getRequest(long id, UpdateProjectDTO dto) throws Exception { return MockMvcRequestBuilders .put(baseUri + "/project/" + id)