diff --git a/pom.xml b/pom.xml
index 9b9b815df..dd9eddd9b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,4 @@
-
+
4.0.0
@@ -6,7 +6,7 @@
org.springframework.boot
spring-boot-starter-parent
3.4.0
-
+
org.springframework.samples
@@ -17,15 +17,14 @@
-
+
17
UTF-8
UTF-8
-
+
2024-11-28T14:37:52Z
-
+
1.0.1
5.3.3
4.7.0
@@ -41,7 +40,7 @@
-
+
org.springframework.boot
spring-boot-starter-actuator
@@ -72,12 +71,12 @@
test
-
+
io.projectreactor
reactor-core
-
+
com.h2database
h2
@@ -94,7 +93,7 @@
runtime
-
+
javax.cache
cache-api
@@ -104,7 +103,7 @@
caffeine
-
+
org.webjars
webjars-locator-lite
@@ -233,8 +232,7 @@
spring-boot-maven-plugin
-
+
build-info
@@ -269,8 +267,7 @@
-
+
io.github.git-commit-id
git-commit-id-maven-plugin
@@ -279,15 +276,14 @@
false
-
+
-
+
org.cyclonedx
cyclonedx-maven-plugin
-
+ org.pitestpitest-maven1.15.0org.pitestpitest-junit5-plugin1.2.1XMLfalsetrue
@@ -347,7 +343,7 @@
unpack
-
+
generate-resources
@@ -374,7 +370,7 @@
-
+
compile
@@ -395,8 +391,7 @@
-
+
org.eclipse.m2e
lifecycle-mapping
@@ -414,7 +409,7 @@
-
+
@@ -427,7 +422,7 @@
-
+
@@ -440,7 +435,7 @@
-
+
@@ -452,4 +447,4 @@
-
+
\ No newline at end of file
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 426ca5c24..049b21ba9 100644
--- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java
@@ -14,240 +14,248 @@
* 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.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}
- *
- * @author Colin But
- * @author 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);
-
- }
-
- @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"));
- }
-
- @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"));
- }
-
-}
+ 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