Skip to content

Commit

Permalink
PI-1566 OPD Assessment (#2483)
Browse files Browse the repository at this point in the history
* PI-1566 OPD Assessment

* PI-1566 OPD Assessment
  • Loading branch information
anthony-britton-moj authored Nov 1, 2023
1 parent b4db13e commit 7d6f2f3
Show file tree
Hide file tree
Showing 24 changed files with 864 additions and 173 deletions.
6 changes: 5 additions & 1 deletion projects/opd-and-delius/deploy/database/access.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ database:
access:
username_key: /opd-and-delius/db-username
password_key: /opd-and-delius/db-password
tables:
- nsi
- nsi_manager
- contact

audit:
username: OpdAndDelius
forename: Probation Integration # TODO change this to something meaningful for your service
forename: OPD and Delius
surname: Service
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.springframework.context.ApplicationListener
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator
import uk.gov.justice.digital.hmpps.data.generator.UserGenerator
import uk.gov.justice.digital.hmpps.user.AuditUserRepository

Expand All @@ -26,8 +27,12 @@ class DataLoader(
@Transactional
override fun onApplicationEvent(are: ApplicationReadyEvent) {
em.saveAll(
PersonGenerator.DEFAULT_PERSON
PersonGenerator.PERSON_OPD_NEW,
PersonGenerator.PERSON_MANAGER,
PersonGenerator.generateEvent(PersonGenerator.PERSON_OPD_NEW)
)
ReferenceDataGenerator.all().forEach { em.persist(it) }
}

fun EntityManager.saveAll(vararg any: Any) = any.forEach { persist(it) }
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.integrations.delius.Event
import uk.gov.justice.digital.hmpps.integrations.delius.Person
import uk.gov.justice.digital.hmpps.integrations.delius.PersonManager

object PersonGenerator {
val DEFAULT_PERSON = generatePerson("A000001")
val PERSON_OPD_NEW = generatePerson("A000001")
val PERSON_MANAGER = generatePersonManager(PERSON_OPD_NEW)
fun generatePerson(
crn: String,
softDeleted: Boolean = false,
id: Long = IdGenerator.getAndIncrement()
) = Person(id, crn)
) = Person(crn, softDeleted, id)

fun generatePersonManager(
person: Person,
providerId: Long = IdGenerator.getAndIncrement(),
teamId: Long = IdGenerator.getAndIncrement(),
staffId: Long = IdGenerator.getAndIncrement(),
active: Boolean = true,
softDeleted: Boolean = false,
id: Long = IdGenerator.getAndIncrement()
) = PersonManager(person, providerId, teamId, staffId, active, softDeleted, id)

fun generateEvent(
person: Person,
active: Boolean = true,
softDeleted: Boolean = false,
id: Long = IdGenerator.getAndIncrement()
) = Event(person, active, softDeleted, id)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.integrations.delius.Dataset
import uk.gov.justice.digital.hmpps.integrations.delius.NsiStatus
import uk.gov.justice.digital.hmpps.integrations.delius.NsiSubType
import uk.gov.justice.digital.hmpps.integrations.delius.NsiType
import uk.gov.justice.digital.hmpps.integrations.delius.contact.entity.ContactType

object ReferenceDataGenerator {
val DS_NSI_SUB_TYPE = generateDataset(Dataset.NSI_SUB_TYPE)
val CONTACT_TYPES = ContactType.Code.entries.map { generateContactType(it.value) }.associateBy { it.code }
val NSI_TYPES = NsiType.Code.entries.map { generateType(it.value) }.associateBy { it.code }
val NSI_SUBTYPES = NsiSubType.Code.entries.map { generateSubType(it.value) }.associateBy { it.code }
val NSI_STATUSES = NsiStatus.Code.entries.map { sc ->
generateStatus(
sc.value,
sc.contactTypeCode?.value?.let { CONTACT_TYPES[it] }
)
}.associateBy { it.code }

fun generateDataset(code: String, id: Long = IdGenerator.getAndIncrement()) = Dataset(code, id)
fun generateContactType(code: String, id: Long = IdGenerator.getAndIncrement()) = ContactType(code, id)
fun generateType(code: String, id: Long = IdGenerator.getAndIncrement()) = NsiType(code, id)
fun generateSubType(code: String, id: Long = IdGenerator.getAndIncrement()) =
NsiSubType(code, DS_NSI_SUB_TYPE.id, id)

fun generateStatus(code: String, contactType: ContactType?, id: Long = IdGenerator.getAndIncrement()) =
NsiStatus(code, contactType, id)

fun all() =
listOf(DS_NSI_SUB_TYPE) + CONTACT_TYPES.values + NSI_TYPES.values + NSI_SUBTYPES.values + NSI_STATUSES.values
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Type": "Notification",
"MessageId": "f39059e7-a62d-4157-929a-fb049015c993",
"Message": "{\"eventType\":\"opd.produced\",\"version\":\"2\",\"description\":\"OPD Assessment\",\"occurredAt\":\"2023-10-30T16:42:25+00:00\",\"detailUrl\":null,\"additionalInformation\":{\"dateCompleted\":\"2023-10-30T16:42:25+00:00\", \"opdResult\":\"SCREENED IN\", \"opdScreenOutOverride\": \"\"},\"personReference\":{\"identifiers\":[{\"type\":\"CRN\",\"value\":\"A000001\"}]}}",
"Timestamp": "2023-10-30T16:42:25+00:00",
"MessageAttributes": {
"eventType": {
"Type": "String",
"Value": "opd.produced"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"Type": "Notification",
"MessageId": "f39059e7-a62d-4157-929a-fb049015c993",
"TopicArn": "arn:aws:sns:eu-west-2:000000000000:hmpps-domain",
"Message": "{\"eventType\":\"opd.produced\",\"version\":\"2\",\"description\":\"OPD Assessment\",\"occurredAt\":\"2023-10-31T13:42:25+01:00\",\"detailUrl\":null,\"additionalInformation\":{\"dateCompleted\":\"2023-10-31T13:42:25+01:00\", \"opdResult\":\"SCREENED IN\", \"opdScreenOutOverride\": \"YES\"},\"personReference\":{\"identifiers\":[{\"type\":\"CRN\",\"value\":\"A000001\"}]}}",
"Timestamp": "2023-10-31T13:42:25Z",
"MessageAttributes": {
"eventType": {
"Type": "String",
"Value": "opd.produced"
}
}
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package uk.gov.justice.digital.hmpps

import com.github.tomakehurst.wiremock.WireMockServer
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.containsString
import org.hamcrest.Matchers.equalTo
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.MethodOrderer
import org.junit.jupiter.api.Order
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestMethodOrder
import org.mockito.kotlin.verify
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.mock.mockito.MockBean
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.integrations.delius.EventRepository
import uk.gov.justice.digital.hmpps.integrations.delius.NsiManagerRepository
import uk.gov.justice.digital.hmpps.integrations.delius.NsiRepository
import uk.gov.justice.digital.hmpps.integrations.delius.NsiStatus
import uk.gov.justice.digital.hmpps.integrations.delius.NsiSubType
import uk.gov.justice.digital.hmpps.integrations.delius.NsiType
import uk.gov.justice.digital.hmpps.integrations.delius.PersonManagerRepository
import uk.gov.justice.digital.hmpps.integrations.delius.contact.entity.ContactRepository
import uk.gov.justice.digital.hmpps.integrations.delius.contact.entity.ContactType
import uk.gov.justice.digital.hmpps.integrations.delius.getByCrn
import uk.gov.justice.digital.hmpps.messaging.HmppsChannelManager
import uk.gov.justice.digital.hmpps.telemetry.TelemetryService
import uk.gov.justice.digital.hmpps.test.CustomMatchers.isCloseTo
import java.time.ZonedDateTime

@SpringBootTest
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
internal class OpdIntegrationTest {
@Value("\${messaging.consumer.queue}")
lateinit var queueName: String

@Autowired
lateinit var channelManager: HmppsChannelManager

@MockBean
lateinit var telemetryService: TelemetryService

@Autowired
lateinit var wireMockServer: WireMockServer

@Autowired
lateinit var personManagerRepository: PersonManagerRepository

@Autowired
lateinit var nsiRepository: NsiRepository

@Autowired
lateinit var nsiManagerRepository: NsiManagerRepository

@Autowired
lateinit var contactRepository: ContactRepository

@Autowired
lateinit var eventRepository: EventRepository

@Order(1)
@Test
fun `process opd assessment`() {
val message = prepMessage("opd-assessment-new", wireMockServer.port())

channelManager.getChannel(queueName).publishAndWait(message)

val com = personManagerRepository.getByCrn(PersonGenerator.PERSON_OPD_NEW.crn)
val nsi = nsiRepository.findNsiByPersonIdAndTypeCode(com.person.id, NsiType.Code.OPD_COMMUNITY_PATHWAY.value)
assertNotNull(nsi!!)
assertThat(nsi.type.code, equalTo(NsiType.Code.OPD_COMMUNITY_PATHWAY.value))
assertThat(nsi.subType?.code, equalTo(NsiSubType.Code.COMMUNITY_PATHWAY.value))
assertThat(nsi.status.code, equalTo(NsiStatus.Code.READY_FOR_SERVICE.value))

val nsiManager = nsiManagerRepository.findAll().firstOrNull { it.nsi.id == nsi.id }
assertNotNull(nsiManager!!)
assertThat(nsiManager.teamId, equalTo(com.teamId))
assertThat(nsiManager.staffId, equalTo(com.staffId))

val opdContact = contactRepository.findAll()
.firstOrNull { it.personId == com.person.id && it.type.code == ContactType.Code.READY_FOR_SERVICES.value }
assertNotNull(opdContact!!)

verify(telemetryService).trackEvent(
"OpdAssessmentScreenedIn",
mapOf(
"crn" to PersonGenerator.PERSON_OPD_NEW.crn,
"date" to "30/10/2023 16:42:25",
"result" to "Screened In"
)
)
}

@Order(2)
@Test
fun `process update to opd assessment`() {
val message = prepMessage("opd-assessment-update", wireMockServer.port())

channelManager.getChannel(queueName).publishAndWait(message)

val com = personManagerRepository.getByCrn(PersonGenerator.PERSON_OPD_NEW.crn)
val nsi = nsiRepository.findNsiByPersonIdAndTypeCode(com.person.id, NsiType.Code.OPD_COMMUNITY_PATHWAY.value)
assertNotNull(nsi!!)
assertThat(
nsi.notes,
containsString(
"""
|OPD Assessment Date: 31/10/2023 13:42:25
|OPD Result: Screened In - with override
|This note was automatically created by the system
""".trimMargin()
)
)

val opdContact = contactRepository.findAll()
.firstOrNull { it.personId == com.person.id && it.type.code == ContactType.Code.READY_FOR_SERVICES.value }
assertNotNull(opdContact!!)
}

@Order(3)
@Test
fun `end opd assessment if event terminated`() {
val com = personManagerRepository.getByCrn(PersonGenerator.PERSON_OPD_NEW.crn)

// create terminated event for this test and remove existing active one
val event = eventRepository.findAll().firstOrNull { it.person.id == com.person.id }!!
eventRepository.deleteById(event.id)
eventRepository.save(PersonGenerator.generateEvent(com.person, active = false))

val message = prepMessage("opd-assessment-update", wireMockServer.port())

channelManager.getChannel(queueName).publishAndWait(message)

val nsi = nsiRepository.findNsiByPersonIdAndTypeCode(com.person.id, NsiType.Code.OPD_COMMUNITY_PATHWAY.value)
assertNotNull(nsi!!)
assertThat(
nsi.actualEndDate!!,
isCloseTo(ZonedDateTime.now())
)
}
}

This file was deleted.

Loading

0 comments on commit 7d6f2f3

Please sign in to comment.