diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java index 049b21ba9..d84bef953 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java @@ -14,248 +14,247 @@ * limitations under the License. */ - package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.owner; - import org.assertj.core.util.Lists; - import org.junit.jupiter.api.BeforeEach; - import org.junit.jupiter.api.Test; - import org.junit.jupiter.api.condition.DisabledInNativeImage; - import org.springframework.beans.factory.annotation.Autowired; - import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; - import org.springframework.data.domain.Page; - import org.springframework.data.domain.PageImpl; - import org.springframework.data.domain.Pageable; - import org.springframework.test.context.aot.DisabledInAotMode; - import org.springframework.test.context.bean.override.mockito.MockitoBean; - import org.springframework.test.web.servlet.MockMvc; - import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; - - import java.time.LocalDate; - import java.util.Optional; - - import static org.hamcrest.Matchers.empty; - import static org.hamcrest.Matchers.greaterThan; - import static org.hamcrest.Matchers.hasItem; - import static org.hamcrest.Matchers.hasProperty; - import static org.hamcrest.Matchers.hasSize; - import static org.hamcrest.Matchers.is; - import static org.hamcrest.Matchers.not; - import static org.junit.jupiter.api.Assertions.assertNull; - import static org.mockito.ArgumentMatchers.any; - import static org.mockito.ArgumentMatchers.anyString; - import static org.mockito.ArgumentMatchers.eq; - import static org.mockito.BDDMockito.given; - import static org.mockito.Mockito.when; - 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.*; - - /** - * Test class for {@link OwnerController} - * - * Authors: Colin But, Wick Dynex - */ - @WebMvcTest(OwnerController.class) - @DisabledInNativeImage - @DisabledInAotMode - class OwnerControllerTests { - - private static final int TEST_OWNER_ID = 1; - - @Autowired - private MockMvc mockMvc; - - @MockitoBean - private OwnerRepository owners; - - private Owner george() { - Owner george = new Owner(); - george.setId(TEST_OWNER_ID); - george.setFirstName("George"); - george.setLastName("Franklin"); - george.setAddress("110 W. Liberty St."); - george.setCity("Madison"); - george.setTelephone("6085551023"); - Pet max = new Pet(); - PetType dog = new PetType(); - dog.setName("dog"); - max.setType(dog); - max.setName("Max"); - max.setBirthDate(LocalDate.now()); - george.addPet(max); - max.setId(1); - return george; - } - - @BeforeEach - void setup() { - - Owner george = george(); - given(this.owners.findByLastNameStartingWith(eq("Franklin"), any(Pageable.class))) - .willReturn(new PageImpl<>(Lists.newArrayList(george))); - - given(this.owners.findAll(any(Pageable.class))).willReturn(new PageImpl<>(Lists.newArrayList(george))); - - given(this.owners.findById(TEST_OWNER_ID)).willReturn(Optional.of(george)); - Visit visit = new Visit(); - visit.setDate(LocalDate.now()); - george.getPet("Max").getVisits().add(visit); - - // Added assertion to cover the branch where the pet is not found - assertNull(george.getPet("NonExistent"), "Expected getPet to return null when pet is not found"); - } - - @Test - void testInitCreationForm() throws Exception { - mockMvc.perform(get("/owners/new")) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } - - @Test - void testProcessCreationFormSuccess() throws Exception { - mockMvc - .perform(post("/owners/new").param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("address", "123 Caramel Street") - .param("city", "London") - .param("telephone", "1316761638")) - .andExpect(status().is3xxRedirection()); - } - - @Test - void testProcessCreationFormHasErrors() throws Exception { - mockMvc - .perform(post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs").param("city", "London")) - .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } - - @Test - void testInitFindForm() throws Exception { - mockMvc.perform(get("/owners/find")) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(view().name("owners/findOwners")); - } - - @Test - void testProcessFindFormSuccess() throws Exception { - Page tasks = new PageImpl<>(Lists.newArrayList(george(), new Owner())); - when(this.owners.findByLastNameStartingWith(anyString(), any(Pageable.class))).thenReturn(tasks); - mockMvc.perform(get("/owners?page=1")).andExpect(status().isOk()).andExpect(view().name("owners/ownersList")); - } - - @Test - void testProcessFindFormByLastName() throws Exception { - Page tasks = new PageImpl<>(Lists.newArrayList(george())); - when(this.owners.findByLastNameStartingWith(eq("Franklin"), any(Pageable.class))).thenReturn(tasks); - mockMvc.perform(get("/owners?page=1").param("lastName", "Franklin")) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID)); - } - - @Test - void testProcessFindFormNoOwnersFound() throws Exception { - Page tasks = new PageImpl<>(Lists.newArrayList()); - when(this.owners.findByLastNameStartingWith(eq("Unknown Surname"), any(Pageable.class))).thenReturn(tasks); - mockMvc.perform(get("/owners?page=1").param("lastName", "Unknown Surname")) - .andExpect(status().isOk()) - .andExpect(model().attributeHasFieldErrors("owner", "lastName")) - .andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound")) - .andExpect(view().name("owners/findOwners")); - - } - - @Test - void testInitUpdateOwnerForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) - .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) - .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } - - @Test - void testProcessUpdateOwnerFormSuccess() throws Exception { - mockMvc - .perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("address", "123 Caramel Street") - .param("city", "London") - .param("telephone", "1616291589")) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } - - @Test - void testProcessUpdateOwnerFormUnchangedSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID)) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } - - @Test - void testProcessUpdateOwnerFormHasErrors() throws Exception { - mockMvc - .perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("address", "") - .param("telephone", "")) - .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } - - @Test - void testShowOwner() throws Exception { - mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) - .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) - .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) - .andExpect(model().attribute("owner", hasProperty("pets", not(empty())))) - .andExpect(model().attribute("owner", - hasProperty("pets", hasItem(hasProperty("visits", hasSize(greaterThan(0))))))) - .andExpect(view().name("owners/ownerDetails")) - .andExpect(result -> { - Owner owner = (Owner) result.getModelAndView().getModel().get("owner"); - // New assertion to exercise the negative branch of getPet - assertNull(owner.getPet("NonExistent"), "Expected getPet to return null when pet is not found"); - }); - } - - @Test - public void testProcessUpdateOwnerFormWithIdMismatch() throws Exception { - int pathOwnerId = 1; - - Owner owner = new Owner(); - owner.setId(2); - owner.setFirstName("John"); - owner.setLastName("Doe"); - owner.setAddress("Center Street"); - owner.setCity("New York"); - owner.setTelephone("0123456789"); - - when(owners.findById(pathOwnerId)).thenReturn(Optional.of(owner)); - - mockMvc.perform(MockMvcRequestBuilders.post("/owners/{ownerId}/edit", pathOwnerId).flashAttr("owner", owner)) - .andExpect(status().is3xxRedirection()) - .andExpect(redirectedUrl("/owners/" + pathOwnerId + "/edit")) - .andExpect(flash().attributeExists("error")); - } - - } - \ No newline at end of file +import org.assertj.core.util.Lists; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledInNativeImage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.test.context.aot.DisabledInAotMode; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.time.LocalDate; +import java.util.Optional; + +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.when; +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.*; + +/** + * Test class for {@link OwnerController} + * + * Authors: Colin But, Wick Dynex + */ +@WebMvcTest(OwnerController.class) +@DisabledInNativeImage +@DisabledInAotMode +class OwnerControllerTests { + + private static final int TEST_OWNER_ID = 1; + + @Autowired + private MockMvc mockMvc; + + @MockitoBean + private OwnerRepository owners; + + private Owner george() { + Owner george = new Owner(); + george.setId(TEST_OWNER_ID); + george.setFirstName("George"); + george.setLastName("Franklin"); + george.setAddress("110 W. Liberty St."); + george.setCity("Madison"); + george.setTelephone("6085551023"); + Pet max = new Pet(); + PetType dog = new PetType(); + dog.setName("dog"); + max.setType(dog); + max.setName("Max"); + max.setBirthDate(LocalDate.now()); + george.addPet(max); + max.setId(1); + return george; + } + + @BeforeEach + void setup() { + + Owner george = george(); + given(this.owners.findByLastNameStartingWith(eq("Franklin"), any(Pageable.class))) + .willReturn(new PageImpl<>(Lists.newArrayList(george))); + + given(this.owners.findAll(any(Pageable.class))).willReturn(new PageImpl<>(Lists.newArrayList(george))); + + given(this.owners.findById(TEST_OWNER_ID)).willReturn(Optional.of(george)); + Visit visit = new Visit(); + visit.setDate(LocalDate.now()); + george.getPet("Max").getVisits().add(visit); + + // Added assertion to cover the branch where the pet is not found + assertNull(george.getPet("NonExistent"), "Expected getPet to return null when pet is not found"); + } + + @Test + void testInitCreationForm() throws Exception { + mockMvc.perform(get("/owners/new")) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("owner")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); + } + + @Test + void testProcessCreationFormSuccess() throws Exception { + mockMvc + .perform(post("/owners/new").param("firstName", "Joe") + .param("lastName", "Bloggs") + .param("address", "123 Caramel Street") + .param("city", "London") + .param("telephone", "1316761638")) + .andExpect(status().is3xxRedirection()); + } + + @Test + void testProcessCreationFormHasErrors() throws Exception { + mockMvc + .perform(post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs").param("city", "London")) + .andExpect(status().isOk()) + .andExpect(model().attributeHasErrors("owner")) + .andExpect(model().attributeHasFieldErrors("owner", "address")) + .andExpect(model().attributeHasFieldErrors("owner", "telephone")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); + } + + @Test + void testInitFindForm() throws Exception { + mockMvc.perform(get("/owners/find")) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("owner")) + .andExpect(view().name("owners/findOwners")); + } + + @Test + void testProcessFindFormSuccess() throws Exception { + Page tasks = new PageImpl<>(Lists.newArrayList(george(), new Owner())); + when(this.owners.findByLastNameStartingWith(anyString(), any(Pageable.class))).thenReturn(tasks); + mockMvc.perform(get("/owners?page=1")).andExpect(status().isOk()).andExpect(view().name("owners/ownersList")); + } + + @Test + void testProcessFindFormByLastName() throws Exception { + Page tasks = new PageImpl<>(Lists.newArrayList(george())); + when(this.owners.findByLastNameStartingWith(eq("Franklin"), any(Pageable.class))).thenReturn(tasks); + mockMvc.perform(get("/owners?page=1").param("lastName", "Franklin")) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID)); + } + + @Test + void testProcessFindFormNoOwnersFound() throws Exception { + Page tasks = new PageImpl<>(Lists.newArrayList()); + when(this.owners.findByLastNameStartingWith(eq("Unknown Surname"), any(Pageable.class))).thenReturn(tasks); + mockMvc.perform(get("/owners?page=1").param("lastName", "Unknown Surname")) + .andExpect(status().isOk()) + .andExpect(model().attributeHasFieldErrors("owner", "lastName")) + .andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound")) + .andExpect(view().name("owners/findOwners")); + + } + + @Test + void testInitUpdateOwnerForm() throws Exception { + mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("owner")) + .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) + .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) + .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) + .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) + .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); + } + + @Test + void testProcessUpdateOwnerFormSuccess() throws Exception { + mockMvc + .perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe") + .param("lastName", "Bloggs") + .param("address", "123 Caramel Street") + .param("city", "London") + .param("telephone", "1616291589")) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); + } + + @Test + void testProcessUpdateOwnerFormUnchangedSuccess() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID)) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); + } + + @Test + void testProcessUpdateOwnerFormHasErrors() throws Exception { + mockMvc + .perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe") + .param("lastName", "Bloggs") + .param("address", "") + .param("telephone", "")) + .andExpect(status().isOk()) + .andExpect(model().attributeHasErrors("owner")) + .andExpect(model().attributeHasFieldErrors("owner", "address")) + .andExpect(model().attributeHasFieldErrors("owner", "telephone")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); + } + + @Test + void testShowOwner() throws Exception { + mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)) + .andExpect(status().isOk()) + .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) + .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) + .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) + .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) + .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) + .andExpect(model().attribute("owner", hasProperty("pets", not(empty())))) + .andExpect(model().attribute("owner", + hasProperty("pets", hasItem(hasProperty("visits", hasSize(greaterThan(0))))))) + .andExpect(view().name("owners/ownerDetails")) + .andExpect(result -> { + Owner owner = (Owner) result.getModelAndView().getModel().get("owner"); + // New assertion to exercise the negative branch of getPet + assertNull(owner.getPet("NonExistent"), "Expected getPet to return null when pet is not found"); + }); + } + + @Test + public void testProcessUpdateOwnerFormWithIdMismatch() throws Exception { + int pathOwnerId = 1; + + Owner owner = new Owner(); + owner.setId(2); + owner.setFirstName("John"); + owner.setLastName("Doe"); + owner.setAddress("Center Street"); + owner.setCity("New York"); + owner.setTelephone("0123456789"); + + when(owners.findById(pathOwnerId)).thenReturn(Optional.of(owner)); + + mockMvc.perform(MockMvcRequestBuilders.post("/owners/{ownerId}/edit", pathOwnerId).flashAttr("owner", owner)) + .andExpect(status().is3xxRedirection()) + .andExpect(redirectedUrl("/owners/" + pathOwnerId + "/edit")) + .andExpect(flash().attributeExists("error")); + } + +}