Skip to content

Commit

Permalink
PI-1599 addeded .updated meessage processing
Browse files Browse the repository at this point in the history
  • Loading branch information
stevomcallister committed Nov 1, 2023
1 parent b04023f commit 1393dc8
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"eventType": "accommodation.cas3.booking.cancelled.updated",
"version": 1,
"description": "A cas3 booking has been cancelled",
"detailUrl": "http://localhost:{wiremock.port}/cas3-api/events/booking-cancelled/12345",
"occurredAt": "2022-12-04T10:42:43+00:00",
"additionalInformation": {
"applicationId": "68df9f6c-3fcb-4ec6-8fcf-96551cd9b080"
},
"personReference": {
"identifiers": [
{
"type": "CRN",
"value": "A000001"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"eventType": "accommodation.cas3.person.arrived.updated",
"version": 1,
"description": "A cas3 person has arrived",
"detailUrl": "http://localhost:{wiremock.port}/cas3-api/events/person-arrived/12345",
"occurredAt": "2022-12-04T10:42:43+00:00",
"additionalInformation": {
"applicationId": "68df9f6c-3fcb-4ec6-8fcf-96551cd9b080"
},
"personReference": {
"identifiers": [
{
"type": "CRN",
"value": "A000001"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"eventType": "accommodation.cas3.person.departed",
"eventType": "accommodation.cas3.person.departed.updated",
"version": 1,
"description": "A cas3 person departed",
"detailUrl": "http://localhost:{wiremock.port}/cas3-api/events/person-departed/12345",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"id": "364145f9-0af8-488e-9901-b4c46cd9ba37",
"timestamp": "2022-12-30T14:53:44",
"eventType": "accommodation.cas3.booking.cancelled.updated",
"eventDetails": {
"applicationId": "68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
"applicationUrl": "https://approved-premises-dev.hmpps.service.justice.gov.uk/booking/68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
"personReference": {
"crn": "A000001",
"noms": "A0001AA"
},
"bookingId": "14c80733-4b6d-4f35-b724-66955aac320c",
"bookingUrl": "https://approved-premises-dev.hmpps.service.justice.gov.uk/someURLtoTheBooking",
"cancellationReason": "Not appropriate",
"cancellationContext": "Suitability"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"id": "364145f9-0af8-488e-9901-b4c46cd9ba37",
"timestamp": "2022-12-30T14:53:44",
"eventType": "accommodation.cas3.person.arrived.updated",
"eventDetails": {
"applicationId": "68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
"applicationUrl": "https://approved-premises-dev.hmpps.service.justice.gov.uk/booking/68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
"personReference": {
"crn": "A000001",
"noms": "A0001AA"
},
"bookingId": "14c80733-4b6d-4f35-b724-66955aac320e",
"bookingUrl": "https://approved-premises-dev.hmpps.service.justice.gov.uk/someURLtoTheBooking",
"premises": {
"addressLine1": "12 Church Street",
"addressLine2": "",
"postcode": "BB1 1BB",
"town": "Bimbly Town",
"region": "Bibbinghammcshireshire"
},
"arrivedAt": "2022-11-30T12:00:00",
"notes": "person arrived"
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "364145f9-0af8-488e-9901-b4c46cd9ba37",
"timestamp": "2022-12-30T14:53:44",
"eventType": "accommodation.cas3.person-departed ",
"eventType": "accommodation.cas3.person.departed.updated",
"eventDetails": {
"applicationId": "68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
"applicationUrl": "https://approved-premises-dev.hmpps.service.justice.gov.uk/booking/68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "364145f9-0af8-488e-9901-b4c46cd9ba37",
"timestamp": "2022-11-30T14:53:44",
"eventType": "accommodation.cas3.person-departed ",
"eventType": "accommodation.cas3.person.departed ",
"eventDetails": {
"applicationId": "68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
"applicationUrl": "https://approved-premises-dev.hmpps.service.justice.gov.uk/booking/68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,32 @@
"status": 200,
"bodyFileName": "cas3-person-departed-update.json"
}
},
{
"request": {
"method": "GET",
"urlPath": "/cas3-api/events/booking-cancelled/12345"
},
"response": {
"headers": {
"Content-Type": "application/json"
},
"status": 200,
"bodyFileName": "cas3-booking-cancelled-update.json"
}
},
{
"request": {
"method": "GET",
"urlPath": "/cas3-api/events/person-arrived/12345"
},
"response": {
"headers": {
"Content-Type": "application/json"
},
"status": 200,
"bodyFileName": "cas3-person-arrived-update.json"
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.github.tomakehurst.wiremock.WireMockServer
import org.hamcrest.MatcherAssert
import org.hamcrest.Matchers
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.Mockito
Expand Down Expand Up @@ -63,6 +64,7 @@ internal class CASIntegrationTest {
lateinit var objectMapper: ObjectMapper

@Test
@Order(1)
fun `referral submitted message is processed correctly`() {
val eventName = "referral-submitted"
val event = prepEvent(eventName, wireMockServer.port())
Expand All @@ -79,6 +81,7 @@ internal class CASIntegrationTest {
}

@Test
@Order(2)
fun `booking cancelled message is processed correctly`() {
val eventName = "booking-cancelled"
val event = prepEvent(eventName, wireMockServer.port())
Expand All @@ -96,6 +99,7 @@ internal class CASIntegrationTest {
}

@Test
@Order(3)
fun `booking confirmed message is processed correctly`() {
val eventName = "booking-confirmed"
val event = prepEvent(eventName, wireMockServer.port())
Expand All @@ -113,6 +117,7 @@ internal class CASIntegrationTest {
}

@Test
@Order(4)
fun `booking provisionally made message is processed correctly`() {
val eventName = "booking-provisionally-made"
val event = prepEvent(eventName, wireMockServer.port())
Expand All @@ -130,6 +135,7 @@ internal class CASIntegrationTest {
}

@Test
@Order(5)
fun `person arrived message is processed correctly`() {
val eventName = "person-arrived"
val event = prepEvent(eventName, wireMockServer.port())
Expand All @@ -156,6 +162,7 @@ internal class CASIntegrationTest {
}

@Test
@Order(6)
fun `person departed message is processed correctly`() {
val eventName = "person-departed"
val event = prepEvent(eventName, wireMockServer.port())
Expand All @@ -176,10 +183,13 @@ internal class CASIntegrationTest {
}

@Test
@Order(7)
fun `person departed message update is processed correctly`() {
val eventName = "person-departed-update"
val event = prepEvent(eventName, wireMockServer.port())

val existingEventDetails = ResourceLoader.file<EventDetails<PersonDeparted>>("cas3-person-departed")
val existingContact = contactRepository.getByExternalReference(existingEventDetails.eventDetails.urn)
val existingNotes = existingContact!!.notes
// When it is received
channelManager.getChannel(queueName).publishAndWait(event)

Expand All @@ -188,7 +198,57 @@ internal class CASIntegrationTest {
val eventDetails = ResourceLoader.file<EventDetails<PersonDeparted>>("cas3-$eventName")
val contact = contactRepository.getByExternalReference(eventDetails.eventDetails.urn)

MatcherAssert.assertThat(contact!!.type.code, Matchers.equalTo("EADP"))
MatcherAssert.assertThat(contact.notes, Matchers.equalTo(eventDetails.eventDetails.noteText))
MatcherAssert.assertThat(
contact!!.notes,
Matchers.equalTo(eventDetails.eventDetails.noteText + System.lineSeparator() + existingNotes)
)
}

@Test
@Order(8)
fun `person arrived updated message is processed correctly`() {
val eventName = "person-arrived-update"
val event = prepEvent(eventName, wireMockServer.port())
val existingEventDetails = ResourceLoader.file<EventDetails<PersonArrived>>("cas3-person-arrived-update")
val existingContact = contactRepository.getByExternalReference(existingEventDetails.eventDetails.urn)
val existingNotes = existingContact!!.notes

// When it is received
channelManager.getChannel(queueName).publishAndWait(event)

// Then it is logged to telemetry
Mockito.verify(telemetryService).notificationReceived(event)

val eventDetails = ResourceLoader.file<EventDetails<PersonArrived>>("cas3-$eventName")
val contact = contactRepository.getByExternalReference(eventDetails.eventDetails.urn)

MatcherAssert.assertThat(
contact!!.notes,
Matchers.equalTo(eventDetails.eventDetails.noteText + System.lineSeparator() + existingNotes)
)
}

@Test
@Order(9)
fun `booking cancelled updated message is processed correctly`() {
val eventName = "booking-cancelled-update"
val event = prepEvent(eventName, wireMockServer.port())
val existingEventDetails = ResourceLoader.file<EventDetails<BookingCancelled>>("cas3-booking-cancelled-update")
val existingContact = contactRepository.getByExternalReference(existingEventDetails.eventDetails.urn)
val existingNotes = existingContact!!.notes

// When it is received
channelManager.getChannel(queueName).publishAndWait(event)

// Then it is logged to telemetry
Mockito.verify(telemetryService).notificationReceived(event)

val eventDetails = ResourceLoader.file<EventDetails<BookingCancelled>>("cas3-$eventName")
val contact = contactRepository.getByExternalReference(eventDetails.eventDetails.urn)

MatcherAssert.assertThat(
contact!!.notes,
Matchers.equalTo(eventDetails.eventDetails.noteText + System.lineSeparator() + existingNotes)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,22 @@ class ContactService(
private val telemetryService: TelemetryService
) : AuditableService(auditedInteractionService) {

fun <T : Cas3Event> createContact(
fun <T : Cas3Event> createOrUpdateContact(
crn: String,
person: Person? = null,
replaceNotes: Boolean = true,
getEvent: () -> EventDetails<T>
) = audit(BusinessInteractionCode.UPDATE_CONTACT) {
val event = getEvent()
val personId = person?.id ?: personRepository.getByCrn(crn).id
val existing = contactRepository.getByExternalReference(event.eventDetails.urn)
if (existing != null) {
if (existing.startTime < event.timestamp) {
existing.notes = event.eventDetails.noteText
if (replaceNotes) {
existing.notes = event.eventDetails.noteText
} else {
existing.notes = "${existing.notes}${System.lineSeparator()}${event.eventDetails.noteText}"
}
existing.date = event.timestamp.toLocalDate()
existing.startTime = event.timestamp
contactRepository.save(existing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,37 @@ class Handler(
val event = notification.message
when (event.eventType) {
"accommodation.cas3.referral.submitted" -> {
contactService.createContact(event.crn()) {
contactService.createOrUpdateContact(event.crn()) {
cas3ApiClient.getApplicationSubmittedDetails(event.url())
}
telemetryService.trackEvent("ApplicationSubmitted", event.telemetryProperties())
}

"accommodation.cas3.booking.cancelled" -> {
contactService.createContact(event.crn()) {
contactService.createOrUpdateContact(event.crn()) {
cas3ApiClient.getBookingCancelledDetails(event.url())
}
telemetryService.trackEvent("ApplicationSubmitted", event.telemetryProperties())
telemetryService.trackEvent("BookingCancelled", event.telemetryProperties())
}

"accommodation.cas3.booking.confirmed" -> {
contactService.createContact(event.crn()) {
contactService.createOrUpdateContact(event.crn()) {
cas3ApiClient.getBookingConfirmedDetails(event.url())
}
telemetryService.trackEvent("ApplicationSubmitted", event.telemetryProperties())
telemetryService.trackEvent("BookingConfirmed", event.telemetryProperties())
}

"accommodation.cas3.booking.provisionally-made" -> {
contactService.createContact(event.crn()) {
contactService.createOrUpdateContact(event.crn()) {
cas3ApiClient.getBookingProvisionallyMade(event.url())
}
telemetryService.trackEvent("ApplicationSubmitted", event.telemetryProperties())
telemetryService.trackEvent("bookingProvisionallyMade", event.telemetryProperties())
}

"accommodation.cas3.person.arrived" -> {
val person = personRepository.getByCrn(event.crn())
val detail = cas3ApiClient.getPersonArrived(event.url())
contactService.createContact(event.crn(), person) {
contactService.createOrUpdateContact(event.crn(), person) {
detail
}
addressService.updateMainAddress(person, detail.eventDetails)
Expand All @@ -67,13 +67,34 @@ class Handler(
"accommodation.cas3.person.departed" -> {
val person = personRepository.getByCrn(event.crn())
val detail = cas3ApiClient.getPersonDeparted(event.url())
contactService.createContact(event.crn(), person) {
contactService.createOrUpdateContact(event.crn(), person) {
detail
}
addressService.endMainCAS3Address(person, detail.eventDetails.departedAt)
telemetryService.trackEvent("PersonDeparted", event.telemetryProperties())
}

"accommodation.cas3.person.arrived.updated" -> {
contactService.createOrUpdateContact(event.crn(), replaceNotes = false) {
cas3ApiClient.getPersonArrived(event.url())
}
telemetryService.trackEvent("PersonArrivedUpdated", event.telemetryProperties())
}

"accommodation.cas3.person.departed.updated" -> {
contactService.createOrUpdateContact(event.crn(), replaceNotes = false) {
cas3ApiClient.getPersonDeparted(event.url())
}
telemetryService.trackEvent("PersonDepartedUpdated", event.telemetryProperties())
}

"accommodation.cas3.booking.cancelled.updated" -> {
contactService.createOrUpdateContact(event.crn(), replaceNotes = false) {
cas3ApiClient.getBookingCancelledDetails(event.url())
}
telemetryService.trackEvent("BookingCancelledUpdated", event.telemetryProperties())
}

else -> throw IllegalArgumentException("Unexpected event type ${event.eventType}")
}
}
Expand Down

0 comments on commit 1393dc8

Please sign in to comment.