// SPDX-License-Identifier: AGPL-3.0-or-later // SPDX-FileCopyrightText: 2023-2024 swt23w23 package catering.staff; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.endsWith; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.salespointframework.core.Currencies.EURO; 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.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import java.time.LocalDateTime; import java.time.YearMonth; import java.util.Set; import javax.money.MonetaryAmount; import org.javamoney.moneta.Money; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.salespointframework.order.OrderManagement; import org.salespointframework.useraccount.UserAccountManagement; 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.data.domain.Pageable; import org.springframework.http.HttpHeaders; import org.springframework.security.test.context.support.WithAnonymousUser; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import catering.order.CustomCart; import catering.order.CustomOrder; import catering.order.OrderType; import catering.users.User; import catering.users.UserManagement; @AutoConfigureMockMvc @SpringBootTest class StaffControllerIntegrationTests { @Autowired MockMvc mvc; MockHttpServletRequestBuilder createStaff = post("/staff/add") .param("name", "Karl Baum") .param("wage", "10") .param("job", "COOK"); @Autowired private StaffManagement staffManagement; @Autowired private OrderManagement orderManagement; @Autowired private UserManagement userManagement; @Autowired private UserAccountManagement userAccountManagement; Employee defaultEmployee; Long defaultEmployeeId; User defaultCustomer; Employee orderEmployee; CustomOrder defaultStaffOrder; Employee removeEmployeeAssociatedWithOrder; CustomOrder removeEmployeeAssociatedWithOrderCustomOrder; CustomOrder createCustomOrder(LocalDateTime start, LocalDateTime end, Set staff) { CustomOrder order = orderManagement.save(new CustomOrder(defaultCustomer.getUserAccount().getId(), new CustomCart(OrderType.EVENT_CATERING, start, end))); staff.forEach(order::addEmployee); return orderManagement.save(order); } @BeforeEach void setup() throws Exception { orderManagement.findAll(Pageable.unpaged()).forEach(orderManagement::delete); staffManagement.findAll().map(Employee::getId).forEach(staffManagement::delete); defaultEmployee = staffManagement.save(new Employee("Dieter Baum", JobType.COOK, Money.of(0, EURO))); defaultEmployeeId = defaultEmployee.getId(); if (userAccountManagement.findByUsername("hemming").isEmpty()) { userManagement.createCustomer("hemming", "Nürnberger Platz", "123", "Hemming Quark"); } defaultCustomer = userManagement.getUserByName("hemming").get(); orderEmployee = staffManagement.save(new Employee("Tyler Baum", JobType.COOK, Money.of(10, EURO))); defaultStaffOrder = createCustomOrder(LocalDateTime.of(2023, 12, 20, 10, 0), LocalDateTime.of(2023, 12, 20, 21, 0), Set.of(orderEmployee)); removeEmployeeAssociatedWithOrder = staffManagement .save(new Employee("Mark Baum", JobType.COOK, Money.of(10, EURO))); removeEmployeeAssociatedWithOrderCustomOrder = createCustomOrder(LocalDateTime.of(2022, 12, 20, 10, 0), LocalDateTime.of(2022, 12, 20, 21, 0), Set.of(removeEmployeeAssociatedWithOrder)); } @AfterEach void tearDown() throws Exception { staffManagement.delete(defaultEmployeeId); defaultEmployee = null; defaultEmployeeId = null; } @Test @WithMockUser(username = "admin", password = "admin", roles = "ADMIN") void viewStaff() throws Exception { mvc.perform(get("/staff")) .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()))); } @Test @WithMockUser(username = "admin", password = "admin", roles = "ADMIN") void addStaff() throws Exception { assertThat(staffManagement.findAll().stream()) .extracting("name") .doesNotContain("Karl Baum"); mvc.perform(createStaff).andExpect(redirectedUrl("/staff")); assertThat(staffManagement.findAll().stream()) .extracting("name") .contains("Karl Baum"); } @Test @WithMockUser(username = "admin", password = "admin", roles = "ADMIN") void modifyStaff() throws Exception { mvc.perform(post("/staff/edit/" + defaultEmployeeId.toString()) .param("name", "Dieter Bäume") .param("wage", "10") .param("job", "SERVICE")).andExpect(redirectedUrl("/staff")) .andExpect(redirectedUrl("/staff")); assertThat(staffManagement.findById(defaultEmployeeId).get()) .extracting("name", "job") .containsExactly("Dieter Bäume", JobType.SERVICE); } @Test @WithMockUser(username = "admin", password = "admin", roles = "ADMIN") void removeStaff() throws Exception { assertThat(staffManagement.findAll().stream()) .extracting("name") .contains("Dieter Baum"); mvc.perform(post("/staff/remove").param("id", defaultEmployeeId.toString())); assertThat(staffManagement.findAll().stream()) .extracting("name") .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 Lohn"))) .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 Lohn"))) .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("wage", "10") .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("wage", "10") .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 = "admin", password = "admin", roles = "ADMIN") void viewHoursOfWork() throws Exception { mvc.perform(get("/staff").queryParam("month", "2023-12")) .andExpect(status().isOk()) .andExpect(content().string(containsString("11.0"))); } @Test @WithMockUser(username = "dieter", password = "123", roles = "CUSTOMER") void refuseCustomer() throws Exception { mvc.perform(get("/staff")).andExpect(status().isForbidden()); mvc.perform(get("/staff/edit/" + defaultEmployeeId.toString())).andExpect(status().isForbidden()); } @Test @WithAnonymousUser void refuseAnonymous() throws Exception { mvc.perform(get("/staff")) .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"))); } @Test @WithMockUser(username = "admin", password = "admin", roles = "ADMIN") void removeStaffAssoicatetWithAnOrder() throws Exception { MonetaryAmount price = removeEmployeeAssociatedWithOrderCustomOrder.getTotal(); assertThat(removeEmployeeAssociatedWithOrderCustomOrder.getStaff().contains(removeEmployeeAssociatedWithOrder)) .isTrue(); assertThat(staffManagement.findAll().stream()) .extracting("name") .contains("Mark Baum"); mvc.perform(post("/staff/remove").param("id", removeEmployeeAssociatedWithOrder.getId().toString())); assertThat(staffManagement.findAll().stream()) .extracting("name") .doesNotContain("Mark Baum"); assertThat(removeEmployeeAssociatedWithOrderCustomOrder.getTotal().isEqualTo(price)).isTrue(); } }