Skip to content

Commit

Permalink
Merge pull request #2737 from ministryofjustice/CAS-1261-cas3-rejecti…
Browse files Browse the repository at this point in the history
…on-referral-seed-job

CAS-1261 Add system notes to rejection referral seed job
  • Loading branch information
muhammad-elabdulla authored Dec 20, 2024
2 parents a1fee39 + 8ed2720 commit 47da9c3
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ 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.AssessmentEntity
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentReferralHistoryNoteRepository
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentReferralHistorySystemNoteEntity
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentRepository
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ReferralHistorySystemNoteType
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.jpa.entity.UserEntity
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserRepository
import uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.SeedJob
import java.time.OffsetDateTime
import java.util.UUID
Expand All @@ -16,12 +22,15 @@ import java.util.UUID
class Cas3ReferralRejectionSeedJob(
private val assessmentRepository: AssessmentRepository,
private val referralRejectionReasonRepository: ReferralRejectionReasonRepository,
private val assessmentReferralHistoryNoteRepository: AssessmentReferralHistoryNoteRepository,
private val userRepository: UserRepository,
) : SeedJob<Cas3ReferralRejectionSeedCsvRow>(
requiredHeaders = setOf(
"assessment_id",
"rejection_reason",
"rejection_reason_detail",
"is_withdrawn",
"delius_username",
),
runInTransaction = false,
) {
Expand All @@ -32,6 +41,7 @@ class Cas3ReferralRejectionSeedJob(
rejectionReason = columns["rejection_reason"]!!.trim(),
rejectionReasonDetail = columns["rejection_reason_detail"]!!.trim(),
isWithdrawn = columns["is_withdrawn"]!!.trim().equals("true", ignoreCase = true),
deliusUsername = columns["delius_username"]!!.trim(),
)

override fun processRow(row: Cas3ReferralRejectionSeedCsvRow) {
Expand All @@ -40,6 +50,8 @@ class Cas3ReferralRejectionSeedJob(

@SuppressWarnings("TooGenericExceptionCaught")
private fun rejectAssessment(row: Cas3ReferralRejectionSeedCsvRow) {
val userRequest = userRepository.findByDeliusUsername(row.deliusUsername.uppercase()) ?: error("User with delius username ${row.deliusUsername} not found")

val assessment =
assessmentRepository.findByIdOrNull(row.assessmentId) ?: error("Assessment with id ${row.assessmentId} not found")

Expand All @@ -48,8 +60,10 @@ class Cas3ReferralRejectionSeedJob(
}

if (assessment is TemporaryAccommodationAssessmentEntity) {
val rejectionReason = referralRejectionReasonRepository.findByNameAndActive(row.rejectionReason, ServiceName.temporaryAccommodation.value)
?: error("Rejection reason ${row.rejectionReason} not found")
val rejectionReason = referralRejectionReasonRepository.findByNameAndActive(
row.rejectionReason,
ServiceName.temporaryAccommodation.value,
) ?: error("Rejection reason ${row.rejectionReason} not found")

try {
assessment.submittedAt = OffsetDateTime.now()
Expand All @@ -59,7 +73,8 @@ class Cas3ReferralRejectionSeedJob(
assessment.referralRejectionReasonDetail = row.rejectionReasonDetail
assessment.isWithdrawn = row.isWithdrawn

assessmentRepository.save(assessment)
val savedAssessment = assessmentRepository.save(assessment)
savedAssessment.addSystemNote(userRequest, ReferralHistorySystemNoteType.REJECTED)
} catch (e: Throwable) {
log.error("Failed to update assessment with id ${row.assessmentId}", e)
error("Failed to update assessment with id ${row.assessmentId}")
Expand All @@ -70,11 +85,25 @@ class Cas3ReferralRejectionSeedJob(
error("Assessment with id ${row.assessmentId} is not a temporary accommodation assessment")
}
}

fun AssessmentEntity.addSystemNote(user: UserEntity, type: ReferralHistorySystemNoteType) {
this.referralHistoryNotes += assessmentReferralHistoryNoteRepository.save(
AssessmentReferralHistorySystemNoteEntity(
id = UUID.randomUUID(),
assessment = this,
createdAt = OffsetDateTime.now(),
message = "",
createdByUser = user,
type = type,
),
)
}
}

data class Cas3ReferralRejectionSeedCsvRow(
val assessmentId: UUID,
val rejectionReason: String,
val rejectionReasonDetail: String?,
val isWithdrawn: Boolean,
val deliusUsername: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Cas3ReferralRejectionSeedJobTest : SeedTestBase() {

withCsv(
"cas3-referral-rejection-csv",
rowsToCsv(listOf(Cas3ReferralRejectionSeedCsvRow(assessment.id, rejectedReason, rejectedReasonDetail, false))),
rowsToCsv(listOf(Cas3ReferralRejectionSeedCsvRow(assessment.id, rejectedReason, rejectedReasonDetail, false, user.deliusUsername))),
)

seedService.seedData(SeedFileType.temporaryAccommodationReferralRejection, "cas3-referral-rejection-csv.csv")
Expand All @@ -64,12 +64,13 @@ class Cas3ReferralRejectionSeedJobTest : SeedTestBase() {
"rejection_reason",
"rejection_reason_detail",
"is_withdrawn",
"delius_username",
)
.newRow()

rows.forEach {
builder
.withQuotedFields(it.assessmentId, it.rejectionReason, it.rejectionReasonDetail!!, it.isWithdrawn)
.withQuotedFields(it.assessmentId, it.rejectionReason, it.rejectionReasonDetail!!, it.isWithdrawn, it.deliusUsername)
.newRow()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,58 @@ 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.ProbationRegionEntityFactory
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.factory.UserEntityFactory
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentReferralHistoryNoteRepository
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.jpa.entity.UserRepository
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 mockAssessmentRepository = mockk<AssessmentRepository>()
private val mockReferralRejectionReasonRepository = mockk<ReferralRejectionReasonRepository>()
private val mockAssertAssessmentHasSystemNoteRepository = mockk<AssessmentReferralHistoryNoteRepository>()
private val mockUserRepository = mockk<UserRepository>()

private val assessmentId = UUID.randomUUID()
private val deliusUsername = randomStringLowerCase(20).uppercase()

private val userEntity = UserEntityFactory()
.withYieldedProbationRegion {
ProbationRegionEntityFactory()
.produce()
}
.produce()

private val seedJob = Cas3ReferralRejectionSeedJob(
assessmentRepository = assessmentRepository,
referralRejectionReasonRepository = referralRejectionReasonRepository,
assessmentRepository = mockAssessmentRepository,
referralRejectionReasonRepository = mockReferralRejectionReasonRepository,
assessmentReferralHistoryNoteRepository = mockAssertAssessmentHasSystemNoteRepository,
userRepository = mockUserRepository,
)

@Test
fun `When the assessment is not Temporary Accommodation assessment expect error`() {
val assessmentId = UUID.randomUUID()
fun `When the user doesn't exist expect an error`() {
every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns null

assertThatThrownBy {
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false, deliusUsername))
}.hasMessage("User with delius username $deliusUsername not found")
}

@Test
fun `When the assessment is not Temporary Accommodation assessment expect an error`() {
every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns userEntity

every { assessmentRepository.findByIdOrNull(assessmentId) } returns
every { mockAssessmentRepository.findByIdOrNull(assessmentId) } returns
ApprovedPremisesAssessmentEntityFactory()
.withApplication(
ApprovedPremisesApplicationEntityFactory()
Expand All @@ -42,26 +69,26 @@ class Cas3ReferralRejectionSeedJobTest {
.produce()

assertThatThrownBy {
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false))
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false, deliusUsername))
}.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()
fun `When an assessment doesn't exist expect an error`() {
every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns userEntity

every { assessmentRepository.findByIdOrNull(assessmentId) } returns null
every { mockAssessmentRepository.findByIdOrNull(assessmentId) } returns null

assertThatThrownBy {
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", randomStringLowerCase(20), false))
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", randomStringLowerCase(20), false, deliusUsername))
}.hasMessage("Assessment with id $assessmentId not found")
}

@Test
fun `When the application has been allocated expect error`() {
val assessmentId = UUID.randomUUID()
fun `When the application has been allocated expect an error`() {
every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns userEntity

every { assessmentRepository.findByIdOrNull(assessmentId) } returns
every { mockAssessmentRepository.findByIdOrNull(assessmentId) } returns
TemporaryAccommodationAssessmentEntityFactory()
.withApplication(
TemporaryAccommodationApplicationEntityFactory()
Expand All @@ -72,16 +99,17 @@ class Cas3ReferralRejectionSeedJobTest {
.produce()

assertThatThrownBy {
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false))
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false, deliusUsername))
}.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()
fun `When the rejection reason doesn't exist expect an error`() {
val notExistRejectionReason = "not exist rejection reason"

every { assessmentRepository.findByIdOrNull(assessmentId) } returns
every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns userEntity

every { mockAssessmentRepository.findByIdOrNull(assessmentId) } returns
TemporaryAccommodationAssessmentEntityFactory()
.withApplication(
TemporaryAccommodationApplicationEntityFactory()
Expand All @@ -90,16 +118,15 @@ class Cas3ReferralRejectionSeedJobTest {
)
.produce()

every { referralRejectionReasonRepository.findByNameAndActive(notExistRejectionReason, ServiceName.temporaryAccommodation.value) } returns null
every { mockReferralRejectionReasonRepository.findByNameAndActive(notExistRejectionReason, ServiceName.temporaryAccommodation.value) } returns null

assertThatThrownBy {
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, notExistRejectionReason, null, false))
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, notExistRejectionReason, null, false, deliusUsername))
}.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()
Expand All @@ -108,15 +135,17 @@ class Cas3ReferralRejectionSeedJobTest {
)
.produce()

every { assessmentRepository.findByIdOrNull(assessmentId) } returns assessment
every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns userEntity

every { mockAssessmentRepository.findByIdOrNull(assessmentId) } returns assessment

every { referralRejectionReasonRepository.findByNameAndActive("rejection reason", ServiceName.temporaryAccommodation.value) } returns
every { mockReferralRejectionReasonRepository.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")
every { mockAssessmentRepository.save(any()) } throws RuntimeException("Failed to update assessment with id $assessmentId")

assertThatThrownBy {
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false))
seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false, deliusUsername))
}.hasMessage("Failed to update assessment with id $assessmentId")
}
}

0 comments on commit 47da9c3

Please sign in to comment.