mirror of
https://github.com/st-tu-dresden-praktikum/swt23w23
synced 2024-07-19 21:04:36 +02:00
parent
a46d2ad169
commit
0119b1cfa0
|
@ -300,6 +300,7 @@ image:models/design/staff.svg[class design diagram - Staff]
|
|||
|StaffController |A Spring MVC Controller for handling staff-related operations such as adding, removing, and updating staff data. It interacts with StaffManagement.
|
||||
|StaffManagement |A class that manages interactions and logic with StaffRepository. It provides methods to find, save/add, list, and delete staff members.
|
||||
|StaffRepository |An extension of 'CrudRepository' that provides standard methods to perform CRUD operations on staff objects.
|
||||
|StaffForm |A Form to cache a user input that was made during registration or updating an Employee.
|
||||
|===
|
||||
|
||||
=== Link between analysis and design
|
||||
|
|
|
@ -6,6 +6,8 @@ skinparam groupInheritance 2
|
|||
package Spring {
|
||||
class CrudRepository
|
||||
class Streamable
|
||||
class Errors
|
||||
class Model
|
||||
}
|
||||
|
||||
package catering.staff {
|
||||
|
@ -32,13 +34,18 @@ package catering.staff {
|
|||
class StaffController {
|
||||
+ StaffController(staffRepository: StaffRepository)
|
||||
+ getStaff(model: Model): String
|
||||
+ getStaff(model: Model, form: StaffForm): String
|
||||
+ removeEmployee(employee: Employee, model: Model): String
|
||||
+ addEmployee(name: String, job: JobType): String
|
||||
+ addEmployee(form:StaffForm, result:Errors, model: Model): String
|
||||
+ editEmployee(employee: Employee, model Model): String
|
||||
+ updateEmployee(employee: Employee, name: String, job: JobType): String
|
||||
+ editEmployee(model Model, form:StaffForm): String
|
||||
+ updateEmployee(employee: Employee, form:StaffForm): String
|
||||
}
|
||||
StaffController --> StaffManagement : -staffManagement
|
||||
StaffController ..> Employee
|
||||
StaffController ..> StaffForm
|
||||
StaffController ..> Model
|
||||
StaffController ..> Errors
|
||||
|
||||
class StaffManagement {
|
||||
+ StaffManagement(staffRepository: StaffRepository)
|
||||
|
@ -56,6 +63,16 @@ package catering.staff {
|
|||
StaffRepository ..|> Streamable
|
||||
StaffRepository o-- Employee
|
||||
|
||||
class StaffForm {
|
||||
- name: String
|
||||
+ StaffForm(): void
|
||||
+ getName(): String
|
||||
+ getJob(): JobType
|
||||
+ setName(name:String): void
|
||||
+ setJob(job:JobType): void
|
||||
+ validate(e:Errors): void
|
||||
}
|
||||
StaffForm ..> JobType : -job
|
||||
}
|
||||
|
||||
@enduml
|
||||
|
|
BIN
src/main/asciidoc/models/design/staff.svg
(Stored with Git LFS)
BIN
src/main/asciidoc/models/design/staff.svg
(Stored with Git LFS)
Binary file not shown.
|
@ -3,11 +3,15 @@ package catering.staff;
|
|||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.Errors;
|
||||
|
||||
@Controller
|
||||
public class StaffController {
|
||||
|
@ -21,10 +25,26 @@ public class StaffController {
|
|||
@GetMapping("/staff")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public String getStaff(Model model) {
|
||||
return getStaff(model, new StaffForm());
|
||||
}
|
||||
|
||||
public String getStaff(Model model, @Valid StaffForm form) {
|
||||
model.addAttribute("staff", staffManagement.findAll());
|
||||
model.addAttribute("form", form);
|
||||
return "staff";
|
||||
}
|
||||
|
||||
@PostMapping("/staff/add")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public String addEmployee(@Valid @ModelAttribute("form") StaffForm form, Errors result, Model model) {
|
||||
form.validate(result);
|
||||
if (result.hasErrors()) {
|
||||
return getStaff(model, form);
|
||||
}
|
||||
staffManagement.save(new Employee(form.getName(), form.getJob()));
|
||||
return "redirect:/staff";
|
||||
}
|
||||
|
||||
@PostMapping("/staff/remove")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public String removeEmployee(@RequestParam("id") Employee employee, Model model) {
|
||||
|
@ -32,25 +52,30 @@ public class StaffController {
|
|||
return "redirect:/staff";
|
||||
}
|
||||
|
||||
@PostMapping("/staff/add")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public String addEmployee(@RequestParam String name, @RequestParam JobType job) {
|
||||
staffManagement.save(new Employee(name, job));
|
||||
return "redirect:/staff";
|
||||
}
|
||||
|
||||
@GetMapping("/staff/edit/{id}")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public String editEmployee(@PathVariable("id") Employee employee, Model model) {
|
||||
model.addAttribute("employee", employee);
|
||||
StaffForm form = new StaffForm();
|
||||
form.setJob(employee.getJob());
|
||||
form.setName(employee.getName());
|
||||
return editEmployee(model, form);
|
||||
}
|
||||
|
||||
public String editEmployee(Model model, @Valid StaffForm form) {
|
||||
model.addAttribute("form", form);
|
||||
return "edit-staff";
|
||||
}
|
||||
|
||||
@PostMapping("/staff/edit/{id}")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public String updateEmployee(@PathVariable("id") Employee employee, @RequestParam String name, @RequestParam JobType job) {
|
||||
employee.setJob(job);
|
||||
employee.setName(name);
|
||||
public String updateEmployee(@PathVariable("id") Employee employee, @Valid @ModelAttribute("form") StaffForm form,
|
||||
Errors result, Model model) {
|
||||
form.validate(result);
|
||||
if (result.hasErrors()) {
|
||||
return editEmployee(model, form);
|
||||
}
|
||||
employee.setJob(form.getJob());
|
||||
employee.setName(form.getName());
|
||||
staffManagement.save(employee);
|
||||
return "redirect:/staff";
|
||||
}
|
||||
|
|
38
src/main/java/catering/staff/StaffForm.java
Normal file
38
src/main/java/catering/staff/StaffForm.java
Normal file
|
@ -0,0 +1,38 @@
|
|||
package catering.staff;
|
||||
|
||||
import org.springframework.validation.Errors;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
public class StaffForm {
|
||||
|
||||
private @NotEmpty String name;
|
||||
private @NotNull JobType job;
|
||||
|
||||
public StaffForm() {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public JobType getJob() {
|
||||
return job;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setJob(JobType job) {
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
public void validate(Errors e) {
|
||||
if (job == null) {
|
||||
e.rejectValue("job", "job is not a job type");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -7,17 +7,18 @@
|
|||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<form th:object="${employee}" method="post">
|
||||
<input type="hidden" th:field="*{id}" />
|
||||
<form th:object="${form}" method="post">
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="name">Name:</label>
|
||||
<input class="form-control" type="text" th:field="*{name}" required />
|
||||
<input class="form-control" type="text" th:field="*{name}" th:errorclass="is-invalid" required/>
|
||||
<div th:if="${#fields.hasErrors('name')}" class="invalid-feedback">Ungültiger Name</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="job">Beruf:</label>
|
||||
<select name="job" class="form-select">
|
||||
<option th:each="type : ${T(catering.staff.JobType).values()}" th:value="${type}" th:selected="${type.name() == employee.job.name()}" th:text="${type}" required></option>
|
||||
<select th:field="*{job}" class="form-select" th:errorclass="is-invalid">
|
||||
<option th:each="type : ${T(catering.staff.JobType).values()}" th:value="${type}" th:text="${type}" required></option>
|
||||
</select>
|
||||
<div th:if="${#fields.hasErrors('job')}" class="invalid-feedback">Ungültiger Job</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">Speichern</button>
|
||||
<a th:href="@{/staff}"><button type="button" class="btn btn-danger">Abbrechen</button></a>
|
||||
|
|
|
@ -37,16 +37,18 @@
|
|||
</div>
|
||||
<div>
|
||||
<h2>Personal Hinzufügen</h2>
|
||||
<form action="/staff/add" method="post">
|
||||
<form th:object="${form}" th:action="@{/staff/add}" method="post">
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="name">Name</label>
|
||||
<input class="form-control" type="text" name="name" required />
|
||||
<input class="form-control" type="text" th:field="*{name}" th:errorclass="is-invalid" required>
|
||||
<div th:if="${#fields.hasErrors('name')}" class="invalid-feedback">Ungültiger Name</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="job">Beruf:</label>
|
||||
<select name="job" class="form-select">
|
||||
<select th:field="*{job}" class="form-select" th:errorclass="is-invalid">
|
||||
<option th:each="type : ${T(catering.staff.JobType).values()}" th:value="${type}" th:text="${type}" required></option>
|
||||
</select>
|
||||
<div th:if="${#fields.hasErrors('job')}" class="invalid-feedback">Ungültiger Job</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">Hinzufügen</button>
|
||||
</form>
|
||||
|
|
|
@ -29,8 +29,8 @@ class StaffControllerIntegrationTests {
|
|||
MockMvc mvc;
|
||||
|
||||
MockHttpServletRequestBuilder createStaff = post("/staff/add")
|
||||
.param("name", "Karl Baum")
|
||||
.param("job", "COOK");
|
||||
.param("name", "Karl Baum")
|
||||
.param("job", "COOK");
|
||||
|
||||
@Autowired
|
||||
private StaffManagement staffManagement;
|
||||
|
@ -55,16 +55,16 @@ class StaffControllerIntegrationTests {
|
|||
@WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
|
||||
void viewStaff() throws Exception {
|
||||
mvc.perform(get("/staff"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString(defaultEmployee.getName())));
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString(defaultEmployee.getName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
|
||||
void viewStaffEditPage() throws Exception {
|
||||
mvc.perform(get("/staff/edit/" + defaultEmployeeId.toString()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString(defaultEmployee.getName())));
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString(defaultEmployee.getName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -83,12 +83,12 @@ class StaffControllerIntegrationTests {
|
|||
@WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
|
||||
void modifyStaff() throws Exception {
|
||||
mvc.perform(post("/staff/edit/" + defaultEmployeeId.toString())
|
||||
.param("name", "Dieter Bäume")
|
||||
.param("job", "SERVICE")).andExpect(redirectedUrl("/staff"))
|
||||
.andExpect(redirectedUrl("/staff"));
|
||||
.param("name", "Dieter Bäume")
|
||||
.param("job", "SERVICE")).andExpect(redirectedUrl("/staff"))
|
||||
.andExpect(redirectedUrl("/staff"));
|
||||
assertThat(staffManagement.findById(defaultEmployeeId).get())
|
||||
.extracting("name", "job")
|
||||
.containsExactly("Dieter Bäume", JobType.SERVICE);
|
||||
.extracting("name", "job")
|
||||
.containsExactly("Dieter Bäume", JobType.SERVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -103,6 +103,53 @@ class StaffControllerIntegrationTests {
|
|||
.doesNotContain("Dieter Baum");
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
|
||||
void addStaffWrong() throws Exception {
|
||||
mvc.perform(post("/staff/add"))
|
||||
.andExpect(content().string(containsString("Ungültiger Name")))
|
||||
.andExpect(content().string(containsString("Ungültiger Job")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
|
||||
void editStaffWrong() throws Exception {
|
||||
mvc.perform(post("/staff/edit/" + defaultEmployeeId.toString()))
|
||||
.andExpect(content().string(containsString("Ungültiger Name")))
|
||||
.andExpect(content().string(containsString("Ungültiger Job")));
|
||||
assertThat(staffManagement.findById(defaultEmployeeId).get())
|
||||
.extracting("name", "job")
|
||||
.containsExactly("Dieter Baum", JobType.COOK);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
|
||||
void addStaffWithWrongJobType() throws Exception {
|
||||
assertThat(staffManagement.findAll().stream())
|
||||
.extracting("name")
|
||||
.doesNotContain("Paul Kunst");
|
||||
mvc.perform(post("/staff/add")
|
||||
.param("name", "Paul Kunst")
|
||||
.param("job", "notAJob"))
|
||||
.andExpect(content().string(containsString("Ungültiger Job")));
|
||||
assertThat(staffManagement.findAll().stream())
|
||||
.extracting("name")
|
||||
.doesNotContain("Paul Kunst");
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
|
||||
void editStaffWithWrongJobType() throws Exception {
|
||||
mvc.perform(
|
||||
post("/staff/edit/" + defaultEmployeeId.toString())
|
||||
.param("name", defaultEmployee.getName())
|
||||
.param("job", "notAJob"))
|
||||
.andExpect(content().string(containsString("Ungültiger Job")));
|
||||
assertThat(staffManagement.findById(defaultEmployeeId).get())
|
||||
.extracting("name", "job")
|
||||
.containsExactly("Dieter Baum", JobType.COOK);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(username = "dieter", password = "123", roles = "CUSTOMER")
|
||||
void refuseCustomer() throws Exception {
|
||||
|
@ -114,10 +161,10 @@ class StaffControllerIntegrationTests {
|
|||
@WithAnonymousUser
|
||||
void refuseAnonymous() throws Exception {
|
||||
mvc.perform(get("/staff"))
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andExpect(header().string(HttpHeaders.LOCATION, endsWith("/login")));
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andExpect(header().string(HttpHeaders.LOCATION, endsWith("/login")));
|
||||
mvc.perform(get("/staff/edit/" + defaultEmployeeId))
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andExpect(header().string(HttpHeaders.LOCATION, endsWith("/login")));
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andExpect(header().string(HttpHeaders.LOCATION, endsWith("/login")));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue