diff --git a/Readme.md b/Readme.md index 1874b0a..bcfc727 100644 --- a/Readme.md +++ b/Readme.md @@ -59,7 +59,7 @@ docker compose up # Keycloak ### Keycloak Token -1. Auf der Projektebene [GetBearerToken.http](GetBearerToken.http) öffnen. +1. Auf der Projektebene [GetBearerToken.http](requests/GetBearerToken.http) öffnen. 2. Neben der Request auf den grünen Pfeil drücken 3. Aus dem Reponse das access_token kopieren diff --git a/GetBearerToken.http b/requests/GetBearerToken.http similarity index 100% rename from GetBearerToken.http rename to requests/GetBearerToken.http diff --git a/requests/createProject.http b/requests/createProject.http index add2394..885c49e 100644 --- a/requests/createProject.http +++ b/requests/createProject.http @@ -1,15 +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, - "contractorName": "Peter File", - "comment": "goal of project", - "startDate": "01.01.2000", - "plannedEndDate": "01.01.2001" +### 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 diff --git a/requests/getAllProjects.http b/requests/getAllProjects.http new file mode 100644 index 0000000..21a4ceb --- /dev/null +++ b/requests/getAllProjects.http @@ -0,0 +1,3 @@ +### GET request to example server +GET http://localhost:8080/projects +Authorization: Bearer {{auth_token}} \ No newline at end of file diff --git a/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java b/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java index c41b134..4158fee 100644 --- a/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java +++ b/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java @@ -1,40 +1,39 @@ -package de.szut.lf8_starter.project; - -import de.szut.lf8_starter.project.dto.CreateProjectDto; -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 jakarta.validation.Valid; -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.RestController; - -@RestController -@RequestMapping(value = "/projects") -public class CreateProjectAction { - private final ProjectService projectService; - private final ProjectMapper projectMapper; - - public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) { - this.projectService = projectService; - this.projectMapper = mappingService; - } - - @Operation(summary = "Creates a new Project") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}), - @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content), - @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)}) - @PostMapping - public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) { - ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto); - - projectEntity = this.projectService.create(projectEntity); - - return this.projectMapper.mapToGetDto(projectEntity); - } -} +package de.szut.lf8_starter.project; + +import de.szut.lf8_starter.project.dto.CreateProjectDto; +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 jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping(value = "/projects") +public class CreateProjectAction { + private final ProjectService projectService; + private final ProjectMapper projectMapper; + + public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) { + this.projectService = projectService; + this.projectMapper = mappingService; + } + + @Operation(summary = "Creates a new Project") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}), + @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content), + @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)}) + @PostMapping + @ResponseStatus(code = HttpStatus.CREATED) + public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) { + ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto); + + projectEntity = this.projectService.create(projectEntity); + + return this.projectMapper.mapToGetDto(projectEntity); + } +} diff --git a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java index 4c6ab0d..64d22b7 100644 --- a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java +++ b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java @@ -1,42 +1,45 @@ -package de.szut.lf8_starter.project.dto; - -import com.fasterxml.jackson.annotation.JsonFormat; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; - -import java.time.LocalDate; -import java.util.List; - -@Getter -@Setter -public class CreateProjectDto { - @NotBlank - private String name; - - @NotNull - private long leadingEmployee; - - private List employees; - - @NotNull - private long contractor; - - @NotBlank - private String contractorName; - - @NotBlank - private String comment; - - @JsonFormat(pattern = "dd.MM.yyyy") - @NotNull - private LocalDate startDate; - - @JsonFormat(pattern = "dd.MM.yyyy") - @NotNull - private LocalDate plannedEndDate; - - @JsonFormat(pattern = "dd.MM.yyyy") - private LocalDate endDate; -} +package de.szut.lf8_starter.project.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDate; +import java.util.List; + +@Getter +@Setter +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +public class CreateProjectDto { + @NotBlank + private String name; + + @NotNull + private long leadingEmployee; + + private List employees; + + @NotNull + private long contractor; + + @NotBlank + private String contractorName; + + @NotBlank + private String comment; + + @JsonFormat(pattern = "dd.MM.yyyy") + @NotNull + private LocalDate startDate; + + @JsonFormat(pattern = "dd.MM.yyyy") + @NotNull + private LocalDate plannedEndDate; + + @JsonFormat(pattern = "dd.MM.yyyy") + private LocalDate endDate; +} diff --git a/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java b/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java index c90cd50..250a6a0 100644 --- a/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java +++ b/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java @@ -1,45 +1,34 @@ -package de.szut.lf8_starter.project.dto; - -import com.fasterxml.jackson.annotation.JsonFormat; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; - -import java.time.LocalDate; -import java.util.List; - -@Getter -@Setter -public class GetProjectDto { - private long id; - - @NotBlank - private String name; - - @NotNull - private long leadingEmployee; - - private List employees; - - @NotNull - private long contractor; - - @NotBlank - private String contractorName; - - @NotBlank - private String comment; - - @NotNull - @JsonFormat(pattern = "dd.MM.yyyy") - private LocalDate startDate; - - @NotNull - @JsonFormat(pattern = "dd.MM.yyyy") - private LocalDate plannedEndDate; - - @NotNull - @JsonFormat(pattern = "dd.MM.yyyy") - private LocalDate endDate; -} +package de.szut.lf8_starter.project.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDate; +import java.util.List; + +@Getter +@Setter +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +public class GetProjectDto { + private long id; + private String name; + private long leadingEmployee; + private List employees; + private long contractor; + private String contractorName; + private String comment; + + @JsonFormat(pattern = "dd.MM.yyyy") + private LocalDate startDate; + + @JsonFormat(pattern = "dd.MM.yyyy") + private LocalDate plannedEndDate; + + @JsonFormat(pattern = "dd.MM.yyyy") + private LocalDate endDate; +} diff --git a/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java b/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java new file mode 100644 index 0000000..06d02b6 --- /dev/null +++ b/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java @@ -0,0 +1,71 @@ +package de.szut.lf8_starter.integration.project; + +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 static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@AutoConfigureMockMvc(addFilters = false) +public class CreateProjectActionTest { + @Autowired + private MockMvc mockMvc; + @Autowired + private ProjectRepository projectRepository; + + @Test + void createProjectTest() throws Exception { + String content = """ + { + "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" + } + """; + + final var contentAsString = this.mockMvc.perform( + post("/projects").content(content).contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isCreated()) + .andExpect(jsonPath("name", is("name"))) + .andExpect(jsonPath("leading_employee", is(1))) + .andExpect(jsonPath("employees", is(Arrays.asList(2, 3)))) + .andExpect(jsonPath("contractor", is(4))) + .andExpect(jsonPath("contractor_name", is("Peter File"))) + .andExpect(jsonPath("comment", is("goal of project"))) + .andExpect(jsonPath("start_date", is("01.01.2000"))) + .andExpect(jsonPath("planned_end_date", is("01.01.2001"))) + .andReturn() + .getResponse() + .getContentAsString(); + + final var id = Long.parseLong(new JSONObject(contentAsString).get("id").toString()); + + final var project = this.projectRepository.findById(id); + assertThat(project.get().getName()).isEqualTo("name"); + assertThat(project.get().getLeadingEmployee()).isEqualTo(1); + assertThat(project.get().getContractor()).isEqualTo(4); + assertThat(project.get().getContractorName()).isEqualTo("Peter File"); + assertThat(project.get().getComment()).isEqualTo("goal of project"); + assertThat(project.get().getStartDate()).isEqualTo(LocalDate.of(2000, 1, 1)); + assertThat(project.get().getPlannedEndDate()).isEqualTo(LocalDate.of(2001, 1, 1)); + } +} diff --git a/src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccess.java b/src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccessTest.java similarity index 80% rename from src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccess.java rename to src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccessTest.java index 906b63f..22981bb 100644 --- a/src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccess.java +++ b/src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccessTest.java @@ -1,60 +1,56 @@ -package de.szut.lf8_starter.integration.project; - -import de.szut.lf8_starter.project.ProjectEntity; -import de.szut.lf8_starter.project.ProjectRepository; -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.web.client.TestRestTemplate; -import org.springframework.test.web.servlet.MockMvc; - -import java.time.LocalDate; -import java.util.List; - -import static org.hamcrest.collection.IsCollectionWithSize.hasSize; -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; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@AutoConfigureMockMvc(addFilters = false) -public class ProjectFindAllSuccess { - @Autowired - private ProjectRepository projectRepository; - - @Autowired - private MockMvc mockMvc; - - @Autowired - private TestRestTemplate restTemplate; - - @Test - void findAllProjects() 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")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", hasSize(1))) - .andExpect(jsonPath("$[0].id").value(1)) - .andExpect(jsonPath("$[0].comment").value("comment")) - .andExpect(jsonPath("$[0].contractor").value(1)) - .andExpect(jsonPath("$[0].contractorName").value("contractorName")) - .andExpect(jsonPath("$[0].endDate").value("01.01.2024")) - .andExpect(jsonPath("$[0].leadingEmployee").value(1)) - .andExpect(jsonPath("$[0].name").value("name")) - .andExpect(jsonPath("$[0].startDate").value("01.01.2021")) - .andExpect(jsonPath("$[0].employees").isArray()) - .andExpect(jsonPath("$[0].employees", hasSize(3))); - } -} +package de.szut.lf8_starter.integration.project; + +import de.szut.lf8_starter.project.ProjectEntity; +import de.szut.lf8_starter.project.ProjectRepository; +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.test.web.servlet.MockMvc; + +import java.time.LocalDate; +import java.util.List; + +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +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; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@AutoConfigureMockMvc(addFilters = false) +public class ProjectFindAllSuccessTest { + @Autowired + private ProjectRepository projectRepository; + + @Autowired + private MockMvc mockMvc; + + @Test + void findAllProjectsTest() 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")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", hasSize(1))) + .andExpect(jsonPath("$[0].id").value(1)) + .andExpect(jsonPath("$[0].comment").value("comment")) + .andExpect(jsonPath("$[0].contractor").value(1)) + .andExpect(jsonPath("$[0].contractor_name").value("contractorName")) + .andExpect(jsonPath("$[0].end_date").value("01.01.2024")) + .andExpect(jsonPath("$[0].leading_employee").value(1)) + .andExpect(jsonPath("$[0].name").value("name")) + .andExpect(jsonPath("$[0].start_date").value("01.01.2021")) + .andExpect(jsonPath("$[0].employees").isArray()) + .andExpect(jsonPath("$[0].employees", hasSize(3))); + } +}