generated from ministryofjustice/hmpps-template-kotlin
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2733 from ministryofjustice/CAS-1261-seed-job-cas…
…3-referral-rejected Create a seed job for CAS3 referral rejection
- Loading branch information
Showing
10 changed files
with
290 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
...k/gov/justice/digital/hmpps/approvedpremisesapi/seed/cas3/Cas3ReferralRejectionSeedJob.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.cas3 | ||
|
||
import org.slf4j.LoggerFactory | ||
import org.springframework.data.repository.findByIdOrNull | ||
import org.springframework.stereotype.Component | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ServiceName | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentDecision | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentRepository | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ReferralRejectionReasonRepository | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.TemporaryAccommodationAssessmentEntity | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.SeedJob | ||
import java.time.OffsetDateTime | ||
import java.util.UUID | ||
|
||
@Component | ||
class Cas3ReferralRejectionSeedJob( | ||
private val assessmentRepository: AssessmentRepository, | ||
private val referralRejectionReasonRepository: ReferralRejectionReasonRepository, | ||
) : SeedJob<Cas3ReferralRejectionSeedCsvRow>( | ||
requiredHeaders = setOf( | ||
"assessment_id", | ||
"rejection_reason", | ||
"rejection_reason_detail", | ||
"is_withdrawn", | ||
), | ||
runInTransaction = false, | ||
) { | ||
private val log = LoggerFactory.getLogger(this::class.java) | ||
|
||
override fun deserializeRow(columns: Map<String, String>) = Cas3ReferralRejectionSeedCsvRow( | ||
assessmentId = UUID.fromString(columns["assessment_id"]!!.trim()), | ||
rejectionReason = columns["rejection_reason"]!!.trim(), | ||
rejectionReasonDetail = columns["rejection_reason_detail"]!!.trim(), | ||
isWithdrawn = columns["is_withdrawn"]!!.trim().equals("true", ignoreCase = true), | ||
) | ||
|
||
override fun processRow(row: Cas3ReferralRejectionSeedCsvRow) { | ||
rejectAssessment(row) | ||
} | ||
|
||
@SuppressWarnings("TooGenericExceptionCaught") | ||
private fun rejectAssessment(row: Cas3ReferralRejectionSeedCsvRow) { | ||
val assessment = | ||
assessmentRepository.findByIdOrNull(row.assessmentId) ?: error("Assessment with id ${row.assessmentId} not found") | ||
|
||
if (assessment.reallocatedAt != null) { | ||
error("The application has been reallocated, this assessment is read only") | ||
} | ||
|
||
if (assessment is TemporaryAccommodationAssessmentEntity) { | ||
val rejectionReason = referralRejectionReasonRepository.findByNameAndActive(row.rejectionReason, ServiceName.temporaryAccommodation.value) | ||
?: error("Rejection reason ${row.rejectionReason} not found") | ||
|
||
try { | ||
assessment.submittedAt = OffsetDateTime.now() | ||
assessment.decision = AssessmentDecision.REJECTED | ||
assessment.completedAt = null | ||
assessment.referralRejectionReason = rejectionReason | ||
assessment.referralRejectionReasonDetail = row.rejectionReasonDetail | ||
assessment.isWithdrawn = row.isWithdrawn | ||
|
||
assessmentRepository.save(assessment) | ||
} catch (e: Throwable) { | ||
log.error("Failed to update assessment with id ${row.assessmentId}", e) | ||
error("Failed to update assessment with id ${row.assessmentId}") | ||
} | ||
|
||
log.info("Assessment with id ${row.assessmentId} has been successfully rejected") | ||
} else { | ||
error("Assessment with id ${row.assessmentId} is not a temporary accommodation assessment") | ||
} | ||
} | ||
} | ||
|
||
data class Cas3ReferralRejectionSeedCsvRow( | ||
val assessmentId: UUID, | ||
val rejectionReason: String, | ||
val rejectionReasonDetail: String?, | ||
val isWithdrawn: Boolean, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
...gital/hmpps/approvedpremisesapi/integration/seed/cas3/Cas3ReferralRejectionSeedJobTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.seed.cas3 | ||
|
||
import org.assertj.core.api.Assertions.assertThat | ||
import org.junit.jupiter.api.Test | ||
import org.springframework.data.repository.findByIdOrNull | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.SeedFileType | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.givenAUser | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.seed.SeedTestBase | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentDecision | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.CsvBuilder | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.cas3.Cas3ReferralRejectionSeedCsvRow | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.randomStringLowerCase | ||
import java.time.OffsetDateTime | ||
|
||
class Cas3ReferralRejectionSeedJobTest : SeedTestBase() { | ||
@Test | ||
fun `Reject an assessment update the assessment status to Rejected`() { | ||
val user = givenAUser().first | ||
|
||
val applicationSchema = temporaryAccommodationApplicationJsonSchemaEntityFactory.produceAndPersist { | ||
withPermissiveSchema() | ||
} | ||
|
||
val assessmentSchema = temporaryAccommodationAssessmentJsonSchemaEntityFactory.produceAndPersist { | ||
withPermissiveSchema() | ||
} | ||
|
||
val application = temporaryAccommodationApplicationEntityFactory.produceAndPersist { | ||
withProbationRegion(user.probationRegion) | ||
withCreatedByUser(user) | ||
withApplicationSchema(applicationSchema) | ||
withSubmittedAt(OffsetDateTime.now().minusDays(10)) | ||
} | ||
|
||
val assessment = temporaryAccommodationAssessmentEntityFactory.produceAndPersist { | ||
withApplication(application) | ||
withAllocatedToUser(user) | ||
withAssessmentSchema(assessmentSchema) | ||
} | ||
|
||
val rejectedReason = "Another reason (please add)" | ||
val rejectedReasonDetail = randomStringLowerCase(30) | ||
|
||
withCsv( | ||
"cas3-referral-rejection-csv", | ||
rowsToCsv(listOf(Cas3ReferralRejectionSeedCsvRow(assessment.id, rejectedReason, rejectedReasonDetail, false))), | ||
) | ||
|
||
seedService.seedData(SeedFileType.temporaryAccommodationReferralRejection, "cas3-referral-rejection-csv.csv") | ||
|
||
val persistedAssessment = temporaryAccommodationAssessmentRepository.findByIdOrNull(assessment.id)!! | ||
assertThat(persistedAssessment).isNotNull | ||
assertThat(persistedAssessment.decision).isEqualTo(AssessmentDecision.REJECTED) | ||
assertThat(persistedAssessment.completedAt).isNull() | ||
assertThat(persistedAssessment.referralRejectionReason?.name).isEqualTo(rejectedReason) | ||
assertThat(persistedAssessment.referralRejectionReasonDetail).isEqualTo(rejectedReasonDetail) | ||
assertThat(persistedAssessment.isWithdrawn).isFalse() | ||
} | ||
|
||
private fun rowsToCsv(rows: List<Cas3ReferralRejectionSeedCsvRow>): String { | ||
val builder = CsvBuilder() | ||
.withUnquotedFields( | ||
"assessment_id", | ||
"rejection_reason", | ||
"rejection_reason_detail", | ||
"is_withdrawn", | ||
) | ||
.newRow() | ||
|
||
rows.forEach { | ||
builder | ||
.withQuotedFields(it.assessmentId, it.rejectionReason, it.rejectionReasonDetail!!, it.isWithdrawn) | ||
.newRow() | ||
} | ||
|
||
return builder.build() | ||
} | ||
} |
122 changes: 122 additions & 0 deletions
122
...tice/digital/hmpps/approvedpremisesapi/unit/seed/cas3/Cas3ReferralRejectionSeedJobTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package uk.gov.justice.digital.hmpps.approvedpremisesapi.unit.seed.cas3 | ||
|
||
import io.mockk.every | ||
import io.mockk.mockk | ||
import org.assertj.core.api.Assertions.assertThatThrownBy | ||
import org.junit.jupiter.api.Test | ||
import org.springframework.data.repository.findByIdOrNull | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ServiceName | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.ApprovedPremisesApplicationEntityFactory | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.ApprovedPremisesAssessmentEntityFactory | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.TemporaryAccommodationApplicationEntityFactory | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.TemporaryAccommodationAssessmentEntityFactory | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentRepository | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ReferralRejectionReasonEntity | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ReferralRejectionReasonRepository | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.cas3.Cas3ReferralRejectionSeedCsvRow | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.cas3.Cas3ReferralRejectionSeedJob | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.randomStringLowerCase | ||
import java.time.OffsetDateTime | ||
import java.util.UUID | ||
|
||
class Cas3ReferralRejectionSeedJobTest { | ||
private val assessmentRepository = mockk<AssessmentRepository>() | ||
private val referralRejectionReasonRepository = mockk<ReferralRejectionReasonRepository>() | ||
|
||
private val seedJob = Cas3ReferralRejectionSeedJob( | ||
assessmentRepository = assessmentRepository, | ||
referralRejectionReasonRepository = referralRejectionReasonRepository, | ||
) | ||
|
||
@Test | ||
fun `When the assessment is not Temporary Accommodation assessment expect error`() { | ||
val assessmentId = UUID.randomUUID() | ||
|
||
every { assessmentRepository.findByIdOrNull(assessmentId) } returns | ||
ApprovedPremisesAssessmentEntityFactory() | ||
.withApplication( | ||
ApprovedPremisesApplicationEntityFactory() | ||
.withDefaults() | ||
.produce(), | ||
) | ||
.produce() | ||
|
||
assertThatThrownBy { | ||
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false)) | ||
}.hasMessage("Assessment with id $assessmentId is not a temporary accommodation assessment") | ||
} | ||
|
||
@Test | ||
fun `When an assessment doesn't exist expect error`() { | ||
val assessmentId = UUID.randomUUID() | ||
|
||
every { assessmentRepository.findByIdOrNull(assessmentId) } returns null | ||
|
||
assertThatThrownBy { | ||
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", randomStringLowerCase(20), false)) | ||
}.hasMessage("Assessment with id $assessmentId not found") | ||
} | ||
|
||
@Test | ||
fun `When the application has been allocated expect error`() { | ||
val assessmentId = UUID.randomUUID() | ||
|
||
every { assessmentRepository.findByIdOrNull(assessmentId) } returns | ||
TemporaryAccommodationAssessmentEntityFactory() | ||
.withApplication( | ||
TemporaryAccommodationApplicationEntityFactory() | ||
.withDefaults() | ||
.produce(), | ||
) | ||
.withReallocatedAt(OffsetDateTime.now()) | ||
.produce() | ||
|
||
assertThatThrownBy { | ||
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false)) | ||
}.hasMessage("The application has been reallocated, this assessment is read only") | ||
} | ||
|
||
@Test | ||
fun `When the rejection reason doesn't exist expect error`() { | ||
val assessmentId = UUID.randomUUID() | ||
val notExistRejectionReason = "not exist rejection reason" | ||
|
||
every { assessmentRepository.findByIdOrNull(assessmentId) } returns | ||
TemporaryAccommodationAssessmentEntityFactory() | ||
.withApplication( | ||
TemporaryAccommodationApplicationEntityFactory() | ||
.withDefaults() | ||
.produce(), | ||
) | ||
.produce() | ||
|
||
every { referralRejectionReasonRepository.findByNameAndActive(notExistRejectionReason, ServiceName.temporaryAccommodation.value) } returns null | ||
|
||
assertThatThrownBy { | ||
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, notExistRejectionReason, null, false)) | ||
}.hasMessage("Rejection reason $notExistRejectionReason not found") | ||
} | ||
|
||
@Test | ||
fun `When save an assessment and an exception happened expect logging error`() { | ||
val assessmentId = UUID.randomUUID() | ||
val assessment = TemporaryAccommodationAssessmentEntityFactory() | ||
.withApplication( | ||
TemporaryAccommodationApplicationEntityFactory() | ||
.withDefaults() | ||
.produce(), | ||
) | ||
.produce() | ||
|
||
every { assessmentRepository.findByIdOrNull(assessmentId) } returns assessment | ||
|
||
every { referralRejectionReasonRepository.findByNameAndActive("rejection reason", ServiceName.temporaryAccommodation.value) } returns | ||
ReferralRejectionReasonEntity(UUID.randomUUID(), "rejection reason", true, ServiceName.temporaryAccommodation.value, 1) | ||
|
||
every { assessmentRepository.save(any()) } throws RuntimeException("Failed to update assessment with id $assessmentId") | ||
|
||
assertThatThrownBy { | ||
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false)) | ||
}.hasMessage("Failed to update assessment with id $assessmentId") | ||
} | ||
} |