Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ class OfficialVisitUpdateService(
startTime = it.startTime,
),
)
}.also {
auditingService.recordAuditEvent(auditChangeEvent)
}

auditingService.recordAuditEvent(auditChangeEvent)

return OfficialVisitUpdateSlotResponse(
officialVisitId = updatedVisit.officialVisitId,
prisonerNumber = updatedVisit.prisonerNumber,
Expand All @@ -116,6 +116,19 @@ class OfficialVisitUpdateService(
val ove = officialVisitRepository.findByOfficialVisitIdAndPrisonCode(officialVisitId, prisonCode)
?: throw EntityNotFoundException("Official visit with id $officialVisitId and prison code $prisonCode not found")

val auditChangeEvent = auditVisitChangeEvent {
officialVisitId(ove.officialVisitId)
summaryText("Update visit comments")
eventSource("DPS")
user(user)
prisonCode(ove.prisonCode)
prisonerNumber(ove.prisonerNumber)
changes {
change("Prisoner notes", ove.prisonerNotes, request.prisonerNotes)
change("Staff notes", ove.staffNotes, request.staffNotes)
}
}

val updatedVisit = officialVisitRepository.saveAndFlush(
ove.apply {
staffNotes = request.staffNotes
Expand All @@ -137,6 +150,8 @@ class OfficialVisitUpdateService(
)
}

auditingService.recordAuditEvent(auditChangeEvent)

return OfficialVisitUpdateCommentsResponse(
officialVisitId = updatedVisit.officialVisitId,
prisonerNumber = updatedVisit.prisonerNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ abstract class AuditEventDsl {
username = user.username,
userFullName = user.name,
summaryText = summaryText,
detailText = detailsText(),
detailText = detailsText().take(1000),
)
}
}
Expand All @@ -108,10 +108,12 @@ class ChangeVisitDsl : AuditEventDsl() {
}

override fun detailsText(): String = run {
if (changes.changes().isEmpty()) return@run "No recorded changes."
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this even a thing? Should we record an audit change event if there is no actual change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably? They submitted it..


changes.changes().joinToString(
separator = "; ",
postfix = ".",
) { "${it.descriptiveText} changed from ${it.old} to ${it.new}" }
) { "${it.descriptiveText} changed from ${it.old ?: "''"} to ${it.new ?: "''"}" }
}

@AuditEventDslMarker
Expand All @@ -126,9 +128,11 @@ class ChangeVisitDsl : AuditEventDsl() {
changes.add(Change(descriptiveText, old?.toMediumFormatStyle(), new?.toMediumFormatStyle()))
}

fun changes() = changes.filter { it.old != it.new }
fun changes() = changes.filter { it.hasChanged }

data class Change<T : Any>(val descriptiveText: String, val old: T?, val new: T?)
data class Change<T : Any>(val descriptiveText: String, val old: T?, val new: T?) {
val hasChanged: Boolean = old != new
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
alter table audited_event alter column detail_text type varchar(1000);
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,21 @@ class OfficialVisitUpdateServiceTest {
assertThat(visit.updatedBy).isEqualTo(MOORLAND_PRISON_USER.username)
assertThat(visit.updatedTime).isNotNull
verify(officialVisitRepository, times(1)).saveAndFlush(visit)

val auditEventCaptor = argumentCaptor<AuditEventDto>()
verify(auditingService).recordAuditEvent(auditEventCaptor.capture())

with(auditEventCaptor.firstValue) {
officialVisitId isEqualTo 7
prisonerNumber isEqualTo MOORLAND_PRISONER.number
prisonCode isEqualTo MOORLAND
eventSource isEqualTo "DPS"
username isEqualTo MOORLAND_PRISON_USER.username
userFullName isEqualTo MOORLAND_PRISON_USER.name
summaryText isEqualTo "Update visit comments"
detailText isEqualTo "Prisoner notes changed from '' to prisoner updated; Staff notes changed from '' to staff updated."
eventDateTime isCloseTo now()
}
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,54 @@ class AuditEventServiceTest {
}
}

@Test
fun `should be audit change event with no recorded changes`() {
val auditEvent = auditVisitChangeEvent {
officialVisitId(1)
summaryText("Test summary change text")
eventSource("DPS")
user(MOORLAND_PRISON_USER)
prisonCode(MOORLAND)
prisonerNumber("A1234AA")
changes { change("FIELD_1", 1, 1) }
}

with(auditEvent) {
officialVisitId isEqualTo 1
summaryText isEqualTo "Test summary change text"
eventSource isEqualTo "DPS"
eventDateTime isCloseTo now()
username isEqualTo MOORLAND_PRISON_USER.username
userFullName isEqualTo MOORLAND_PRISON_USER.name
prisonerNumber isEqualTo "A1234AA"
detailText isEqualTo "No recorded changes."
}
}

@Test
fun `should be audit change event with truncated details`() {
val auditEvent = auditVisitChangeEvent {
officialVisitId(1)
summaryText("Test summary change text")
eventSource("DPS")
user(MOORLAND_PRISON_USER)
prisonCode(MOORLAND)
prisonerNumber("A1234AA")
changes { change("FIELD_1", "a".repeat(1), "b".repeat(1001)) }
}

with(auditEvent) {
officialVisitId isEqualTo 1
summaryText isEqualTo "Test summary change text"
eventSource isEqualTo "DPS"
eventDateTime isCloseTo now()
username isEqualTo MOORLAND_PRISON_USER.username
userFullName isEqualTo MOORLAND_PRISON_USER.name
prisonerNumber isEqualTo "A1234AA"
detailText isEqualTo "FIELD_1 changed from a to ".plus("b".repeat(1001)).take(1000)
}
}

@Test
fun `should be audit cancellation event when recorded changes`() {
val auditEvent = auditVisitCancellationEvent {
Expand Down
Loading