From 2c6016a1de8c4b7b08e9a64909d63e61b5c0648f Mon Sep 17 00:00:00 2001 From: George Barnes Date: Mon, 11 Aug 2025 09:43:45 +0100 Subject: [PATCH 1/9] Fix share id tests --- .../preapi/security/AuthorisationService.java | 3 +- .../preapi/services/BookingService.java | 3 +- .../reform/preapi/services/CaseService.java | 3 ++ .../security/AuthorisationServiceTest.java | 15 +++++++++ .../preapi/services/BookingServiceTest.java | 32 +++++++++++++++++++ .../preapi/services/CaseServiceTest.java | 26 +++++++++++++++ 6 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/preapi/security/AuthorisationService.java b/src/main/java/uk/gov/hmcts/reform/preapi/security/AuthorisationService.java index e1efe32f51..33711c86f3 100644 --- a/src/main/java/uk/gov/hmcts/reform/preapi/security/AuthorisationService.java +++ b/src/main/java/uk/gov/hmcts/reform/preapi/security/AuthorisationService.java @@ -170,7 +170,8 @@ public boolean hasUpsertAccess(UserAuthentication authentication, CreateRecordin public boolean hasUpsertAccess(UserAuthentication authentication, CreateShareBookingDTO dto) { return authentication.getUserId().equals(dto.getSharedByUser()) - && (authentication.isAdmin() || hasBookingAccess(authentication, dto.getBookingId())); + && (authentication.isAdmin() || hasBookingAccess(authentication, dto.getBookingId())) + || authentication.hasRole("ROLE_SUPER_USER"); } public boolean hasUpsertAccess(UserAuthentication authentication, CreateCaseDTO dto) { diff --git a/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java b/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java index 875cd89f46..5fe39879c1 100644 --- a/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java +++ b/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java @@ -126,6 +126,7 @@ public Page searchBy( @Transactional @PreAuthorize("@authorisationService.hasUpsertAccess(authentication, #createBookingDTO)") public UpsertResult upsert(CreateBookingDTO createBookingDTO) { + var auth = ((UserAuthentication) SecurityContextHolder.getContext().getAuthentication()); if (bookingAlreadyDeleted(createBookingDTO.getId())) { throw new ResourceInDeletedStateException("BookingDTO", createBookingDTO.getId().toString()); @@ -137,7 +138,7 @@ public UpsertResult upsert(CreateBookingDTO createBookingDTO) { var caseEntity = caseRepository.findByIdAndDeletedAtIsNull(createBookingDTO.getCaseId()) .orElseThrow(() -> new NotFoundException("Case: " + createBookingDTO.getCaseId())); - if (caseEntity.getState() != CaseState.OPEN) { + if (caseEntity.getState() != CaseState.OPEN && !auth.hasRole("ROLE_SUPER_USER")) { throw new ResourceInWrongStateException( "Booking", createBookingDTO.getId(), diff --git a/src/main/java/uk/gov/hmcts/reform/preapi/services/CaseService.java b/src/main/java/uk/gov/hmcts/reform/preapi/services/CaseService.java index 446596c65f..dec19f85fd 100644 --- a/src/main/java/uk/gov/hmcts/reform/preapi/services/CaseService.java +++ b/src/main/java/uk/gov/hmcts/reform/preapi/services/CaseService.java @@ -125,12 +125,15 @@ public UpsertResult upsert(CreateCaseDTO createCaseDTO) { var isCaseClosureCancellation = false; var isCasePendingClosure = false; + var auth = ((UserAuthentication) SecurityContextHolder.getContext().getAuthentication()); + if (isUpdate) { if (foundCase.get().isDeleted()) { throw new ResourceInDeletedStateException("CaseDTO", createCaseDTO.getId().toString()); } if (foundCase.get().getState() != CaseState.OPEN && foundCase.get().getState() == createCaseDTO.getState() + && !auth.hasRole("ROLE_SUPER_USER") ) { throw new ResourceInWrongStateException( "Resource Case(" diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/security/AuthorisationServiceTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/security/AuthorisationServiceTest.java index 6ad8c59c50..0d50b6620e 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/security/AuthorisationServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/security/AuthorisationServiceTest.java @@ -778,6 +778,21 @@ void hasUpsertAccessUserIsNotSharing() { assertFalse(authorisationService.hasUpsertAccess(authenticationUser, dto)); } + @DisplayName("Should grant upsert access when the authenticated super user is not the one sharing the booking,") + @Test + void hasUpsertAccessSuperUserIsNotSharing() { + var dto = new CreateShareBookingDTO(); + + dto.setSharedByUser(UUID.randomUUID()); + dto.setBookingId(UUID.randomUUID()); + + when(authenticationUser.getUserId()).thenReturn(UUID.randomUUID()); + when(authenticationUser.isAdmin()).thenReturn(false); + when(authenticationUser.hasRole("ROLE_SUPER_USER")).thenReturn(true); + + assertTrue(authorisationService.hasUpsertAccess(authenticationUser, dto)); + } + @DisplayName("Should grant upsert access when the authenticated user is an admin") @Test void hasUpsertAccessUserIsAdmin() { diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java index 2d0dca865d..077832b72f 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java @@ -248,6 +248,8 @@ void upsertCreateBookingCaseNotFound() { @DisplayName("Create/update a booking when case is not OPEN") @Test void upsertCreateBookingCaseNotOpen() { + setAuthentication(); + var bookingModel = new CreateBookingDTO(); var caseId = UUID.randomUUID(); bookingModel.setId(UUID.randomUUID()); @@ -277,6 +279,35 @@ void upsertCreateBookingCaseNotOpen() { verify(bookingRepository, never()).save(any()); } + @DisplayName("Create/update a booking when case is not OPEN but user is Super Admin") + @Test + void upsertCreateBookingCaseNotOpenWithSuperAdmin() { + var mockAuth = mock(UserAuthentication.class); + when(mockAuth.isAdmin()).thenReturn(true); + when(mockAuth.isAppUser()).thenReturn(true); + when(mockAuth.hasRole("ROLE_SUPER_USER")).thenReturn(true); + SecurityContextHolder.getContext().setAuthentication(mockAuth); + + var bookingModel = new CreateBookingDTO(); + var caseId = UUID.randomUUID(); + bookingModel.setId(UUID.randomUUID()); + bookingModel.setCaseId(caseId); + bookingModel.setParticipants(Set.of()); + + var aCase = new Case(); + aCase.setId(UUID.randomUUID()); + aCase.setState(CaseState.CLOSED); + + var bookingEntity = new Booking(); + when(caseRepository.findByIdAndDeletedAtIsNull(caseId)).thenReturn(Optional.of(aCase)); + when(bookingRepository.findById(bookingModel.getId())).thenReturn(Optional.of(bookingEntity)); + when(bookingRepository.existsById(bookingModel.getId())).thenReturn(true); + when(caseRepository.findByIdAndDeletedAtIsNull(bookingModel.getCaseId())).thenReturn(Optional.of(new Case())); + when(bookingRepository.save(bookingEntity)).thenReturn(bookingEntity); + + assertThat(bookingService.upsert(bookingModel)).isEqualTo(UpsertResult.UPDATED); + } + @DisplayName("Update a booking when case not found") @Test void upsertUpdateBookingCaseNotFound() { @@ -676,6 +707,7 @@ private void setAuthentication() { var mockAuth = mock(UserAuthentication.class); when(mockAuth.isAdmin()).thenReturn(true); when(mockAuth.isAppUser()).thenReturn(true); + when(mockAuth.hasRole("ROLE_SUPER_USER")).thenReturn(false); SecurityContextHolder.getContext().setAuthentication(mockAuth); } } diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java index dea59377c6..504b37946a 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java @@ -543,6 +543,11 @@ void updateBadRequest() { @Test @DisplayName("Should throw ResourceInWrongStateException when attempting to update a case in wrong state") void updateCaseNotOpenBadRequest() { + var mockAuth = mock(UserAuthentication.class); + when(mockAuth.isAdmin()).thenReturn(true); + when(mockAuth.hasRole("ROLE_SUPER_USER")).thenReturn(false); + SecurityContextHolder.getContext().setAuthentication(mockAuth); + caseEntity.setState(CaseState.CLOSED); var testingCase = createTestingCase(); var caseDTOModel = new CreateCaseDTO(testingCase); @@ -564,6 +569,27 @@ void updateCaseNotOpenBadRequest() { verify(caseRepository, never()).save(any()); } + @Test + @DisplayName("Should allow attempt to update a case in wrong state when Super Admin") + void updateCaseNotOpenAllowedAsSuperAdmin() { + var mockAuth = mock(UserAuthentication.class); + when(mockAuth.isAdmin()).thenReturn(true); + when(mockAuth.hasRole("ROLE_SUPER_USER")).thenReturn(true); + SecurityContextHolder.getContext().setAuthentication(mockAuth); + + caseEntity.setState(CaseState.CLOSED); + var testingCase = createTestingCase(); + var caseDTOModel = new CreateCaseDTO(testingCase); + caseDTOModel.setState(CaseState.CLOSED); + + when(caseRepository.findById(caseDTOModel.getId())).thenReturn(Optional.of(caseEntity)); + caseService.upsert(caseDTOModel); + + verify(courtRepository, times(1)).findById(caseDTOModel.getCourtId()); + verify(caseRepository, times(1)).findById(caseDTOModel.getId()); + verify(caseRepository, times(1)).saveAndFlush(any()); + } + @Test @DisplayName("Should throw ResourceInWrongStateException when setting state to PENDING_CLOSURE with open bookings") void updateCasePendingClosureBadRequest() { From 4904845d387cebe1e528db81da5007f5a50b65ce Mon Sep 17 00:00:00 2001 From: George Barnes Date: Mon, 11 Aug 2025 11:30:19 +0100 Subject: [PATCH 2/9] Fix after master pull --- .../preapi/services/CaseServiceTest.java | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java index 8fccf5efdd..2c34674263 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java @@ -66,9 +66,9 @@ @SuppressWarnings({"PMD.LawOfDemeter", "PMD.TooManyMethods"}) class CaseServiceTest { - private static Case caseEntity; + private Case caseEntity; - private static List allCaseEntities = new ArrayList<>(); + private List allCaseEntities = new ArrayList<>(); @MockitoBean private CaseRepository caseRepository; @@ -100,18 +100,10 @@ class CaseServiceTest { @Autowired private CaseService caseService; - @BeforeAll - static void setUp() { - caseEntity = new Case(); - caseEntity.setId(UUID.randomUUID()); - var court = new Court(); - court.setId(UUID.randomUUID()); - caseEntity.setCourt(court); + @BeforeEach + void setUp() { + caseEntity = createTestingCase(); caseEntity.setReference("1234567890"); - caseEntity.setTest(false); - caseEntity.setCreatedAt(Timestamp.from(Instant.now())); - caseEntity.setModifiedAt(Timestamp.from(Instant.now())); - allCaseEntities.add(caseEntity); } @@ -120,9 +112,6 @@ void reset() { when(emailServiceFactory.getEnabledEmailService()).thenReturn(govNotify); when(emailServiceFactory.getEnabledEmailService(eq("GovNotify"))).thenReturn(govNotify); when(emailServiceFactory.isEnabled()).thenReturn(false); - - caseEntity.setDeletedAt(null); - caseEntity.setState(CaseState.OPEN); } @DisplayName("Find a case by it's id and return a model") From dd06f87aa0fc5873544b6da54d70df39ee7cd755 Mon Sep 17 00:00:00 2001 From: George Barnes Date: Mon, 11 Aug 2025 13:42:30 +0100 Subject: [PATCH 3/9] Fix typo --- .../uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java index 2c34674263..8407f6e290 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/services/CaseServiceTest.java @@ -1,7 +1,6 @@ package uk.gov.hmcts.reform.preapi.services; import feign.FeignException; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From 93ffaec8b6b7989de11b9b358656c4be93a639ac Mon Sep 17 00:00:00 2001 From: George Barnes Date: Mon, 11 Aug 2025 14:36:33 +0100 Subject: [PATCH 4/9] Add missing from stash --- .../preapi/controllers/BookingController.java | 1 - .../reform/preapi/dto/CreateBookingDTO.java | 2 - .../dto/validators/NotPastDateConstraint.java | 20 ---- .../dto/validators/NotPastDateValidator.java | 27 ----- .../preapi/services/BookingService.java | 11 ++ .../validators/NotPastDateValidatorTest.java | 112 +++++++++--------- .../preapi/services/BookingServiceTest.java | 13 +- 7 files changed, 79 insertions(+), 107 deletions(-) delete mode 100644 src/main/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateConstraint.java delete mode 100644 src/main/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidator.java diff --git a/src/main/java/uk/gov/hmcts/reform/preapi/controllers/BookingController.java b/src/main/java/uk/gov/hmcts/reform/preapi/controllers/BookingController.java index 725c3e3e26..e70838090c 100644 --- a/src/main/java/uk/gov/hmcts/reform/preapi/controllers/BookingController.java +++ b/src/main/java/uk/gov/hmcts/reform/preapi/controllers/BookingController.java @@ -248,7 +248,6 @@ public ResponseEntity undeleteBooking(@PathVariable UUID bookingId) { return ok().build(); } - private void validateRequestWithBody(UUID bookingId, CreateBookingDTO createBookingDTO) { if (!bookingId.equals(createBookingDTO.getId())) { throw new PathPayloadMismatchException("bookingId", "bookingDTO.id"); diff --git a/src/main/java/uk/gov/hmcts/reform/preapi/dto/CreateBookingDTO.java b/src/main/java/uk/gov/hmcts/reform/preapi/dto/CreateBookingDTO.java index 91d8973930..48e8ecd4c2 100644 --- a/src/main/java/uk/gov/hmcts/reform/preapi/dto/CreateBookingDTO.java +++ b/src/main/java/uk/gov/hmcts/reform/preapi/dto/CreateBookingDTO.java @@ -6,7 +6,6 @@ import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.NoArgsConstructor; -import uk.gov.hmcts.reform.preapi.dto.validators.BookingScheduledForNotPastOrNotChangedConstraint; import uk.gov.hmcts.reform.preapi.dto.validators.ParticipantTypeConstraint; import uk.gov.hmcts.reform.preapi.entities.Booking; @@ -20,7 +19,6 @@ @NoArgsConstructor @Schema(description = "CreateBookingDTO") @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@BookingScheduledForNotPastOrNotChangedConstraint(message = "scheduled_for is required and must not be before today") public class CreateBookingDTO { @Schema(description = "CreateBookingId") @NotNull(message = "id is required") diff --git a/src/main/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateConstraint.java b/src/main/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateConstraint.java deleted file mode 100644 index 26d0b52b20..0000000000 --- a/src/main/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateConstraint.java +++ /dev/null @@ -1,20 +0,0 @@ -package uk.gov.hmcts.reform.preapi.dto.validators; - -import jakarta.validation.Constraint; -import jakarta.validation.Payload; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Documented -@Constraint(validatedBy = NotPastDateValidator.class) -@Target({ ElementType.METHOD, ElementType.FIELD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface NotPastDateConstraint { - String message() default "Date must not be in the past"; - Class[] groups() default {}; - Class[] payload() default {}; -} diff --git a/src/main/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidator.java b/src/main/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidator.java deleted file mode 100644 index 22231c8571..0000000000 --- a/src/main/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidator.java +++ /dev/null @@ -1,27 +0,0 @@ -package uk.gov.hmcts.reform.preapi.dto.validators; - -import jakarta.validation.ConstraintValidator; -import jakarta.validation.ConstraintValidatorContext; - -import java.sql.Timestamp; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.ZoneId; - -public class NotPastDateValidator implements ConstraintValidator { - @Override - public void initialize(NotPastDateConstraint date) { - } - - @Override - public boolean isValid(Timestamp dateField, ConstraintValidatorContext cxt) { - if (dateField == null) { - return false; - } - - var localDateField = LocalDateTime.ofInstant(dateField.toInstant(), ZoneId.of("Europe/London")).toLocalDate(); - var today = LocalDate.now(); - - return !localDateField.isBefore(today); - } -} diff --git a/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java b/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java index 5fe39879c1..5d796677e0 100644 --- a/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java +++ b/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java @@ -19,6 +19,7 @@ import uk.gov.hmcts.reform.preapi.enums.CaseState; import uk.gov.hmcts.reform.preapi.enums.RecordingStatus; import uk.gov.hmcts.reform.preapi.enums.UpsertResult; +import uk.gov.hmcts.reform.preapi.exception.BadRequestException; import uk.gov.hmcts.reform.preapi.exception.NotFoundException; import uk.gov.hmcts.reform.preapi.exception.ResourceInDeletedStateException; import uk.gov.hmcts.reform.preapi.exception.ResourceInWrongStateException; @@ -30,6 +31,8 @@ import java.sql.Timestamp; import java.time.Instant; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; import java.time.temporal.ChronoUnit; import java.util.List; import java.util.Optional; @@ -128,6 +131,14 @@ public Page searchBy( public UpsertResult upsert(CreateBookingDTO createBookingDTO) { var auth = ((UserAuthentication) SecurityContextHolder.getContext().getAuthentication()); + var localDateField = LocalDateTime.ofInstant(createBookingDTO.getScheduledFor().toInstant(), ZoneId.of("Europe/London")).toLocalDate(); + var today = LocalDate.now(); + + if (localDateField.isBefore(today) + && !auth.hasRole("ROLE_SUPER_USER")) { + throw new BadRequestException("Scheduled date must not be in the past"); + } + if (bookingAlreadyDeleted(createBookingDTO.getId())) { throw new ResourceInDeletedStateException("BookingDTO", createBookingDTO.getId().toString()); } diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidatorTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidatorTest.java index 181edec2eb..55ff8d6765 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidatorTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidatorTest.java @@ -1,56 +1,56 @@ -package uk.gov.hmcts.reform.preapi.dto.validators; - -import jakarta.validation.ConstraintValidatorContext; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.sql.Timestamp; -import java.time.ZoneId; -import java.time.ZonedDateTime; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class NotPastDateValidatorTest { - private NotPastDateValidator validator; - private ConstraintValidatorContext constraintValidatorContext; - - @BeforeEach - void setUp() { - validator = new NotPastDateValidator(); - constraintValidatorContext = null; - } - - @DisplayName("Should return false when value is null") - @Test - void isValidWithDateNull() { - assertFalse(validator.isValid(null, constraintValidatorContext)); - } - - @DisplayName("Should return false when value is in the past") - @Test - void isValidWithDateInPast() { - ZonedDateTime pastDateTime = ZonedDateTime.now(ZoneId.of("Europe/London")) - .minusDays(1); - Timestamp pastTimestamp = Timestamp.from(pastDateTime.toInstant()); - assertFalse(validator.isValid(pastTimestamp, constraintValidatorContext)); - } - - @DisplayName("Should return true when value is not in the past") - @Test - void isValidWithDateToday() { - ZonedDateTime currentDateTime = ZonedDateTime.now(ZoneId.of("Europe/London")); - Timestamp currentTimestamp = Timestamp.from(currentDateTime.toInstant()); - assertTrue(validator.isValid(currentTimestamp, constraintValidatorContext)); - } - - @DisplayName("Should return true when value is in the future") - @Test - void givenFutureDate_ReturnsTrue() { - ZonedDateTime futureDateTime = ZonedDateTime.now(ZoneId.of("Europe/London")) - .plusDays(1); - Timestamp futureTimestamp = Timestamp.from(futureDateTime.toInstant()); - assertTrue(validator.isValid(futureTimestamp, constraintValidatorContext)); - } -} +//package uk.gov.hmcts.reform.preapi.dto.validators; +// +//import jakarta.validation.ConstraintValidatorContext; +//import org.junit.jupiter.api.BeforeEach; +//import org.junit.jupiter.api.DisplayName; +//import org.junit.jupiter.api.Test; +// +//import java.sql.Timestamp; +//import java.time.ZoneId; +//import java.time.ZonedDateTime; +// +//import static org.junit.jupiter.api.Assertions.assertFalse; +//import static org.junit.jupiter.api.Assertions.assertTrue; +// +//public class NotPastDateValidatorTest { +// private NotPastDateValidator validator; +// private ConstraintValidatorContext constraintValidatorContext; +// +// @BeforeEach +// void setUp() { +// validator = new NotPastDateValidator(); +// constraintValidatorContext = null; +// } +// +// @DisplayName("Should return false when value is null") +// @Test +// void isValidWithDateNull() { +// assertFalse(validator.isValid(null, constraintValidatorContext)); +// } +// +// @DisplayName("Should return false when value is in the past") +// @Test +// void isValidWithDateInPast() { +// ZonedDateTime pastDateTime = ZonedDateTime.now(ZoneId.of("Europe/London")) +// .minusDays(1); +// Timestamp pastTimestamp = Timestamp.from(pastDateTime.toInstant()); +// assertFalse(validator.isValid(pastTimestamp, constraintValidatorContext)); +// } +// +// @DisplayName("Should return true when value is not in the past") +// @Test +// void isValidWithDateToday() { +// ZonedDateTime currentDateTime = ZonedDateTime.now(ZoneId.of("Europe/London")); +// Timestamp currentTimestamp = Timestamp.from(currentDateTime.toInstant()); +// assertTrue(validator.isValid(currentTimestamp, constraintValidatorContext)); +// } +// +// @DisplayName("Should return true when value is in the future") +// @Test +// void givenFutureDate_ReturnsTrue() { +// ZonedDateTime futureDateTime = ZonedDateTime.now(ZoneId.of("Europe/London")) +// .plusDays(1); +// Timestamp futureTimestamp = Timestamp.from(futureDateTime.toInstant()); +// assertTrue(validator.isValid(futureTimestamp, constraintValidatorContext)); +// } +//} diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java index 077832b72f..d5044362d6 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java @@ -33,6 +33,7 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalTime; +import java.time.Period; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -198,6 +199,7 @@ void upsertBookingSuccessCreated() { caseEntity.setId(caseId); bookingModel.setId(UUID.randomUUID()); bookingModel.setCaseId(caseId); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().plus(Period.ofWeeks(1)))); var participantModel = new CreateParticipantDTO(); participantModel.setId(UUID.randomUUID()); participantModel.setParticipantType(ParticipantType.WITNESS); @@ -229,6 +231,7 @@ void upsertCreateBookingCaseNotFound() { bookingModel.setId(UUID.randomUUID()); bookingModel.setCaseId(caseId); bookingModel.setParticipants(Set.of()); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().plus(Period.ofWeeks(1)))); when(caseRepository.findByIdAndDeletedAtIsNull(caseId)).thenReturn(Optional.empty()); when(bookingRepository.findById(bookingModel.getId())).thenReturn(Optional.empty()); @@ -255,6 +258,7 @@ void upsertCreateBookingCaseNotOpen() { bookingModel.setId(UUID.randomUUID()); bookingModel.setCaseId(caseId); bookingModel.setParticipants(Set.of()); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().plus(Period.ofWeeks(1)))); var aCase = new Case(); aCase.setId(UUID.randomUUID()); @@ -293,6 +297,7 @@ void upsertCreateBookingCaseNotOpenWithSuperAdmin() { bookingModel.setId(UUID.randomUUID()); bookingModel.setCaseId(caseId); bookingModel.setParticipants(Set.of()); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().plus(Period.ofWeeks(1)))); var aCase = new Case(); aCase.setId(UUID.randomUUID()); @@ -316,6 +321,7 @@ void upsertUpdateBookingCaseNotFound() { bookingModel.setId(UUID.randomUUID()); bookingModel.setCaseId(caseId); bookingModel.setParticipants(Set.of()); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().plus(Period.ofWeeks(1)))); var bookingEntity = new Booking(); when(caseRepository.findByIdAndDeletedAtIsNull(caseId)).thenReturn(Optional.empty()); @@ -343,6 +349,7 @@ void upsertBookingSuccessUpdated() { bookingModel.setId(UUID.randomUUID()); bookingModel.setCaseId(caseId); bookingModel.setParticipants(Set.of()); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().plus(Period.ofWeeks(1)))); var bookingEntity = new Booking(); when(caseRepository.findByIdAndDeletedAtIsNull(caseId)).thenReturn(Optional.of(caseEntity)); @@ -362,6 +369,7 @@ void upsertBookingFailureCaseDoesntExist() { bookingModel.setId(UUID.randomUUID()); bookingModel.setCaseId(UUID.randomUUID()); bookingModel.setParticipants(Set.of()); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().plus(Period.ofWeeks(1)))); var bookingEntity = new Booking(); @@ -386,11 +394,12 @@ void upsertBookingFailureAlreadyDeleted() { bookingModel.setId(UUID.randomUUID()); bookingModel.setCaseId(caseId); bookingModel.setParticipants(Set.of()); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().plus(Period.ofWeeks(1)))); when(caseRepository.findByIdAndDeletedAtIsNull(caseId)).thenReturn(Optional.of(caseEntity)); when(bookingRepository.existsByIdAndDeletedAtIsNotNull(bookingModel.getId())).thenReturn(true); assertThatExceptionOfType(ResourceInDeletedStateException.class) - .isThrownBy(() -> { + .isThrownBy(() -> { bookingService.upsert(bookingModel); }) .withMessage("Resource BookingDTO(" @@ -407,6 +416,7 @@ void upsertBookingFailureParticipantAlreadyDeleted() { caseEntity.setId(caseId); bookingModel.setId(UUID.randomUUID()); bookingModel.setCaseId(caseId); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().plus(Period.ofWeeks(1)))); var participantModel = new CreateParticipantDTO(); participantModel.setId(UUID.randomUUID()); participantModel.setParticipantType(ParticipantType.WITNESS); @@ -455,6 +465,7 @@ void createBookingWithParticipantNotAssignedToTheCase() { participantModel.setLastName("Smith"); bookingModel.setParticipants(Set.of(participantModel)); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().plus(Period.ofWeeks(1)))); when(caseRepository.findByIdAndDeletedAtIsNull(caseId)).thenReturn(Optional.of(caseEntity)); when(bookingRepository.findById(bookingModel.getId())).thenReturn(Optional.empty()); From 0adf055edf56f77b9aebc389fc3210a05de6c56a Mon Sep 17 00:00:00 2001 From: George Barnes Date: Mon, 22 Sep 2025 10:07:29 +0100 Subject: [PATCH 5/9] Style&Test fixes --- .../preapi/services/BookingService.java | 3 +- .../controller/BookingControllerTest.java | 26 ++++----- .../validators/NotPastDateValidatorTest.java | 56 ------------------- .../preapi/services/BookingServiceTest.java | 4 +- 4 files changed, 14 insertions(+), 75 deletions(-) delete mode 100644 src/test/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidatorTest.java diff --git a/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java b/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java index 5d796677e0..460d4eaa7a 100644 --- a/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java +++ b/src/main/java/uk/gov/hmcts/reform/preapi/services/BookingService.java @@ -131,7 +131,8 @@ public Page searchBy( public UpsertResult upsert(CreateBookingDTO createBookingDTO) { var auth = ((UserAuthentication) SecurityContextHolder.getContext().getAuthentication()); - var localDateField = LocalDateTime.ofInstant(createBookingDTO.getScheduledFor().toInstant(), ZoneId.of("Europe/London")).toLocalDate(); + var localDateField = LocalDateTime.ofInstant(createBookingDTO.getScheduledFor().toInstant(), + ZoneId.of("Europe/London")).toLocalDate(); var today = LocalDate.now(); if (localDateField.isBefore(today) diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java index 260adef307..fc1392224c 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java @@ -413,7 +413,7 @@ void createBookingEndpoint400ScheduledForMissing() throws Exception { .isEqualTo("{\"scheduledFor\":\"scheduled_for is required and must not be before today\"}"); } - @DisplayName("Should fail to create a booking with 400 response code as scheduledFor is before today") + @DisplayName("Should succeed in creating a booking as admin with scheduledFor is before today") @Test void createBookingEndpoint400ScheduledForInThePast() throws Exception { @@ -422,27 +422,22 @@ void createBookingEndpoint400ScheduledForInThePast() throws Exception { var booking = new CreateBookingDTO(); booking.setId(bookingId); booking.setCaseId(caseId); + booking.setScheduledFor(Timestamp.from(OffsetDateTime.now().plusWeeks(1).toInstant())); booking.setParticipants(getCreateParticipantDTOs()); - booking.setScheduledFor(Timestamp.from(OffsetDateTime.now().minusWeeks(1).toInstant())); CaseDTO mockCaseDTO = new CaseDTO(); when(caseService.findById(caseId)).thenReturn(mockCaseDTO); + when(bookingService.upsert(any(CreateBookingDTO.class))).thenReturn(UpsertResult.CREATED); - MvcResult response = mockMvc.perform(put(getPath(bookingId)) - .with(csrf()) - .content(OBJECT_MAPPER.writeValueAsString(booking)) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .accept(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isBadRequest()) - .andReturn(); - - assertThat(response.getResponse().getContentAsString()) - .isEqualTo( - "{\"scheduledFor\":\"must not be before today\"}" - ); + mockMvc.perform(put(getPath(bookingId)) + .with(csrf()) + .content(OBJECT_MAPPER.writeValueAsString(booking)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isCreated()); } - @DisplayName("Should fail to create a booking with 400 response code as scheduledFor is in the past same day") + @DisplayName("Should succeed in creating a booking as admin with scheduledFor is in the past same day") @Test void createBookingEndpointScheduledForInThePastButToday() throws Exception { @@ -451,7 +446,6 @@ void createBookingEndpointScheduledForInThePastButToday() throws Exception { var booking = new CreateBookingDTO(); booking.setId(bookingId); booking.setCaseId(caseId); - booking.setParticipants(getCreateParticipantDTOs()); booking.setScheduledFor( Timestamp.from(Instant.now().truncatedTo(ChronoUnit.DAYS)) ); diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidatorTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidatorTest.java deleted file mode 100644 index 55ff8d6765..0000000000 --- a/src/test/java/uk/gov/hmcts/reform/preapi/dto/validators/NotPastDateValidatorTest.java +++ /dev/null @@ -1,56 +0,0 @@ -//package uk.gov.hmcts.reform.preapi.dto.validators; -// -//import jakarta.validation.ConstraintValidatorContext; -//import org.junit.jupiter.api.BeforeEach; -//import org.junit.jupiter.api.DisplayName; -//import org.junit.jupiter.api.Test; -// -//import java.sql.Timestamp; -//import java.time.ZoneId; -//import java.time.ZonedDateTime; -// -//import static org.junit.jupiter.api.Assertions.assertFalse; -//import static org.junit.jupiter.api.Assertions.assertTrue; -// -//public class NotPastDateValidatorTest { -// private NotPastDateValidator validator; -// private ConstraintValidatorContext constraintValidatorContext; -// -// @BeforeEach -// void setUp() { -// validator = new NotPastDateValidator(); -// constraintValidatorContext = null; -// } -// -// @DisplayName("Should return false when value is null") -// @Test -// void isValidWithDateNull() { -// assertFalse(validator.isValid(null, constraintValidatorContext)); -// } -// -// @DisplayName("Should return false when value is in the past") -// @Test -// void isValidWithDateInPast() { -// ZonedDateTime pastDateTime = ZonedDateTime.now(ZoneId.of("Europe/London")) -// .minusDays(1); -// Timestamp pastTimestamp = Timestamp.from(pastDateTime.toInstant()); -// assertFalse(validator.isValid(pastTimestamp, constraintValidatorContext)); -// } -// -// @DisplayName("Should return true when value is not in the past") -// @Test -// void isValidWithDateToday() { -// ZonedDateTime currentDateTime = ZonedDateTime.now(ZoneId.of("Europe/London")); -// Timestamp currentTimestamp = Timestamp.from(currentDateTime.toInstant()); -// assertTrue(validator.isValid(currentTimestamp, constraintValidatorContext)); -// } -// -// @DisplayName("Should return true when value is in the future") -// @Test -// void givenFutureDate_ReturnsTrue() { -// ZonedDateTime futureDateTime = ZonedDateTime.now(ZoneId.of("Europe/London")) -// .plusDays(1); -// Timestamp futureTimestamp = Timestamp.from(futureDateTime.toInstant()); -// assertTrue(validator.isValid(futureTimestamp, constraintValidatorContext)); -// } -//} diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java index d5044362d6..f3b5292e61 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java @@ -400,8 +400,8 @@ void upsertBookingFailureAlreadyDeleted() { when(bookingRepository.existsByIdAndDeletedAtIsNotNull(bookingModel.getId())).thenReturn(true); assertThatExceptionOfType(ResourceInDeletedStateException.class) .isThrownBy(() -> { - bookingService.upsert(bookingModel); - }) + bookingService.upsert(bookingModel); + }) .withMessage("Resource BookingDTO(" + bookingModel.getId().toString() + ") is in a deleted state and cannot be updated"); From b8bfc4fb4544d6c1000a3f4cc7df6469936b7a10 Mon Sep 17 00:00:00 2001 From: George Barnes Date: Wed, 24 Sep 2025 09:32:12 +0100 Subject: [PATCH 6/9] Remove redundant tests in BookingController --- .../controller/BookingControllerTest.java | 50 --------------- .../preapi/services/BookingServiceTest.java | 62 +++++++++++++++++++ 2 files changed, 62 insertions(+), 50 deletions(-) diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java index fc1392224c..d3aea473b2 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java @@ -413,56 +413,6 @@ void createBookingEndpoint400ScheduledForMissing() throws Exception { .isEqualTo("{\"scheduledFor\":\"scheduled_for is required and must not be before today\"}"); } - @DisplayName("Should succeed in creating a booking as admin with scheduledFor is before today") - @Test - void createBookingEndpoint400ScheduledForInThePast() throws Exception { - - var caseId = UUID.randomUUID(); - var bookingId = UUID.randomUUID(); - var booking = new CreateBookingDTO(); - booking.setId(bookingId); - booking.setCaseId(caseId); - booking.setScheduledFor(Timestamp.from(OffsetDateTime.now().plusWeeks(1).toInstant())); - booking.setParticipants(getCreateParticipantDTOs()); - - CaseDTO mockCaseDTO = new CaseDTO(); - when(caseService.findById(caseId)).thenReturn(mockCaseDTO); - when(bookingService.upsert(any(CreateBookingDTO.class))).thenReturn(UpsertResult.CREATED); - - mockMvc.perform(put(getPath(bookingId)) - .with(csrf()) - .content(OBJECT_MAPPER.writeValueAsString(booking)) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .accept(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isCreated()); - } - - @DisplayName("Should succeed in creating a booking as admin with scheduledFor is in the past same day") - @Test - void createBookingEndpointScheduledForInThePastButToday() throws Exception { - - var caseId = UUID.randomUUID(); - var bookingId = UUID.randomUUID(); - var booking = new CreateBookingDTO(); - booking.setId(bookingId); - booking.setCaseId(caseId); - booking.setScheduledFor( - Timestamp.from(Instant.now().truncatedTo(ChronoUnit.DAYS)) - ); - booking.setParticipants(getCreateParticipantDTOs()); - - CaseDTO mockCaseDTO = new CaseDTO(); - when(caseService.findById(caseId)).thenReturn(mockCaseDTO); - when(bookingService.upsert(any(CreateBookingDTO.class))).thenReturn(UpsertResult.CREATED); - - mockMvc.perform(put(getPath(bookingId)) - .with(csrf()) - .content(OBJECT_MAPPER.writeValueAsString(booking)) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .accept(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isCreated()); - } - @DisplayName("Should fail to update a booking with 400 response code as its already deleted") @Test void updateBookingEndpoint400() throws Exception { diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java index f3b5292e61..5b724d04ad 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/services/BookingServiceTest.java @@ -19,6 +19,7 @@ import uk.gov.hmcts.reform.preapi.enums.ParticipantType; import uk.gov.hmcts.reform.preapi.enums.RecordingStatus; import uk.gov.hmcts.reform.preapi.enums.UpsertResult; +import uk.gov.hmcts.reform.preapi.exception.BadRequestException; import uk.gov.hmcts.reform.preapi.exception.NotFoundException; import uk.gov.hmcts.reform.preapi.exception.ResourceInDeletedStateException; import uk.gov.hmcts.reform.preapi.exception.ResourceInWrongStateException; @@ -313,6 +314,67 @@ void upsertCreateBookingCaseNotOpenWithSuperAdmin() { assertThat(bookingService.upsert(bookingModel)).isEqualTo(UpsertResult.UPDATED); } + @DisplayName("Create a booking in the past as a superuser") + @Test + void upsertBookingInPastSuperuserCreated() { + var mockAuth = mock(UserAuthentication.class); + when(mockAuth.isAdmin()).thenReturn(true); + when(mockAuth.isAppUser()).thenReturn(true); + when(mockAuth.hasRole("ROLE_SUPER_USER")).thenReturn(true); + SecurityContextHolder.getContext().setAuthentication(mockAuth); + + var bookingModel = new CreateBookingDTO(); + var caseId = UUID.randomUUID(); + var caseEntity = new Case(); + caseEntity.setId(caseId); + bookingModel.setId(UUID.randomUUID()); + bookingModel.setCaseId(caseId); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().minus(Period.ofWeeks(1)))); + bookingModel.setParticipants(Set.of()); + + var bookingEntity = new Booking(); + + when(caseRepository.findByIdAndDeletedAtIsNull(caseId)).thenReturn(Optional.of(caseEntity)); + when(bookingRepository.findById(bookingModel.getId())).thenReturn(Optional.empty()); + when(bookingRepository.existsByIdAndDeletedAtIsNotNull(bookingModel.getId())).thenReturn(false); + when(bookingRepository.existsById(bookingModel.getId())).thenReturn(false); + when(caseRepository.findByIdAndDeletedAtIsNull(bookingModel.getCaseId())).thenReturn(Optional.of(new Case())); + when(bookingRepository.save(bookingEntity)).thenReturn(bookingEntity); + assertThat(bookingService.upsert(bookingModel)).isEqualTo(UpsertResult.CREATED); + } + + @DisplayName("Create a booking in the past as a standard user") + @Test + void upsertBookingInPastWithoutSuperuserCreated() { + var mockAuth = mock(UserAuthentication.class); + when(mockAuth.isAdmin()).thenReturn(false); + when(mockAuth.isAppUser()).thenReturn(true); + when(mockAuth.hasRole("ROLE_SUPER_USER")).thenReturn(false); + SecurityContextHolder.getContext().setAuthentication(mockAuth); + + var bookingModel = new CreateBookingDTO(); + var caseId = UUID.randomUUID(); + var caseEntity = new Case(); + caseEntity.setId(caseId); + bookingModel.setId(UUID.randomUUID()); + bookingModel.setCaseId(caseId); + bookingModel.setScheduledFor(Timestamp.from(Instant.now().minus(Period.ofWeeks(1)))); + bookingModel.setParticipants(Set.of()); + + var bookingEntity = new Booking(); + + when(bookingRepository.findById(bookingModel.getId())).thenReturn(Optional.of(bookingEntity)); + when(bookingRepository.existsById(bookingModel.getId())).thenReturn(true); + when(caseRepository.findByIdAndDeletedAtIsNull(bookingModel.getCaseId())).thenReturn(Optional.empty()); + + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(() -> { + bookingService.upsert(bookingModel); + }) + .withMessage("Scheduled date must not be in the past"); + } + + @DisplayName("Update a booking when case not found") @Test void upsertUpdateBookingCaseNotFound() { From 85a7280bf49b2c910109c62f7b6d527c1a6be6b6 Mon Sep 17 00:00:00 2001 From: George Barnes Date: Wed, 24 Sep 2025 09:46:59 +0100 Subject: [PATCH 7/9] checkstyle cleanup --- .../hmcts/reform/preapi/controller/BookingControllerTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java b/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java index d3aea473b2..caa53c3a54 100644 --- a/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/preapi/controller/BookingControllerTest.java @@ -39,7 +39,6 @@ import java.sql.Timestamp; import java.text.SimpleDateFormat; -import java.time.Instant; import java.time.OffsetDateTime; import java.time.temporal.ChronoUnit; import java.util.List; From ecbd49e40b6d5c279e9faf9d505d6970c599317a Mon Sep 17 00:00:00 2001 From: George Barnes Date: Wed, 24 Sep 2025 10:46:25 +0100 Subject: [PATCH 8/9] Functional Test perms fix --- .../controllers/BookingControllerFT.java | 50 +++++++++++++++---- .../preapi/controllers/CaseControllerFT.java | 6 ++- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/BookingControllerFT.java b/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/BookingControllerFT.java index 8fae44d188..1ca56d6332 100644 --- a/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/BookingControllerFT.java +++ b/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/BookingControllerFT.java @@ -121,7 +121,12 @@ void recordingScheduleDateShouldNotBeAmendedToThePast() throws JsonProcessingExc // set scheduledFor to yesterday createBooking.setScheduledFor(Timestamp.from(OffsetDateTime.now().minusDays(1).toInstant())); - var putResponse = putBooking(createBooking); + putBooking(createBooking); + var putResponse = doPutRequest( + BOOKINGS_ENDPOINT + "/" + createBooking.getId(), + OBJECT_MAPPER.writeValueAsString(createBooking), + TestingSupportRoles.LEVEL_1 + ); assertResponseCode(putResponse, 400); } @@ -447,14 +452,18 @@ void createBookingWithScheduledForThePast() throws JsonProcessingException { var putCase = doPutRequest( CASES_ENDPOINT + "/" + caseEntity.getId(), OBJECT_MAPPER.writeValueAsString(caseEntity), - TestingSupportRoles.SUPER_USER + TestingSupportRoles.LEVEL_1 ); assertResponseCode(putCase, 201); - var putBooking = putBooking(booking); + var putBooking = doPutRequest( + BOOKINGS_ENDPOINT + "/" + booking.getId(), + OBJECT_MAPPER.writeValueAsString(booking), + TestingSupportRoles.LEVEL_1 + ); assertResponseCode(putBooking, 400); - assertThat(putBooking.body().jsonPath().getString("scheduledFor")) - .isEqualTo("must not be before today"); + assertThat(putBooking.body().jsonPath().getString("message")) + .isEqualTo("Scheduled date must not be in the past"); } @DisplayName("Create a booking with a participant that is not part of the case") @@ -607,7 +616,12 @@ void upsertBookingForClosedCase() throws JsonProcessingException { // attempt update booking.setScheduledFor(Timestamp.valueOf(LocalDate.now().atStartOfDay().plusDays(1))); - var putBooking2 = putBooking(booking); + var putBooking2 = doPutRequest( + BOOKINGS_ENDPOINT + "/" + booking.getId(), + OBJECT_MAPPER.writeValueAsString(booking), + TestingSupportRoles.LEVEL_1 + ); + assertResponseCode(putBooking2, 400); assertThat(putBooking2.body().jsonPath().getString("message")) .isEqualTo( @@ -617,7 +631,11 @@ void upsertBookingForClosedCase() throws JsonProcessingException { // attempt create var booking2 = createBooking(caseEntity.getId(), participants); - var putBooking3 = putBooking(booking2); + var putBooking3 = doPutRequest( + BOOKINGS_ENDPOINT + "/" + booking2.getId(), + OBJECT_MAPPER.writeValueAsString(booking2), + TestingSupportRoles.LEVEL_1 + ); assertResponseCode(putBooking3, 400); assertThat(putBooking3.body().jsonPath().getString("message")) .isEqualTo( @@ -654,12 +672,20 @@ void upsertBookingForPendingClosureCase() throws JsonProcessingException { // close case caseEntity.setState(CaseState.PENDING_CLOSURE); caseEntity.setClosedAt(Timestamp.from(Instant.now().minusSeconds(36000))); - var putCase2 = putCase(caseEntity); + var putCase2 = doPutRequest( + CASES_ENDPOINT + "/" + caseEntity.getId(), + OBJECT_MAPPER.writeValueAsString(caseEntity), + TestingSupportRoles.LEVEL_1 + ); assertResponseCode(putCase2, 204); // attempt update booking.setScheduledFor(Timestamp.valueOf(LocalDate.now().atStartOfDay().plusDays(1))); - var putBooking2 = putBooking(booking); + var putBooking2 = doPutRequest( + BOOKINGS_ENDPOINT + "/" + booking.getId(), + OBJECT_MAPPER.writeValueAsString(booking), + TestingSupportRoles.LEVEL_1 + ); assertResponseCode(putBooking2, 400); assertThat(putBooking2.body().jsonPath().getString("message")) .isEqualTo( @@ -669,7 +695,11 @@ void upsertBookingForPendingClosureCase() throws JsonProcessingException { // attempt create var booking2 = createBooking(caseEntity.getId(), participants); - var putBooking3 = putBooking(booking2); + var putBooking3 = doPutRequest( + BOOKINGS_ENDPOINT + "/" + booking2.getId(), + OBJECT_MAPPER.writeValueAsString(booking2), + TestingSupportRoles.LEVEL_1 + ); assertResponseCode(putBooking3, 400); assertThat(putBooking3.body().jsonPath().getString("message")) .isEqualTo( diff --git a/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/CaseControllerFT.java b/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/CaseControllerFT.java index 962173753d..d169461131 100644 --- a/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/CaseControllerFT.java +++ b/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/CaseControllerFT.java @@ -58,7 +58,11 @@ void updateCaseClosedBadRequest() throws JsonProcessingException { // attempt update case dto.setTest(true); - var putCase2 = putCase(dto); + var putCase2 = doPutRequest( + CASES_ENDPOINT + "/" + dto.getId(), + OBJECT_MAPPER.writeValueAsString(dto), + TestingSupportRoles.LEVEL_1 + ); assertResponseCode(putCase2, 400); assertThat(putCase2.body().jsonPath().getString("message")) .isEqualTo("Resource Case(" From 2934384bafc5558d6987111e08b62b78ac4d241c Mon Sep 17 00:00:00 2001 From: George Barnes Date: Wed, 24 Sep 2025 11:11:52 +0100 Subject: [PATCH 9/9] Checkstyle --- .../hmcts/reform/preapi/controllers/BookingControllerFT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/BookingControllerFT.java b/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/BookingControllerFT.java index 1ca56d6332..c07cfc8018 100644 --- a/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/BookingControllerFT.java +++ b/src/functionalTest/java/uk/gov/hmcts/reform/preapi/controllers/BookingControllerFT.java @@ -121,7 +121,7 @@ void recordingScheduleDateShouldNotBeAmendedToThePast() throws JsonProcessingExc // set scheduledFor to yesterday createBooking.setScheduledFor(Timestamp.from(OffsetDateTime.now().minusDays(1).toInstant())); - putBooking(createBooking); + putBooking(createBooking); var putResponse = doPutRequest( BOOKINGS_ENDPOINT + "/" + createBooking.getId(), OBJECT_MAPPER.writeValueAsString(createBooking),