Skip to content

Commit d412bda

Browse files
author
Bingjie Liu
committed
Add tests
1 parent fb228af commit d412bda

17 files changed

+661
-200
lines changed

src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/NomisGateway.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,12 @@ class NomisGateway(
260260

261261
fun getReasonableAdjustments(booking: String): Response<List<ReasonableAdjustment>> {
262262
val treatmentCodes = getReferenceDomains("HEALTH_TREAT").data
263-
val params = treatmentCodes.joinToString(separator = "&") { (value) -> "type=$value" }
263+
val codes = treatmentCodes.map { "type=${it.code}" }.toList()
264+
val params = codes.joinToString(separator = "&", prefix = "?")
264265
val result =
265266
webClient.request<NomisReasonableAdjustments>(
266267
HttpMethod.GET,
267-
"/api/bookings/$booking/reasonable-adjustments?$params",
268+
"/api/bookings/$booking/reasonable-adjustments$params",
268269
authenticationHeaderForCategories(),
269270
UpstreamApi.NOMIS,
270271
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person
2+
3+
import io.kotest.core.spec.style.DescribeSpec
4+
import io.kotest.matchers.shouldBe
5+
import io.kotest.matchers.string.shouldContain
6+
import org.mockito.Mockito
7+
import org.mockito.internal.verification.VerificationModeFactory
8+
import org.mockito.kotlin.doThrow
9+
import org.mockito.kotlin.verify
10+
import org.mockito.kotlin.whenever
11+
import org.springframework.beans.factory.annotation.Autowired
12+
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
13+
import org.springframework.boot.test.mock.mockito.MockBean
14+
import org.springframework.http.HttpStatus
15+
import org.springframework.test.context.ActiveProfiles
16+
import org.springframework.test.web.servlet.MockMvc
17+
import org.springframework.web.reactive.function.client.WebClientResponseException
18+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.removeWhitespaceAndNewlines
19+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.helpers.IntegrationAPIMockMvc
20+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PersonProtectedCharacteristics
21+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response
22+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi
23+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError
24+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetProtectedCharacteristicsService
25+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService
26+
import java.net.URLEncoder
27+
import java.nio.charset.StandardCharsets
28+
29+
@WebMvcTest(controllers = [ProtectedCharacteristicsController::class])
30+
@ActiveProfiles("test")
31+
internal class ProtectedCharacteristicsControllerTest(
32+
@Autowired var springMockMvc: MockMvc,
33+
@MockBean val getProtectedCharacteristicsService: GetProtectedCharacteristicsService,
34+
@MockBean val auditService: AuditService,
35+
) : DescribeSpec(
36+
{
37+
val hmppsId = "9999/11111A"
38+
val encodedHmppsId = URLEncoder.encode(hmppsId, StandardCharsets.UTF_8)
39+
val path = "/v1/persons/$encodedHmppsId/protected-characteristics"
40+
val mockMvc = IntegrationAPIMockMvc(springMockMvc)
41+
42+
describe("GET $path") {
43+
beforeTest {
44+
Mockito.reset(getProtectedCharacteristicsService)
45+
Mockito.reset(auditService)
46+
whenever(getProtectedCharacteristicsService.execute(hmppsId)).thenReturn(
47+
Response(
48+
data =
49+
PersonProtectedCharacteristics(35, "Female", "Unknown", "British", "British", "None", emptyList()),
50+
),
51+
)
52+
}
53+
54+
it("returns a 200 OK status code") {
55+
val result = mockMvc.performAuthorised(path)
56+
57+
result.response.status.shouldBe(HttpStatus.OK.value())
58+
}
59+
60+
it("gets the offences for a person with the matching ID") {
61+
mockMvc.performAuthorised(path)
62+
63+
verify(getProtectedCharacteristicsService, VerificationModeFactory.times(1)).execute(hmppsId)
64+
}
65+
66+
it("returns the offences for a person with the matching ID") {
67+
val result = mockMvc.performAuthorised(path)
68+
69+
result.response.contentAsString.shouldContain(
70+
"""
71+
"data":
72+
{
73+
"age": 35,
74+
"gender": "Female",
75+
"sexualOrientation": "Unknown",
76+
"ethnicity": "British",
77+
"nationality": "British",
78+
"religion": "None",
79+
"disabilities": [],
80+
"maritalStatus": null,
81+
"reasonableAdjustments": [
82+
]
83+
}
84+
85+
""".removeWhitespaceAndNewlines(),
86+
)
87+
}
88+
it("logs audit") {
89+
mockMvc.performAuthorised(path)
90+
91+
verify(
92+
auditService,
93+
VerificationModeFactory.times(1),
94+
).createEvent("GET_PERSON_PROTECTED_CHARACTERISTICS", mapOf("hmppsId" to hmppsId))
95+
}
96+
97+
it("returns an empty list embedded in a JSON object when no offences are found") {
98+
val hmppsIdForPersonWithNoOffences = "0000/11111A"
99+
val encodedHmppsIdForPersonWithNoOffences =
100+
URLEncoder.encode(hmppsIdForPersonWithNoOffences, StandardCharsets.UTF_8)
101+
val offencesPath = "/v1/persons/$encodedHmppsIdForPersonWithNoOffences/protected-characteristics"
102+
103+
whenever(getProtectedCharacteristicsService.execute(hmppsIdForPersonWithNoOffences)).thenReturn(
104+
Response(
105+
data = null,
106+
),
107+
)
108+
109+
val result = mockMvc.performAuthorised(offencesPath)
110+
111+
result.response.contentAsString.shouldContain("\"data\":null".removeWhitespaceAndNewlines())
112+
}
113+
114+
it("returns a 404 NOT FOUND status code when person isn't found in the upstream API") {
115+
whenever(getProtectedCharacteristicsService.execute(hmppsId)).thenReturn(
116+
Response(
117+
data = null,
118+
errors =
119+
listOf(
120+
UpstreamApiError(
121+
causedBy = UpstreamApi.NOMIS,
122+
type = UpstreamApiError.Type.ENTITY_NOT_FOUND,
123+
),
124+
),
125+
),
126+
)
127+
128+
val result = mockMvc.performAuthorised(path)
129+
130+
result.response.status.shouldBe(HttpStatus.NOT_FOUND.value())
131+
}
132+
133+
it("fails with the appropriate error when an upstream service is down") {
134+
whenever(getProtectedCharacteristicsService.execute(hmppsId)).doThrow(
135+
WebClientResponseException(500, "MockError", null, null, null, null),
136+
)
137+
138+
val response = mockMvc.performAuthorised("$path?page=1&perPage=10")
139+
140+
assert(response.response.status == 500)
141+
assert(
142+
response.response.contentAsString.equals(
143+
"{\"status\":500,\"errorCode\":null,\"userMessage\":\"500 MockError\",\"developerMessage\":\"Unable to complete request as an upstream service is not responding\",\"moreInfo\":null}",
144+
),
145+
)
146+
}
147+
}
148+
},
149+
)

src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/nomis/GetAddressesForPersonTest.kt

+7-7
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ class GetAddressesForPersonTest(
3131
{
3232
val nomisApiMockServer = NomisApiMockServer()
3333
val offenderNo = "abc123"
34-
34+
val addressPath = "/api/offenders/$offenderNo/addresses"
3535
beforeEach {
3636
nomisApiMockServer.start()
37-
nomisApiMockServer.stubGetOffenderAddresses(
38-
offenderNo,
37+
nomisApiMockServer.stubNomisApiResponse(
38+
addressPath,
3939
"""
4040
[
4141
{
@@ -95,16 +95,16 @@ class GetAddressesForPersonTest(
9595
}
9696

9797
it("returns an empty list when no addresses are found") {
98-
nomisApiMockServer.stubGetOffenderAddresses(offenderNo, "[]")
98+
nomisApiMockServer.stubNomisApiResponse(addressPath, "[]")
9999

100100
val response = nomisGateway.getAddressesForPerson(offenderNo)
101101

102102
response.data.shouldBeEmpty()
103103
}
104104

105105
it("returns an error when 404 NOT FOUND is returned") {
106-
nomisApiMockServer.stubGetOffenderAddresses(
107-
offenderNo,
106+
nomisApiMockServer.stubNomisApiResponse(
107+
addressPath,
108108
"""
109109
{
110110
"developerMessage": "cannot find person"
@@ -113,7 +113,7 @@ class GetAddressesForPersonTest(
113113
HttpStatus.NOT_FOUND,
114114
)
115115

116-
val response = nomisGateway.getAddressesForPerson(offenderNo)
116+
val response = nomisGateway.getAddressesForPerson(addressPath)
117117

118118
response.hasError(UpstreamApiError.Type.ENTITY_NOT_FOUND).shouldBeTrue()
119119
}

src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/nomis/GetAlertsForPersonTest.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ class GetAlertsForPersonTest(
3535
{
3636
val nomisApiMockServer = NomisApiMockServer()
3737
val offenderNo = "zyx987"
38-
38+
val alertsPath = "/api/offenders/$offenderNo/alerts/v2"
3939
beforeEach {
4040
nomisApiMockServer.start()
41-
nomisApiMockServer.stubGetAlertsForPerson(
42-
offenderNo,
41+
nomisApiMockServer.stubNomisApiResponse(
42+
alertsPath,
4343
"""
4444
[
4545
{
@@ -82,15 +82,15 @@ class GetAlertsForPersonTest(
8282
}
8383

8484
it("returns a person with an empty list of alerts when no alerts are found") {
85-
nomisApiMockServer.stubGetAlertsForPerson(offenderNo, "[]")
85+
nomisApiMockServer.stubNomisApiResponse(alertsPath, "[]")
8686

8787
val response = nomisGateway.getAlertsForPerson(offenderNo)
8888

8989
response.data.shouldBeEmpty()
9090
}
9191

9292
it("returns an error when 404 Not Found is returned because no person is found") {
93-
nomisApiMockServer.stubGetAlertsForPerson(offenderNo, "", HttpStatus.NOT_FOUND)
93+
nomisApiMockServer.stubNomisApiResponse(alertsPath, "", HttpStatus.NOT_FOUND)
9494

9595
val response = nomisGateway.getAlertsForPerson(offenderNo)
9696

src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/nomis/GetImageMetadataForPersonTest.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ class GetImageMetadataForPersonTest(
3333
DescribeSpec({
3434
val nomisApiMockServer = NomisApiMockServer()
3535
val offenderNo = "abc123"
36-
36+
val imagePath = "/api/images/offenders/$offenderNo"
3737
beforeEach {
3838
nomisApiMockServer.start()
39-
nomisApiMockServer.stubGetOffenderImageDetails(
40-
offenderNo,
39+
nomisApiMockServer.stubNomisApiResponse(
40+
imagePath,
4141
"""
4242
[
4343
{
@@ -77,15 +77,15 @@ class GetImageMetadataForPersonTest(
7777
}
7878

7979
it("returns a person without image metadata when no images are found") {
80-
nomisApiMockServer.stubGetOffenderImageDetails(offenderNo, "[]")
80+
nomisApiMockServer.stubNomisApiResponse(imagePath, "[]")
8181

8282
val response = nomisGateway.getImageMetadataForPerson(offenderNo)
8383

8484
response.data.shouldBeEmpty()
8585
}
8686

8787
it("returns an error when 404 Not Found is returned") {
88-
nomisApiMockServer.stubGetOffenderImageDetails(offenderNo, "", HttpStatus.NOT_FOUND)
88+
nomisApiMockServer.stubNomisApiResponse(imagePath, "", HttpStatus.NOT_FOUND)
8989

9090
val response = nomisGateway.getImageMetadataForPerson(offenderNo)
9191

src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/nomis/GetLatestSentenceAdjustmentsForPersonTest.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ class GetLatestSentenceAdjustmentsForPersonTest(
3030
{
3131
val nomisApiMockServer = NomisApiMockServer()
3232
val offenderNo = "abc123"
33-
33+
val sentenceSummaryPath = "/api/offenders/$offenderNo/booking/latest/sentence-summary"
3434
beforeEach {
3535
nomisApiMockServer.start()
36-
nomisApiMockServer.stubGetLatestSentenceAdjustmentsForPerson(
37-
offenderNo,
36+
nomisApiMockServer.stubNomisApiResponse(
37+
sentenceSummaryPath,
3838
"""
3939
{
4040
"prisonerNumber": "A1234AA",
@@ -86,8 +86,8 @@ class GetLatestSentenceAdjustmentsForPersonTest(
8686
}
8787

8888
it("returns an error when 404 NOT FOUND is returned") {
89-
nomisApiMockServer.stubGetLatestSentenceAdjustmentsForPerson(
90-
offenderNo,
89+
nomisApiMockServer.stubNomisApiResponse(
90+
sentenceSummaryPath,
9191
"""
9292
{
9393
"developerMessage": "cannot find person"

src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/nomis/GetLatestSentenceKeyDatesForPersonTest.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ class GetLatestSentenceKeyDatesForPersonTest(
3131
{
3232
val nomisApiMockServer = NomisApiMockServer()
3333
val offenderNo = "abc123"
34-
34+
val sentencePath = "/api/offenders/$offenderNo/sentences"
3535
beforeEach {
3636
nomisApiMockServer.start()
37-
nomisApiMockServer.stubGetLatestSentenceKeyDatesForPerson(
38-
offenderNo,
37+
nomisApiMockServer.stubNomisApiResponse(
38+
sentencePath,
3939
"""
4040
{
4141
"sentenceDetail": {
@@ -180,8 +180,8 @@ class GetLatestSentenceKeyDatesForPersonTest(
180180
}
181181

182182
it("returns an error when 404 NOT FOUND is returned") {
183-
nomisApiMockServer.stubGetLatestSentenceKeyDatesForPerson(
184-
offenderNo,
183+
nomisApiMockServer.stubNomisApiResponse(
184+
sentencePath,
185185
"""
186186
{
187187
"developerMessage": "cannot find person"

src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/nomis/GetOffencesForPersonTest.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ class GetOffencesForPersonTest(
3535
{
3636
val nomisApiMockServer = NomisApiMockServer()
3737
val offenderNo = "zyx987"
38-
38+
val offenceHistoryPath = "/api/bookings/offenderNo/$offenderNo/offenceHistory"
3939
beforeEach {
4040
nomisApiMockServer.start()
41-
nomisApiMockServer.stubGetOffencesForPerson(
42-
offenderNo,
41+
nomisApiMockServer.stubNomisApiResponse(
42+
offenceHistoryPath,
4343
"""
4444
[
4545
{
@@ -84,15 +84,15 @@ class GetOffencesForPersonTest(
8484
}
8585

8686
it("returns a person with an empty list of offences when no offences are found") {
87-
nomisApiMockServer.stubGetOffencesForPerson(offenderNo, "[]")
87+
nomisApiMockServer.stubNomisApiResponse(offenceHistoryPath, "[]")
8888

8989
val response = nomisGateway.getOffencesForPerson(offenderNo)
9090

9191
response.data.shouldBeEmpty()
9292
}
9393

9494
it("returns an error when 404 Not Found is returned because no person is found") {
95-
nomisApiMockServer.stubGetOffencesForPerson(offenderNo, "", HttpStatus.NOT_FOUND)
95+
nomisApiMockServer.stubNomisApiResponse(offenceHistoryPath, "", HttpStatus.NOT_FOUND)
9696

9797
val response = nomisGateway.getOffencesForPerson(offenderNo)
9898

0 commit comments

Comments
 (0)