From 25ed7e8759b586ac80334171f2510ad098449829 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 2 Oct 2024 08:47:36 +0200 Subject: [PATCH 1/5] implement get project by id --- requests/GetBearerToken.http | 10 +++---- .../lf8_starter/project/ProjectService.java | 12 ++++++++ .../{ => action}/CreateProjectAction.java | 5 +++- .../GetAllProjectsAction.java} | 22 +++++++++------ .../project/action/GetProjectAction.java | 28 +++++++++++++++++++ 5 files changed, 62 insertions(+), 15 deletions(-) rename src/main/java/de/szut/lf8_starter/project/{ => action}/CreateProjectAction.java (89%) rename src/main/java/de/szut/lf8_starter/project/{ProjectController.java => action/GetAllProjectsAction.java} (60%) create mode 100644 src/main/java/de/szut/lf8_starter/project/action/GetProjectAction.java diff --git a/requests/GetBearerToken.http b/requests/GetBearerToken.http index f5209ca..abf7e94 100644 --- a/requests/GetBearerToken.http +++ b/requests/GetBearerToken.http @@ -1,6 +1,6 @@ -POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token -Content-Type: application/x-www-form-urlencoded - -grant_type=password&client_id=employee-management-service&username=user&password=test - +POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token +Content-Type: application/x-www-form-urlencoded + +grant_type=password&client_id=employee-management-service&username=user&password=test + > {% client.global.set("auth_token", response.body.access_token); %} \ No newline at end of file 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 4dc8688..a815350 100644 --- a/src/main/java/de/szut/lf8_starter/project/ProjectService.java +++ b/src/main/java/de/szut/lf8_starter/project/ProjectService.java @@ -1,8 +1,10 @@ package de.szut.lf8_starter.project; +import de.szut.lf8_starter.exceptionHandling.ResourceNotFoundException; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Optional; @Service public class ProjectService { @@ -19,4 +21,14 @@ public class ProjectService { public List readAll() { return this.projectRepository.findAll(); } + + public ProjectEntity findById(Long id) { + Optional articleEntity = projectRepository.findById(id); + + if (articleEntity.isEmpty()) { + throw new ResourceNotFoundException("Project with id " + id + " not found"); + } + + return articleEntity.get(); + } } diff --git a/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java b/src/main/java/de/szut/lf8_starter/project/action/CreateProjectAction.java similarity index 89% rename from src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java rename to src/main/java/de/szut/lf8_starter/project/action/CreateProjectAction.java index d54318b..3e636b5 100644 --- a/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java +++ b/src/main/java/de/szut/lf8_starter/project/action/CreateProjectAction.java @@ -1,5 +1,8 @@ -package de.szut.lf8_starter.project; +package de.szut.lf8_starter.project.action; +import de.szut.lf8_starter.project.ProjectEntity; +import de.szut.lf8_starter.project.ProjectMapper; +import de.szut.lf8_starter.project.ProjectService; import de.szut.lf8_starter.project.dto.CreateProjectDto; import de.szut.lf8_starter.project.dto.GetProjectDto; import io.swagger.v3.oas.annotations.Operation; diff --git a/src/main/java/de/szut/lf8_starter/project/ProjectController.java b/src/main/java/de/szut/lf8_starter/project/action/GetAllProjectsAction.java similarity index 60% rename from src/main/java/de/szut/lf8_starter/project/ProjectController.java rename to src/main/java/de/szut/lf8_starter/project/action/GetAllProjectsAction.java index 61ee843..039a104 100644 --- a/src/main/java/de/szut/lf8_starter/project/ProjectController.java +++ b/src/main/java/de/szut/lf8_starter/project/action/GetAllProjectsAction.java @@ -1,32 +1,36 @@ -package de.szut.lf8_starter.project; +package de.szut.lf8_starter.project.action; +import de.szut.lf8_starter.project.ProjectMapper; +import de.szut.lf8_starter.project.ProjectService; import de.szut.lf8_starter.project.dto.GetProjectDto; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping(value = "projects") -public class ProjectController { +public class GetAllProjectsAction { private final ProjectService service; private final ProjectMapper projectMapper; - public ProjectController(ProjectService service, ProjectMapper projectMapper) { + + public GetAllProjectsAction(ProjectService service, ProjectMapper projectMapper) { this.service = service; this.projectMapper = projectMapper; } @Operation(summary = "returns all projects") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "all projects", - content = {@Content(mediaType = "application/json", - schema = @Schema(implementation = GetProjectDto.class))}), - @ApiResponse(responseCode = "401", description = "not authorized", - content = @Content)}) + @ApiResponse(responseCode = "200", description = "all projects", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class)) + }), + @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)}) @GetMapping public List findAll() { return this.service diff --git a/src/main/java/de/szut/lf8_starter/project/action/GetProjectAction.java b/src/main/java/de/szut/lf8_starter/project/action/GetProjectAction.java new file mode 100644 index 0000000..b581197 --- /dev/null +++ b/src/main/java/de/szut/lf8_starter/project/action/GetProjectAction.java @@ -0,0 +1,28 @@ +package de.szut.lf8_starter.project.action; + +import de.szut.lf8_starter.project.ProjectEntity; +import de.szut.lf8_starter.project.ProjectMapper; +import de.szut.lf8_starter.project.ProjectService; +import de.szut.lf8_starter.project.dto.GetProjectDto; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping(value = "projects") +public class GetProjectAction { + private final ProjectService projectService; + private final ProjectMapper projectMapper; + + public GetProjectAction(ProjectService projectService, ProjectMapper projectMapper) { + this.projectService = projectService; + this.projectMapper = projectMapper; + } + + @GetMapping("/{id}") + public ResponseEntity findArticleById(@PathVariable Long id) { + ProjectEntity project = this.projectService.findById(id); + + return new ResponseEntity<>(this.projectMapper.mapToGetDto(project), HttpStatus.OK); + } +} -- 2.45.2 From af090bfeb80695293433c51609785575bbbb9c77 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 2 Oct 2024 08:49:44 +0200 Subject: [PATCH 2/5] Line ending --- requests/GetBearerToken.http | 10 +++++----- requests/getProject.http | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 requests/getProject.http diff --git a/requests/GetBearerToken.http b/requests/GetBearerToken.http index abf7e94..f5209ca 100644 --- a/requests/GetBearerToken.http +++ b/requests/GetBearerToken.http @@ -1,6 +1,6 @@ -POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token -Content-Type: application/x-www-form-urlencoded - -grant_type=password&client_id=employee-management-service&username=user&password=test - +POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token +Content-Type: application/x-www-form-urlencoded + +grant_type=password&client_id=employee-management-service&username=user&password=test + > {% client.global.set("auth_token", response.body.access_token); %} \ No newline at end of file diff --git a/requests/getProject.http b/requests/getProject.http new file mode 100644 index 0000000..7b08e28 --- /dev/null +++ b/requests/getProject.http @@ -0,0 +1,15 @@ +### GET request to example server +POST http://localhost:8080/projects +Authorization: Bearer {{auth_token}} +Content-Type: application/json + +{ + "name": "name", + "leading_employee": 1, + "employees": [2, 3], + "contractor": 4, + "contractor_name": "Peter File", + "comment": "goal of project", + "start_date": "01.01.2000", + "planned_end_date": "01.01.2001" +} \ No newline at end of file -- 2.45.2 From e1bb48d7b1b87ab4e30bf028e5e24f682ebd747c Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 2 Oct 2024 08:51:07 +0200 Subject: [PATCH 3/5] Fix http request --- requests/getProject.http | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/requests/getProject.http b/requests/getProject.http index 7b08e28..5758af5 100644 --- a/requests/getProject.http +++ b/requests/getProject.http @@ -1,15 +1,3 @@ ### GET request to example server -POST http://localhost:8080/projects +GET http://localhost:8080/projects/2 Authorization: Bearer {{auth_token}} -Content-Type: application/json - -{ - "name": "name", - "leading_employee": 1, - "employees": [2, 3], - "contractor": 4, - "contractor_name": "Peter File", - "comment": "goal of project", - "start_date": "01.01.2000", - "planned_end_date": "01.01.2001" -} \ No newline at end of file -- 2.45.2 From beff4aa97100c311f14af1f61e3ed55a415f9114 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 2 Oct 2024 08:56:35 +0200 Subject: [PATCH 4/5] Add integration test --- .../project/action/GetProjectAction.java | 12 ++++ .../project/FindProjectActionTest.java | 60 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 src/test/java/de/szut/lf8_starter/integration/project/FindProjectActionTest.java diff --git a/src/main/java/de/szut/lf8_starter/project/action/GetProjectAction.java b/src/main/java/de/szut/lf8_starter/project/action/GetProjectAction.java index b581197..d04ac20 100644 --- a/src/main/java/de/szut/lf8_starter/project/action/GetProjectAction.java +++ b/src/main/java/de/szut/lf8_starter/project/action/GetProjectAction.java @@ -4,6 +4,11 @@ import de.szut.lf8_starter.project.ProjectEntity; import de.szut.lf8_starter.project.ProjectMapper; import de.szut.lf8_starter.project.ProjectService; import de.szut.lf8_starter.project.dto.GetProjectDto; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +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.*; @@ -19,6 +24,13 @@ public class GetProjectAction { this.projectMapper = projectMapper; } + @Operation(summary = "Find project by ID") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Project found", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class)) + }), + @ApiResponse(responseCode = "404", description = "Project not found", content = @Content) + }) @GetMapping("/{id}") public ResponseEntity findArticleById(@PathVariable Long id) { ProjectEntity project = this.projectService.findById(id); diff --git a/src/test/java/de/szut/lf8_starter/integration/project/FindProjectActionTest.java b/src/test/java/de/szut/lf8_starter/integration/project/FindProjectActionTest.java new file mode 100644 index 0000000..2c09762 --- /dev/null +++ b/src/test/java/de/szut/lf8_starter/integration/project/FindProjectActionTest.java @@ -0,0 +1,60 @@ +package de.szut.lf8_starter.integration.project; + +import de.szut.lf8_starter.project.ProjectEntity; +import de.szut.lf8_starter.project.ProjectRepository; +import org.json.JSONObject; +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.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import java.time.LocalDate; +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +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.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@AutoConfigureMockMvc(addFilters = false) +public class FindProjectActionTest { + @Autowired + private MockMvc mockMvc; + @Autowired + private ProjectRepository projectRepository; + + @Test + void createProjectTest() throws Exception { + var project = new ProjectEntity(); + project.setId(1); + project.setComment("comment"); + project.setContractor(1); + project.setContractorName("contractorName"); + project.setEndDate(LocalDate.of(2024, 1, 1)); + project.setLeadingEmployee(1); + project.setName("name"); + project.setStartDate(LocalDate.of(2021, 1, 1)); + project.setEmployees(List.of(1L,2L,3L)); + this.projectRepository.save(project); + + this.mockMvc.perform(get("/projects/1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("id").value(1)) + .andExpect(jsonPath("comment").value("comment")) + .andExpect(jsonPath("contractor").value(1)) + .andExpect(jsonPath("contractor_name").value("contractorName")) + .andExpect(jsonPath("end_date").value("01.01.2024")) + .andExpect(jsonPath("leading_employee").value(1)) + .andExpect(jsonPath("name").value("name")) + .andExpect(jsonPath("start_date").value("01.01.2021")) + .andExpect(jsonPath("employees").isArray()) + .andExpect(jsonPath("employees", hasSize(3))); + } +} -- 2.45.2 From 785fa87222c4d54f0af315a420f5cb11305d4818 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 2 Oct 2024 09:01:03 +0200 Subject: [PATCH 5/5] Remove unused imports --- .../integration/project/FindProjectActionTest.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/test/java/de/szut/lf8_starter/integration/project/FindProjectActionTest.java b/src/test/java/de/szut/lf8_starter/integration/project/FindProjectActionTest.java index 2c09762..dacb171 100644 --- a/src/test/java/de/szut/lf8_starter/integration/project/FindProjectActionTest.java +++ b/src/test/java/de/szut/lf8_starter/integration/project/FindProjectActionTest.java @@ -2,29 +2,23 @@ package de.szut.lf8_starter.integration.project; import de.szut.lf8_starter.project.ProjectEntity; import de.szut.lf8_starter.project.ProjectRepository; -import org.json.JSONObject; 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.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import java.time.LocalDate; -import java.util.Arrays; import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.is; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; 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.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest @AutoConfigureMockMvc(addFilters = false) -public class FindProjectActionTest { +class FindProjectActionTest { @Autowired private MockMvc mockMvc; @Autowired @@ -41,7 +35,7 @@ public class FindProjectActionTest { project.setLeadingEmployee(1); project.setName("name"); project.setStartDate(LocalDate.of(2021, 1, 1)); - project.setEmployees(List.of(1L,2L,3L)); + project.setEmployees(List.of(1L, 2L, 3L)); this.projectRepository.save(project); this.mockMvc.perform(get("/projects/1")) -- 2.45.2