Skip to content

Commit 6ebcb53

Browse files
[HIA-721]
WIP Adding controller class and tests
1 parent 49e0f57 commit 6ebcb53

File tree

3 files changed

+185
-5
lines changed

3 files changed

+185
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,46 @@
11
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1
22

3+
import org.springframework.beans.factory.annotation.Autowired
34
import org.springframework.boot.context.properties.EnableConfigurationProperties
45
import org.springframework.web.bind.annotation.PathVariable
56
import org.springframework.web.bind.annotation.RequestMapping
7+
import org.springframework.web.bind.annotation.RequestParam
68
import org.springframework.web.bind.annotation.RestController
79
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.AuthorisationConfig
8-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response
10+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException
11+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters
912
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.RiskManagementPlan
13+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi
14+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError
15+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetRiskManagementPlansForCrnService
16+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService
17+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.PaginatedResponse
18+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.paginateWith
1019

1120
@RestController
1221
@EnableConfigurationProperties(AuthorisationConfig::class)
13-
class RiskManagementController {
22+
class RiskManagementController (
23+
@Autowired val getRiskManagementPlansForCrnService: GetRiskManagementPlansForCrnService,
24+
@Autowired val auditService: AuditService
25+
) {
26+
1427
@RequestMapping("/v1/persons/{encodedHmppsId}/risk-management-plan")
1528
fun getRiskManagementPlans(
1629
@PathVariable encodedHmppsId: String,
17-
): Response<List<RiskManagementPlan>> {
18-
return Response(emptyList(), emptyList())
30+
@RequestParam(required = false, defaultValue = "1", name = "page") page: Int,
31+
@RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int,
32+
): PaginatedResponse<RiskManagementPlan> {
33+
val hmppsId = encodedHmppsId.decodeUrlCharacters()
34+
val response = getRiskManagementPlansForCrnService.execute(hmppsId)
35+
if (response.data.isNullOrEmpty()) {
36+
if (response.hasErrorCausedBy(UpstreamApiError.Type.ENTITY_NOT_FOUND, causedBy = UpstreamApi.RISK_MANAGEMENT_PLAN)) {
37+
throw EntityNotFoundException("Could not find person with id: $hmppsId")
38+
}
39+
return emptyList<RiskManagementPlan>().paginateWith(page, perPage)
40+
}
41+
42+
auditService.createEvent("GET_RISK_MANAGEMENT_PLANS", mapOf("hmppsId" to hmppsId))
43+
return response.data.paginateWith(page, perPage)
1944
}
45+
2046
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1
2+
3+
import io.kotest.assertions.json.shouldContainJsonKeyValue
4+
import io.kotest.core.spec.style.DescribeSpec
5+
import io.kotest.matchers.shouldBe
6+
import org.mockito.Mockito
7+
import org.mockito.internal.verification.VerificationModeFactory
8+
import org.mockito.kotlin.any
9+
import org.mockito.kotlin.doThrow
10+
import org.mockito.kotlin.times
11+
import org.mockito.kotlin.verify
12+
import org.mockito.kotlin.whenever
13+
import org.springframework.beans.factory.annotation.Autowired
14+
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
15+
import org.springframework.boot.test.mock.mockito.MockBean
16+
import org.springframework.http.HttpStatus
17+
import org.springframework.test.context.ActiveProfiles
18+
import org.springframework.test.web.servlet.MockMvc
19+
import org.springframework.web.reactive.function.client.WebClientResponseException
20+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.helpers.IntegrationAPIMockMvc
21+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response
22+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.RiskManagementPlan
23+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi
24+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError
25+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetRiskManagementPlansForCrnService
26+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService
27+
import java.net.URLEncoder
28+
import java.nio.charset.StandardCharsets
29+
30+
@WebMvcTest(controllers = [RiskManagementController::class])
31+
@ActiveProfiles("test")
32+
class RiskManagementControllerTest (
33+
@Autowired var springMockMvc: MockMvc,
34+
@MockBean val getRiskManagementService: GetRiskManagementPlansForCrnService,
35+
@MockBean val auditService: AuditService,
36+
) : DescribeSpec({
37+
val hmppsId = "D1974X"
38+
val badHmppsId = "Not a real CRN"
39+
val encodedHmppsId = URLEncoder.encode(hmppsId, StandardCharsets.UTF_8)
40+
val encodedBadHmppsId = URLEncoder.encode(badHmppsId, StandardCharsets.UTF_8)
41+
val basePath = "/v1/persons/hmppsId/risk-management-plan"
42+
val mockMvc = IntegrationAPIMockMvc(springMockMvc)
43+
44+
describe("GET $basePath") {
45+
beforeTest {
46+
whenever(getRiskManagementService.execute(hmppsId)).thenReturn(
47+
Response(
48+
data = listOf(
49+
RiskManagementPlan(
50+
assessmentId = "123450",
51+
dateCompleted = "2024-05-04T01 =04 =20",
52+
initiationDate = "2024-05-04T01 =04 =20",
53+
assessmentStatus = "string",
54+
assessmentType = "string",
55+
keyInformationCurrentSituation = "string",
56+
furtherConsiderationsCurrentSituation = "string",
57+
supervision = "string",
58+
monitoringAndControl = "string",
59+
interventionsAndTreatment = "string",
60+
victimSafetyPlanning = "string",
61+
latestSignLockDate = "2024-05-04T01 =04 =20",
62+
latestCompleteDate = "2024-05-04T01 =04 =20"
63+
),
64+
RiskManagementPlan(
65+
assessmentId = "123451",
66+
dateCompleted = "2024-05-04T01 =04 =20",
67+
initiationDate = "2024-05-04T01 =04 =20",
68+
assessmentStatus = "string",
69+
assessmentType = "string",
70+
keyInformationCurrentSituation = "string",
71+
furtherConsiderationsCurrentSituation = "string",
72+
supervision = "string",
73+
monitoringAndControl = "string",
74+
interventionsAndTreatment = "string",
75+
victimSafetyPlanning = "string",
76+
latestSignLockDate = "2024-05-04T01 =04 =20",
77+
latestCompleteDate = "2024-05-04T01 =04 =20"
78+
)
79+
)
80+
)
81+
)
82+
whenever(getRiskManagementService.execute(hmppsId)).thenReturn(
83+
Response(
84+
null,
85+
errors = listOf(UpstreamApiError(
86+
type = UpstreamApiError.Type.ENTITY_NOT_FOUND,
87+
causedBy = UpstreamApi.RISK_MANAGEMENT_PLAN,
88+
description = "Mock Error"
89+
))
90+
)
91+
)
92+
}
93+
94+
it("Returns 200 OK") {
95+
val result = mockMvc.performAuthorised("/v1/persons/$encodedHmppsId/risk-management-plan")
96+
result.response.status.shouldBe(HttpStatus.OK.value())
97+
}
98+
99+
it("Gets a risk management plan") {
100+
mockMvc.performAuthorised("/v1/persons/$encodedHmppsId/risk-management-plan")
101+
verify(getRiskManagementService, times(1)).execute(hmppsId)
102+
}
103+
104+
it("Gets an error if provided ID has no risk management plan") {
105+
val result = mockMvc.performAuthorised("/v1/persons/$encodedBadHmppsId/risk-management-plan")
106+
verify(getRiskManagementService, times(1)).execute(hmppsId)
107+
assert( result.response.status == 404 )
108+
}
109+
110+
it("logs audit") {
111+
mockMvc.performAuthorised("/v1/persons/$encodedHmppsId/risk-management-plan")
112+
verify(
113+
auditService,
114+
VerificationModeFactory.times(1),
115+
).createEvent(
116+
"GET_RISK_MANAGEMENT_PLANS",
117+
mapOf("hmppsId" to hmppsId),
118+
)
119+
}
120+
121+
122+
it("returns paginated result") {
123+
val result = mockMvc.performAuthorised("/v1/persons/$encodedHmppsId/risk-management-plan")
124+
125+
result.response.contentAsString.shouldContainJsonKeyValue("$.pagination.page", 1)
126+
result.response.contentAsString.shouldContainJsonKeyValue("$.pagination.totalPages", 1)
127+
}
128+
}
129+
130+
describe("GET risk management plans returns Internal Server Error when Upstream api throws an unexpected error") {
131+
beforeTest {
132+
Mockito.reset(getRiskManagementService)
133+
Mockito.reset(auditService)
134+
}
135+
136+
it("fails with the appropriate error when an upstream service is down") {
137+
whenever(getRiskManagementService.execute(any())).doThrow(
138+
WebClientResponseException(500, "MockError", null, null, null, null),
139+
)
140+
141+
val response =
142+
mockMvc.performAuthorised(
143+
"/v1/persons/$encodedHmppsId/risk-management-plan",
144+
)
145+
146+
assert(response.response.status == 500)
147+
assert(
148+
response.response.contentAsString.equals(
149+
"{\"status\":500,\"errorCode\":null,\"userMessage\":\"500 MockError\",\"developerMessage\":\"Unable to complete request as an upstream service is not responding\",\"moreInfo\":null}",
150+
),
151+
)
152+
}
153+
}
154+
})

src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetRiskManagementPlansForCrnServiceTest.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class GetRiskManagementPlansForCrnServiceTest (
5959
latestCompleteDate = "2024-05-04T01 =04 =20"
6060
),
6161
CrnRiskManagementPlan(
62-
assessmentId = "123450",
62+
assessmentId = "123451",
6363
dateCompleted = "2024-05-04T01 =04 =20",
6464
partcompStatus = "string",
6565
initiationDate = "2024-05-04T01 =04 =20",

0 commit comments

Comments
 (0)