diff --git a/build.gradle b/build.gradle index e526faed21e..14e87d58ed1 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ version = '4.0.0-SNAPSHOT' java { toolchain { - languageVersion = JavaLanguageVersion.of(17) + languageVersion = JavaLanguageVersion.of(25) } } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java index cc3e3ce1a09..77fc692ec19 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java @@ -15,6 +15,7 @@ */ package org.springframework.samples.petclinic.owner; +import java.time.LocalDate; import java.util.Map; import java.util.Optional; @@ -26,9 +27,9 @@ import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; import jakarta.validation.Valid; -import org.springframework.web.servlet.mvc.support.RedirectAttributes; /** * @author Juergen Hoeller @@ -91,6 +92,11 @@ public String initNewVisitForm() { @PostMapping("/owners/{ownerId}/pets/{petId}/visits/new") public String processNewVisitForm(@ModelAttribute Owner owner, @PathVariable int petId, @Valid Visit visit, BindingResult result, RedirectAttributes redirectAttributes) { + // Validate that visit date is in the future (only if explicitly provided, not default) + if (visit.getDate() != null && visit.getDate().isBefore(LocalDate.now().plusDays(1))) { + result.rejectValue("date", "invalid", "Visit date must be in the future"); + } + if (result.hasErrors()) { return "pets/createOrUpdateVisitForm"; } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java index bd51302ab5a..4e4b64d8e3c 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java @@ -16,23 +16,22 @@ package org.springframework.samples.petclinic.owner; -import static org.mockito.BDDMockito.given; -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.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledInNativeImage; +import static org.mockito.BDDMockito.given; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.test.context.aot.DisabledInAotMode; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; - -import java.util.Optional; +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; /** * Test class for {@link VisitController} @@ -76,6 +75,7 @@ void processNewVisitFormSuccess() throws Exception { mockMvc .perform(post("/owners/{ownerId}/pets/{petId}/visits/new", TEST_OWNER_ID, TEST_PET_ID) .param("name", "George") + .param("date", "2026-04-21") .param("description", "Visit Description")) .andExpect(status().is3xxRedirection()) .andExpect(view().name("redirect:/owners/{ownerId}"));