diff --git a/pet-clinic-data/src/main/java/guru/springframework/sfgpetclinic/model/BaseEntity.java b/pet-clinic-data/src/main/java/guru/springframework/sfgpetclinic/model/BaseEntity.java index df839eafd..2378e652d 100644 --- a/pet-clinic-data/src/main/java/guru/springframework/sfgpetclinic/model/BaseEntity.java +++ b/pet-clinic-data/src/main/java/guru/springframework/sfgpetclinic/model/BaseEntity.java @@ -25,4 +25,7 @@ public class BaseEntity implements Serializable { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + public boolean isNew() { + return this.id == null; + } } diff --git a/pet-clinic-web/src/main/java/guru/springframework/sfgpetclinic/controllers/OwnerController.java b/pet-clinic-web/src/main/java/guru/springframework/sfgpetclinic/controllers/OwnerController.java index 8ac91ac9f..394432160 100644 --- a/pet-clinic-web/src/main/java/guru/springframework/sfgpetclinic/controllers/OwnerController.java +++ b/pet-clinic-web/src/main/java/guru/springframework/sfgpetclinic/controllers/OwnerController.java @@ -6,12 +6,10 @@ import org.springframework.ui.Model; 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.RequestMapping; +import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; +import javax.validation.Valid; import java.util.List; /** @@ -20,6 +18,7 @@ @RequestMapping("/owners") @Controller public class OwnerController { + private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; private final OwnerService ownerService; @@ -65,10 +64,43 @@ public String processFindForm(Owner owner, BindingResult result, Model model){ } @GetMapping("/{ownerId}") - public ModelAndView showOwner(@PathVariable("ownerId") Long ownerId) { + public ModelAndView showOwner(@PathVariable Long ownerId) { ModelAndView mav = new ModelAndView("owners/ownerDetails"); mav.addObject(ownerService.findById(ownerId)); return mav; } + @GetMapping("/new") + public String initCreationForm(Model model) { + model.addAttribute("owner", Owner.builder().build()); + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } + + @PostMapping("/new") + public String processCreationForm(@Valid Owner owner, BindingResult result) { + if (result.hasErrors()) { + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } else { + Owner savedOwner = ownerService.save(owner); + return "redirect:/owners/" + savedOwner.getId(); + } + } + + @GetMapping("/{ownerId}/edit") + public String initUpdateOwnerForm(@PathVariable Long ownerId, Model model) { + model.addAttribute(ownerService.findById(ownerId)); + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } + + @PostMapping("/{ownerId}/edit") + public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, @PathVariable Long ownerId) { + if (result.hasErrors()) { + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } else { + owner.setId(ownerId); + Owner savedOwner = ownerService.save(owner); + return "redirect:/owners/" + savedOwner.getId(); + } + } + } diff --git a/pet-clinic-web/src/test/java/guru/springframework/sfgpetclinic/controllers/OwnerControllerTest.java b/pet-clinic-web/src/test/java/guru/springframework/sfgpetclinic/controllers/OwnerControllerTest.java index ea178b3f1..4de58d0d7 100644 --- a/pet-clinic-web/src/test/java/guru/springframework/sfgpetclinic/controllers/OwnerControllerTest.java +++ b/pet-clinic-web/src/test/java/guru/springframework/sfgpetclinic/controllers/OwnerControllerTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentMatchers; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -18,9 +19,9 @@ import static org.hamcrest.Matchers.*; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; 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.*; @ExtendWith(MockitoExtension.class) @@ -89,5 +90,49 @@ void displayOwner() throws Exception { } + @Test + void initCreationForm() throws Exception { + mockMvc.perform(get("/owners/new")) + .andExpect(status().isOk()) + .andExpect(view().name("owners/createOrUpdateOwnerForm")) + .andExpect(model().attributeExists("owner")); + + verifyZeroInteractions(ownerService); + } + + @Test + void processCreationForm() throws Exception { + when(ownerService.save(ArgumentMatchers.any())).thenReturn(Owner.builder().id(1l).build()); + + mockMvc.perform(post("/owners/new")) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/1")) + .andExpect(model().attributeExists("owner")); + + verify(ownerService).save(ArgumentMatchers.any()); + } + + @Test + void initUpdateOwnerForm() throws Exception { + when(ownerService.findById(anyLong())).thenReturn(Owner.builder().id(1l).build()); + + mockMvc.perform(get("/owners/1/edit")) + .andExpect(status().isOk()) + .andExpect(view().name("owners/createOrUpdateOwnerForm")) + .andExpect(model().attributeExists("owner")); + + verifyZeroInteractions(ownerService); + } + + @Test + void processUpdateOwnerForm() throws Exception { + when(ownerService.save(ArgumentMatchers.any())).thenReturn(Owner.builder().id(1l).build()); + mockMvc.perform(post("/owners/1/edit")) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/1")) + .andExpect(model().attributeExists("owner")); + + verify(ownerService).save(ArgumentMatchers.any()); + } } \ No newline at end of file