From 79ab6f7f48b2858c69a998d391270c9d9dea3223 Mon Sep 17 00:00:00 2001 From: Rajbir Singh Date: Thu, 24 Oct 2024 09:44:46 +0200 Subject: [PATCH 1/4] PMT-40: define Endpoint --- api/pmt.yml | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/api/pmt.yml b/api/pmt.yml index 4df472f..083bb68 100644 --- a/api/pmt.yml +++ b/api/pmt.yml @@ -112,6 +112,31 @@ components: plannedEnd: type: string format: date-time + Project: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + goal: + type: string + customerId: + type: integer + format: int64 + administratorId: + type: integer + format: int64 + start: + type: string + format: date-time + plannedEnd: + type: string + format: date-time + realEnd: + type: string + format: date-time AddEmployeeDTO: type: object properties: @@ -160,6 +185,13 @@ components: type: array items: $ref: "#/components/schemas/Employee" + EmployeeProjectsDTO: + type: object + properties: + projects: + type: array + items: + $ref: '#/components/schemas/Project' responses: Unauthorized: description: "Unauthorized" @@ -416,3 +448,27 @@ paths: $ref: '#/components/responses/NotFound' 500: $ref: "#/components/responses/InternalError" + /employye/{id}/projects: + get: + description: "getAllProjects" + operationId: "Get a List of all Projects from a specific Employee" + parameters: + - in: path + name: id + schema: + type: integer + format: int64 + required: true + responses: + 200: + content: + application/json: + schema: + $ref: "#/components/schemas/EmployeeProjectsDTO" + description: 'Get a List of all Projects from a specific Employee' + 401: + $ref: "#/components/responses/Unauthorized" + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalError' From 096c25e33be204176290d0fd95653c7f17da3ac0 Mon Sep 17 00:00:00 2001 From: Rajbir Singh Date: Thu, 24 Oct 2024 09:49:53 +0200 Subject: [PATCH 2/4] PMT-40: Implement Endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dominik Säume --- src/main/java/de/hmmh/pmt/ApiController.java | 16 ++++++++++++++++ src/main/java/de/hmmh/pmt/util/Mapper.java | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/main/java/de/hmmh/pmt/ApiController.java b/src/main/java/de/hmmh/pmt/ApiController.java index 4d35d4f..a740e23 100644 --- a/src/main/java/de/hmmh/pmt/ApiController.java +++ b/src/main/java/de/hmmh/pmt/ApiController.java @@ -3,6 +3,7 @@ package de.hmmh.pmt; import com.fasterxml.jackson.databind.ObjectMapper; import de.hmmh.pmt.db.*; +import de.hmmh.pmt.db.Project; import de.hmmh.pmt.dtos.*; import de.hmmh.pmt.employee.ApiClientFactory; import de.hmmh.pmt.employee.dtos.EmployeeResponseDTO; @@ -237,4 +238,19 @@ public class ApiController implements DefaultApi { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } + + @Override + public ResponseEntity getAListOfAllProjectsFromASpecificEmployee(Long id) { + List allocationsByEmployee = allocationRepository.findAllByEmployeeId(id); + + Set projects = allocationsByEmployee.stream() + .map(Allocation::getProject) + .collect(Collectors.toSet()); + + EmployeeProjectsDTO response = new EmployeeProjectsDTO(); + for (Project project : projects) { + response.addProjectsItem(mapper.mapProject(project)); + } + return new ResponseEntity<>(HttpStatus.OK); + } } diff --git a/src/main/java/de/hmmh/pmt/util/Mapper.java b/src/main/java/de/hmmh/pmt/util/Mapper.java index 63c22c4..0537580 100644 --- a/src/main/java/de/hmmh/pmt/util/Mapper.java +++ b/src/main/java/de/hmmh/pmt/util/Mapper.java @@ -82,4 +82,16 @@ public class Mapper { project.setPlannedEnd(dto.getPlannedEnd()); return project; } + public de.hmmh.pmt.dtos.Project mapProject(Project project){ + de.hmmh.pmt.dtos.Project dto = new de.hmmh.pmt.dtos.Project(); + dto.setId(project.getId()); + dto.setName(project.getName()); + dto.setGoal(project.getGoal()); + dto.setCustomerId(project.getCustomerId()); + dto.setAdministratorId(project.getAdministratorId()); + dto.setStart(project.getStart()); + dto.setPlannedEnd(project.getPlannedEnd()); + dto.setRealEnd(project.getRealEnd()); + return dto; + } } From 6b430ae2514b82ceb559cb08762474a4b40b1a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20S=C3=A4ume?= Date: Thu, 24 Oct 2024 10:30:56 +0200 Subject: [PATCH 3/4] PMT-40: Fix Endpoint --- src/main/java/de/hmmh/pmt/ApiController.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/de/hmmh/pmt/ApiController.java b/src/main/java/de/hmmh/pmt/ApiController.java index a740e23..ebb8879 100644 --- a/src/main/java/de/hmmh/pmt/ApiController.java +++ b/src/main/java/de/hmmh/pmt/ApiController.java @@ -241,16 +241,19 @@ public class ApiController implements DefaultApi { @Override public ResponseEntity getAListOfAllProjectsFromASpecificEmployee(Long id) { + ApiTools.CheckEmployeeRecord employeeRecord = apiTools.checkEmployeeExists(id); + if (employeeRecord.status() != HttpStatus.OK) { + return new ResponseEntity<>(employeeRecord.status()); + } + List allocationsByEmployee = allocationRepository.findAllByEmployeeId(id); - Set projects = allocationsByEmployee.stream() - .map(Allocation::getProject) - .collect(Collectors.toSet()); - EmployeeProjectsDTO response = new EmployeeProjectsDTO(); - for (Project project : projects) { - response.addProjectsItem(mapper.mapProject(project)); + response.setProjects(new ArrayList<>()); + for (Allocation allocation : allocationsByEmployee) { + response.addProjectsItem(mapper.mapProject(allocation.getProject())); } - return new ResponseEntity<>(HttpStatus.OK); + + return ResponseEntity.ok(response); } } From 49244526ef625ff6b4eecae913766535e66bca17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20S=C3=A4ume?= Date: Thu, 24 Oct 2024 10:31:09 +0200 Subject: [PATCH 4/4] PMT-40: Write Tests for Endpoint Implementation --- .../project/GetAllProjectsByEmployeeTest.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/test/java/de/hmmh/pmt/project/GetAllProjectsByEmployeeTest.java diff --git a/src/test/java/de/hmmh/pmt/project/GetAllProjectsByEmployeeTest.java b/src/test/java/de/hmmh/pmt/project/GetAllProjectsByEmployeeTest.java new file mode 100644 index 0000000..99d681a --- /dev/null +++ b/src/test/java/de/hmmh/pmt/project/GetAllProjectsByEmployeeTest.java @@ -0,0 +1,74 @@ +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.employee.dtos.EmployeeResponseDTO; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.HttpClientErrorException; + +import java.util.List; +import java.util.Map; + +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasSize; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class GetAllProjectsByEmployeeTest extends IntegrationTest { + + @Test + void successfullyGetAllProjectsByEmployee() throws Exception { + when(this.mockEmployeeApi.findById(Mockito.anyLong())) + .thenReturn(new EmployeeResponseDTO()); + + Map allProjects = createTestProjectData(); + Map allAllocations = createTestAllocationData(allProjects); + + List allocations = allAllocations + .values() + .stream() + .filter(allocation -> allocation.getEmployeeId().equals(TEST_EMPLOYEE_A_ID)) + .toList(); + + mvc + .perform(get(baseUri + "/employye/" + TEST_EMPLOYEE_A_ID + "/projects")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.projects", hasSize(allocations.size()))) + .andExpect(jsonPath("$.projects[*].id").exists()) + .andExpect(jsonPath("$.projects[*].name").exists()) + .andExpect(jsonPath("$.projects[*].goal").exists()) + .andExpect(jsonPath("$.projects[*].customerId").exists()) + .andExpect(jsonPath("$.projects[*].administratorId").exists()) + .andExpect(jsonPath("$.projects[*].plannedEnd").exists()) + .andExpect(jsonPath("$.projects[*].realEnd").exists()); + } + + @Test + void shouldReturnEmptyListWhenNoAllocationsFound() throws Exception { + when(this.mockEmployeeApi.findById(Mockito.anyLong())) + .thenReturn(new EmployeeResponseDTO()); + + createTestProjectData(); + + mvc + .perform(get(baseUri + "/employye/" + TEST_EMPLOYEE_A_ID + "/projects")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.projects", empty())); + } + + @Test + void shouldReturnNotFoundWhenEmployeeDoesNotExist() throws Exception { + when(this.mockEmployeeApi.findById(Mockito.anyLong())) + .thenThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND)); + + mvc + .perform(get(baseUri + "/employye/0/projects")) + .andExpect(status().isNotFound()); + } +}