From 9260e96df7fe9452df2fb85ce1a072bfda4e23ce Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 23 Oct 2024 09:10:48 +0200 Subject: [PATCH] Done --- .../lf8_starter/employee/EmployeeService.java | 34 ++++++++ .../lf8_starter/project/ProjectService.java | 4 +- .../employee/AddEmployeeToProjectAction.java | 34 ++++---- ...TokenResponseDto.java => EmployeeDto.java} | 17 ++-- .../project/AddEmployeeToProjectTest.java | 83 +++++++++++++++++++ 5 files changed, 150 insertions(+), 22 deletions(-) create mode 100644 src/main/java/de/szut/lf8_starter/employee/EmployeeService.java rename src/main/java/de/szut/lf8_starter/project/dto/{BearerTokenResponseDto.java => EmployeeDto.java} (51%) create mode 100644 src/test/java/de/szut/lf8_starter/integration/project/AddEmployeeToProjectTest.java diff --git a/src/main/java/de/szut/lf8_starter/employee/EmployeeService.java b/src/main/java/de/szut/lf8_starter/employee/EmployeeService.java new file mode 100644 index 0000000..a78f76b --- /dev/null +++ b/src/main/java/de/szut/lf8_starter/employee/EmployeeService.java @@ -0,0 +1,34 @@ +package de.szut.lf8_starter.employee; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Service; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; + +@Service +public class EmployeeService { + private final RestTemplate restTemplate; + + public EmployeeService(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + public boolean employeeExists(String accessToken, Long employeeId) { + HttpHeaders headers = new HttpHeaders(); + headers.setBearerAuth(accessToken.replace("Bearer ", "")); + + HttpEntity requestEntity = new HttpEntity<>(headers); + + String url = "https://employee.szut.dev/employees/" + employeeId; + + try { + restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); + } catch (HttpClientErrorException.NotFound e) { + return false; + } + + return true; + } +} diff --git a/src/main/java/de/szut/lf8_starter/project/ProjectService.java b/src/main/java/de/szut/lf8_starter/project/ProjectService.java index 31efbec..17afcea 100644 --- a/src/main/java/de/szut/lf8_starter/project/ProjectService.java +++ b/src/main/java/de/szut/lf8_starter/project/ProjectService.java @@ -25,10 +25,8 @@ public class ProjectService { return projectRepository.findById(id); } - public ProjectEntity update(ProjectEntity project) { + public void update(ProjectEntity project) { this.projectRepository.save(project); - - return project; } public void delete(Long id) { diff --git a/src/main/java/de/szut/lf8_starter/project/action/employee/AddEmployeeToProjectAction.java b/src/main/java/de/szut/lf8_starter/project/action/employee/AddEmployeeToProjectAction.java index 541f832..1e14ae0 100644 --- a/src/main/java/de/szut/lf8_starter/project/action/employee/AddEmployeeToProjectAction.java +++ b/src/main/java/de/szut/lf8_starter/project/action/employee/AddEmployeeToProjectAction.java @@ -1,27 +1,36 @@ package de.szut.lf8_starter.project.action.employee; +import de.szut.lf8_starter.employee.EmployeeService; import de.szut.lf8_starter.project.ProjectEntity; import de.szut.lf8_starter.project.ProjectService; -import org.springframework.http.*; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; import java.util.Optional; @RestController public class AddEmployeeToProjectAction { private final ProjectService projectService; - private final RestTemplate restTemplate; + private final EmployeeService employeeService; - public AddEmployeeToProjectAction(ProjectService projectService, RestTemplate restTemplate) { + public AddEmployeeToProjectAction(ProjectService projectService, EmployeeService employeeService) { this.projectService = projectService; - this.restTemplate = restTemplate; + this.employeeService = employeeService; } - + @Operation(summary = "Add an employee to a project") + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "Employee added to project"), + @ApiResponse(responseCode = "404", description = "Project or employee not found", content = @Content) + }) @PostMapping("/projects/{projectId}/employees/{employeeId}") public ResponseEntity create( @PathVariable Long projectId, @@ -34,15 +43,12 @@ public class AddEmployeeToProjectAction { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } - HttpHeaders headers = new HttpHeaders(); - headers.setBearerAuth(accessToken.replace("Bearer ", "")); + if (!this.employeeService.employeeExists(accessToken, employeeId)) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } - HttpEntity requestEntity = new HttpEntity<>(headers); - - String url = "https://employee.szut.dev/employees/" + employeeId; - ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); - - System.out.println("Employee Data: " + response.getBody()); + project.get().getEmployees().add(employeeId); + this.projectService.update(project.get()); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } diff --git a/src/main/java/de/szut/lf8_starter/project/dto/BearerTokenResponseDto.java b/src/main/java/de/szut/lf8_starter/project/dto/EmployeeDto.java similarity index 51% rename from src/main/java/de/szut/lf8_starter/project/dto/BearerTokenResponseDto.java rename to src/main/java/de/szut/lf8_starter/project/dto/EmployeeDto.java index 7bd40eb..05909e1 100644 --- a/src/main/java/de/szut/lf8_starter/project/dto/BearerTokenResponseDto.java +++ b/src/main/java/de/szut/lf8_starter/project/dto/EmployeeDto.java @@ -1,15 +1,22 @@ package de.szut.lf8_starter.project.dto; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.annotation.JsonNaming; import lombok.Getter; import lombok.Setter; -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonIgnoreProperties(ignoreUnknown = true) +import java.util.List; + @Getter @Setter -public class BearerTokenResponseDto { - private String accessToken; +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +public class EmployeeDto { + private long id; + private String firstName; + private String lastName; + private String street; + private String postcode; + private String city; + private String phone; + private List skillSet; } diff --git a/src/test/java/de/szut/lf8_starter/integration/project/AddEmployeeToProjectTest.java b/src/test/java/de/szut/lf8_starter/integration/project/AddEmployeeToProjectTest.java new file mode 100644 index 0000000..b8a79ff --- /dev/null +++ b/src/test/java/de/szut/lf8_starter/integration/project/AddEmployeeToProjectTest.java @@ -0,0 +1,83 @@ +package de.szut.lf8_starter.integration.project; + +import de.szut.lf8_starter.employee.EmployeeService; +import de.szut.lf8_starter.project.ProjectEntity; +import de.szut.lf8_starter.project.ProjectService; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.Optional; + +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@AutoConfigureMockMvc(addFilters = false) +class AddEmployeeToProjectActionIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private ProjectService projectService; + + @MockBean + private EmployeeService employeeService; + + @Test + void testAddEmployeeToProject() throws Exception { + Long projectId = 1L; + Long employeeId = 1L; + String accessToken = "Bearer valid_token"; + + ProjectEntity projectEntity = new ProjectEntity(); + projectEntity.setId(projectId); + + when(projectService.findById(projectId)).thenReturn(Optional.of(projectEntity)); + when(employeeService.employeeExists(accessToken, employeeId)).thenReturn(true); + + mockMvc.perform(post("/projects/{projectId}/employees/{employeeId}", projectId, employeeId) + .header(HttpHeaders.AUTHORIZATION, accessToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNoContent()); + } + + @Test + void testAddEmployeeToProject_ProjectNotFound() throws Exception { + Long projectId = 1L; + Long employeeId = 1L; + String accessToken = "Bearer valid_token"; + + when(projectService.findById(projectId)).thenReturn(Optional.empty()); + + mockMvc.perform(post("/projects/{projectId}/employees/{employeeId}", projectId, employeeId) + .header(HttpHeaders.AUTHORIZATION, accessToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + } + + @Test + void testAddEmployeeToProject_EmployeeNotFound() throws Exception { + Long projectId = 1L; + Long employeeId = 1L; + String accessToken = "Bearer valid_token"; + + ProjectEntity projectEntity = new ProjectEntity(); + projectEntity.setId(projectId); + + when(projectService.findById(projectId)).thenReturn(Optional.of(projectEntity)); + when(employeeService.employeeExists(accessToken, employeeId)).thenReturn(false); + + mockMvc.perform(post("/projects/{projectId}/employees/{employeeId}", projectId, employeeId) + .header(HttpHeaders.AUTHORIZATION, accessToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + } +} \ No newline at end of file