From ef72abe1ad091ba6b1685516ce07673ead460f02 Mon Sep 17 00:00:00 2001 From: Chiara Date: Thu, 8 Feb 2024 11:11:17 +0000 Subject: [PATCH 01/20] HIA-574 -- New local image for case-notes --- Dockerfile.setup-case-notes-api | 9 +++++++++ docker-compose.yml | 10 ++++++++++ .../prismMocks/case-notes-api-docs.json | 1 + src/main/resources/application-local-docker.yml | 2 ++ src/main/resources/application-local.yml | 2 ++ src/main/resources/application-test.yml | 3 ++- src/main/resources/application.yml | 2 ++ 7 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Dockerfile.setup-case-notes-api create mode 100644 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/prismMocks/case-notes-api-docs.json diff --git a/Dockerfile.setup-case-notes-api b/Dockerfile.setup-case-notes-api new file mode 100644 index 000000000..153bde133 --- /dev/null +++ b/Dockerfile.setup-case-notes-api @@ -0,0 +1,9 @@ +FROM node:current-alpine3.17 + +RUN apk update && apk add bash + +COPY src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/prismMocks/case-notes-api-docs.json /case-notes-api-docs.json + +RUN npm install -g @stoplight/prism-cli + +CMD prism mock -p 4010 -h 0.0.0.0 /case-notes-api-docs.json diff --git a/docker-compose.yml b/docker-compose.yml index 9cb91f349..6cd6e600e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -114,6 +114,16 @@ services: ports: - '4070:4010' + case-notes-api: + build: + context: . + dockerfile: Dockerfile.setup-case-notes-api + container_name: case-notes-api + healthcheck: + test: 'wget --header="Authorization: Bearer abc" http://0.0.0.0:4010/case-notes/1234 -O /dev/null' + ports: + - '4080:4010' + local-stack-aws: image: localstack/localstack:0.14.0 container_name: local-stack-aws diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/prismMocks/case-notes-api-docs.json b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/prismMocks/case-notes-api-docs.json new file mode 100644 index 000000000..44f81a53e --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/prismMocks/case-notes-api-docs.json @@ -0,0 +1 @@ +{"openapi":"3.0.1","info":{"title":"HMPPS Offender Case Notes","description":"HMPPS Offender Case Notes API","contact":{"name":"HMPPS Digital Studio","email":"feedback@digital.justice.gov.uk"},"version":"2024-02-06.5013.89d6695"},"servers":[{"url":"https://offender-case-notes.service.justice.gov.uk","description":"Prod"},{"url":"https://preprod.offender-case-notes.service.justice.gov.uk","description":"PreProd"},{"url":"https://dev.offender-case-notes.service.justice.gov.uk","description":"Development"},{"url":"http://localhost:8080","description":"Local"}],"tags":[{"name":"publish-notes","description":"Prison Notes Controller"},{"name":"case-notes","description":"Case Note Controller"}],"paths":{"/queue-admin/retry-dlq/{dlqName}":{"put":{"tags":["hmpps-queue-resource"],"operationId":"retryDlq","parameters":[{"name":"dlqName","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RetryDlqResult"}}}}}}},"/queue-admin/retry-all-dlqs":{"put":{"tags":["hmpps-queue-resource"],"operationId":"retryAllDlqs","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RetryDlqResult"}}}}}}}},"/queue-admin/purge-queue/{queueName}":{"put":{"tags":["hmpps-queue-resource"],"operationId":"purgeQueue","parameters":[{"name":"queueName","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PurgeQueueResult"}}}}}}},"/case-notes/{offenderIdentifier}/{caseNoteIdentifier}":{"get":{"tags":["case-notes"],"summary":"Retrieves a case note","operationId":"getCaseNote","parameters":[{"name":"offenderIdentifier","in":"path","description":"Offender Identifier","required":true,"schema":{"type":"string"},"example":"A1234AA"},{"name":"caseNoteIdentifier","in":"path","description":"Case Note Id","required":true,"schema":{"type":"string"},"example":"518b2200-6489-4c77-8514-10cf80ccd488"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseNote"}}}},"404":{"description":"Offender or case note not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"tags":["case-notes"],"summary":"Amend Case Note for offender","description":"Amend a case note information adds and additional entry to the note","operationId":"amendCaseNote","parameters":[{"name":"offenderIdentifier","in":"path","description":"Offender Identifier","required":true,"schema":{"type":"string"},"example":"A1234AA"},{"name":"caseNoteIdentifier","in":"path","description":"Case Note Id","required":true,"schema":{"type":"string"},"example":"518b2200-6489-4c77-8514-10cf80ccd488"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCaseNote"}}},"required":true},"responses":{"404":{"description":"No case notes where found for this offender and case note id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"The Case Note has been recorded. The updated object is returned including the status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseNote"}}}}}}},"/case-notes/types/{parentType}":{"put":{"tags":["case-notes"],"summary":"Update Case Note Type","description":"Creates a new case note type","operationId":"updateCaseNoteType","parameters":[{"name":"parentType","in":"path","description":"Parent Case Note Type","required":true,"schema":{"type":"string"},"example":"OBS"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCaseNoteType"}}},"required":true},"responses":{"404":{"description":"The case note type is not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"The case note type has been updated. The updated object is returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseNoteTypeDto"}}}}}},"post":{"tags":["case-notes"],"summary":"Add New Case Note Sub Type","description":"Creates a new case note sub type","operationId":"createCaseNoteSubType","parameters":[{"name":"parentType","in":"path","description":"Parent Case Note Type","required":true,"schema":{"type":"string"},"example":"GEN"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCaseNoteType"}}},"required":true},"responses":{"201":{"description":"The Case Note Sub Type has been recorded. The updated object is returned including the status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseNoteTypeDto"}}}},"409":{"description":"The case note sub type has already been recorded. The current unmodified object (including status) is returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/case-notes/types/{parentType}/{subType}":{"put":{"tags":["case-notes"],"summary":"Update Case Note Sub Type","description":"Creates a new case note sub type","operationId":"updateCaseNoteSubType","parameters":[{"name":"parentType","in":"path","description":"Parent Case Note Type","required":true,"schema":{"type":"string"},"example":"OBS"},{"name":"subType","in":"path","description":"Sub Case Note Type","required":true,"schema":{"type":"string"},"example":"GEN"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCaseNoteType"}}},"required":true},"responses":{"404":{"description":"The case note sub type is not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"The case note sub type update has been updated. The updated object is returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseNoteTypeDto"}}}}}}},"/publish-notes":{"post":{"tags":["publish-notes"],"summary":"Publish sensitive case notes","operationId":"publishCaseNotes","parameters":[{"name":"fromDateTime","in":"query","description":"A timestamp that indicates the earliest record required","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"toDateTime","in":"query","description":"A timestamp that indicates the latest record required","required":true,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Number of notes to be published (asynchronously)","content":{"application/json":{"schema":{"type":"integer","format":"int32"}}}}}}},"/case-notes/{offenderIdentifier}":{"get":{"tags":["case-notes"],"summary":"Retrieves a list of case notes","operationId":"getCaseNotes","parameters":[{"name":"offenderIdentifier","in":"path","description":"Offender Identifier","required":true,"schema":{"type":"string"},"example":"A1234AA"},{"name":"filter","in":"query","description":"Optionally specify a case note filter","required":true,"schema":{"$ref":"#/components/schemas/CaseNoteFilter"}},{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageCaseNote"}}}},"404":{"description":"Offender not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["case-notes"],"summary":"Add Case Note for offender","description":"Creates a note for a specific type/subType","operationId":"createCaseNote","parameters":[{"name":"offenderIdentifier","in":"path","description":"Offender Identifier","required":true,"schema":{"type":"string"},"example":"A1234AA"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCaseNote"}}},"required":true},"responses":{"201":{"description":"The Case Note has been recorded. The updated object is returned including the status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseNote"}}}},"409":{"description":"The case note has already been recorded under the booking. The current unmodified object (including status) is returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/case-notes/types":{"get":{"tags":["case-notes"],"summary":"Retrieves a list of case note types","operationId":"getCaseNoteTypes","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CaseNoteTypeDto"}}}}},"404":{"description":"Case notes types not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["case-notes"],"summary":"Add New Case Note Type","description":"Creates a new case note type","operationId":"createCaseNoteType","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCaseNoteType"}}},"required":true},"responses":{"409":{"description":"The case note type has already been recorded. The current unmodified object (including status) is returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"The Case Note Type has been recorded. The updated object is returned including the status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseNoteTypeDto"}}}}}}},"/queue-admin/get-dlq-messages/{dlqName}":{"get":{"tags":["hmpps-queue-resource"],"operationId":"getDlqMessages","parameters":[{"name":"dlqName","in":"path","required":true,"schema":{"type":"string"}},{"name":"maxMessages","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":100}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GetDlqResult"}}}}}}},"/case-notes/types-for-user":{"get":{"tags":["case-notes"],"summary":"Retrieves a list of case note types for this user","operationId":"getUserCaseNoteTypes","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CaseNoteTypeDto"}}}}},"404":{"description":"Case notes types not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/case-notes/{offenderIdentifier}/{caseNoteId}":{"delete":{"tags":["case-notes"],"summary":"Deletes a case note","operationId":"softDeleteCaseNote","parameters":[{"name":"offenderIdentifier","in":"path","description":"Offender Identifier","required":true,"schema":{"type":"string"},"example":"A1234AA"},{"name":"caseNoteId","in":"path","description":"Case Note Id","required":true,"schema":{"type":"string"},"example":"518b2200-6489-4c77-8514-10cf80ccd488"}],"responses":{"200":{"description":"OK"},"404":{"description":"Offender or case note not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/case-notes/amendment/{offenderIdentifier}/{caseNoteAmendmentId}":{"delete":{"tags":["case-notes"],"summary":"Deletes a case note amendment","operationId":"softDeleteCaseNoteAmendment","parameters":[{"name":"offenderIdentifier","in":"path","description":"Offender Identifier","required":true,"schema":{"type":"string"},"example":"A1234AA"},{"name":"caseNoteAmendmentId","in":"path","description":"Case Note Amendment Id","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"200":{"description":"OK"},"404":{"description":"Offender or case note not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"DlqMessage":{"required":["body","messageId"],"type":"object","properties":{"body":{"type":"object","additionalProperties":{"type":"object"}},"messageId":{"type":"string"}}},"RetryDlqResult":{"required":["messages","messagesFoundCount"],"type":"object","properties":{"messagesFoundCount":{"type":"integer","format":"int32"},"messages":{"type":"array","items":{"$ref":"#/components/schemas/DlqMessage"}}}},"PurgeQueueResult":{"required":["messagesFoundCount"],"type":"object","properties":{"messagesFoundCount":{"type":"integer","format":"int32"}}},"UpdateCaseNote":{"required":["text"],"type":"object","properties":{"text":{"type":"string","description":"Text of case note","example":"This is a case note message"}},"description":"Amend a Case Note"},"ErrorResponse":{"required":["status"],"type":"object","properties":{"status":{"type":"integer","format":"int32"},"errorCode":{"type":"integer","format":"int32"},"userMessage":{"type":"string"},"developerMessage":{"type":"string"},"moreInfo":{"type":"string"}}},"CaseNote":{"required":["amendments","authorName","authorUserId","caseNoteId","creationDateTime","eventId","occurrenceDateTime","offenderIdentifier","sensitive","source","subType","subTypeDescription","text","type","typeDescription"],"type":"object","properties":{"caseNoteId":{"type":"string","description":"Case Note Id (unique)","example":"12311312"},"offenderIdentifier":{"type":"string","description":"Offender Unique Identifier","example":"A1234AA"},"type":{"type":"string","description":"Case Note Type","example":"KA"},"typeDescription":{"type":"string","description":"Case Note Type Description","example":"Key Worker"},"subType":{"type":"string","description":"Case Note Sub Type","example":"KS"},"subTypeDescription":{"type":"string","description":"Case Note Sub Type Description","example":"Key Worker Session"},"source":{"type":"string","description":"Source Type","example":"INST"},"creationDateTime":{"type":"string","description":"Date and Time of Case Note creation","format":"date-time"},"occurrenceDateTime":{"type":"string","description":"Date and Time of when case note contact with offender was made","format":"date-time"},"authorName":{"type":"string","description":"Full name of case note author","example":"John Smith"},"authorUserId":{"type":"string","description":"User Id of case note author - staffId for nomis users, userId for auth users","example":"12345"},"text":{"type":"string","description":"Case Note Text","example":"This is some text"},"locationId":{"type":"string","description":"Location Id representing where Case Note was made.","example":"MDI"},"eventId":{"type":"integer","description":"Delius number representation of the case note id - will be negative for sensitive case note types","format":"int32","example":-23},"sensitive":{"type":"boolean","description":"Sensitive Note","example":true},"amendments":{"type":"array","description":"Ordered list of amendments to the case note (oldest first)","items":{"$ref":"#/components/schemas/CaseNoteAmendment"}}},"description":"Case Note"},"CaseNoteAmendment":{"required":["additionalNoteText","authorName","authorUserId","authorUserName","caseNoteAmendmentId","creationDateTime"],"type":"object","properties":{"caseNoteAmendmentId":{"type":"integer","description":"Amendment Case Note Id (unique)","format":"int64","example":123232},"creationDateTime":{"type":"string","description":"Date and Time of Case Note creation","format":"date-time"},"authorUserName":{"type":"string","description":"Username of the user amending the case note","example":"USER1"},"authorName":{"type":"string","description":"Name of the user amending the case note","example":"Mickey Mouse"},"authorUserId":{"type":"string","description":"User Id of the user amending the case note - staffId for nomis users, userId for auth users","example":"12345"},"additionalNoteText":{"type":"string","description":"Additional Case Note Information","example":"Some Additional Text"}},"description":"Case Note Amendment"},"UpdateCaseNoteType":{"required":["description"],"type":"object","properties":{"description":{"type":"string","description":"Type Description","example":"General Note Type"},"active":{"type":"boolean","description":"Active Type","example":true},"sensitive":{"type":"boolean","description":"Sensitive Case Note Type, default true","example":true},"restrictedUse":{"type":"boolean","description":"Restricted Use, default true","example":true}},"description":"Update a Case Note Type"},"CaseNoteTypeDto":{"required":["activeFlag","code","description"],"type":"object","properties":{"code":{"type":"string","description":"Case Note Code","example":"OBSERVE"},"description":{"type":"string","description":"Case Note description.","example":"Observations"},"activeFlag":{"type":"string","description":"Active indicator flag.","example":"Y","enum":["Y,N"]},"subCodes":{"type":"array","description":"List of case note sub types","nullable":true,"items":{"$ref":"#/components/schemas/CaseNoteTypeDto"}},"source":{"type":"string","description":"Source of Case Note Type, legacy case note are null","example":"OCNS"},"sensitive":{"type":"boolean","description":"Indicates the type of note is sensitive","example":true},"restrictedUse":{"type":"boolean","description":"Indicates the type of note can only be created by a sub-set of users (e.g. POMs)","example":true}},"description":"Case Note Type"},"NewCaseNote":{"required":["locationId","occurrenceDateTime","subType","text","type"],"type":"object","properties":{"locationId":{"type":"string","description":"Location where case note was made, if blank it will be looked up in Nomis","example":"MDI"},"type":{"type":"string","description":"Type of case note","example":"GEN"},"subType":{"type":"string","description":"Sub Type of case note","example":"OBS"},"occurrenceDateTime":{"type":"string","description":"Occurrence time of case note","format":"date-time"},"text":{"type":"string","description":"Text of case note","example":"This is a case note message"}},"description":"Create a Case Note"},"NewCaseNoteType":{"required":["description","type"],"type":"object","properties":{"type":{"type":"string","description":"Type of case note","example":"GEN"},"description":{"type":"string","description":"Type Description","example":"General Note Type"},"active":{"type":"boolean","description":"Active Type, default true","example":true},"sensitive":{"type":"boolean","description":"Sensitive Case Note Type, default true","example":true},"restrictedUse":{"type":"boolean","description":"Restricted Use, default true","example":true}},"description":"Create a New Case Note Type"},"GetDlqResult":{"required":["messages","messagesFoundCount","messagesReturnedCount"],"type":"object","properties":{"messagesFoundCount":{"type":"integer","format":"int32"},"messagesReturnedCount":{"type":"integer","format":"int32"},"messages":{"type":"array","items":{"$ref":"#/components/schemas/DlqMessage"}}}},"CaseNoteFilter":{"type":"object","properties":{"type":{"type":"string","description":"Filter by Case Note Type","example":"KA"},"subType":{"type":"string","description":"Filter by Case Note Sub Type","example":"KS"},"startDate":{"type":"string","description":"Filter case notes from this date","format":"date-time"},"endDate":{"type":"string","description":"Filter case notes up to this date","format":"date-time"},"locationId":{"type":"string","description":"Filter by the location","example":"MDI"},"authorUsername":{"type":"string","description":"Filter by username","example":"USER1"}},"description":"Case Note Filter"},"Pageable":{"type":"object","properties":{"page":{"minimum":0,"type":"integer","format":"int32"},"size":{"minimum":1,"type":"integer","format":"int32"},"sort":{"type":"array","items":{"type":"string"}}}},"PageCaseNote":{"type":"object","properties":{"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"first":{"type":"boolean"},"last":{"type":"boolean"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/CaseNote"}},"number":{"type":"integer","format":"int32"},"sort":{"$ref":"#/components/schemas/SortObject"},"numberOfElements":{"type":"integer","format":"int32"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"empty":{"type":"boolean"}}},"PageableObject":{"type":"object","properties":{"offset":{"type":"integer","format":"int64"},"sort":{"$ref":"#/components/schemas/SortObject"},"pageSize":{"type":"integer","format":"int32"},"unpaged":{"type":"boolean"},"pageNumber":{"type":"integer","format":"int32"},"paged":{"type":"boolean"}}},"SortObject":{"type":"object","properties":{"empty":{"type":"boolean"},"sorted":{"type":"boolean"},"unsorted":{"type":"boolean"}}}}}} diff --git a/src/main/resources/application-local-docker.yml b/src/main/resources/application-local-docker.yml index f45b4c6e8..7a622ecbe 100644 --- a/src/main/resources/application-local-docker.yml +++ b/src/main/resources/application-local-docker.yml @@ -15,6 +15,8 @@ services: base-url: http://adjudications-api:4010 create-and-vary-licence: base-url: http://create-and-vary-licence-api:4010 + case-notes: + base-url: http://case-notes-api:4010 hmpps-auth: base-url: http://hmpps-auth:8080 diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 0307814e9..0497773d6 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -17,6 +17,8 @@ services: base-url: http://localhost:4045 create-and-vary-licence: base-url: http://localhost:4070 + case-notes: + base-url: http://localhost:4080 hmpps.sqs: provider: localstack diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index 0166e7286..c9b24977c 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -26,6 +26,8 @@ services: base-url: http://localhost:4006 create-and-vary-licence: base-url: http://localhost:4007 + case-notes: + base-url: http://localhost:4008 hmpps.sqs: provider: localstack @@ -57,4 +59,3 @@ authorisation: - "/health/readiness" - "/health/liveness" - "/info" - - diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f8c191dea..1765d3fb8 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -71,6 +71,8 @@ services: base-url: http://localhost:4045 create-and-vary-licence: base-url: http://localhost:4070 + case-notes: + base-url: http://localhost:4080 sentry: traces-sample-rate: "0.05" From f68d51ec11f81f76ac79468732ff7b4e9935a723 Mon Sep 17 00:00:00 2001 From: Chiara Date: Thu, 8 Feb 2024 12:04:59 +0000 Subject: [PATCH 02/20] WIP - setting up gateway --- .../gateways/CaseNotesGateway.kt | 49 +++++++++++++++++++ .../models/hmpps/PageCaseNote.kt | 5 ++ .../models/hmpps/UpstreamApi.kt | 2 +- .../models/nomis/NomisPageCaseNote.kt | 11 +++++ .../caseNotes/CaseNotesGatewayTest.kt | 46 +++++++++++++++++ .../mockservers/CaseNotesApiMockServer.kt | 26 ++++++++++ 6 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt create mode 100644 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt create mode 100644 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt create mode 100644 src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt create mode 100644 src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/mockservers/CaseNotesApiMockServer.kt diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt new file mode 100644 index 000000000..f7c6b67c6 --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt @@ -0,0 +1,49 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Value +import org.springframework.http.HttpMethod +import org.springframework.stereotype.Component +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.WebClientWrapper +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisPageCaseNote + +@Component +class CaseNotesGateway(@Value("\${services.case-notes.base-url") baseUrl: String) { + private val webClient = WebClientWrapper(baseUrl) + + @Autowired + lateinit var hmppsAuthGateway: HmppsAuthGateway + + fun getCaseNotesForPerson(id: String): Response> { + val result = webClient.request( + HttpMethod.GET, + "/case-notes/$id", + authenticationHeader(), + UpstreamApi.CASE_NOTES, + ) + + return when (result) { + is WebClientWrapper.WebClientWrapperResponse.Success -> { + Response(data = result.data.map { it.toPageCaseNote() }) + } + + is WebClientWrapper.WebClientWrapperResponse.Error -> { + Response( + data = emptyList(), + errors = result.errors, + ) + } + } + } + + private fun authenticationHeader(): Map { + val token = hmppsAuthGateway.getClientToken("CaseNotes") + + return mapOf( + "Authorization" to "Bearer $token", + ) + } +} diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt new file mode 100644 index 000000000..9862396b3 --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt @@ -0,0 +1,5 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps + +data class PageCaseNote( + val caseNoteId: String? = null, +) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/UpstreamApi.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/UpstreamApi.kt index 1dfc669a8..a31fce3a9 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/UpstreamApi.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/UpstreamApi.kt @@ -1,5 +1,5 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps enum class UpstreamApi { - NOMIS, PRISONER_OFFENDER_SEARCH, PROBATION_OFFENDER_SEARCH, NDELIUS, ASSESS_RISKS_AND_NEEDS, ADJUDICATIONS, CVL, TEST + NOMIS, PRISONER_OFFENDER_SEARCH, PROBATION_OFFENDER_SEARCH, NDELIUS, ASSESS_RISKS_AND_NEEDS, ADJUDICATIONS, CVL, CASE_NOTES, TEST } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt new file mode 100644 index 000000000..2488e4e66 --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt @@ -0,0 +1,11 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis + +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote + +data class NomisPageCaseNote( + val caseNoteId: String, +) { + fun toPageCaseNote(): PageCaseNote = PageCaseNote( + caseNoteId = this.caseNoteId, + ) +} diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt new file mode 100644 index 000000000..07165fe9e --- /dev/null +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt @@ -0,0 +1,46 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.caseNotes + +import io.kotest.core.spec.style.DescribeSpec +import org.mockito.Mockito +import org.mockito.kotlin.whenever +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.context.ContextConfiguration +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.CaseNotesGateway +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.HmppsAuthGateway +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.mockservers.CaseNotesApiMockServer +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.mockservers.HmppsAuthMockServer + +@ActiveProfiles("test") +@ContextConfiguration( + initializers = [ConfigDataApplicationContextInitializer::class], + classes = [CaseNotesGateway::class], +) +class CaseNotesGatewayTest( + @MockBean val hmppsAuthGateway: HmppsAuthGateway, + val caseNotesGateway: CaseNotesGateway, +) : DescribeSpec( + { + val caseNotesApiMockServer = CaseNotesApiMockServer() + beforeEach { + caseNotesApiMockServer.start() + + Mockito.reset(hmppsAuthGateway) + whenever(hmppsAuthGateway.getClientToken("CaseNotes")).thenReturn( + HmppsAuthMockServer.TOKEN, + ) + } + + afterTest { + caseNotesApiMockServer.stop() + } + + it("authenticates using HMPPS Auth with credentials") { + caseNotesGateway.getCaseNotesForPerson(id = "123") + + org.mockito.kotlin.verify(hmppsAuthGateway, org.mockito.internal.verification.VerificationModeFactory.times(1)) + .getClientToken("CaseNotes") + } + }, +) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/mockservers/CaseNotesApiMockServer.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/mockservers/CaseNotesApiMockServer.kt new file mode 100644 index 000000000..cc2526fea --- /dev/null +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/mockservers/CaseNotesApiMockServer.kt @@ -0,0 +1,26 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.mockservers + +import com.github.tomakehurst.wiremock.WireMockServer +import com.github.tomakehurst.wiremock.client.WireMock +import org.springframework.http.HttpStatus + +class CaseNotesApiMockServer : WireMockServer(WIREMOCK_PORT) { + companion object { + private const val WIREMOCK_PORT = 4008 + } + + fun getCaseNotes(id: String, body: String, status: HttpStatus = HttpStatus.OK) { + stubFor( + WireMock.get("/case-notes/$id") + .withHeader( + "Authorization", + WireMock.matching("Bearer ${HmppsAuthMockServer.TOKEN}"), + ).willReturn( + WireMock.aResponse() + .withHeader("Content-Type", "application/json") + .withStatus(status.value()) + .withBody(body.trimIndent()), + ), + ) + } +} From 6381a87316aae895a6e32036ebf3cbd61a0b0dd3 Mon Sep 17 00:00:00 2001 From: Chiara Date: Thu, 8 Feb 2024 13:18:56 +0000 Subject: [PATCH 03/20] WIP - entities ok, need to fix env --- .../hmppsintegrationapi/gateways/CaseNotesGateway.kt | 4 ++-- .../hmpps/hmppsintegrationapi/models/hmpps/CaseNote.kt | 4 ++++ .../hmppsintegrationapi/models/hmpps/PageCaseNote.kt | 2 +- .../hmppsintegrationapi/models/nomis/NomisCaseNote.kt | 5 +++++ .../models/nomis/NomisPageCaseNote.kt | 7 +++++-- .../gateways/caseNotes/CaseNotesGatewayTest.kt | 10 ++++++++++ .../mockservers/CaseNotesApiMockServer.kt | 2 +- 7 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNote.kt create mode 100644 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisCaseNote.kt diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt index f7c6b67c6..d467fc425 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt @@ -11,14 +11,14 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisPageCaseNote @Component -class CaseNotesGateway(@Value("\${services.case-notes.base-url") baseUrl: String) { +class CaseNotesGateway(@Value("\${case-notes.base-url") baseUrl: String) { private val webClient = WebClientWrapper(baseUrl) @Autowired lateinit var hmppsAuthGateway: HmppsAuthGateway fun getCaseNotesForPerson(id: String): Response> { - val result = webClient.request( + val result = webClient.requestList( HttpMethod.GET, "/case-notes/$id", authenticationHeader(), diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNote.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNote.kt new file mode 100644 index 000000000..a4c6c117a --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNote.kt @@ -0,0 +1,4 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +data class CaseNote( + val caseNoteId: String? = null, +) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt index 9862396b3..ad362dc29 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt @@ -1,5 +1,5 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps data class PageCaseNote( - val caseNoteId: String? = null, + val caseNotes: List? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisCaseNote.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisCaseNote.kt new file mode 100644 index 000000000..8acdf29ca --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisCaseNote.kt @@ -0,0 +1,5 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis + +data class NomisCaseNote( + val caseNoteId: String, +) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt index 2488e4e66..52bcc6c97 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt @@ -1,11 +1,14 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote data class NomisPageCaseNote( - val caseNoteId: String, + val caseNotes: List ? = emptyList(), ) { fun toPageCaseNote(): PageCaseNote = PageCaseNote( - caseNoteId = this.caseNoteId, + caseNotes = this.caseNotes?.map { + CaseNote(caseNoteId = it.caseNoteId) + }, ) } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt index 07165fe9e..0341a1452 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt @@ -1,16 +1,19 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.caseNotes import io.kotest.core.spec.style.DescribeSpec +import io.kotest.matchers.shouldBe import org.mockito.Mockito import org.mockito.kotlin.whenever import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.http.HttpStatus import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.ContextConfiguration import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.CaseNotesGateway import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.HmppsAuthGateway import uk.gov.justice.digital.hmpps.hmppsintegrationapi.mockservers.CaseNotesApiMockServer import uk.gov.justice.digital.hmpps.hmppsintegrationapi.mockservers.HmppsAuthMockServer +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError @ActiveProfiles("test") @ContextConfiguration( @@ -42,5 +45,12 @@ class CaseNotesGatewayTest( org.mockito.kotlin.verify(hmppsAuthGateway, org.mockito.internal.verification.VerificationModeFactory.times(1)) .getClientToken("CaseNotes") } + + it("upstream API returns an error, return error") { + caseNotesApiMockServer.stubGetCaseNotes("123", "", HttpStatus.BAD_REQUEST) + val response = caseNotesGateway.getCaseNotesForPerson(id = "123") + response.data.shouldBe(emptyList()) + response.errors[0].type.shouldBe(UpstreamApiError.Type.BAD_REQUEST) + } }, ) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/mockservers/CaseNotesApiMockServer.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/mockservers/CaseNotesApiMockServer.kt index cc2526fea..9d32a4e4f 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/mockservers/CaseNotesApiMockServer.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/mockservers/CaseNotesApiMockServer.kt @@ -9,7 +9,7 @@ class CaseNotesApiMockServer : WireMockServer(WIREMOCK_PORT) { private const val WIREMOCK_PORT = 4008 } - fun getCaseNotes(id: String, body: String, status: HttpStatus = HttpStatus.OK) { + fun stubGetCaseNotes(id: String, body: String, status: HttpStatus = HttpStatus.OK) { stubFor( WireMock.get("/case-notes/$id") .withHeader( From 69f5f5837ff549fe0517814e2e707a194cfcf1c9 Mon Sep 17 00:00:00 2001 From: Chiara Date: Thu, 8 Feb 2024 13:57:03 +0000 Subject: [PATCH 04/20] Fixed path for gateway --- .../hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt | 2 +- src/main/resources/application-dev.yml | 2 ++ src/main/resources/application-preprod.yml | 2 ++ src/main/resources/application-prod.yml | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt index d467fc425..bb4f244c9 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt @@ -11,7 +11,7 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisPageCaseNote @Component -class CaseNotesGateway(@Value("\${case-notes.base-url") baseUrl: String) { +class CaseNotesGateway(@Value("\${services.case-notes.base-url}") baseUrl: String) { private val webClient = WebClientWrapper(baseUrl) @Autowired diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index ef62a24b5..f2e830305 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -15,6 +15,8 @@ services: base-url: https://manage-adjudications-api-dev.hmpps.service.justice.gov.uk create-and-vary-licence: base-url: https://create-and-vary-a-licence-api-dev.hmpps.service.justice.gov.uk + case-notes: + base-url: https://dev.offender-case-notes.service.justice.gov.uk hmpps-auth: base-url: https://sign-in-dev.hmpps.service.justice.gov.uk username: ${CLIENT_ID} diff --git a/src/main/resources/application-preprod.yml b/src/main/resources/application-preprod.yml index e2c88fb7a..6e741a2ea 100644 --- a/src/main/resources/application-preprod.yml +++ b/src/main/resources/application-preprod.yml @@ -15,6 +15,8 @@ services: base-url: https://manage-adjudications-api-preprod.hmpps.service.justice.gov.uk create-and-vary-licence: base-url: https://create-and-vary-a-licence-api-preprod.hmpps.service.justice.gov.uk + case-notes: + base-url: https://preprod.offender-case-notes.service.justice.gov.uk hmpps-auth: base-url: https://sign-in-preprod.hmpps.service.justice.gov.uk username: ${CLIENT_ID} diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index ccafdd5c0..ec6ca7dff 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -15,6 +15,8 @@ services: base-url: https://manage-adjudications-api-prod.hmpps.service.justice.gov.uk create-and-vary-licence: base-url: https://create-and-vary-a-licence-api-prod.hmpps.service.justice.gov.uk + case-notes: + base-url: https://prod.offender-case-notes.service.justice.gov.uk hmpps-auth: base-url: https://sign-in.hmpps.service.justice.gov.uk username: ${CLIENT_ID} From 520cd52ea6e5399c036355c2d7530b65a4c8a1e2 Mon Sep 17 00:00:00 2001 From: AlexHerbertMadeTech Date: Thu, 8 Feb 2024 14:29:55 +0000 Subject: [PATCH 05/20] [HIA-574] Adding more stuff --- .../gateways/CaseNotesGateway.kt | 23 +++++---- .../services/GetCaseNoteForPersonService.kt | 12 +++++ .../caseNotes/CaseNotesGatewayTest.kt | 51 ++++++++++--------- .../GetCaseNoteForPersonServiceTest.kt | 41 +++++++++++++++ 4 files changed, 92 insertions(+), 35 deletions(-) create mode 100755 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt create mode 100755 src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt index bb4f244c9..b9f53b737 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt @@ -11,28 +11,31 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisPageCaseNote @Component -class CaseNotesGateway(@Value("\${services.case-notes.base-url}") baseUrl: String) { +class CaseNotesGateway( + @Value("\${services.case-notes.base-url}") baseUrl: String, +) { private val webClient = WebClientWrapper(baseUrl) @Autowired lateinit var hmppsAuthGateway: HmppsAuthGateway - fun getCaseNotesForPerson(id: String): Response> { - val result = webClient.requestList( - HttpMethod.GET, - "/case-notes/$id", - authenticationHeader(), - UpstreamApi.CASE_NOTES, - ) + fun getCaseNotesForPerson(id: String): Response { + val result = + webClient.request( + HttpMethod.GET, + "/case-notes/$id", + authenticationHeader(), + UpstreamApi.CASE_NOTES, + ) return when (result) { is WebClientWrapper.WebClientWrapperResponse.Success -> { - Response(data = result.data.map { it.toPageCaseNote() }) + Response(data = result.data.toPageCaseNote()) } is WebClientWrapper.WebClientWrapperResponse.Error -> { Response( - data = emptyList(), + data = PageCaseNote(null), errors = result.errors, ) } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt new file mode 100755 index 000000000..ee06ab447 --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt @@ -0,0 +1,12 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.services + +import org.springframework.beans.factory.annotation.Autowired +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.CaseNotesGateway + +class GetCaseNoteForPersonService( + @Autowired val caseNotesGateway: CaseNotesGateway, + @Autowired val getPersonService: GetPersonService, +) { + fun doSomething() { + } +} diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt index 0341a1452..92de08416 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt @@ -13,6 +13,7 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.CaseNotesGatewa import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.HmppsAuthGateway import uk.gov.justice.digital.hmpps.hmppsintegrationapi.mockservers.CaseNotesApiMockServer import uk.gov.justice.digital.hmpps.hmppsintegrationapi.mockservers.HmppsAuthMockServer +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError @ActiveProfiles("test") @@ -24,33 +25,33 @@ class CaseNotesGatewayTest( @MockBean val hmppsAuthGateway: HmppsAuthGateway, val caseNotesGateway: CaseNotesGateway, ) : DescribeSpec( - { - val caseNotesApiMockServer = CaseNotesApiMockServer() - beforeEach { - caseNotesApiMockServer.start() + { + val caseNotesApiMockServer = CaseNotesApiMockServer() + beforeEach { + caseNotesApiMockServer.start() - Mockito.reset(hmppsAuthGateway) - whenever(hmppsAuthGateway.getClientToken("CaseNotes")).thenReturn( - HmppsAuthMockServer.TOKEN, - ) - } + Mockito.reset(hmppsAuthGateway) + whenever(hmppsAuthGateway.getClientToken("CaseNotes")).thenReturn( + HmppsAuthMockServer.TOKEN, + ) + } - afterTest { - caseNotesApiMockServer.stop() - } + afterTest { + caseNotesApiMockServer.stop() + } - it("authenticates using HMPPS Auth with credentials") { - caseNotesGateway.getCaseNotesForPerson(id = "123") + it("authenticates using HMPPS Auth with credentials") { + caseNotesGateway.getCaseNotesForPerson(id = "123") - org.mockito.kotlin.verify(hmppsAuthGateway, org.mockito.internal.verification.VerificationModeFactory.times(1)) - .getClientToken("CaseNotes") - } + org.mockito.kotlin.verify(hmppsAuthGateway, org.mockito.internal.verification.VerificationModeFactory.times(1)) + .getClientToken("CaseNotes") + } - it("upstream API returns an error, return error") { - caseNotesApiMockServer.stubGetCaseNotes("123", "", HttpStatus.BAD_REQUEST) - val response = caseNotesGateway.getCaseNotesForPerson(id = "123") - response.data.shouldBe(emptyList()) - response.errors[0].type.shouldBe(UpstreamApiError.Type.BAD_REQUEST) - } - }, -) + it("upstream API returns an error, return error") { + caseNotesApiMockServer.stubGetCaseNotes("123", "", HttpStatus.BAD_REQUEST) + val response = caseNotesGateway.getCaseNotesForPerson(id = "123") + response.data.shouldBe(PageCaseNote(null)) + response.errors[0].type.shouldBe(UpstreamApiError.Type.BAD_REQUEST) + } + }, + ) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt new file mode 100755 index 000000000..fb2d86dd3 --- /dev/null +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt @@ -0,0 +1,41 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.services + +import io.kotest.core.spec.style.DescribeSpec +import org.mockito.Mockito +import org.mockito.kotlin.whenever +import org.springframework.boot.test.mock.mockito.MockBean +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.CaseNotesGateway +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Identifiers +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Person +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response + +class GetCaseNoteForPersonServiceTest( + @MockBean val mockCaseNotesGateway: CaseNotesGateway, + @MockBean val mockGetPersonService: GetPersonService, + val serviceUnderTest: GetCaseNoteForPersonService = GetCaseNoteForPersonService(mockCaseNotesGateway, mockGetPersonService), +) : DescribeSpec( + { + val hmppsId = "1234/56789B" + val nomisNumber = "Z99999ZZ" + val person = Person(firstName = "Julianna", lastName = "Blake", identifiers = Identifiers(nomisNumber = nomisNumber)) + val caseNotes = + PageCaseNote( + caseNotes = + listOf( + CaseNote( + caseNoteId = "12345ABC", + ), + ), + ) + + beforeEach { + Mockito.reset(mockGetPersonService) + Mockito.reset(mockCaseNotesGateway) + + whenever(mockGetPersonService.execute(hmppsId = hmppsId)).thenReturn(Response(person)) + whenever(mockCaseNotesGateway.getCaseNotesForPerson(id = nomisNumber)).thenReturn(Response(caseNotes)) + } + }, + ) From 221310b0e8c35475a64f5ef7ed166b2161c21fc2 Mon Sep 17 00:00:00 2001 From: Chiara Date: Thu, 8 Feb 2024 14:32:24 +0000 Subject: [PATCH 06/20] Fixed linting --- .../caseNotes/CaseNotesGatewayTest.kt | 50 +++++++++---------- .../GetCaseNoteForPersonServiceTest.kt | 50 +++++++++++-------- 2 files changed, 53 insertions(+), 47 deletions(-) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt index 92de08416..e6416995c 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt @@ -25,33 +25,33 @@ class CaseNotesGatewayTest( @MockBean val hmppsAuthGateway: HmppsAuthGateway, val caseNotesGateway: CaseNotesGateway, ) : DescribeSpec( - { - val caseNotesApiMockServer = CaseNotesApiMockServer() - beforeEach { - caseNotesApiMockServer.start() + { + val caseNotesApiMockServer = CaseNotesApiMockServer() + beforeEach { + caseNotesApiMockServer.start() - Mockito.reset(hmppsAuthGateway) - whenever(hmppsAuthGateway.getClientToken("CaseNotes")).thenReturn( - HmppsAuthMockServer.TOKEN, - ) - } + Mockito.reset(hmppsAuthGateway) + whenever(hmppsAuthGateway.getClientToken("CaseNotes")).thenReturn( + HmppsAuthMockServer.TOKEN, + ) + } - afterTest { - caseNotesApiMockServer.stop() - } + afterTest { + caseNotesApiMockServer.stop() + } - it("authenticates using HMPPS Auth with credentials") { - caseNotesGateway.getCaseNotesForPerson(id = "123") + it("authenticates using HMPPS Auth with credentials") { + caseNotesGateway.getCaseNotesForPerson(id = "123") - org.mockito.kotlin.verify(hmppsAuthGateway, org.mockito.internal.verification.VerificationModeFactory.times(1)) - .getClientToken("CaseNotes") - } + org.mockito.kotlin.verify(hmppsAuthGateway, org.mockito.internal.verification.VerificationModeFactory.times(1)) + .getClientToken("CaseNotes") + } - it("upstream API returns an error, return error") { - caseNotesApiMockServer.stubGetCaseNotes("123", "", HttpStatus.BAD_REQUEST) - val response = caseNotesGateway.getCaseNotesForPerson(id = "123") - response.data.shouldBe(PageCaseNote(null)) - response.errors[0].type.shouldBe(UpstreamApiError.Type.BAD_REQUEST) - } - }, - ) + it("upstream API returns an error, return error") { + caseNotesApiMockServer.stubGetCaseNotes("123", "", HttpStatus.BAD_REQUEST) + val response = caseNotesGateway.getCaseNotesForPerson(id = "123") + response.data.shouldBe(PageCaseNote(null)) + response.errors[0].type.shouldBe(UpstreamApiError.Type.BAD_REQUEST) + } + }, +) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt index fb2d86dd3..f031ecb39 100755 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt @@ -3,7 +3,9 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.services import io.kotest.core.spec.style.DescribeSpec import org.mockito.Mockito import org.mockito.kotlin.whenever +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.context.ContextConfiguration import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.CaseNotesGateway import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Identifiers @@ -11,31 +13,35 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNot import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Person import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response +@ContextConfiguration( + initializers = [ConfigDataApplicationContextInitializer::class], + classes = [GetCaseNoteForPersonService::class], +) class GetCaseNoteForPersonServiceTest( @MockBean val mockCaseNotesGateway: CaseNotesGateway, @MockBean val mockGetPersonService: GetPersonService, - val serviceUnderTest: GetCaseNoteForPersonService = GetCaseNoteForPersonService(mockCaseNotesGateway, mockGetPersonService), + private val getCaseNoteForPersonService: GetCaseNoteForPersonService, ) : DescribeSpec( - { - val hmppsId = "1234/56789B" - val nomisNumber = "Z99999ZZ" - val person = Person(firstName = "Julianna", lastName = "Blake", identifiers = Identifiers(nomisNumber = nomisNumber)) - val caseNotes = - PageCaseNote( - caseNotes = - listOf( - CaseNote( - caseNoteId = "12345ABC", - ), - ), - ) + { + val hmppsId = "1234/56789B" + val nomisNumber = "Z99999ZZ" + val person = Person(firstName = "Julianna", lastName = "Blake", identifiers = Identifiers(nomisNumber = nomisNumber)) + val caseNotes = + PageCaseNote( + caseNotes = + listOf( + CaseNote( + caseNoteId = "12345ABC", + ), + ), + ) - beforeEach { - Mockito.reset(mockGetPersonService) - Mockito.reset(mockCaseNotesGateway) + beforeEach { + Mockito.reset(mockGetPersonService) + Mockito.reset(mockCaseNotesGateway) - whenever(mockGetPersonService.execute(hmppsId = hmppsId)).thenReturn(Response(person)) - whenever(mockCaseNotesGateway.getCaseNotesForPerson(id = nomisNumber)).thenReturn(Response(caseNotes)) - } - }, - ) + whenever(mockGetPersonService.execute(hmppsId = hmppsId)).thenReturn(Response(person)) + whenever(mockCaseNotesGateway.getCaseNotesForPerson(id = nomisNumber)).thenReturn(Response(caseNotes)) + } + }, +) From 7a2ed491ca75f72b48688d775f8d0486d64f65a4 Mon Sep 17 00:00:00 2001 From: Chiara Date: Thu, 8 Feb 2024 15:01:33 +0000 Subject: [PATCH 07/20] Service OK --- .../services/GetCaseNoteForPersonService.kt | 17 +++++++++++- .../GetCaseNoteForPersonServiceTest.kt | 26 ++++++++++++++----- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt index ee06ab447..abc1cfd89 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt @@ -2,11 +2,26 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.services import org.springframework.beans.factory.annotation.Autowired import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.CaseNotesGateway +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response class GetCaseNoteForPersonService( @Autowired val caseNotesGateway: CaseNotesGateway, @Autowired val getPersonService: GetPersonService, ) { - fun doSomething() { + fun execute(hmppsId: String): Response { + val personResponse = getPersonService.execute(hmppsId = hmppsId) + val nomisNumber = personResponse.data?.identifiers?.nomisNumber + + var caseNotes: Response = Response(data = PageCaseNote(null)) + + if (nomisNumber != null) { + caseNotes = caseNotesGateway.getCaseNotesForPerson(id = nomisNumber) + } + + return Response( + data = caseNotes.data, + errors = personResponse.errors + caseNotes.errors, + ) } } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt index f031ecb39..8bfec1d13 100755 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt @@ -1,7 +1,10 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.services import io.kotest.core.spec.style.DescribeSpec +import io.kotest.matchers.shouldBe import org.mockito.Mockito +import org.mockito.internal.verification.VerificationModeFactory +import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer import org.springframework.boot.test.mock.mockito.MockBean @@ -18,8 +21,8 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response classes = [GetCaseNoteForPersonService::class], ) class GetCaseNoteForPersonServiceTest( - @MockBean val mockCaseNotesGateway: CaseNotesGateway, - @MockBean val mockGetPersonService: GetPersonService, + @MockBean val caseNotesGateway: CaseNotesGateway, + @MockBean val getPersonService: GetPersonService, private val getCaseNoteForPersonService: GetCaseNoteForPersonService, ) : DescribeSpec( { @@ -37,11 +40,22 @@ class GetCaseNoteForPersonServiceTest( ) beforeEach { - Mockito.reset(mockGetPersonService) - Mockito.reset(mockCaseNotesGateway) + Mockito.reset(getPersonService) + Mockito.reset(caseNotesGateway) - whenever(mockGetPersonService.execute(hmppsId = hmppsId)).thenReturn(Response(person)) - whenever(mockCaseNotesGateway.getCaseNotesForPerson(id = nomisNumber)).thenReturn(Response(caseNotes)) + whenever(getPersonService.execute(hmppsId = hmppsId)).thenReturn(Response(person)) + whenever(caseNotesGateway.getCaseNotesForPerson(id = nomisNumber)).thenReturn(Response(caseNotes)) + } + + it("performs a search according to hmpps Id") { + getCaseNoteForPersonService.execute(hmppsId) + verify(getPersonService, VerificationModeFactory.times(1)).execute(hmppsId = hmppsId) + } + + it("should return case notes from gateway") { + val result = getCaseNoteForPersonService.execute(hmppsId = hmppsId) + result.data.caseNotes?.first()?.caseNoteId.shouldBe("12345ABC") + result.errors.count().shouldBe(0) } }, ) From 6bcee129e9869ba4a06ab75a3535f476092a76fb Mon Sep 17 00:00:00 2001 From: AlexHerbertMadeTech Date: Thu, 8 Feb 2024 16:29:08 +0000 Subject: [PATCH 08/20] [HIA-574] Adding a controller and ensuring our service is a bean --- .../controllers/v1/CaseNoteController.kt | 31 +++++++++++++++++++ .../services/GetCaseNoteForPersonService.kt | 2 ++ 2 files changed, 33 insertions(+) create mode 100755 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteController.kt diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteController.kt new file mode 100755 index 000000000..11b955305 --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteController.kt @@ -0,0 +1,31 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1 + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNoteForPersonService +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService + +@RestController +@RequestMapping("/v1/caseNotes") +class CaseNoteController( + @Autowired val getCaseNoteForPersonService: GetCaseNoteForPersonService, + @Autowired val auditService: AuditService, +) { + @GetMapping("{id}") + fun getCaseNotesForPerson( + @PathVariable id: String, + ): Response { + val response = getCaseNoteForPersonService.execute(id) + + if (!response.errors.isEmpty()) { + // do something? + } + + return response + } +} diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt index abc1cfd89..a7b74d4c4 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt @@ -1,10 +1,12 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.services import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.CaseNotesGateway import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response +@Service class GetCaseNoteForPersonService( @Autowired val caseNotesGateway: CaseNotesGateway, @Autowired val getPersonService: GetPersonService, From 9e5c61982234ff78f0cace92af59094b598e2834 Mon Sep 17 00:00:00 2001 From: AlexHerbertMadeTech Date: Thu, 8 Feb 2024 16:48:14 +0000 Subject: [PATCH 09/20] [HIA-574] Adding a test --- .../controllers/v1/CaseNoteControllerTest.kt | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100755 src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt new file mode 100755 index 000000000..604bff57e --- /dev/null +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt @@ -0,0 +1,47 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1 + +import io.kotest.core.spec.style.DescribeSpec +import io.kotest.matchers.shouldBe +import org.mockito.Mockito +import org.mockito.kotlin.whenever +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.http.HttpStatus +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.web.servlet.MockMvc +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.helpers.IntegrationAPIMockMvc +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNoteForPersonService + +@WebMvcTest(controllers = [EPFPersonDetailController::class]) +@ActiveProfiles("test") +class CaseNoteControllerTest( + @Autowired var springMockMvc: MockMvc, + @Autowired val getCaseNoteForPersonService: GetCaseNoteForPersonService, +) : DescribeSpec({ + val hmppsId = "X12345" + val path = "/v1/caseNotes/$hmppsId" + val mockMvc = IntegrationAPIMockMvc(springMockMvc) + val pageCaseNote = + PageCaseNote( + listOf( + CaseNote(caseNoteId = "abcd1234"), + ), + ) + + describe("GET $path") { + beforeTest { + Mockito.reset(getCaseNoteForPersonService) + whenever(getCaseNoteForPersonService.execute(hmppsId)).thenReturn( + Response(data = pageCaseNote, errors = listOf()), + ) + } + } + + it("returns a 200 OK status code") { + val result = mockMvc.performAuthorised(path) + result.response.status.shouldBe(HttpStatus.OK.value()) + } + }) From 81387ab336915a8ef8386a741116157f61e1b660 Mon Sep 17 00:00:00 2001 From: AlexHerbertMadeTech Date: Thu, 8 Feb 2024 16:51:05 +0000 Subject: [PATCH 10/20] [HIA-574] Fixing a test --- .../controllers/v1/CaseNoteControllerTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt index 604bff57e..f17a3b147 100755 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt @@ -15,7 +15,7 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNot import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNoteForPersonService -@WebMvcTest(controllers = [EPFPersonDetailController::class]) +@WebMvcTest(controllers = [CaseNoteController::class]) @ActiveProfiles("test") class CaseNoteControllerTest( @Autowired var springMockMvc: MockMvc, From 1d05b19e807c53d75e9db0aaf31b65be36e99f16 Mon Sep 17 00:00:00 2001 From: Chiara Date: Fri, 9 Feb 2024 10:31:24 +0000 Subject: [PATCH 11/20] Controller instantiated for thin slice --- .../controllers/v1/CaseNoteController.kt | 31 ------- .../v1/person/CaseNoteController.kt | 35 +++++++ .../controllers/v1/CaseNoteControllerTest.kt | 47 ---------- .../v1/person/CaseNoteControllerTest.kt | 93 +++++++++++++++++++ 4 files changed, 128 insertions(+), 78 deletions(-) delete mode 100755 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteController.kt create mode 100755 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteController.kt delete mode 100755 src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt create mode 100755 src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteControllerTest.kt diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteController.kt deleted file mode 100755 index 11b955305..000000000 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteController.kt +++ /dev/null @@ -1,31 +0,0 @@ -package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1 - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNoteForPersonService -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService - -@RestController -@RequestMapping("/v1/caseNotes") -class CaseNoteController( - @Autowired val getCaseNoteForPersonService: GetCaseNoteForPersonService, - @Autowired val auditService: AuditService, -) { - @GetMapping("{id}") - fun getCaseNotesForPerson( - @PathVariable id: String, - ): Response { - val response = getCaseNoteForPersonService.execute(id) - - if (!response.errors.isEmpty()) { - // do something? - } - - return response - } -} diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteController.kt new file mode 100755 index 000000000..5ac9670b9 --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteController.kt @@ -0,0 +1,35 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNoteForPersonService +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService + +@RestController +@RequestMapping("/v1/persons") +class CaseNoteController( + @Autowired val getCaseNoteForPersonService: GetCaseNoteForPersonService, + @Autowired val auditService: AuditService, +) { + @GetMapping("{encodedHmppsId}/case-notes") + fun getCaseNotesForPerson( + @PathVariable encodedHmppsId: String, + ): Map { + val hmppsId = encodedHmppsId.decodeUrlCharacters() + val response = getCaseNoteForPersonService.execute(hmppsId) + + if (response.hasErrorCausedBy(UpstreamApiError.Type.ENTITY_NOT_FOUND, causedBy = UpstreamApi.CASE_NOTES)) { + throw EntityNotFoundException("Could not find person with id: $hmppsId") + } + auditService.createEvent("GET_CASE_NOTES", "Person case notes with hmpps id: $hmppsId has been retrieved") + return mapOf("data" to response.data) + } +} diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt deleted file mode 100755 index f17a3b147..000000000 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/CaseNoteControllerTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1 - -import io.kotest.core.spec.style.DescribeSpec -import io.kotest.matchers.shouldBe -import org.mockito.Mockito -import org.mockito.kotlin.whenever -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest -import org.springframework.http.HttpStatus -import org.springframework.test.context.ActiveProfiles -import org.springframework.test.web.servlet.MockMvc -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.helpers.IntegrationAPIMockMvc -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNoteForPersonService - -@WebMvcTest(controllers = [CaseNoteController::class]) -@ActiveProfiles("test") -class CaseNoteControllerTest( - @Autowired var springMockMvc: MockMvc, - @Autowired val getCaseNoteForPersonService: GetCaseNoteForPersonService, -) : DescribeSpec({ - val hmppsId = "X12345" - val path = "/v1/caseNotes/$hmppsId" - val mockMvc = IntegrationAPIMockMvc(springMockMvc) - val pageCaseNote = - PageCaseNote( - listOf( - CaseNote(caseNoteId = "abcd1234"), - ), - ) - - describe("GET $path") { - beforeTest { - Mockito.reset(getCaseNoteForPersonService) - whenever(getCaseNoteForPersonService.execute(hmppsId)).thenReturn( - Response(data = pageCaseNote, errors = listOf()), - ) - } - } - - it("returns a 200 OK status code") { - val result = mockMvc.performAuthorised(path) - result.response.status.shouldBe(HttpStatus.OK.value()) - } - }) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteControllerTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteControllerTest.kt new file mode 100755 index 000000000..89b9fee3f --- /dev/null +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteControllerTest.kt @@ -0,0 +1,93 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person + +import io.kotest.core.spec.style.DescribeSpec +import io.kotest.matchers.shouldBe +import io.kotest.matchers.string.shouldContain +import org.mockito.Mockito +import org.mockito.internal.verification.VerificationModeFactory +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.http.HttpStatus +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.web.servlet.MockMvc +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.removeWhitespaceAndNewlines +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.helpers.IntegrationAPIMockMvc +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNoteForPersonService +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService +import java.net.URLEncoder +import java.nio.charset.StandardCharsets + +@WebMvcTest(controllers = [CaseNoteController::class]) +@ActiveProfiles("test") +class CaseNoteControllerTest( + @Autowired var springMockMvc: MockMvc, + @MockBean val getCaseNoteForPersonService: GetCaseNoteForPersonService, + @MockBean val auditService: AuditService, +) : DescribeSpec( + { + val hmppsId = "9999/11111A" + val encodedHmppsId = URLEncoder.encode(hmppsId, StandardCharsets.UTF_8) + val path = "/v1/persons/$encodedHmppsId/case-notes" + val mockMvc = IntegrationAPIMockMvc(springMockMvc) + val pageCaseNote = + PageCaseNote( + listOf( + CaseNote(caseNoteId = "abcd1234"), + ), + ) + describe("GET $path") { + beforeTest { + Mockito.reset(getCaseNoteForPersonService) + Mockito.reset(auditService) + whenever(getCaseNoteForPersonService.execute(hmppsId)).thenReturn( + Response( + data = pageCaseNote, + errors = emptyList(), + ), + ) + } + + it("returns a 200 OK status code") { + val result = mockMvc.performAuthorised(path) + + result.response.status.shouldBe(HttpStatus.OK.value()) + } + + it("gets the case notes for a person with the matching ID") { + mockMvc.performAuthorised(path) + + verify(getCaseNoteForPersonService, VerificationModeFactory.times(1)).execute(hmppsId) + } + + it("returns the case notes for a person with the matching ID") { + val result = mockMvc.performAuthorised(path) + + result.response.contentAsString.shouldContain( + """ + "data": + { + "caseNotes": [ + { + "caseNoteId": "abcd1234" + } + ] + } + + """.removeWhitespaceAndNewlines(), + ) + } + + it("logs audit") { + mockMvc.performAuthorised(path) + + verify(auditService, VerificationModeFactory.times(1)).createEvent("GET_CASE_NOTES", "Person case notes with hmpps id: $hmppsId has been retrieved") + } + } + }, +) From d76647601f6df962861802451676debb1f282c69 Mon Sep 17 00:00:00 2001 From: Chiara Date: Fri, 9 Feb 2024 11:46:58 +0000 Subject: [PATCH 12/20] WIP - api current returns empty array, fixing --- ...teController.kt => CaseNotesController.kt} | 6 +-- ...ice.kt => GetCaseNotesForPersonService.kt} | 2 +- src/main/resources/application-dev.yml | 1 + .../resources/application-local-docker.yml | 1 + src/main/resources/application-local.yml | 1 + src/main/resources/application-test.yml | 1 + ...llerTest.kt => CaseNotesControllerTest.kt} | 14 +++---- ...kt => GetCaseNotesForPersonServiceTest.kt} | 6 +-- .../smoke/person/CaseNotesSmokeTest.kt | 39 +++++++++++++++++++ 9 files changed, 57 insertions(+), 14 deletions(-) rename src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/{CaseNoteController.kt => CaseNotesController.kt} (92%) rename src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/{GetCaseNoteForPersonService.kt => GetCaseNotesForPersonService.kt} (96%) rename src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/{CaseNoteControllerTest.kt => CaseNotesControllerTest.kt} (87%) rename src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/{GetCaseNoteForPersonServiceTest.kt => GetCaseNotesForPersonServiceTest.kt} (93%) create mode 100644 src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt similarity index 92% rename from src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteController.kt rename to src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt index 5ac9670b9..f115994d2 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt @@ -10,13 +10,13 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlChar import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNoteForPersonService +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNotesForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @RestController @RequestMapping("/v1/persons") -class CaseNoteController( - @Autowired val getCaseNoteForPersonService: GetCaseNoteForPersonService, +class CaseNotesController( + @Autowired val getCaseNoteForPersonService: GetCaseNotesForPersonService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/case-notes") diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonService.kt similarity index 96% rename from src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt rename to src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonService.kt index a7b74d4c4..1468c737d 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonService.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonService.kt @@ -7,7 +7,7 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNot import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response @Service -class GetCaseNoteForPersonService( +class GetCaseNotesForPersonService( @Autowired val caseNotesGateway: CaseNotesGateway, @Autowired val getPersonService: GetPersonService, ) { diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index f2e830305..a2040c335 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -39,6 +39,7 @@ authorisation: - "/v1/persons/.*/risks" - "/v1/persons/.*/adjudications" - "/v1/persons/.*/licences/conditions" + - "/v1/persons/.*/case-notes" ctrlo: - "/v1/epf/person-details/.*/.*" kubernetes-health-check-client: diff --git a/src/main/resources/application-local-docker.yml b/src/main/resources/application-local-docker.yml index 7a622ecbe..802cbfdbd 100644 --- a/src/main/resources/application-local-docker.yml +++ b/src/main/resources/application-local-docker.yml @@ -36,6 +36,7 @@ authorisation: - "/v1/persons/.*/needs" - "/v1/persons/.*/risks" - "/v1/persons/.*/reported-adjudications" + - "/v1/persons/.*/case-notes" - "/v1/epf/person-details/.*/.*" - "/health" - "/health/ping" diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 0497773d6..95974c846 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -42,6 +42,7 @@ authorisation: - "/v1/persons/.*/needs" - "/v1/persons/.*/risks" - "/v1/persons/.*/reported-adjudications" + - "/v1/persons/.*/case-notes" - "/v1/epf/person-details/.*/.*" - "/health" - "/health/ping" diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index c9b24977c..b9c50a71f 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -54,6 +54,7 @@ authorisation: - "/v1/epf/person-details/.*/.*" - "/v1/persons/.*/adjudications" - "/v1/persons/.*/licences/conditions" + - "/v1/persons/.*/case-notes" - "/health" - "/health/ping" - "/health/readiness" diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteControllerTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesControllerTest.kt similarity index 87% rename from src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteControllerTest.kt rename to src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesControllerTest.kt index 89b9fee3f..9da1525a2 100755 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNoteControllerTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesControllerTest.kt @@ -18,16 +18,16 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.helpers.IntegrationAPIMo import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNoteForPersonService +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNotesForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService import java.net.URLEncoder import java.nio.charset.StandardCharsets -@WebMvcTest(controllers = [CaseNoteController::class]) +@WebMvcTest(controllers = [CaseNotesController::class]) @ActiveProfiles("test") -class CaseNoteControllerTest( +class CaseNotesControllerTest( @Autowired var springMockMvc: MockMvc, - @MockBean val getCaseNoteForPersonService: GetCaseNoteForPersonService, + @MockBean val getCaseNotesForPersonService: GetCaseNotesForPersonService, @MockBean val auditService: AuditService, ) : DescribeSpec( { @@ -43,9 +43,9 @@ class CaseNoteControllerTest( ) describe("GET $path") { beforeTest { - Mockito.reset(getCaseNoteForPersonService) + Mockito.reset(getCaseNotesForPersonService) Mockito.reset(auditService) - whenever(getCaseNoteForPersonService.execute(hmppsId)).thenReturn( + whenever(getCaseNotesForPersonService.execute(hmppsId)).thenReturn( Response( data = pageCaseNote, errors = emptyList(), @@ -62,7 +62,7 @@ class CaseNoteControllerTest( it("gets the case notes for a person with the matching ID") { mockMvc.performAuthorised(path) - verify(getCaseNoteForPersonService, VerificationModeFactory.times(1)).execute(hmppsId) + verify(getCaseNotesForPersonService, VerificationModeFactory.times(1)).execute(hmppsId) } it("returns the case notes for a person with the matching ID") { diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonServiceTest.kt similarity index 93% rename from src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt rename to src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonServiceTest.kt index 8bfec1d13..2db1a2461 100755 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNoteForPersonServiceTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonServiceTest.kt @@ -18,12 +18,12 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response @ContextConfiguration( initializers = [ConfigDataApplicationContextInitializer::class], - classes = [GetCaseNoteForPersonService::class], + classes = [GetCaseNotesForPersonService::class], ) -class GetCaseNoteForPersonServiceTest( +class GetCaseNotesForPersonServiceTest( @MockBean val caseNotesGateway: CaseNotesGateway, @MockBean val getPersonService: GetPersonService, - private val getCaseNoteForPersonService: GetCaseNoteForPersonService, + private val getCaseNoteForPersonService: GetCaseNotesForPersonService, ) : DescribeSpec( { val hmppsId = "1234/56789B" diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt new file mode 100644 index 000000000..d4910a5c4 --- /dev/null +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt @@ -0,0 +1,39 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.smoke.person + +import io.kotest.assertions.json.shouldEqualJson +import io.kotest.core.spec.style.DescribeSpec +import io.kotest.matchers.shouldBe +import org.springframework.http.HttpStatus +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.removeWhitespaceAndNewlines +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.helpers.IntegrationAPIHttpClient +import java.net.URLEncoder +import java.nio.charset.StandardCharsets + +class CaseNotesSmokeTest : DescribeSpec( + { + val hmppsId = "ABC123" + val encodedHmppsId = URLEncoder.encode(hmppsId, StandardCharsets.UTF_8) + val basePath = "v1/persons/$encodedHmppsId/case-notes" + val httpClient = IntegrationAPIHttpClient() + + it("returns case notes for a person") { + val response = httpClient.performAuthorised(basePath) + response.statusCode().shouldBe(HttpStatus.OK.value()) + response.body().shouldEqualJson( + """ + { + "data": + { + "caseNotes": [ + { + "caseNoteId": "12311312" + } + ] + } + } + + """.removeWhitespaceAndNewlines(), + ) + } + }, +) From a595fbee1a82a476a75dbe095af0568e044a02ba Mon Sep 17 00:00:00 2001 From: Chiara Date: Fri, 9 Feb 2024 13:18:59 +0000 Subject: [PATCH 13/20] Fixed smoke test --- .../hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt index 52bcc6c97..af02daba9 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt @@ -4,10 +4,10 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote data class NomisPageCaseNote( - val caseNotes: List ? = emptyList(), + val content: List = listOf(), ) { fun toPageCaseNote(): PageCaseNote = PageCaseNote( - caseNotes = this.caseNotes?.map { + caseNotes = this.content.map { CaseNote(caseNoteId = it.caseNoteId) }, ) From 1cd650d2053f17b9b0be9f06af050897bde3fe25 Mon Sep 17 00:00:00 2001 From: Chiara Date: Sun, 11 Feb 2024 08:30:07 +0000 Subject: [PATCH 14/20] API doc --- openapi.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/openapi.yml b/openapi.yml index fa900bbd6..c2f1c96ba 100644 --- a/openapi.yml +++ b/openapi.yml @@ -516,6 +516,28 @@ paths: PersonNotFoundError: $ref: "#/components/examples/PersonNotFoundError" + /v1/persons/{HmppsId}/case-notes: + get: + summary: Returns case notes associated with a person. + parameters: + - $ref: "#/components/parameters/HmppsId" + responses: + "200": + description: Successfully found case notes for a person with the provided HMPPS ID. + content: + application/json: + schema: + $ref: "#/components/schemas/CaseNotesData" + "404": + description: Failed to find case notes for a person with the provided HMPPS ID. + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + examples: + PersonNotFoundError: + $ref: "#/components/examples/PersonNotFoundError" + /{TBC}/v1/persons/{Id}/accommodations: get: summary: FUTURE ENDPOINT - Returns accommodation and referral information associated with a person. @@ -806,6 +828,11 @@ components: ageAtRelease: type: integer format: int64 + CaseNote: + type: object + properties: + caseNoteId: + type: string CaseSentence: required: - date @@ -1158,6 +1185,11 @@ components: canRemove: type: boolean nullable: true + PageCaseNote: + type: object + properties: + caseNote: + $ref: '#/components/schemas/CaseNote' Pagination: type: object properties: From b74af798bdacbf54b927182926a911bf56c88139 Mon Sep 17 00:00:00 2001 From: Chiara Date: Sun, 11 Feb 2024 08:31:05 +0000 Subject: [PATCH 15/20] Edit --- openapi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi.yml b/openapi.yml index c2f1c96ba..273cc4724 100644 --- a/openapi.yml +++ b/openapi.yml @@ -527,7 +527,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/CaseNotesData" + $ref: "#/components/schemas/PageCaseNote" "404": description: Failed to find case notes for a person with the provided HMPPS ID. content: From 3c455432e9ed9316a09dd8261aee7b8319664344 Mon Sep 17 00:00:00 2001 From: Chiara Date: Mon, 12 Feb 2024 09:55:46 +0000 Subject: [PATCH 16/20] rekicking pipeline --- .../hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt index d4910a5c4..b3584f734 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt @@ -16,7 +16,7 @@ class CaseNotesSmokeTest : DescribeSpec( val basePath = "v1/persons/$encodedHmppsId/case-notes" val httpClient = IntegrationAPIHttpClient() - it("returns case notes for a person") { + it("returns case notes for a person.") { val response = httpClient.performAuthorised(basePath) response.statusCode().shouldBe(HttpStatus.OK.value()) response.body().shouldEqualJson( From 38b3e57d9a15fa0f90e8ca71a4343801ec323378 Mon Sep 17 00:00:00 2001 From: Chiara Date: Mon, 12 Feb 2024 12:10:15 +0000 Subject: [PATCH 17/20] Changed structure --- openapi.yml | 9 +++---- .../v1/person/CaseNotesController.kt | 11 +++++--- .../gateways/CaseNotesGateway.kt | 8 +++--- .../models/hmpps/PageCaseNote.kt | 5 ---- .../models/nomis/NomisPageCaseNote.kt | 9 +++---- .../services/GetCaseNotesForPersonService.kt | 6 ++--- .../v1/person/CaseNotesControllerTest.kt | 26 +++++++++---------- .../caseNotes/CaseNotesGatewayTest.kt | 3 +-- .../GetCaseNotesForPersonServiceTest.kt | 13 ++++------ .../smoke/person/CaseNotesSmokeTest.kt | 24 ++++++++++------- 10 files changed, 53 insertions(+), 61 deletions(-) delete mode 100644 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt diff --git a/openapi.yml b/openapi.yml index 273cc4724..5643240b2 100644 --- a/openapi.yml +++ b/openapi.yml @@ -527,7 +527,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/PageCaseNote" + $ref: "#/components/schemas/CaseNoteData" "404": description: Failed to find case notes for a person with the provided HMPPS ID. content: @@ -1185,11 +1185,8 @@ components: canRemove: type: boolean nullable: true - PageCaseNote: - type: object - properties: - caseNote: - $ref: '#/components/schemas/CaseNote' + CaseNoteData: + type: string Pagination: type: object properties: diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt index f115994d2..98aebd34c 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt @@ -4,14 +4,17 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNotesForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.PaginatedResponse +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.paginateWith @RestController @RequestMapping("/v1/persons") @@ -22,7 +25,9 @@ class CaseNotesController( @GetMapping("{encodedHmppsId}/case-notes") fun getCaseNotesForPerson( @PathVariable encodedHmppsId: String, - ): Map { + @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getCaseNoteForPersonService.execute(hmppsId) @@ -30,6 +35,6 @@ class CaseNotesController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_CASE_NOTES", "Person case notes with hmpps id: $hmppsId has been retrieved") - return mapOf("data" to response.data) + return response.data.paginateWith(page, perPage) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt index b9f53b737..8cc813a16 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/CaseNotesGateway.kt @@ -5,7 +5,7 @@ import org.springframework.beans.factory.annotation.Value import org.springframework.http.HttpMethod import org.springframework.stereotype.Component import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.WebClientWrapper -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisPageCaseNote @@ -19,7 +19,7 @@ class CaseNotesGateway( @Autowired lateinit var hmppsAuthGateway: HmppsAuthGateway - fun getCaseNotesForPerson(id: String): Response { + fun getCaseNotesForPerson(id: String): Response> { val result = webClient.request( HttpMethod.GET, @@ -30,12 +30,12 @@ class CaseNotesGateway( return when (result) { is WebClientWrapper.WebClientWrapperResponse.Success -> { - Response(data = result.data.toPageCaseNote()) + Response(data = result.data.toCaseNotes()) } is WebClientWrapper.WebClientWrapperResponse.Error -> { Response( - data = PageCaseNote(null), + data = emptyList(), errors = result.errors, ) } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt deleted file mode 100644 index ad362dc29..000000000 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PageCaseNote.kt +++ /dev/null @@ -1,5 +0,0 @@ -package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps - -data class PageCaseNote( - val caseNotes: List? = null, -) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt index af02daba9..18a974182 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/nomis/NomisPageCaseNote.kt @@ -1,14 +1,11 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote data class NomisPageCaseNote( val content: List = listOf(), ) { - fun toPageCaseNote(): PageCaseNote = PageCaseNote( - caseNotes = this.content.map { - CaseNote(caseNoteId = it.caseNoteId) - }, - ) + fun toCaseNotes(): List = this.content.map { + CaseNote(caseNoteId = it.caseNoteId) + } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonService.kt index 1468c737d..eb79f26ee 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonService.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonService.kt @@ -3,7 +3,7 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.services import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.CaseNotesGateway -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response @Service @@ -11,11 +11,11 @@ class GetCaseNotesForPersonService( @Autowired val caseNotesGateway: CaseNotesGateway, @Autowired val getPersonService: GetPersonService, ) { - fun execute(hmppsId: String): Response { + fun execute(hmppsId: String): Response> { val personResponse = getPersonService.execute(hmppsId = hmppsId) val nomisNumber = personResponse.data?.identifiers?.nomisNumber - var caseNotes: Response = Response(data = PageCaseNote(null)) + var caseNotes: Response> = Response(data = emptyList()) if (nomisNumber != null) { caseNotes = caseNotesGateway.getCaseNotesForPerson(id = nomisNumber) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesControllerTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesControllerTest.kt index 9da1525a2..b3c2a74e0 100755 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesControllerTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesControllerTest.kt @@ -16,7 +16,6 @@ import org.springframework.test.web.servlet.MockMvc import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.removeWhitespaceAndNewlines import uk.gov.justice.digital.hmpps.hmppsintegrationapi.helpers.IntegrationAPIMockMvc import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCaseNotesForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @@ -36,10 +35,10 @@ class CaseNotesControllerTest( val path = "/v1/persons/$encodedHmppsId/case-notes" val mockMvc = IntegrationAPIMockMvc(springMockMvc) val pageCaseNote = - PageCaseNote( - listOf( - CaseNote(caseNoteId = "abcd1234"), - ), + + listOf( + CaseNote(caseNoteId = "abcd1234"), + ) describe("GET $path") { beforeTest { @@ -70,15 +69,14 @@ class CaseNotesControllerTest( result.response.contentAsString.shouldContain( """ - "data": - { - "caseNotes": [ - { - "caseNoteId": "abcd1234" - } - ] - } - + { + "data":[ + {"caseNoteId":"abcd1234"} + ], + "pagination":{ + "isLastPage":true,"count":1,"page":1,"perPage":10,"totalCount":1,"totalPages":1 + } + } """.removeWhitespaceAndNewlines(), ) } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt index e6416995c..0341a1452 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/caseNotes/CaseNotesGatewayTest.kt @@ -13,7 +13,6 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.CaseNotesGatewa import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.HmppsAuthGateway import uk.gov.justice.digital.hmpps.hmppsintegrationapi.mockservers.CaseNotesApiMockServer import uk.gov.justice.digital.hmpps.hmppsintegrationapi.mockservers.HmppsAuthMockServer -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError @ActiveProfiles("test") @@ -50,7 +49,7 @@ class CaseNotesGatewayTest( it("upstream API returns an error, return error") { caseNotesApiMockServer.stubGetCaseNotes("123", "", HttpStatus.BAD_REQUEST) val response = caseNotesGateway.getCaseNotesForPerson(id = "123") - response.data.shouldBe(PageCaseNote(null)) + response.data.shouldBe(emptyList()) response.errors[0].type.shouldBe(UpstreamApiError.Type.BAD_REQUEST) } }, diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonServiceTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonServiceTest.kt index 2db1a2461..c1398b248 100755 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonServiceTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetCaseNotesForPersonServiceTest.kt @@ -12,7 +12,6 @@ import org.springframework.test.context.ContextConfiguration import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.CaseNotesGateway import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Identifiers -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PageCaseNote import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Person import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response @@ -30,12 +29,9 @@ class GetCaseNotesForPersonServiceTest( val nomisNumber = "Z99999ZZ" val person = Person(firstName = "Julianna", lastName = "Blake", identifiers = Identifiers(nomisNumber = nomisNumber)) val caseNotes = - PageCaseNote( - caseNotes = - listOf( - CaseNote( - caseNoteId = "12345ABC", - ), + listOf( + CaseNote( + caseNoteId = "12345ABC", ), ) @@ -54,7 +50,8 @@ class GetCaseNotesForPersonServiceTest( it("should return case notes from gateway") { val result = getCaseNoteForPersonService.execute(hmppsId = hmppsId) - result.data.caseNotes?.first()?.caseNoteId.shouldBe("12345ABC") + result.data.size.shouldBe(1) + result.data.first()?.caseNoteId.shouldBe("12345ABC") result.errors.count().shouldBe(0) } }, diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt index b3584f734..09675372d 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/CaseNotesSmokeTest.kt @@ -22,16 +22,20 @@ class CaseNotesSmokeTest : DescribeSpec( response.body().shouldEqualJson( """ { - "data": - { - "caseNotes": [ - { - "caseNoteId": "12311312" - } - ] - } - } - + "data": [ + { + "caseNoteId": "12311312" + } + ], + "pagination": { + "isLastPage": true, + "count": 1, + "page": 1, + "perPage": 10, + "totalCount": 1, + "totalPages": 1 + } + } """.removeWhitespaceAndNewlines(), ) } From 74e68fb318d597f22c13c5f16f8cf20b6c41237f Mon Sep 17 00:00:00 2001 From: Chiara Date: Mon, 12 Feb 2024 14:01:05 +0000 Subject: [PATCH 18/20] changed schema --- openapi.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/openapi.yml b/openapi.yml index 5643240b2..3ef0d0816 100644 --- a/openapi.yml +++ b/openapi.yml @@ -828,11 +828,16 @@ components: ageAtRelease: type: integer format: int64 - CaseNote: + CaseNoteData: type: object properties: - caseNoteId: - type: string + caseNotes: + type: array + minItems: 0 + items: + $ref: "#/components/schemas/CaseNoteData" + pagination: + $ref: "#/components/schemas/Pagination" CaseSentence: required: - date @@ -1185,8 +1190,6 @@ components: canRemove: type: boolean nullable: true - CaseNoteData: - type: string Pagination: type: object properties: From 4e1e685c0693b574e9db9ae55bdf67a43c0d4b6d Mon Sep 17 00:00:00 2001 From: Chiara Date: Tue, 13 Feb 2024 10:05:23 +0000 Subject: [PATCH 19/20] Edits --- openapi.yml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/openapi.yml b/openapi.yml index 3ef0d0816..36abe7ce7 100644 --- a/openapi.yml +++ b/openapi.yml @@ -527,7 +527,15 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/CaseNoteData" + type: object + properties: + data: + type: array + minItems: 0 + items: + $ref: "#/components/schemas/CaseNoteData" + pagination: + $ref: "#/components/schemas/Pagination" "404": description: Failed to find case notes for a person with the provided HMPPS ID. content: @@ -835,9 +843,13 @@ components: type: array minItems: 0 items: - $ref: "#/components/schemas/CaseNoteData" - pagination: - $ref: "#/components/schemas/Pagination" + $ref: "#/components/schemas/CaseNote" + CaseNote: + type: object + properties: + caseNoteId: + type: string + example: 1234 CaseSentence: required: - date From a28d20fad129bca1ea2de7bc8c9bd686e327133b Mon Sep 17 00:00:00 2001 From: Chiara Date: Tue, 13 Feb 2024 10:45:00 +0000 Subject: [PATCH 20/20] Removing parent --- openapi.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/openapi.yml b/openapi.yml index 36abe7ce7..00b37dee6 100644 --- a/openapi.yml +++ b/openapi.yml @@ -533,7 +533,7 @@ paths: type: array minItems: 0 items: - $ref: "#/components/schemas/CaseNoteData" + $ref: "#/components/schemas/CaseNote" pagination: $ref: "#/components/schemas/Pagination" "404": @@ -836,14 +836,6 @@ components: ageAtRelease: type: integer format: int64 - CaseNoteData: - type: object - properties: - caseNotes: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/CaseNote" CaseNote: type: object properties: