Compare commits

...

10 Commits

Author SHA1 Message Date
Phan Huy Tran
fca0ab89ed REfactor
All checks were successful
Quality Check / Tests (pull_request) Successful in 54s
Quality Check / Checkstyle Main (pull_request) Successful in 55s
2024-10-02 08:24:04 +02:00
Phan Huy Tran
273202842c IDK 2024-10-02 08:21:10 +02:00
Phan Huy Tran
79300c77ee Fix line endings
All checks were successful
Quality Check / Tests (pull_request) Successful in 51s
Quality Check / Checkstyle Main (pull_request) Successful in 53s
2024-09-25 14:25:55 +02:00
Phan Huy Tran
a365c7aee3 Fix tests 2024-09-25 14:25:31 +02:00
Phan Huy Tran
ffb1a1586a Ensure Snake Case in JSON 2024-09-25 14:25:28 +02:00
Phan Huy Tran
6723b49f7d Write integration test 2024-09-25 14:25:28 +02:00
Phan Huy Tran
e209379f41 Order files 2024-09-25 14:25:28 +02:00
Phan Huy Tran
a5c627ccaa Line ending 2024-09-25 14:25:25 +02:00
Phan Huy Tran
2f92dd3faa Rebase 2024-09-25 14:25:22 +02:00
Phan Huy Tran
be52740c53 Implement create project route 2024-09-25 14:25:19 +02:00
9 changed files with 263 additions and 202 deletions

@ -59,7 +59,7 @@ docker compose up
# Keycloak # Keycloak
### Keycloak Token ### 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 2. Neben der Request auf den grünen Pfeil drücken
3. Aus dem Reponse das access_token kopieren 3. Aus dem Reponse das access_token kopieren

@ -1,15 +1,15 @@
### GET request to example server ### GET request to example server
POST http://localhost:8080/projects POST http://localhost:8080/projects
Authorization: Bearer {{auth_token}} Authorization: Bearer {{auth_token}}
Content-Type: application/json Content-Type: application/json
{ {
"name": "name", "name": "name",
"leading_employee": 1, "leading_employee": 1,
"employees": [2, 3], "employees": [2, 3],
"contractor": 4, "contractor": 4,
"contractorName": "Peter File", "contractor_name": "Peter File",
"comment": "goal of project", "comment": "goal of project",
"startDate": "01.01.2000", "start_date": "01.01.2000",
"plannedEndDate": "01.01.2001" "planned_end_date": "01.01.2001"
} }

@ -0,0 +1,3 @@
### GET request to example server
GET http://localhost:8080/projects
Authorization: Bearer {{auth_token}}

@ -1,40 +1,39 @@
package de.szut.lf8_starter.project; package de.szut.lf8_starter.project;
import de.szut.lf8_starter.project.dto.CreateProjectDto; import de.szut.lf8_starter.project.dto.CreateProjectDto;
import de.szut.lf8_starter.project.dto.GetProjectDto; import de.szut.lf8_starter.project.dto.GetProjectDto;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.responses.ApiResponses;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping(value = "/projects")
@RestController public class CreateProjectAction {
@RequestMapping(value = "/projects") private final ProjectService projectService;
public class CreateProjectAction { private final ProjectMapper projectMapper;
private final ProjectService projectService;
private final ProjectMapper projectMapper; public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) {
this.projectService = projectService;
public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) { this.projectMapper = mappingService;
this.projectService = projectService; }
this.projectMapper = mappingService;
} @Operation(summary = "Creates a new Project")
@ApiResponses(value = {
@Operation(summary = "Creates a new Project") @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}),
@ApiResponses(value = { @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
@ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}), @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
@ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content), @PostMapping
@ApiResponse(responseCode = "401", description = "not authorized", content = @Content)}) @ResponseStatus(code = HttpStatus.CREATED)
@PostMapping public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) { ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
projectEntity = this.projectService.create(projectEntity);
projectEntity = this.projectService.create(projectEntity);
return this.projectMapper.mapToGetDto(projectEntity);
return this.projectMapper.mapToGetDto(projectEntity); }
} }
}

@ -1,42 +1,45 @@
package de.szut.lf8_starter.project.dto; package de.szut.lf8_starter.project.dto;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotBlank; import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import jakarta.validation.constraints.NotNull; import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.Getter; import jakarta.validation.constraints.NotBlank;
import lombok.Setter; import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import java.time.LocalDate; import lombok.Setter;
import java.util.List;
import java.time.LocalDate;
@Getter import java.util.List;
@Setter
public class CreateProjectDto { @Getter
@NotBlank @Setter
private String name; @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class CreateProjectDto {
@NotNull @NotBlank
private long leadingEmployee; private String name;
private List<Long> employees; @NotNull
private long leadingEmployee;
@NotNull
private long contractor; private List<Long> employees;
@NotBlank @NotNull
private String contractorName; private long contractor;
@NotBlank @NotBlank
private String comment; private String contractorName;
@JsonFormat(pattern = "dd.MM.yyyy") @NotBlank
@NotNull private String comment;
private LocalDate startDate;
@JsonFormat(pattern = "dd.MM.yyyy")
@JsonFormat(pattern = "dd.MM.yyyy") @NotNull
@NotNull private LocalDate startDate;
private LocalDate plannedEndDate;
@JsonFormat(pattern = "dd.MM.yyyy")
@JsonFormat(pattern = "dd.MM.yyyy") @NotNull
private LocalDate endDate; private LocalDate plannedEndDate;
}
@JsonFormat(pattern = "dd.MM.yyyy")
private LocalDate endDate;
}

@ -1,45 +1,34 @@
package de.szut.lf8_starter.project.dto; package de.szut.lf8_starter.project.dto;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotBlank; import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import jakarta.validation.constraints.NotNull; import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.Getter; import jakarta.validation.constraints.NotBlank;
import lombok.Setter; import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import java.time.LocalDate; import lombok.Setter;
import java.util.List;
import java.time.LocalDate;
@Getter import java.util.List;
@Setter
public class GetProjectDto { @Getter
private long id; @Setter
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@NotBlank public class GetProjectDto {
private String name; private long id;
private String name;
@NotNull private long leadingEmployee;
private long leadingEmployee; private List<Long> employees;
private long contractor;
private List<Long> employees; private String contractorName;
private String comment;
@NotNull
private long contractor; @JsonFormat(pattern = "dd.MM.yyyy")
private LocalDate startDate;
@NotBlank
private String contractorName; @JsonFormat(pattern = "dd.MM.yyyy")
private LocalDate plannedEndDate;
@NotBlank
private String comment; @JsonFormat(pattern = "dd.MM.yyyy")
private LocalDate endDate;
@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;
}

@ -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));
}
}

@ -1,60 +1,56 @@
package de.szut.lf8_starter.integration.project; package de.szut.lf8_starter.integration.project;
import de.szut.lf8_starter.project.ProjectEntity; import de.szut.lf8_starter.project.ProjectEntity;
import de.szut.lf8_starter.project.ProjectRepository; import de.szut.lf8_starter.project.ProjectRepository;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MockMvc;
import java.time.LocalDate;
import java.time.LocalDate; import java.util.List;
import java.util.List;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
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.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @AutoConfigureMockMvc(addFilters = false)
@AutoConfigureMockMvc(addFilters = false) public class ProjectFindAllSuccessTest {
public class ProjectFindAllSuccess { @Autowired
@Autowired private ProjectRepository projectRepository;
private ProjectRepository projectRepository;
@Autowired
@Autowired private MockMvc mockMvc;
private MockMvc mockMvc;
@Test
@Autowired void findAllProjectsTest() throws Exception {
private TestRestTemplate restTemplate; var project = new ProjectEntity();
project.setId(1);
@Test project.setComment("comment");
void findAllProjects() throws Exception { project.setContractor(1);
var project = new ProjectEntity(); project.setContractorName("contractorName");
project.setId(1); project.setEndDate(LocalDate.of(2024, 1, 1));
project.setComment("comment"); project.setLeadingEmployee(1);
project.setContractor(1); project.setName("name");
project.setContractorName("contractorName"); project.setStartDate(LocalDate.of(2021, 1, 1));
project.setEndDate(LocalDate.of(2024, 1, 1)); project.setEmployees(List.of(1L,2L,3L));
project.setLeadingEmployee(1); this.projectRepository.save(project);
project.setName("name");
project.setStartDate(LocalDate.of(2021, 1, 1)); this.mockMvc.perform(get("/projects"))
project.setEmployees(List.of(1L,2L,3L)); .andExpect(status().isOk())
this.projectRepository.save(project); .andExpect(jsonPath("$", hasSize(1)))
.andExpect(jsonPath("$[0].id").value(1))
this.mockMvc.perform(get("/projects")) .andExpect(jsonPath("$[0].comment").value("comment"))
.andExpect(status().isOk()) .andExpect(jsonPath("$[0].contractor").value(1))
.andExpect(jsonPath("$", hasSize(1))) .andExpect(jsonPath("$[0].contractor_name").value("contractorName"))
.andExpect(jsonPath("$[0].id").value(1)) .andExpect(jsonPath("$[0].end_date").value("01.01.2024"))
.andExpect(jsonPath("$[0].comment").value("comment")) .andExpect(jsonPath("$[0].leading_employee").value(1))
.andExpect(jsonPath("$[0].contractor").value(1)) .andExpect(jsonPath("$[0].name").value("name"))
.andExpect(jsonPath("$[0].contractorName").value("contractorName")) .andExpect(jsonPath("$[0].start_date").value("01.01.2021"))
.andExpect(jsonPath("$[0].endDate").value("01.01.2024")) .andExpect(jsonPath("$[0].employees").isArray())
.andExpect(jsonPath("$[0].leadingEmployee").value(1)) .andExpect(jsonPath("$[0].employees", hasSize(3)));
.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)));
}
}