@@ -5,6 +5,7 @@ import com.fasterxml.jackson.module.kotlin.readValue
5
5
import io.kotest.assertions.throwables.shouldThrow
6
6
import io.kotest.core.spec.style.DescribeSpec
7
7
import io.kotest.matchers.shouldBe
8
+ import jakarta.validation.ValidationException
8
9
import org.mockito.kotlin.any
9
10
import org.mockito.kotlin.argThat
10
11
import org.mockito.kotlin.doReturn
@@ -14,17 +15,22 @@ import org.mockito.kotlin.verify
14
15
import org.mockito.kotlin.whenever
15
16
import software.amazon.awssdk.services.sqs.SqsAsyncClient
16
17
import software.amazon.awssdk.services.sqs.model.SendMessageRequest
18
+ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException
17
19
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.MessageFailedException
18
20
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.MockMvcExtensions.objectMapper
19
- import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.ExpressionOfInterest
20
21
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.HmppsMessage
21
22
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.HmppsMessageEventType
23
+ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.NomisNumber
24
+ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response
25
+ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi
26
+ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError
22
27
import uk.gov.justice.hmpps.sqs.HmppsQueue
23
28
import uk.gov.justice.hmpps.sqs.HmppsQueueService
24
29
import kotlin.test.assertEquals
25
30
26
31
class PutExpressionInterestServiceTest :
27
32
DescribeSpec ({
33
+ val mockGetPersonService = mock<GetPersonService >()
28
34
val mockQueueService = mock<HmppsQueueService >()
29
35
val mockObjectMapper = mock<ObjectMapper >()
30
36
val mockSqsClient = mock<SqsAsyncClient >()
@@ -36,22 +42,27 @@ class PutExpressionInterestServiceTest :
36
42
}
37
43
38
44
val queId = " jobsboardintegration"
39
- val service = PutExpressionInterestService (mockQueueService, mockObjectMapper)
45
+ val service = PutExpressionInterestService (mockGetPersonService, mockQueueService, mockObjectMapper)
40
46
41
47
beforeTest {
42
48
reset(mockQueueService, mockSqsClient, mockObjectMapper)
43
49
whenever(mockQueueService.findByQueueId(queId)).thenReturn(eoiQueue)
44
50
}
45
51
46
52
describe(" sendExpressionOfInterest" ) {
53
+ beforeTest {
54
+ " H1234" .let { whenever(mockGetPersonService.getNomisNumber(it)).thenReturn(Response (NomisNumber (it))) }
55
+ }
56
+
47
57
it(" should send a valid message successfully to SQS" ) {
48
- val expressionOfInterest = ExpressionOfInterest (jobId = " 12345" , prisonNumber = " H1234" )
58
+ val jobId = " 12345"
59
+ val hmppsId = " H1234"
49
60
val messageBody = """ {"messageId":"1","eventType":"ExpressionOfInterestCreated","messageAttributes":{"jobId":"12345","prisonNumber":"H1234"}}"""
50
61
51
62
whenever(mockObjectMapper.writeValueAsString(any<HmppsMessage >()))
52
63
.thenReturn(messageBody)
53
64
54
- service.sendExpressionOfInterest(expressionOfInterest )
65
+ service.sendExpressionOfInterest(hmppsId, jobId )
55
66
56
67
verify(mockSqsClient).sendMessage(
57
68
argThat<SendMessageRequest > { request: SendMessageRequest ? ->
@@ -62,14 +73,15 @@ class PutExpressionInterestServiceTest :
62
73
}
63
74
64
75
it(" should throw MessageFailedException when SQS fails" ) {
65
- val expressionInterest = ExpressionOfInterest (jobId = " 12345" , prisonNumber = " H1234" )
76
+ val jobId = " 12345"
77
+ val hmppsId = " H1234"
66
78
67
79
whenever(mockSqsClient.sendMessage(any<SendMessageRequest >()))
68
80
.thenThrow(RuntimeException (" Failed to send message to SQS" ))
69
81
70
82
val exception =
71
83
shouldThrow<MessageFailedException > {
72
- service.sendExpressionOfInterest(expressionInterest )
84
+ service.sendExpressionOfInterest(hmppsId, jobId )
73
85
}
74
86
75
87
exception.message shouldBe " Failed to send message to SQS"
@@ -105,7 +117,8 @@ class PutExpressionInterestServiceTest :
105
117
}
106
118
107
119
it(" should serialize ExpressionOfInterestMessage with ExpressionOfInterestCreated type" ) {
108
- val expressionOfInterest = ExpressionOfInterest (jobId = " 12345" , prisonNumber = " H1234" )
120
+ val jobId = " 12345"
121
+ val hmppsId = " H1234"
109
122
val expectedMessage =
110
123
HmppsMessage (
111
124
messageId = " 1" ,
@@ -129,7 +142,7 @@ class PutExpressionInterestServiceTest :
129
142
whenever(mockObjectMapper.writeValueAsString(any<HmppsMessage >()))
130
143
.thenReturn(expectedMessageBody)
131
144
132
- service.sendExpressionOfInterest(expressionOfInterest )
145
+ service.sendExpressionOfInterest(hmppsId, jobId )
133
146
134
147
verify(mockSqsClient).sendMessage(
135
148
argThat<SendMessageRequest > { request ->
@@ -139,4 +152,38 @@ class PutExpressionInterestServiceTest :
139
152
)
140
153
}
141
154
}
155
+
156
+ describe(" sendExpressionOfInterest, with errors at HMPPS ID translation" ) {
157
+ val validHmppsId = " AABCD1ABC"
158
+ val invalidHmppsId = " INVALID_ID"
159
+ val jobId = " 5678"
160
+
161
+ it(" should throw EntityNotFoundException. if ENTITY_NOT_FOUND error occurs" ) {
162
+ val hmppsId = validHmppsId
163
+ val notFoundResponse = errorResponseNomisNumber(UpstreamApiError .Type .ENTITY_NOT_FOUND , " Entity not found" )
164
+ whenever(mockGetPersonService.getNomisNumber(hmppsId)).thenReturn(notFoundResponse)
165
+
166
+ val exception = shouldThrow<EntityNotFoundException > { service.sendExpressionOfInterest(hmppsId, jobId) }
167
+
168
+ assertEquals(" Could not find person with id: $hmppsId " , exception.message)
169
+ }
170
+
171
+ it(" should throw ValidationException if an invalid hmppsId is provided" ) {
172
+ val hmppsId = invalidHmppsId
173
+ val invalidIdBadRequestResponse = errorResponseNomisNumber(UpstreamApiError .Type .BAD_REQUEST , " Invalid HMPPS ID" )
174
+ whenever(mockGetPersonService.getNomisNumber(hmppsId)).thenReturn(invalidIdBadRequestResponse)
175
+
176
+ val exception = shouldThrow<ValidationException > { service.sendExpressionOfInterest(hmppsId, jobId) }
177
+
178
+ assertEquals(" Invalid HMPPS ID: $hmppsId " , exception.message)
179
+ }
180
+ }
142
181
})
182
+
183
+ private fun errorResponseNomisNumber (
184
+ errorType : UpstreamApiError .Type ,
185
+ errorDescription : String ,
186
+ ) = Response <NomisNumber ?>(
187
+ data = null ,
188
+ errors = listOf (UpstreamApiError (type = errorType, description = errorDescription, causedBy = UpstreamApi .PRISONER_OFFENDER_SEARCH )),
189
+ )
0 commit comments