Skip to content

Commit

Permalink
Use CasResult for Booking Changed Function
Browse files Browse the repository at this point in the history
  • Loading branch information
davidatkinsuk committed Jan 6, 2025
1 parent 8ec2e73 commit 6a7ce73
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ class PremisesController(
newDepartureDate = body.newDepartureDate,
)

val dateChange = extractResultEntityOrThrow(result)
val dateChange = extractEntityFromCasResult(result)

return ResponseEntity.ok(dateChangeTransformer.transformJpaToApi(dateChange))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserQualifica
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.serviceScopeMatches
import uk.gov.justice.digital.hmpps.approvedpremisesapi.model.PersonInfoResult
import uk.gov.justice.digital.hmpps.approvedpremisesapi.model.validated
import uk.gov.justice.digital.hmpps.approvedpremisesapi.model.validatedCasResult
import uk.gov.justice.digital.hmpps.approvedpremisesapi.problem.InternalServerErrorProblem
import uk.gov.justice.digital.hmpps.approvedpremisesapi.results.AuthorisableActionResult
import uk.gov.justice.digital.hmpps.approvedpremisesapi.results.CasResult
Expand Down Expand Up @@ -423,7 +424,7 @@ class BookingService(
user: UserEntity,
newArrivalDate: LocalDate?,
newDepartureDate: LocalDate?,
) = validated {
) = validatedCasResult {
val effectiveNewArrivalDate = newArrivalDate ?: booking.arrivalDate
val effectiveNewDepartureDate = newDepartureDate ?: booking.departureDate

Expand All @@ -439,11 +440,11 @@ class BookingService(
?: throw InternalServerErrorProblem("No bed ID present on Booking: ${booking.id}")

getBookingWithConflictingDates(effectiveNewArrivalDate, expectedLastUnavailableDate, booking.id, bedId)?.let {
return@validated it.id hasConflictError "A Booking already exists for dates from ${it.arrivalDate} to ${it.lastUnavailableDate} which overlaps with the desired dates"
return@validatedCasResult it.id hasConflictError "A Booking already exists for dates from ${it.arrivalDate} to ${it.lastUnavailableDate} which overlaps with the desired dates"
}

getLostBedWithConflictingDates(effectiveNewArrivalDate, expectedLastUnavailableDate, null, bedId)?.let {
return@validated it.id hasConflictError "A Lost Bed already exists for dates from ${it.startDate} to ${it.endDate} which overlaps with the desired dates"
return@validatedCasResult it.id hasConflictError "A Lost Bed already exists for dates from ${it.startDate} to ${it.endDate} which overlaps with the desired dates"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.Cas1Booking
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.WithdrawableEntityType
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.WithdrawalContext
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.WithdrawalTriggeredByUser
import uk.gov.justice.digital.hmpps.approvedpremisesapi.unit.util.assertThat
import java.time.LocalDate
import java.time.OffsetDateTime
import java.util.UUID
Expand Down Expand Up @@ -2020,9 +2021,9 @@ class BookingServiceTest {
newDepartureDate = LocalDate.parse("2023-07-14"),
)

assertThat(result is ValidatableActionResult.ConflictError).isTrue
result as ValidatableActionResult.ConflictError
assertThat(result.message).contains("A Booking already exists")
assertThat(result)
.isConflictError()
.hasMessageContaining("A Booking already exists")
}

@Test
Expand Down Expand Up @@ -2052,9 +2053,9 @@ class BookingServiceTest {
newDepartureDate = LocalDate.parse("2023-07-14"),
)

assertThat(result is ValidatableActionResult.ConflictError).isTrue
result as ValidatableActionResult.ConflictError
assertThat(result.message).contains("A Lost Bed already exists")
assertThat(result)
.isConflictError()
.hasMessageContaining("A Lost Bed already exists")
}

@Test
Expand All @@ -2076,9 +2077,9 @@ class BookingServiceTest {
newDepartureDate = LocalDate.parse("2023-07-14"),
)

assertThat(result is ValidatableActionResult.FieldValidationError).isTrue
result as ValidatableActionResult.FieldValidationError
assertThat(result.validationMessages).containsEntry("$.newDepartureDate", "beforeBookingArrivalDate")
assertThat(result)
.isFieldValidationError()
.hasMessage("$.newDepartureDate", "beforeBookingArrivalDate")
}

@Test
Expand All @@ -2105,9 +2106,9 @@ class BookingServiceTest {
newDepartureDate = LocalDate.parse("2023-07-16"),
)

assertThat(result is ValidatableActionResult.FieldValidationError).isTrue
result as ValidatableActionResult.FieldValidationError
assertThat(result.validationMessages).containsEntry("$.newArrivalDate", "arrivalDateCannotBeChangedOnArrivedBooking")
assertThat(result)
.isFieldValidationError()
.hasMessage("$.newArrivalDate", "arrivalDateCannotBeChangedOnArrivedBooking")
}

@Test
Expand Down Expand Up @@ -2137,9 +2138,7 @@ class BookingServiceTest {
newDepartureDate = LocalDate.parse("2023-07-16"),
)

assertThat(result is ValidatableActionResult.GeneralValidationError).isTrue
result as ValidatableActionResult.GeneralValidationError
assertThat(result.message).isEqualTo("This Booking is cancelled and as such cannot be modified")
assertThat(result).isGeneralValidationError("This Booking is cancelled and as such cannot be modified")
}

@Test
Expand Down Expand Up @@ -2168,8 +2167,8 @@ class BookingServiceTest {
newDepartureDate = LocalDate.parse("2023-07-15"),
)

assertThat(result is ValidatableActionResult.Success).isTrue
result as ValidatableActionResult.Success
assertThat(result).isSuccess()
result as CasResult.Success

verify {
mockDateChangeRepository.save(
Expand Down Expand Up @@ -2216,8 +2215,8 @@ class BookingServiceTest {
newDepartureDate = LocalDate.parse("2023-07-22"),
)

assertThat(result is ValidatableActionResult.Success).isTrue
result as ValidatableActionResult.Success
assertThat(result).isSuccess()
result as CasResult.Success

verify {
mockDateChangeRepository.save(
Expand Down Expand Up @@ -2276,8 +2275,8 @@ class BookingServiceTest {
newDepartureDate = newDepartureDate,
)

assertThat(result is ValidatableActionResult.Success).isTrue
result as ValidatableActionResult.Success
assertThat(result).isSuccess()
result as CasResult.Success

verify {
mockDateChangeRepository.save(
Expand Down Expand Up @@ -2345,8 +2344,8 @@ class BookingServiceTest {
newDepartureDate = newDepartureDate,
)

assertThat(result is ValidatableActionResult.Success).isTrue
result as ValidatableActionResult.Success
assertThat(result).isSuccess()
result as CasResult.Success

verify(exactly = 1) {
mockCas1BookingDomainEventService.bookingChanged(
Expand Down Expand Up @@ -2391,8 +2390,8 @@ class BookingServiceTest {
newDepartureDate = newDepartureDate,
)

assertThat(result is ValidatableActionResult.Success).isTrue
result as ValidatableActionResult.Success
assertThat(result).isSuccess()
result as CasResult.Success

verify {
mockDateChangeRepository.save(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ class CasResultAssertions<T>(actual: CasResult<T>) : AbstractAssert<CasResultAss
return CasSuccessResultAssertions(actual as CasResult.Success)
}

fun isConflictError(): CasResultConflictErrorAssertions<T> {
if (actual !is CasResult.ConflictError) {
failWithMessage("Expected CasResult.ConflictError but was <%s>", actual.javaClass.simpleName, actual)
}
return CasResultConflictErrorAssertions(actual as CasResult.ConflictError)
}

fun isFieldValidationError(): CasResultFieldValidationErrorAssertions<T> {
if (actual !is CasResult.FieldValidationError) {
failWithMessage("Expected CasResult.FieldValidationError but was <%s>", actual.javaClass.simpleName, actual)
}
return CasResultFieldValidationErrorAssertions(actual as CasResult.FieldValidationError)
}

@Deprecated("Use the chained version isFieldValidationError()")
fun isFieldValidationError(field: String, expectedMessage: String): CasResultAssertions<T> {
if (actual !is CasResult.FieldValidationError) {
failWithMessage("Expected CasResult.FieldValidationError but was <%s>", actual.javaClass.simpleName, actual)
Expand Down Expand Up @@ -86,3 +101,53 @@ class CasSuccessResultAssertions<T>(actual: CasResult.Success<T>) : AbstractAsse
check.invoke(actual.value)
}
}

class CasResultConflictErrorAssertions<T>(actual: CasResult.ConflictError<T>) :
AbstractAssert<CasResultConflictErrorAssertions<T>, CasResult.ConflictError<T>>(
actual,
CasResultConflictErrorAssertions::class.java,
) {
fun hasEntityId(expected: Any): CasResultConflictErrorAssertions<T> {
val value = actual.conflictingEntityId
if (value != expected) {
failWithMessage("Expected ConflictError Entity Id value to be <%s> but was:<%s>", expected, value)
}
return this
}

fun hasMessage(expected: Any): CasResultConflictErrorAssertions<T> {
val value = actual.message
if (value != expected) {
failWithMessage("Expected ConflictError Message value to be <%s> but was:<%s>", expected, value)
}
return this
}

fun hasMessageContaining(expected: String): CasResultConflictErrorAssertions<T> {
val value = actual.message
assertThat(value).contains(expected)
return this
}
}

class CasResultFieldValidationErrorAssertions<T>(actual: CasResult.FieldValidationError<T>) :
AbstractAssert<CasResultFieldValidationErrorAssertions<T>, CasResult.FieldValidationError<T>>(
actual,
CasResultFieldValidationErrorAssertions::class.java,
) {
fun hasMessage(field: String, expectedMessage: String): CasResultFieldValidationErrorAssertions<T> {
val validationMessages = actual.validationMessages

if (!validationMessages.containsKey(field)) {
failWithMessage("Expected field <%s> not found in validation messages", field)
} else if (validationMessages[field] != expectedMessage) {
failWithMessage(
"Expected field <%s> to have message <%s> but was <%s>",
field,
expectedMessage,
validationMessages[field],
)
}
return this
}
}

0 comments on commit 6a7ce73

Please sign in to comment.