From 205c9d9a7191acfd602b1bdab8ef5d7272a3250a Mon Sep 17 00:00:00 2001 From: Thiloparn <48439369+Thiloparn@users.noreply.github.com> Date: Sat, 27 Mar 2021 21:39:13 +0100 Subject: [PATCH 1/2] Arreglos para user, cambio de urls y organizacion de jsp , y test de controladores de speed y food Offers --- pom.xml | 5 + .../configuration/SecurityConfiguration.java | 6 +- .../springframework/cheapy/model/Offer.java | 6 +- .../cheapy/model/SpeedOffer.java | 3 - .../springframework/cheapy/model/User.java | 5 - .../cheapy/web/FoodOfferController.java | 19 +-- .../cheapy/web/SpeedOfferController.java | 19 +-- src/main/resources/db/mysql/data.sql | 20 +-- .../food}/createOrUpdateFoodOfferForm.jsp | 0 .../food}/foodOffersShow.jsp | 0 .../nu}/createOrUpdateNuOfferForm.jsp | 0 .../{nuOffers => offers/nu}/nuOffersShow.jsp | 0 .../speed}/createOrUpdateSpeedOfferForm.jsp | 0 .../speed}/speedOffersShow.jsp | 0 .../time}/createOrUpdateTimeOfferForm.jsp | 0 .../time}/timeOffersShow.jsp | 0 .../cheapy/web/FoodOfferControllerTests.java | 137 ++++++++++++++++ .../cheapy/web/SpeedOfferControllerTests.java | 149 ++++++++++++++++++ 18 files changed, 319 insertions(+), 50 deletions(-) rename src/main/webapp/WEB-INF/jsp/{foodOffers => offers/food}/createOrUpdateFoodOfferForm.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{foodOffers => offers/food}/foodOffersShow.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{nuOffers => offers/nu}/createOrUpdateNuOfferForm.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{nuOffers => offers/nu}/nuOffersShow.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{speedOffers => offers/speed}/createOrUpdateSpeedOfferForm.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{speedOffers => offers/speed}/speedOffersShow.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{timeOffers => offers/time}/createOrUpdateTimeOfferForm.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{timeOffers => offers/time}/timeOffersShow.jsp (100%) create mode 100644 src/test/java/org/springframework/cheapy/web/FoodOfferControllerTests.java create mode 100644 src/test/java/org/springframework/cheapy/web/SpeedOfferControllerTests.java diff --git a/pom.xml b/pom.xml index 38e0cd40b..c0ab78aad 100644 --- a/pom.xml +++ b/pom.xml @@ -69,6 +69,11 @@ org.springframework.security spring-security-taglibs + + org.springframework.security + spring-security-test + test + org.springframework.boot spring-boot-starter-security diff --git a/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java b/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java index 4c119fe2c..25a12bc0d 100644 --- a/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java +++ b/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java @@ -44,12 +44,12 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { .antMatchers("/usuarios/new").permitAll() .antMatchers("/admin/**").hasAnyAuthority("admin") - .antMatchers("/speedOffers/**").hasAnyAuthority("admin", "client") - .antMatchers("/foodOffers/**").hasAnyAuthority("admin", "client") .antMatchers("/owners/**").hasAnyAuthority("owner", "admin") .antMatchers("/clients/new").permitAll() - .antMatchers("/offers/**").hasAnyAuthority("admin") + .antMatchers("/offers/**/new").hasAnyAuthority("admin","client") + .antMatchers("/offers/**/activate").hasAnyAuthority("admin","client") + .antMatchers("/offers/**").permitAll() .and().formLogin() .loginPage("/login").permitAll() diff --git a/src/main/java/org/springframework/cheapy/model/Offer.java b/src/main/java/org/springframework/cheapy/model/Offer.java index c41ca9040..f5c92c10d 100644 --- a/src/main/java/org/springframework/cheapy/model/Offer.java +++ b/src/main/java/org/springframework/cheapy/model/Offer.java @@ -29,10 +29,7 @@ import org.springframework.format.annotation.DateTimeFormat; @MappedSuperclass public class Offer extends BaseEntity { - - /** - * - */ + private static final long serialVersionUID = 1L; //Clase padre @@ -46,7 +43,6 @@ public class Offer extends BaseEntity { @Future private LocalDateTime end; - private String code; @Enumerated(value = EnumType.STRING) diff --git a/src/main/java/org/springframework/cheapy/model/SpeedOffer.java b/src/main/java/org/springframework/cheapy/model/SpeedOffer.java index 0ef65d7a2..021a89106 100644 --- a/src/main/java/org/springframework/cheapy/model/SpeedOffer.java +++ b/src/main/java/org/springframework/cheapy/model/SpeedOffer.java @@ -10,9 +10,6 @@ import javax.validation.constraints.NotNull; @Table(name = "speed_offers") public class SpeedOffer extends Offer { - /** - * - */ private static final long serialVersionUID = 1L; @NotNull diff --git a/src/main/java/org/springframework/cheapy/model/User.java b/src/main/java/org/springframework/cheapy/model/User.java index bd5b2dd30..e9c232562 100644 --- a/src/main/java/org/springframework/cheapy/model/User.java +++ b/src/main/java/org/springframework/cheapy/model/User.java @@ -7,7 +7,6 @@ import javax.validation.constraints.NotBlank; @Entity @Table(name = "users") -//@MappedSuperclass public class User{ @Id @@ -18,10 +17,6 @@ public class User{ boolean enabled; - - /** - * - */ private static final long serialVersionUID = 1L; diff --git a/src/main/java/org/springframework/cheapy/web/FoodOfferController.java b/src/main/java/org/springframework/cheapy/web/FoodOfferController.java index af191c66d..c41974569 100644 --- a/src/main/java/org/springframework/cheapy/web/FoodOfferController.java +++ b/src/main/java/org/springframework/cheapy/web/FoodOfferController.java @@ -20,7 +20,7 @@ import org.springframework.web.bind.annotation.PostMapping; @Controller public class FoodOfferController { - private static final String VIEWS_FOOD_OFFER_CREATE_OR_UPDATE_FORM = "foodOffers/createOrUpdateFoodOfferForm"; + private static final String VIEWS_FOOD_OFFER_CREATE_OR_UPDATE_FORM = "offers/food/createOrUpdateFoodOfferForm"; private final FoodOfferService foodOfferService; private final ClientService clientService; @@ -31,19 +31,14 @@ public class FoodOfferController { this.clientService = clientService; } - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } - - @GetMapping("/foodOffers/new") + @GetMapping("/offers/food/new") public String initCreationForm(Map model) { FoodOffer foodOffer = new FoodOffer(); model.put("foodOffer", foodOffer); return VIEWS_FOOD_OFFER_CREATE_OR_UPDATE_FORM; } - @PostMapping("/foodOffers/new") + @PostMapping("/offers/food/new") public String processCreationForm(@Valid FoodOffer foodOffer, BindingResult result) { if (result.hasErrors()) { return VIEWS_FOOD_OFFER_CREATE_OR_UPDATE_FORM; @@ -53,11 +48,11 @@ public class FoodOfferController { foodOffer.setClient(client); foodOffer.setType(StatusOffer.hidden); this.foodOfferService.saveFoodOffer(foodOffer); - return "redirect:/foodOffers/" + foodOffer.getId(); + return "redirect:/offers/food/" + foodOffer.getId(); } } - @GetMapping(value = "/foodOffers/{foodOfferId}/activate") + @GetMapping(value = "/offers/food/{foodOfferId}/activate") public String activateFoodOffer(@PathVariable("foodOfferId") final int foodOfferId, ModelMap modelMap) { FoodOffer foodOffer = this.foodOfferService.findFoodOfferById(foodOfferId); Client client = this.clientService.getCurrentClient(); @@ -68,7 +63,7 @@ public class FoodOfferController { } else { modelMap.addAttribute("message", "You don't have access to this food offer"); } - return "redirect:/foodOffers/"; + return "redirect:/offers/food/" + foodOffer.getId(); } @GetMapping("/offers/food/{foodOfferId}") public String processShowForm(@PathVariable("foodOfferId") int foodOfferId, Map model) { @@ -77,7 +72,7 @@ public class FoodOfferController { model.put("foodOffer", foodOffer); - return "foodOffers/foodOffersShow"; + return "offers/food/foodOffersShow"; } } diff --git a/src/main/java/org/springframework/cheapy/web/SpeedOfferController.java b/src/main/java/org/springframework/cheapy/web/SpeedOfferController.java index f9678e4bc..7b9e071b8 100644 --- a/src/main/java/org/springframework/cheapy/web/SpeedOfferController.java +++ b/src/main/java/org/springframework/cheapy/web/SpeedOfferController.java @@ -37,7 +37,7 @@ import org.springframework.web.bind.annotation.PostMapping; @Controller public class SpeedOfferController { - private static final String VIEWS_SPEED_OFFER_CREATE_OR_UPDATE_FORM = "speedOffers/createOrUpdateSpeedOfferForm"; + private static final String VIEWS_SPEED_OFFER_CREATE_OR_UPDATE_FORM = "offers/speed/createOrUpdateSpeedOfferForm"; private final SpeedOfferService speedOfferService; private final ClientService clientService; @@ -47,19 +47,14 @@ public class SpeedOfferController { this.clientService = clientService; } - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } - - @GetMapping("/speedOffers/new") + @GetMapping("/offers/speed/new") public String initCreationForm(Map model) { SpeedOffer speedOffer = new SpeedOffer(); model.put("speedOffer", speedOffer); return VIEWS_SPEED_OFFER_CREATE_OR_UPDATE_FORM; } - @PostMapping("/speedOffers/new") + @PostMapping("/offers/speed/new") public String processCreationForm(@Valid SpeedOffer speedOffer, BindingResult result) { if (result.hasErrors()) { return VIEWS_SPEED_OFFER_CREATE_OR_UPDATE_FORM; @@ -69,11 +64,11 @@ public class SpeedOfferController { speedOffer.setClient(client); speedOffer.setType(StatusOffer.hidden); this.speedOfferService.saveSpeedOffer(speedOffer); - return "redirect:/speedOffers/" + speedOffer.getId(); + return "redirect:/offers/speed/" + speedOffer.getId(); } } - @GetMapping(value = "/speedOffers/{speedOfferId}/activate") + @GetMapping(value = "/offers/speed/{speedOfferId}/activate") public String activateSpeedOffer(@PathVariable("speedOfferId") final int speedOfferId, ModelMap modelMap) { SpeedOffer speedOffer = this.speedOfferService.findSpeedOfferById(speedOfferId); Client client = this.clientService.getCurrentClient(); @@ -84,7 +79,7 @@ public class SpeedOfferController { } else { modelMap.addAttribute("message", "You don't have access to this speed offer"); } - return "redirect:/speedOffers/"; + return "redirect:/offers/speed/" + speedOffer.getId(); } @GetMapping("/offers/speed/{speedOfferId}") @@ -92,6 +87,6 @@ public class SpeedOfferController { SpeedOffer speedOffer=this.speedOfferService.findSpeedOfferById(speedOfferId); model.put("speedOffer", speedOffer); - return "speedOffers/speedOffersShow"; + return "offers/speed/speedOffersShow"; } } diff --git a/src/main/resources/db/mysql/data.sql b/src/main/resources/db/mysql/data.sql index 30ae2672e..73fcd9849 100644 --- a/src/main/resources/db/mysql/data.sql +++ b/src/main/resources/db/mysql/data.sql @@ -9,17 +9,17 @@ INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', ' INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435'); INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','admin','admin', TRUE ); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','admin','admin', TRUE ); INSERT INTO authorities VALUES ('admin','admin'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','manoli','manoli', TRUE ); -INSERT INTO authorities VALUES ('manoli','cliente'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','david','david', TRUE ); -INSERT INTO authorities VALUES ('david','cliente'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','paco','paco', TRUE ); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','manoli','manoli', TRUE ); +INSERT INTO authorities VALUES ('manoli','client'); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','david','david', TRUE ); +INSERT INTO authorities VALUES ('david','client'); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','paco','paco', TRUE ); INSERT INTO authorities VALUES ('paco','usuario'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','lolo','lolo', TRUE ); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','lolo','lolo', TRUE ); INSERT INTO authorities VALUES ('lolo','usuario'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','pepe','pepe', TRUE ); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','pepe','pepe', TRUE ); INSERT INTO authorities VALUES ('pepe','usuario'); INSERT INTO usuarios VALUES (1, 'admin', 'admin', 'admin', 'C/admin', '000000000', 'admin@gmail.com','admin'); @@ -27,8 +27,8 @@ INSERT INTO usuarios VALUES (2, 'Paco', 'Naranjo', '21154416G', 'C/Esperanza', ' INSERT INTO usuarios VALUES (3, 'Lolo', 'Lopez', '25486596L', 'C/Macarena', '690670547' ,'Lolo@gmail.com','lolo'); INSERT INTO usuarios VALUES (4, 'Pepe', 'Lopez', '12456776V', 'C/Macarena', '690670547', 'Pepe@gmail.com','pepe'); -INSERT INTO clients VALUES (1,'manoli@gmail.com','C/Betis','10:00','22:00','608726190', 'description 1', 'code1', 'ESPAÑOLA','manoli'); -INSERT INTO clients VALUES (2,'david@gmail.com','C/Sevilla','09:30','22:00','608726190', 'description 2', 'code2', 'americana','david'); +INSERT INTO clients VALUES (1,'manoli@gmail.com','C/Betis','10:00','22:00','608726190', 'description 1', 'code1', 'ESPAÑOLA','manoli'); +INSERT INTO clients VALUES (2,'david@gmail.com','C/Sevilla','09:30','22:00','608726190', 'description 2', 'code2', 'americana','david'); INSERT INTO food_offers(start, end, code, type, client_id, food, discount, units) VALUES ('2021-06-15 12:00:00', '2021-06-16 12:00:00', 'FO-1', 'active', null, 'macarrones', '15%', 10); INSERT INTO speed_offers(start, end, code, type, client_id, gold, discount_gold, silver, discount_silver, bronze, discount_bronze) VALUES ('2021-06-15 12:00:00', '2021-06-16 12:00:00', 'SP-1', 'active', null, 5, '15%', 10, '10%', 15, '5%'); diff --git a/src/main/webapp/WEB-INF/jsp/foodOffers/createOrUpdateFoodOfferForm.jsp b/src/main/webapp/WEB-INF/jsp/offers/food/createOrUpdateFoodOfferForm.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/foodOffers/createOrUpdateFoodOfferForm.jsp rename to src/main/webapp/WEB-INF/jsp/offers/food/createOrUpdateFoodOfferForm.jsp diff --git a/src/main/webapp/WEB-INF/jsp/foodOffers/foodOffersShow.jsp b/src/main/webapp/WEB-INF/jsp/offers/food/foodOffersShow.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/foodOffers/foodOffersShow.jsp rename to src/main/webapp/WEB-INF/jsp/offers/food/foodOffersShow.jsp diff --git a/src/main/webapp/WEB-INF/jsp/nuOffers/createOrUpdateNuOfferForm.jsp b/src/main/webapp/WEB-INF/jsp/offers/nu/createOrUpdateNuOfferForm.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/nuOffers/createOrUpdateNuOfferForm.jsp rename to src/main/webapp/WEB-INF/jsp/offers/nu/createOrUpdateNuOfferForm.jsp diff --git a/src/main/webapp/WEB-INF/jsp/nuOffers/nuOffersShow.jsp b/src/main/webapp/WEB-INF/jsp/offers/nu/nuOffersShow.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/nuOffers/nuOffersShow.jsp rename to src/main/webapp/WEB-INF/jsp/offers/nu/nuOffersShow.jsp diff --git a/src/main/webapp/WEB-INF/jsp/speedOffers/createOrUpdateSpeedOfferForm.jsp b/src/main/webapp/WEB-INF/jsp/offers/speed/createOrUpdateSpeedOfferForm.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/speedOffers/createOrUpdateSpeedOfferForm.jsp rename to src/main/webapp/WEB-INF/jsp/offers/speed/createOrUpdateSpeedOfferForm.jsp diff --git a/src/main/webapp/WEB-INF/jsp/speedOffers/speedOffersShow.jsp b/src/main/webapp/WEB-INF/jsp/offers/speed/speedOffersShow.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/speedOffers/speedOffersShow.jsp rename to src/main/webapp/WEB-INF/jsp/offers/speed/speedOffersShow.jsp diff --git a/src/main/webapp/WEB-INF/jsp/timeOffers/createOrUpdateTimeOfferForm.jsp b/src/main/webapp/WEB-INF/jsp/offers/time/createOrUpdateTimeOfferForm.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/timeOffers/createOrUpdateTimeOfferForm.jsp rename to src/main/webapp/WEB-INF/jsp/offers/time/createOrUpdateTimeOfferForm.jsp diff --git a/src/main/webapp/WEB-INF/jsp/timeOffers/timeOffersShow.jsp b/src/main/webapp/WEB-INF/jsp/offers/time/timeOffersShow.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/timeOffers/timeOffersShow.jsp rename to src/main/webapp/WEB-INF/jsp/offers/time/timeOffersShow.jsp diff --git a/src/test/java/org/springframework/cheapy/web/FoodOfferControllerTests.java b/src/test/java/org/springframework/cheapy/web/FoodOfferControllerTests.java new file mode 100644 index 000000000..c2e4a4348 --- /dev/null +++ b/src/test/java/org/springframework/cheapy/web/FoodOfferControllerTests.java @@ -0,0 +1,137 @@ +package org.springframework.cheapy.web; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +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.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; + +import java.time.LocalDateTime; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.cheapy.configuration.SecurityConfiguration; +import org.springframework.cheapy.model.Client; +import org.springframework.cheapy.model.FoodOffer; +import org.springframework.cheapy.model.User; +import org.springframework.cheapy.service.ClientService; +import org.springframework.cheapy.service.FoodOfferService; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.security.config.annotation.web.WebSecurityConfigurer; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; + + + +@WebMvcTest(value = FoodOfferController.class, +excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = WebSecurityConfigurer.class), +excludeAutoConfiguration = SecurityConfiguration.class) +class FoodOfferControllerTest { + + private static final int TEST_CLIENT_ID = 1; + private static final int TEST_FOODOFFER_ID = 1; + + @Autowired + private MockMvc mockMvc; + + @MockBean + private FoodOfferService foodOfferService; + + @MockBean + private ClientService clientService; + + private FoodOffer fo1; + + @BeforeEach + void setup() { + User user1 = new User(); + user1.setUsername("user1"); + user1.setPassword("user1"); + Client client1 = new Client(); + client1.setId(TEST_CLIENT_ID); + client1.setEmail("client1"); + client1.setAddress("client1"); + client1.setInit("01:00"); + client1.setFinish("01:01"); + client1.setTelephone("123456789"); + client1.setDescription("client1"); + client1.setCode("client1"); + client1.setFood("client1"); + client1.setUsername(user1); + BDDMockito.given(this.clientService.getCurrentClient()).willReturn(client1); + + FoodOffer fo1test = new FoodOffer(); + fo1test.setId(TEST_FOODOFFER_ID); + fo1test.setStart(LocalDateTime.of(2021, 12, 23, 12, 30)); + fo1test.setEnd(LocalDateTime.of(2022, 12, 23, 12, 30)); + fo1test.setFood("fo1test"); + fo1test.setDiscount("fo1test"); + fo1test.setUnits(1); + fo1test.setClient(client1); + this.fo1 = fo1test; + BDDMockito.given(this.foodOfferService.findFoodOfferById(TEST_FOODOFFER_ID)).willReturn(this.fo1); + + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testInitCreationForm() throws Exception { + mockMvc.perform(get("/offers/food/new")) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("foodOffer")) + .andExpect(view().name("offers/food/createOrUpdateFoodOfferForm")); + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testProcessCreationFormSuccess() throws Exception { + mockMvc.perform(post("/offers/food/new") + .with(csrf()) + .param("start", "23/12/2021 12:30") + .param("end", "23/12/2022 12:30") + .param("food", "food") + .param("discount", "10%") + .param("units", "1")) + .andExpect(status().is3xxRedirection()); + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testProcessCreationFormHasErrors() throws Exception { + mockMvc.perform(post("/offers/food/new") + .with(csrf()) + .param("start", "lsqdufhlqhf") + .param("end", "") + .param("food", "") + .param("discount", "") + .param("units", "qsdfy")) + .andExpect(model().attributeHasErrors("foodOffer")) + .andExpect(model().attributeHasFieldErrors("foodOffer", "start")) + .andExpect(model().attributeHasFieldErrors("foodOffer", "end")) + .andExpect(model().attributeHasFieldErrors("foodOffer", "food")) + .andExpect(model().attributeHasFieldErrors("foodOffer", "discount")) + .andExpect(model().attributeHasFieldErrors("foodOffer", "units")) + .andExpect(view().name("offers/food/createOrUpdateFoodOfferForm")); + } + + @WithMockUser(value = "user1", authorities = "client") + @Test + void testActivateSuccess() throws Exception { + mockMvc.perform(get("/offers/food/{foodOfferId}/activate", TEST_FOODOFFER_ID)) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/offers/food/"+TEST_FOODOFFER_ID)); + } + + @WithMockUser(value = "user1", authorities = "client") + @Test + void testActivateHasErrors() throws Exception { + mockMvc.perform(get("/offers/food/{foodOfferId}/activate", TEST_FOODOFFER_ID+1)) + .andExpect(view().name("exception")); + } +} \ No newline at end of file diff --git a/src/test/java/org/springframework/cheapy/web/SpeedOfferControllerTests.java b/src/test/java/org/springframework/cheapy/web/SpeedOfferControllerTests.java new file mode 100644 index 000000000..c20615d3d --- /dev/null +++ b/src/test/java/org/springframework/cheapy/web/SpeedOfferControllerTests.java @@ -0,0 +1,149 @@ +package org.springframework.cheapy.web; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +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.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; + +import java.time.LocalDateTime; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.cheapy.configuration.SecurityConfiguration; +import org.springframework.cheapy.model.Client; +import org.springframework.cheapy.model.SpeedOffer; +import org.springframework.cheapy.model.User; +import org.springframework.cheapy.service.ClientService; +import org.springframework.cheapy.service.SpeedOfferService; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.security.config.annotation.web.WebSecurityConfigurer; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; + + + +@WebMvcTest(value = SpeedOfferController.class, +excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = WebSecurityConfigurer.class), +excludeAutoConfiguration = SecurityConfiguration.class) +class SpeedOfferControllerTest { + + private static final int TEST_CLIENT_ID = 1; + private static final int TEST_SPEEDOFFER_ID = 1; + + @Autowired + private MockMvc mockMvc; + + @MockBean + private SpeedOfferService speedOfferService; + + @MockBean + private ClientService clientService; + + private SpeedOffer sp1; + + @BeforeEach + void setup() { + User user1 = new User(); + user1.setUsername("user1"); + user1.setPassword("user1"); + Client client1 = new Client(); + client1.setId(TEST_CLIENT_ID); + client1.setEmail("client1"); + client1.setAddress("client1"); + client1.setInit("01:00"); + client1.setFinish("01:01"); + client1.setTelephone("123456789"); + client1.setDescription("client1"); + client1.setCode("client1"); + client1.setFood("client1"); + client1.setUsername(user1); + BDDMockito.given(this.clientService.getCurrentClient()).willReturn(client1); + + SpeedOffer sp1test = new SpeedOffer(); + sp1test.setId(TEST_SPEEDOFFER_ID); + sp1test.setStart(LocalDateTime.of(2021, 12, 23, 12, 30)); + sp1test.setEnd(LocalDateTime.of(2022, 12, 23, 12, 30)); + sp1test.setGold(5); + sp1test.setDiscountGold("15%"); + sp1test.setSilver(10); + sp1test.setDiscountGold("10%"); + sp1test.setGold(15); + sp1test.setDiscountGold("5%"); + sp1test.setClient(client1); + this.sp1 = sp1test; + BDDMockito.given(this.speedOfferService.findSpeedOfferById(TEST_SPEEDOFFER_ID)).willReturn(this.sp1); + + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testInitCreationForm() throws Exception { + mockMvc.perform(get("/offers/speed/new")) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("speedOffer")) + .andExpect(view().name("offers/speed/createOrUpdateSpeedOfferForm")); + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testProcessCreationFormSuccess() throws Exception { + mockMvc.perform(post("/offers/speed/new") + .with(csrf()) + .param("start", "23/12/2021 12:30") + .param("end", "23/12/2022 12:30") + .param("gold", "5") + .param("discountGold", "15%") + .param("silver", "10") + .param("discountSilver", "10%") + .param("bronze", "15") + .param("discountBronze", "5%")) + .andExpect(status().is3xxRedirection()); + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testProcessCreationFormHasErrors() throws Exception { + mockMvc.perform(post("/offers/speed/new") + .with(csrf()) + .param("start", "lsqdufhlqhf") + .param("end", "") + .param("gold", "gold") + .param("discountGold", "") + .param("silver", "") + .param("discountSilver", "") + .param("bronze", "") + .param("discountBronze", "")) + .andExpect(model().attributeHasErrors("speedOffer")) + .andExpect(model().attributeHasFieldErrors("speedOffer", "start")) + .andExpect(model().attributeHasFieldErrors("speedOffer", "end")) + .andExpect(model().attributeHasFieldErrors("speedOffer", "gold")) + .andExpect(model().attributeHasFieldErrors("speedOffer", "discountGold")) + .andExpect(model().attributeHasFieldErrors("speedOffer", "silver")) + .andExpect(model().attributeHasFieldErrors("speedOffer", "discountSilver")) + .andExpect(model().attributeHasFieldErrors("speedOffer", "bronze")) + .andExpect(model().attributeHasFieldErrors("speedOffer", "discountBronze")) + .andExpect(view().name("offers/speed/createOrUpdateSpeedOfferForm")); + } + + @WithMockUser(value = "user1", authorities = "client") + @Test + void testActivateSuccess() throws Exception { + mockMvc.perform(get("/offers/speed/{speedOfferId}/activate", TEST_SPEEDOFFER_ID)) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/offers/speed/"+TEST_SPEEDOFFER_ID)); + } + + @WithMockUser(value = "user1", authorities = "client") + @Test + void testActivateHasErrors() throws Exception { + mockMvc.perform(get("/offers/speed/{speedOfferId}/activate", TEST_SPEEDOFFER_ID+1)) + .andExpect(view().name("exception")); + } +} \ No newline at end of file From 2d251f9bcd2da57a3f3609733a3fdcdba2066a5d Mon Sep 17 00:00:00 2001 From: abemorcardc Date: Sun, 28 Mar 2021 00:49:12 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Tests=20de=20TimeOffer=20y=20NuOffer,=20y?= =?UTF-8?q?=20arreglos=20en=20data.sql=20y=20urls=20Adem=C3=A1s,=20cambios?= =?UTF-8?q?=20en=20las=20urls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 + .../configuration/SecurityConfiguration.java | 5 +- .../cheapy/web/FoodOfferController.java | 22 ++- .../cheapy/web/NuOfferController.java | 23 ++- .../cheapy/web/SpeedOfferController.java | 21 +-- .../cheapy/web/TimeOfferController.java | 24 ++- src/main/resources/db/mysql/data.sql | 18 +-- .../food}/createOrUpdateFoodOfferForm.jsp | 0 .../food}/foodOffersShow.jsp | 0 .../nu}/createOrUpdateNuOfferForm.jsp | 0 .../{nuOffers => offers/nu}/nuOffersShow.jsp | 0 .../speed}/createOrUpdateSpeedOfferForm.jsp | 0 .../speed}/speedOffersShow.jsp | 0 .../time}/createOrUpdateTimeOfferForm.jsp | 2 +- .../time}/timeOffersShow.jsp | 0 .../cheapy/web/NuOfferControllerTests.java | 149 ++++++++++++++++++ .../cheapy/web/TimeOfferControllerTests.java | 140 ++++++++++++++++ 17 files changed, 342 insertions(+), 67 deletions(-) rename src/main/webapp/WEB-INF/jsp/{foodOffers => offers/food}/createOrUpdateFoodOfferForm.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{foodOffers => offers/food}/foodOffersShow.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{nuOffers => offers/nu}/createOrUpdateNuOfferForm.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{nuOffers => offers/nu}/nuOffersShow.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{speedOffers => offers/speed}/createOrUpdateSpeedOfferForm.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{speedOffers => offers/speed}/speedOffersShow.jsp (100%) rename src/main/webapp/WEB-INF/jsp/{timeOffers => offers/time}/createOrUpdateTimeOfferForm.jsp (95%) rename src/main/webapp/WEB-INF/jsp/{timeOffers => offers/time}/timeOffersShow.jsp (100%) create mode 100644 src/test/java/org/springframework/cheapy/web/NuOfferControllerTests.java create mode 100644 src/test/java/org/springframework/cheapy/web/TimeOfferControllerTests.java diff --git a/pom.xml b/pom.xml index 38e0cd40b..ea5d3a91d 100644 --- a/pom.xml +++ b/pom.xml @@ -69,6 +69,11 @@ org.springframework.security spring-security-taglibs + + org.springframework.security + spring-security-test + test + org.springframework.boot spring-boot-starter-security diff --git a/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java b/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java index 4c119fe2c..68efbd66b 100644 --- a/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java +++ b/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java @@ -48,8 +48,11 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { .antMatchers("/foodOffers/**").hasAnyAuthority("admin", "client") .antMatchers("/owners/**").hasAnyAuthority("owner", "admin") + .antMatchers("/offers/**/new").hasAnyAuthority("admin", "client") + .antMatchers("/offers/**/activate").hasAnyAuthority("admin","client") + .antMatchers("/clients/new").permitAll() - .antMatchers("/offers/**").hasAnyAuthority("admin") + .antMatchers("/offers/**").permitAll() .and().formLogin() .loginPage("/login").permitAll() diff --git a/src/main/java/org/springframework/cheapy/web/FoodOfferController.java b/src/main/java/org/springframework/cheapy/web/FoodOfferController.java index af191c66d..33696f3bc 100644 --- a/src/main/java/org/springframework/cheapy/web/FoodOfferController.java +++ b/src/main/java/org/springframework/cheapy/web/FoodOfferController.java @@ -2,7 +2,9 @@ package org.springframework.cheapy.web; import java.util.Map; + import javax.validation.Valid; + import org.springframework.cheapy.model.Client; import org.springframework.cheapy.model.FoodOffer; import org.springframework.cheapy.model.StatusOffer; @@ -11,16 +13,14 @@ import org.springframework.cheapy.service.FoodOfferService; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @Controller public class FoodOfferController { - private static final String VIEWS_FOOD_OFFER_CREATE_OR_UPDATE_FORM = "foodOffers/createOrUpdateFoodOfferForm"; + private static final String VIEWS_FOOD_OFFER_CREATE_OR_UPDATE_FORM = "offers/food/createOrUpdateFoodOfferForm"; private final FoodOfferService foodOfferService; private final ClientService clientService; @@ -31,19 +31,15 @@ public class FoodOfferController { this.clientService = clientService; } - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } - @GetMapping("/foodOffers/new") + @GetMapping("/offers/food/new") public String initCreationForm(Map model) { FoodOffer foodOffer = new FoodOffer(); model.put("foodOffer", foodOffer); return VIEWS_FOOD_OFFER_CREATE_OR_UPDATE_FORM; } - @PostMapping("/foodOffers/new") + @PostMapping("/offers/food/new") public String processCreationForm(@Valid FoodOffer foodOffer, BindingResult result) { if (result.hasErrors()) { return VIEWS_FOOD_OFFER_CREATE_OR_UPDATE_FORM; @@ -53,11 +49,11 @@ public class FoodOfferController { foodOffer.setClient(client); foodOffer.setType(StatusOffer.hidden); this.foodOfferService.saveFoodOffer(foodOffer); - return "redirect:/foodOffers/" + foodOffer.getId(); + return "redirect:/offers/food/" + foodOffer.getId(); } } - @GetMapping(value = "/foodOffers/{foodOfferId}/activate") + @GetMapping(value = "/offers/food/{foodOfferId}/activate") public String activateFoodOffer(@PathVariable("foodOfferId") final int foodOfferId, ModelMap modelMap) { FoodOffer foodOffer = this.foodOfferService.findFoodOfferById(foodOfferId); Client client = this.clientService.getCurrentClient(); @@ -68,7 +64,7 @@ public class FoodOfferController { } else { modelMap.addAttribute("message", "You don't have access to this food offer"); } - return "redirect:/foodOffers/"; + return "redirect:/offers/food/"+foodOfferId; } @GetMapping("/offers/food/{foodOfferId}") public String processShowForm(@PathVariable("foodOfferId") int foodOfferId, Map model) { @@ -77,7 +73,7 @@ public class FoodOfferController { model.put("foodOffer", foodOffer); - return "foodOffers/foodOffersShow"; + return "offers/food/foodOffersShow"; } } diff --git a/src/main/java/org/springframework/cheapy/web/NuOfferController.java b/src/main/java/org/springframework/cheapy/web/NuOfferController.java index c6ad3c47f..5649386ba 100644 --- a/src/main/java/org/springframework/cheapy/web/NuOfferController.java +++ b/src/main/java/org/springframework/cheapy/web/NuOfferController.java @@ -12,9 +12,7 @@ import org.springframework.cheapy.service.NuOfferService; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -22,7 +20,7 @@ import org.springframework.web.bind.annotation.PostMapping; @Controller public class NuOfferController { - private static final String VIEWS_NU_OFFER_CREATE_OR_UPDATE_FORM = "nuOffers/createOrUpdateNuOfferForm"; + private static final String VIEWS_NU_OFFER_CREATE_OR_UPDATE_FORM = "offers/nu/createOrUpdateNuOfferForm"; private final NuOfferService nuOfferService; private final ClientService clientService; @@ -35,19 +33,16 @@ public class NuOfferController { } - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } - @GetMapping("/nuOffers/new") + + @GetMapping("/offers/nu/new") public String initCreationForm(Map model) { NuOffer nuOffer = new NuOffer(); model.put("nuOffer", nuOffer); return VIEWS_NU_OFFER_CREATE_OR_UPDATE_FORM; } - @PostMapping("/nuOffers/new") + @PostMapping("/offers/nu/new") public String processCreationForm(@Valid NuOffer nuOffer, BindingResult result) { if (result.hasErrors()) { return VIEWS_NU_OFFER_CREATE_OR_UPDATE_FORM; @@ -61,10 +56,10 @@ public class NuOfferController { this.nuOfferService.saveNuOffer(nuOffer); - return "redirect:/nuOffers/" + nuOffer.getId(); + return "redirect:/offers/nu/"+nuOffer.getId(); } } - @GetMapping(value ="/nuOffers/{nuOfferId}/activate") + @GetMapping(value ="/offers/nu/{nuOfferId}/activate") public String activateNuOffer(@PathVariable("nuOfferId") final int nuOfferId, final ModelMap modelMap) { Client client = this.clientService.getCurrentClient(); NuOffer nuOffer=this.nuOfferService.findNuOfferById(nuOfferId); @@ -73,11 +68,11 @@ public class NuOfferController { nuOffer.setCode("NU-"+nuOfferId); this.nuOfferService.saveNuOffer(nuOffer); - return "redirect:/nuOffers/" + nuOffer.getId(); + } else { modelMap.addAttribute("message", "You don't have access to this number offer"); } - return "redirect:/nuOffers/"; + return "redirect:/offers/nu/"+nuOffer.getId(); } @@ -89,7 +84,7 @@ public class NuOfferController { model.put("nuOffer", nuOffer); - return "nuOffers/nuOffersShow"; + return "offers/nu/nuOffersShow"; } diff --git a/src/main/java/org/springframework/cheapy/web/SpeedOfferController.java b/src/main/java/org/springframework/cheapy/web/SpeedOfferController.java index f9678e4bc..f41a85803 100644 --- a/src/main/java/org/springframework/cheapy/web/SpeedOfferController.java +++ b/src/main/java/org/springframework/cheapy/web/SpeedOfferController.java @@ -28,16 +28,14 @@ import org.springframework.cheapy.service.SpeedOfferService; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @Controller public class SpeedOfferController { - private static final String VIEWS_SPEED_OFFER_CREATE_OR_UPDATE_FORM = "speedOffers/createOrUpdateSpeedOfferForm"; + private static final String VIEWS_SPEED_OFFER_CREATE_OR_UPDATE_FORM = "offers/speed/createOrUpdateSpeedOfferForm"; private final SpeedOfferService speedOfferService; private final ClientService clientService; @@ -47,19 +45,14 @@ public class SpeedOfferController { this.clientService = clientService; } - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } - - @GetMapping("/speedOffers/new") + @GetMapping("/offers/speed/new") public String initCreationForm(Map model) { SpeedOffer speedOffer = new SpeedOffer(); model.put("speedOffer", speedOffer); return VIEWS_SPEED_OFFER_CREATE_OR_UPDATE_FORM; } - @PostMapping("/speedOffers/new") + @PostMapping("/offers/speed/new") public String processCreationForm(@Valid SpeedOffer speedOffer, BindingResult result) { if (result.hasErrors()) { return VIEWS_SPEED_OFFER_CREATE_OR_UPDATE_FORM; @@ -69,11 +62,11 @@ public class SpeedOfferController { speedOffer.setClient(client); speedOffer.setType(StatusOffer.hidden); this.speedOfferService.saveSpeedOffer(speedOffer); - return "redirect:/speedOffers/" + speedOffer.getId(); + return "redirect:/offers/speed/" + speedOffer.getId(); } } - @GetMapping(value = "/speedOffers/{speedOfferId}/activate") + @GetMapping(value = "/offers/speed/{speedOfferId}/activate") public String activateSpeedOffer(@PathVariable("speedOfferId") final int speedOfferId, ModelMap modelMap) { SpeedOffer speedOffer = this.speedOfferService.findSpeedOfferById(speedOfferId); Client client = this.clientService.getCurrentClient(); @@ -84,7 +77,7 @@ public class SpeedOfferController { } else { modelMap.addAttribute("message", "You don't have access to this speed offer"); } - return "redirect:/speedOffers/"; + return "redirect:/offers/speed/" + speedOffer.getId(); } @GetMapping("/offers/speed/{speedOfferId}") @@ -92,6 +85,6 @@ public class SpeedOfferController { SpeedOffer speedOffer=this.speedOfferService.findSpeedOfferById(speedOfferId); model.put("speedOffer", speedOffer); - return "speedOffers/speedOffersShow"; + return "offers/speed/speedOffersShow"; } } diff --git a/src/main/java/org/springframework/cheapy/web/TimeOfferController.java b/src/main/java/org/springframework/cheapy/web/TimeOfferController.java index b1bc2e528..80980ae54 100644 --- a/src/main/java/org/springframework/cheapy/web/TimeOfferController.java +++ b/src/main/java/org/springframework/cheapy/web/TimeOfferController.java @@ -1,19 +1,18 @@ package org.springframework.cheapy.web; import java.util.Map; + import javax.validation.Valid; import org.springframework.cheapy.model.Client; -import org.springframework.cheapy.model.TimeOffer; import org.springframework.cheapy.model.StatusOffer; +import org.springframework.cheapy.model.TimeOffer; import org.springframework.cheapy.service.ClientService; import org.springframework.cheapy.service.TimeOfferService; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -21,7 +20,7 @@ import org.springframework.web.bind.annotation.PostMapping; @Controller public class TimeOfferController { - private static final String VIEWS_NU_OFFER_CREATE_OR_UPDATE_FORM = "timeOffers/createOrUpdateTimeOfferForm"; + private static final String VIEWS_NU_OFFER_CREATE_OR_UPDATE_FORM = "offers/time/createOrUpdateTimeOfferForm"; private final TimeOfferService timeOfferService; private final ClientService clientService; @@ -34,19 +33,15 @@ public class TimeOfferController { } - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } - @GetMapping("/timeOffers/new") + @GetMapping("/offers/time/new") public String initCreationForm(Map model) { TimeOffer timeOffer = new TimeOffer(); model.put("timeOffer", timeOffer); return VIEWS_NU_OFFER_CREATE_OR_UPDATE_FORM; } - @PostMapping("/timeOffers/new") + @PostMapping("/offers/time/new") public String processCreationForm(@Valid TimeOffer timeOffer, BindingResult result) { if (result.hasErrors()) { return VIEWS_NU_OFFER_CREATE_OR_UPDATE_FORM; @@ -60,10 +55,10 @@ public class TimeOfferController { this.timeOfferService.saveTimeOffer(timeOffer); - return "redirect:/TimeOffers/" + timeOffer.getId(); + return "redirect:/offers/time/" + timeOffer.getId(); } } - @GetMapping(value ="/timeOffers/{timeOfferId}/activate") + @GetMapping(value ="/offers/time/{timeOfferId}/activate") public String activateTimeOffer(@PathVariable("timeOfferId") final int timeOfferId, final ModelMap modelMap) { Client client = this.clientService.getCurrentClient(); TimeOffer timeOffer=this.timeOfferService.findTimeOfferById(timeOfferId); @@ -72,11 +67,10 @@ public class TimeOfferController { timeOffer.setCode("TI-"+timeOfferId); this.timeOfferService.saveTimeOffer(timeOffer); - return "redirect:/timeOffers/" + timeOffer.getId(); } else { modelMap.addAttribute("message", "You don't have access to this time offer"); } - return "redirect:/timeOffers/"; + return "redirect:/offers/time/" + timeOffer.getId(); } @@ -88,7 +82,7 @@ public class TimeOfferController { model.put("timeOffer", timeOffer); - return "timeOffers/timeOffersShow"; + return "offers/time/timeOffersShow"; } diff --git a/src/main/resources/db/mysql/data.sql b/src/main/resources/db/mysql/data.sql index 30ae2672e..435f10c15 100644 --- a/src/main/resources/db/mysql/data.sql +++ b/src/main/resources/db/mysql/data.sql @@ -9,17 +9,17 @@ INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', ' INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435'); INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','admin','admin', TRUE ); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','admin','admin', TRUE ); INSERT INTO authorities VALUES ('admin','admin'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','manoli','manoli', TRUE ); -INSERT INTO authorities VALUES ('manoli','cliente'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','david','david', TRUE ); -INSERT INTO authorities VALUES ('david','cliente'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','paco','paco', TRUE ); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','manoli','manoli', TRUE ); +INSERT INTO authorities VALUES ('manoli','client'); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','david','david', TRUE ); +INSERT INTO authorities VALUES ('david','client'); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','paco','paco', TRUE ); INSERT INTO authorities VALUES ('paco','usuario'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','lolo','lolo', TRUE ); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','lolo','lolo', TRUE ); INSERT INTO authorities VALUES ('lolo','usuario'); -INSERT INTO users (dtype,username,password,enabled) VALUES ('user','pepe','pepe', TRUE ); +INSERT INTO users (dtype,username,password,enabled) VALUES ('User','pepe','pepe', TRUE ); INSERT INTO authorities VALUES ('pepe','usuario'); INSERT INTO usuarios VALUES (1, 'admin', 'admin', 'admin', 'C/admin', '000000000', 'admin@gmail.com','admin'); @@ -33,5 +33,5 @@ INSERT INTO clients VALUES (2,'david@gmail.com','C/Sevilla','09:30','22:00','60 INSERT INTO food_offers(start, end, code, type, client_id, food, discount, units) VALUES ('2021-06-15 12:00:00', '2021-06-16 12:00:00', 'FO-1', 'active', null, 'macarrones', '15%', 10); INSERT INTO speed_offers(start, end, code, type, client_id, gold, discount_gold, silver, discount_silver, bronze, discount_bronze) VALUES ('2021-06-15 12:00:00', '2021-06-16 12:00:00', 'SP-1', 'active', null, 5, '15%', 10, '10%', 15, '5%'); INSERT INTO time_offers(start, end, code, type, client_id, init, finish, discount) VALUES ('2021-06-15 12:00:00', '2021-06-16 12:00:00', 'jkhlljk', 'active', null, '12:00:00', '13:00:00', '10%'); -INSERT INTO speed_offers(start, end, code, type, client_id, gold, discount_gold, silver, discount_silver, bronze, discount_bronze) VALUES ('2021-06-15 12:00:00', '2021-06-16 12:00:00', 'jkhlljk', 'active', null,5,'25%',10,'15%',15,'10%' ); +INSERT INTO speed_offers(id,start, end, code, type, client_id, gold, discount_gold, silver, discount_silver, bronze, discount_bronze) VALUES (3,'2021-06-15 12:00:00', '2021-06-16 12:00:00', 'jkhlljk', 'active', 1,5,'25%',10,'15%',15,'10%' ); INSERT INTO nu_offers(start, end, code, type, client_id, gold, discount_gold, silver, discount_silver, bronze, discount_bronze) VALUES ('2021-06-15 12:00:00', '2021-06-16 12:00:00', 'jkhlljk', 'active', null,15,'25%',10,'15%',5,'10%' ); diff --git a/src/main/webapp/WEB-INF/jsp/foodOffers/createOrUpdateFoodOfferForm.jsp b/src/main/webapp/WEB-INF/jsp/offers/food/createOrUpdateFoodOfferForm.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/foodOffers/createOrUpdateFoodOfferForm.jsp rename to src/main/webapp/WEB-INF/jsp/offers/food/createOrUpdateFoodOfferForm.jsp diff --git a/src/main/webapp/WEB-INF/jsp/foodOffers/foodOffersShow.jsp b/src/main/webapp/WEB-INF/jsp/offers/food/foodOffersShow.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/foodOffers/foodOffersShow.jsp rename to src/main/webapp/WEB-INF/jsp/offers/food/foodOffersShow.jsp diff --git a/src/main/webapp/WEB-INF/jsp/nuOffers/createOrUpdateNuOfferForm.jsp b/src/main/webapp/WEB-INF/jsp/offers/nu/createOrUpdateNuOfferForm.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/nuOffers/createOrUpdateNuOfferForm.jsp rename to src/main/webapp/WEB-INF/jsp/offers/nu/createOrUpdateNuOfferForm.jsp diff --git a/src/main/webapp/WEB-INF/jsp/nuOffers/nuOffersShow.jsp b/src/main/webapp/WEB-INF/jsp/offers/nu/nuOffersShow.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/nuOffers/nuOffersShow.jsp rename to src/main/webapp/WEB-INF/jsp/offers/nu/nuOffersShow.jsp diff --git a/src/main/webapp/WEB-INF/jsp/speedOffers/createOrUpdateSpeedOfferForm.jsp b/src/main/webapp/WEB-INF/jsp/offers/speed/createOrUpdateSpeedOfferForm.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/speedOffers/createOrUpdateSpeedOfferForm.jsp rename to src/main/webapp/WEB-INF/jsp/offers/speed/createOrUpdateSpeedOfferForm.jsp diff --git a/src/main/webapp/WEB-INF/jsp/speedOffers/speedOffersShow.jsp b/src/main/webapp/WEB-INF/jsp/offers/speed/speedOffersShow.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/speedOffers/speedOffersShow.jsp rename to src/main/webapp/WEB-INF/jsp/offers/speed/speedOffersShow.jsp diff --git a/src/main/webapp/WEB-INF/jsp/timeOffers/createOrUpdateTimeOfferForm.jsp b/src/main/webapp/WEB-INF/jsp/offers/time/createOrUpdateTimeOfferForm.jsp similarity index 95% rename from src/main/webapp/WEB-INF/jsp/timeOffers/createOrUpdateTimeOfferForm.jsp rename to src/main/webapp/WEB-INF/jsp/offers/time/createOrUpdateTimeOfferForm.jsp index 0dc37f439..e8f92db9c 100644 --- a/src/main/webapp/WEB-INF/jsp/timeOffers/createOrUpdateTimeOfferForm.jsp +++ b/src/main/webapp/WEB-INF/jsp/offers/time/createOrUpdateTimeOfferForm.jsp @@ -17,7 +17,7 @@ - +
diff --git a/src/main/webapp/WEB-INF/jsp/timeOffers/timeOffersShow.jsp b/src/main/webapp/WEB-INF/jsp/offers/time/timeOffersShow.jsp similarity index 100% rename from src/main/webapp/WEB-INF/jsp/timeOffers/timeOffersShow.jsp rename to src/main/webapp/WEB-INF/jsp/offers/time/timeOffersShow.jsp diff --git a/src/test/java/org/springframework/cheapy/web/NuOfferControllerTests.java b/src/test/java/org/springframework/cheapy/web/NuOfferControllerTests.java new file mode 100644 index 000000000..8e418a679 --- /dev/null +++ b/src/test/java/org/springframework/cheapy/web/NuOfferControllerTests.java @@ -0,0 +1,149 @@ +package org.springframework.cheapy.web; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +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.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; + +import java.time.LocalDateTime; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.cheapy.configuration.SecurityConfiguration; +import org.springframework.cheapy.model.Client; +import org.springframework.cheapy.model.NuOffer; +import org.springframework.cheapy.model.User; +import org.springframework.cheapy.service.ClientService; +import org.springframework.cheapy.service.NuOfferService; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.security.config.annotation.web.WebSecurityConfigurer; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; +import org.springframework.test.web.servlet.MockMvc; + +@WebMvcTest(value = NuOfferController.class, +excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = WebSecurityConfigurer.class), +excludeAutoConfiguration = SecurityConfiguration.class) +class NuOfferControllerTest { + + private static final int TEST_CLIENT_ID = 1; + private static final int TEST_NUOFFER_ID = 1; + + @Autowired + private MockMvc mockMvc; + + @MockBean + private NuOfferService nuOfferService; + + @MockBean + private ClientService clientService; + + private NuOffer nu1; + + @BeforeEach + void setup() { + User user1 = new User(); + user1.setUsername("user1"); + user1.setPassword("user1"); + Client client1 = new Client(); + client1.setId(TEST_CLIENT_ID); + client1.setEmail("client1"); + client1.setAddress("client1"); + client1.setInit("01:00"); + client1.setFinish("01:01"); + client1.setTelephone("123456789"); + client1.setDescription("client1"); + client1.setCode("client1"); + client1.setFood("client1"); + client1.setUsername(user1); + BDDMockito.given(this.clientService.getCurrentClient()).willReturn(client1); + + NuOffer nu1test = new NuOffer(); + nu1test.setId(TEST_NUOFFER_ID); + nu1test.setStart(LocalDateTime.of(2021, 12, 23, 12, 30)); + nu1test.setEnd(LocalDateTime.of(2022, 12, 23, 12, 30)); + nu1test.setGold(5); + nu1test.setDiscountGold("15%"); + nu1test.setSilver(10); + nu1test.setDiscountGold("10%"); + nu1test.setGold(15); + nu1test.setDiscountGold("5%"); + nu1test.setClient(client1); + this.nu1 = nu1test; + BDDMockito.given(this.nuOfferService.findNuOfferById(TEST_NUOFFER_ID)).willReturn(this.nu1); + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testInitCreationForm() throws Exception { + mockMvc.perform(get("/offers/nu/new")) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("nuOffer")) + .andExpect(view().name("offers/nu/createOrUpdateNuOfferForm")); + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testProcessCreationFormSuccess() throws Exception { + mockMvc.perform(post("/offers/nu/new") + .with(SecurityMockMvcRequestPostProcessors.csrf()) + .param("start", "23/12/2021 12:30") + .param("end", "23/12/2022 12:30") + .param("gold", "5") + .param("discountGold", "15") + .param("silver", "10") + .param("discountSilver", "10") + .param("bronze", "15") + .param("discountBronze", "5")) + .andExpect(status().is3xxRedirection()); + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testProcessCreationFormHasErrors() throws Exception { + mockMvc.perform(post("/offers/nu/new") + .with(csrf()) + .param("start", "lsqdufhlqhf") + .param("end", "") + .param("gold", "gold") + .param("discountGold", "") + .param("silver", "") + .param("discountSilver", "") + .param("bronze", "") + .param("discountBronze", "")) + .andExpect(model().attributeHasErrors("nuOffer")) + .andExpect(model().attributeHasFieldErrors("nuOffer", "start")) + .andExpect(model().attributeHasFieldErrors("nuOffer", "end")) + .andExpect(model().attributeHasFieldErrors("nuOffer", "gold")) + .andExpect(model().attributeHasFieldErrors("nuOffer", "discountGold")) + .andExpect(model().attributeHasFieldErrors("nuOffer", "silver")) + .andExpect(model().attributeHasFieldErrors("nuOffer", "discountSilver")) + .andExpect(model().attributeHasFieldErrors("nuOffer", "bronze")) + .andExpect(model().attributeHasFieldErrors("nuOffer", "discountBronze")) + .andExpect(view().name("offers/nu/createOrUpdateNuOfferForm")); + } + + @WithMockUser(value = "user1", authorities = "client") + @Test + void testActivateSuccess() throws Exception { + mockMvc.perform(get("/offers/nu/{nuOfferId}/activate", TEST_NUOFFER_ID)) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/offers/nu/"+TEST_NUOFFER_ID)); + } + + @WithMockUser(value = "user1", authorities = "client") + @Test + void testActivateHasErrors() throws Exception { + mockMvc.perform(get("/offers/nu/{nuOfferId}/activate", TEST_NUOFFER_ID+1)) + .andExpect(view().name("exception")); + } + + +} \ No newline at end of file diff --git a/src/test/java/org/springframework/cheapy/web/TimeOfferControllerTests.java b/src/test/java/org/springframework/cheapy/web/TimeOfferControllerTests.java new file mode 100644 index 000000000..df93d9ac6 --- /dev/null +++ b/src/test/java/org/springframework/cheapy/web/TimeOfferControllerTests.java @@ -0,0 +1,140 @@ +package org.springframework.cheapy.web; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +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.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; + +import java.time.LocalDateTime; +import java.time.LocalTime; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.cheapy.configuration.SecurityConfiguration; +import org.springframework.cheapy.model.Client; +import org.springframework.cheapy.model.TimeOffer; +import org.springframework.cheapy.model.User; +import org.springframework.cheapy.service.ClientService; +import org.springframework.cheapy.service.TimeOfferService; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.security.config.annotation.web.WebSecurityConfigurer; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; +import org.springframework.test.web.servlet.MockMvc; + +@WebMvcTest(value = TimeOfferController.class, +excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = WebSecurityConfigurer.class), +excludeAutoConfiguration = SecurityConfiguration.class) +class TimeOfferControllerTest { + + private static final int TEST_CLIENT_ID = 1; + private static final int TEST_TIMEOFFER_ID = 1; + + @Autowired + private MockMvc mockMvc; + + @MockBean + private TimeOfferService timeOfferService; + + @MockBean + private ClientService clientService; + + private TimeOffer time1; + + @BeforeEach + void setup() { + User user1 = new User(); + user1.setUsername("user1"); + user1.setPassword("user1"); + Client client1 = new Client(); + client1.setId(TEST_CLIENT_ID); + client1.setEmail("client1"); + client1.setAddress("client1"); + client1.setInit("01:00"); + client1.setFinish("01:01"); + client1.setTelephone("123456789"); + client1.setDescription("client1"); + client1.setCode("client1"); + client1.setFood("client1"); + client1.setUsername(user1); + BDDMockito.given(this.clientService.getCurrentClient()).willReturn(client1); + + TimeOffer time1test = new TimeOffer(); + time1test.setId(TEST_TIMEOFFER_ID); + time1test.setStart(LocalDateTime.of(2021, 12, 23, 12, 30)); + time1test.setEnd(LocalDateTime.of(2022, 12, 23, 12, 30)); + time1test.setInit(LocalTime.of(12, 00)); + time1test.setFinish(LocalTime.of(13, 00)); + time1test.setDiscount("10"); + time1test.setClient(client1); + this.time1 = time1test; + BDDMockito.given(this.timeOfferService.findTimeOfferById(TEST_TIMEOFFER_ID)).willReturn(this.time1); + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testInitCreationForm() throws Exception { + mockMvc.perform(get("/offers/time/new")) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("timeOffer")) + .andExpect(view().name("offers/time/createOrUpdateTimeOfferForm")); + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testProcessCreationFormSuccess() throws Exception { + mockMvc.perform(post("/offers/time/new") + .with(SecurityMockMvcRequestPostProcessors.csrf()) + .param("start", "23/12/2021 12:30") + .param("end", "23/12/2022 12:30") + .param("init", "12:30") + .param("finish", "13:30") + .param("discount", "10")) + .andExpect(status().is3xxRedirection()); + } + + @WithMockUser(value = "spring", authorities = "client") + @Test + void testProcessCreationFormHasErrors() throws Exception { + mockMvc.perform(post("/offers/time/new") + .with(csrf()) + .param("start", "lsqdufhlqhf") + .param("end", "") + .param("init", "gold") + .param("finish", "") + .param("discount", "")) + .andExpect(model().attributeHasErrors("timeOffer")) + .andExpect(model().attributeHasFieldErrors("timeOffer", "start")) + .andExpect(model().attributeHasFieldErrors("timeOffer", "end")) + .andExpect(model().attributeHasFieldErrors("timeOffer", "init")) + .andExpect(model().attributeHasFieldErrors("timeOffer", "finish")) + .andExpect(model().attributeHasFieldErrors("timeOffer", "discount")) + .andExpect(view().name("offers/time/createOrUpdateTimeOfferForm")); + } + + @WithMockUser(value = "user1", authorities = "client") + @Test + void testActivateSuccess() throws Exception { + mockMvc.perform(get("/offers/time/{timeOfferId}/activate", TEST_TIMEOFFER_ID)) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/offers/time/"+TEST_TIMEOFFER_ID)); + } + + @WithMockUser(value = "user1", authorities = "client") + @Test + void testActivateHasErrors() throws Exception { + mockMvc.perform(get("/offers/time/{timeOfferId}/activate", TEST_TIMEOFFER_ID+1)) + .andExpect(view().name("exception")); + } + + + + +} \ No newline at end of file