diff --git a/hearing-integration-test/src/test/java/uk/gov/moj/cpp/hearing/it/HearingForTodayIT.java b/hearing-integration-test/src/test/java/uk/gov/moj/cpp/hearing/it/HearingForTodayIT.java index 5b947bac5..11d3f116c 100644 --- a/hearing-integration-test/src/test/java/uk/gov/moj/cpp/hearing/it/HearingForTodayIT.java +++ b/hearing-integration-test/src/test/java/uk/gov/moj/cpp/hearing/it/HearingForTodayIT.java @@ -1,10 +1,13 @@ package uk.gov.moj.cpp.hearing.it; +import static com.google.common.collect.ImmutableMap.of; import static java.time.LocalDate.now; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static java.util.UUID.randomUUID; import static javax.ws.rs.core.Response.Status.OK; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.hasItem; @@ -33,7 +36,9 @@ import static uk.gov.moj.cpp.hearing.test.matchers.BeanMatcher.isBean; import static uk.gov.moj.cpp.hearing.utils.RestUtils.poll; import static uk.gov.moj.cpp.hearing.utils.WireMockStubUtils.setupAsMagistrateUser; +import static uk.gov.moj.cpp.hearing.utils.WireMockStubUtils.setupAsSystemUser; import static uk.gov.moj.cpp.hearing.utils.WireMockStubUtils.stubUsersAndGroupsUserRoles; +import static uk.gov.moj.cpp.platform.test.feature.toggle.FeatureStubber.stubFeaturesFor; import uk.gov.justice.core.courts.ApplicationStatus; import uk.gov.justice.core.courts.BreachType; @@ -54,6 +59,8 @@ import uk.gov.justice.core.courts.SummonsTemplateType; import uk.gov.justice.hearing.courts.CourtApplicationSummaries; import uk.gov.justice.hearing.courts.GetHearings; +import uk.gov.justice.hearing.courts.HearingCases; +import uk.gov.justice.hearing.courts.HearingCasesForDay; import uk.gov.justice.hearing.courts.HearingSummaries; import uk.gov.justice.services.common.http.HeaderConstants; import uk.gov.justice.services.test.utils.core.http.RequestParams; @@ -68,6 +75,7 @@ import java.util.UUID; import java.util.concurrent.TimeUnit; +import com.google.common.collect.ImmutableMap; import org.hamcrest.Matcher; import org.junit.jupiter.api.Test; @@ -272,6 +280,38 @@ public void shouldRetrieveApplicationWithCourtOrderHearingForTodayForLoggedOnUse ); } + @Test + public void shouldRetrieveHearingCasesForDayForSystemUser() { + final UUID userId = randomUUID(); + setupAsSystemUser(userId); + stubUsersAndGroupsUserRoles(getLoggedInUser()); + final ImmutableMap features = of("hearingCasesForDay", true); + stubFeaturesFor("hearing", features); + + final UUID hearingId = randomUUID(); + final UUID courtCentreId = randomUUID(); + final UUID roomId = randomUUID(); + final InitiateHearingCommand initiateHearingCommand = createHearingForToday(hearingId, courtCentreId, roomId, userId, null); + final String hearingDate = initiateHearingCommand.getHearing().getHearingDays().get(0).getSittingDay().toLocalDate().toString(); + + initiateHearing(getRequestSpec(), initiateHearingCommand); + + final String response = getHearingCasesForDayPollForMatch(userId, hearingDate, 30, isBean(HearingCasesForDay.class) + .with(HearingCasesForDay::getHearingCases, hasSize(greaterThanOrEqualTo(1))) + .with(HearingCasesForDay::getHearingCases, hasItem(isBean(HearingCases.class) + .with(HearingCases::getHearingId, is(hearingId)) + .with(HearingCases::getCourtCentreId, is(courtCentreId)) + .with(HearingCases::getCourtRoomId, is(roomId)) + .with(HearingCases::getHearingDate, is(LocalDate.now().toString())) + ) + ) + ); + + //adding dummy assertion, real checks are inside the isBean(...) matcher + System.out.println(response); + assertThat(response, containsString(hearingId.toString())); + } + private static void getHearingForTodayPollForMatch(final UUID userId, final long timeout, final BeanMatcher resultMatcher) { final RequestParams requestParams = requestParams(getURL("hearing.get.hearings-for-today"), "application/vnd.hearing.get.hearings-for-today+json") .withHeader(HeaderConstants.USER_ID, userId) @@ -286,6 +326,20 @@ private static void getHearingForTodayPollForMatch(final UUID userId, final long ); } + private static String getHearingCasesForDayPollForMatch(final UUID userId, final String date, final long timeout, final BeanMatcher resultMatcher) { + final RequestParams requestParams = requestParams(getURL("hearing.get.hearing-cases-for-day", date), "application/vnd.hearing.get.hearing-cases-for-day+json") + .withHeader(HeaderConstants.USER_ID, userId) + .build(); + + final Matcher expectedConditions = allOf(status().is(OK), jsonPayloadMatchesBean(HearingCasesForDay.class, resultMatcher)); + return poll(requestParams) + .timeout(timeout, TimeUnit.SECONDS) + .until( + status().is(OK), + expectedConditions + ).getPayload(); + } + private InitiateHearingCommand createHearingForToday(final UUID hearingId, final UUID courtCentreId, final UUID roomId, final UUID userId, List courtApplicationList) { final UUID prosecutionCaseId = randomUUID(); diff --git a/hearing-integration-test/src/test/resources/endpoint.properties b/hearing-integration-test/src/test/resources/endpoint.properties index 410331f61..b9571b199 100644 --- a/hearing-integration-test/src/test/resources/endpoint.properties +++ b/hearing-integration-test/src/test/resources/endpoint.properties @@ -6,6 +6,7 @@ hearing.get.hearing=/hearing-service/query/api/rest/hearing/hearings/{0} hearing.get.hearing-for-manage-hearing=/hearing-service/query/api/rest/hearing/hearings/{0} hearing.get.hearings=/hearing-service/query/api/rest/hearing/hearings?date={0}&startTime={1}&endTime={2}&courtCentreId={3}&roomId={4} hearing.get.hearings-for-today=/hearing-service/query/api/rest/hearing/hearings-for-today +hearing.get.hearing-cases-for-day=/hearing-service/query/api/rest/hearing/hearing-cases-for-day?date={0} hearing.get-draft-result=hearing-service/query/api/rest/hearing/hearings/{0}/draft-result hearing.get-draft-result-v2=hearing-service/query/api/rest/hearing/hearings/{0}/{1}/draft-result hearing.get-results=hearing-service/query/api/rest/hearing/hearings/{0}/{1} diff --git a/hearing-json/src/main/resources/json/schema/query/hearing.get.hearing-cases-for-day.json b/hearing-json/src/main/resources/json/schema/query/hearing.get.hearing-cases-for-day.json new file mode 100644 index 000000000..21268bcb3 --- /dev/null +++ b/hearing-json/src/main/resources/json/schema/query/hearing.get.hearing-cases-for-day.json @@ -0,0 +1,42 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "http://justice.gov.uk/hearing/courts/get.hearing-cases-for-day.json", + "type": "object", + "properties": { + "hearingCases": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/hearingCase" + } + } + }, + "additionalProperties": false, + "definitions": { + "hearingCase": { + "type": "object", + "properties": { + "hearingId": { + "$ref": "http://justice.gov.uk/domain/core/common/definitions.json#/definitions/uuid" + }, + "courtCentreId": { + "$ref": "http://justice.gov.uk/domain/core/common/definitions.json#/definitions/uuid" + }, + "courtRoomId": { + "$ref": "http://justice.gov.uk/domain/core/common/definitions.json#/definitions/uuid" + }, + "hearingDate": { + "type": "string", + "format": "date" + }, + "prosecutionCases": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "http://justice.gov.uk/domain/core/common/definitions.json#/definitions/uuid" + } + } + } + } + } +} \ No newline at end of file diff --git a/hearing-query/hearing-query-api/src/main/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApi.java b/hearing-query/hearing-query-api/src/main/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApi.java index d01e5eb57..9d115d4d2 100644 --- a/hearing-query/hearing-query-api/src/main/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApi.java +++ b/hearing-query/hearing-query-api/src/main/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApi.java @@ -1,24 +1,27 @@ package uk.gov.moj.cpp.hearing.query.api; import static java.util.UUID.fromString; -import static uk.gov.justice.services.messaging.JsonObjects.createArrayBuilder; -import static uk.gov.justice.services.messaging.JsonObjects.createObjectBuilder; import static uk.gov.justice.services.core.enveloper.Enveloper.envelop; import static uk.gov.justice.services.messaging.JsonEnvelope.envelopeFrom; import static uk.gov.justice.services.messaging.JsonEnvelope.metadataFrom; +import static uk.gov.justice.services.messaging.JsonObjects.createArrayBuilder; +import static uk.gov.justice.services.messaging.JsonObjects.createObjectBuilder; import static uk.gov.justice.services.messaging.JsonObjects.getString; import static uk.gov.justice.services.messaging.JsonObjects.getUUID; import uk.gov.justice.core.courts.CrackedIneffectiveTrial; import uk.gov.justice.hearing.courts.GetHearings; +import uk.gov.justice.hearing.courts.HearingCasesForDay; import uk.gov.justice.services.common.converter.JsonObjectToObjectConverter; import uk.gov.justice.services.common.converter.ObjectToJsonObjectConverter; +import uk.gov.justice.services.core.accesscontrol.AccessControlViolationException; import uk.gov.justice.services.core.annotation.Component; import uk.gov.justice.services.core.annotation.Handles; import uk.gov.justice.services.core.annotation.ServiceComponent; import uk.gov.justice.services.core.dispatcher.EnvelopePayloadTypeConverter; import uk.gov.justice.services.core.dispatcher.JsonEnvelopeRepacker; import uk.gov.justice.services.core.enveloper.Enveloper; +import uk.gov.justice.services.core.featurecontrol.FeatureControlGuard; import uk.gov.justice.services.core.requester.Requester; import uk.gov.justice.services.messaging.Envelope; import uk.gov.justice.services.messaging.JsonEnvelope; @@ -60,7 +63,6 @@ import java.util.stream.Collectors; import javax.inject.Inject; - import javax.json.JsonObject; import javax.json.JsonValue; import javax.ws.rs.BadRequestException; @@ -80,6 +82,7 @@ public class HearingQueryApi { private static final String GET_HEARING_EVENT_LOG_COUNT = "hearing.get-hearing-event-log-count"; private static final String GET_HEARING_EVENT_LOG_FOR_DOCUMENTS= "hearing.get-hearing-event-log-for-documents"; private static final String NO_LOGGED_IN_USER_ID_FOUND_TO_PERFORM_HEARINGS_SEARCH = "No Logged in UserId found to perform hearings search"; + private static final String FEATURE_HEARING_CASES_FOR_DAY = "hearingCasesForDay"; @Inject private Requester requester; @@ -140,6 +143,9 @@ public class HearingQueryApi { @Inject private ObjectToJsonObjectConverter objectToJsonObjectConverter; + @Inject + private FeatureControlGuard featureControlGuard; + @Handles("hearing.get.hearings") public JsonEnvelope findHearings(final JsonEnvelope query) { @@ -155,6 +161,21 @@ public JsonEnvelope findHearings(final JsonEnvelope query) { return getJsonEnvelope(envelope); } + @Handles("hearing.get.hearing-cases-for-day") + public JsonEnvelope findHearingCasesForDay(final JsonEnvelope query) { + final Optional optionalUserId = query.metadata().userId(); + if (optionalUserId.isEmpty()) { + throw new BadRequestException(NO_LOGGED_IN_USER_ID_FOUND_TO_PERFORM_HEARINGS_SEARCH); + } + + if (!featureControlGuard.isFeatureEnabled(FEATURE_HEARING_CASES_FOR_DAY)){ + throw new AccessControlViolationException("Forbidden! 'get.hearing-cases-for-day' feature not enabled."); + } + + final Envelope envelope = this.hearingQueryView.findHearingCasesForDay(query); + return getJsonEnvelope(envelope); + } + @Handles("hearing.get.hearings-check-in") public JsonEnvelope getHearingCheckIn(final JsonEnvelope query) { diff --git a/hearing-query/hearing-query-api/src/main/resources/uk/gov/moj/cpp/hearing/query/api/accesscontrol/hearing-query-api.drl b/hearing-query/hearing-query-api/src/main/resources/uk/gov/moj/cpp/hearing/query/api/accesscontrol/hearing-query-api.drl index 8890cc837..2c28673a2 100644 --- a/hearing-query/hearing-query-api/src/main/resources/uk/gov/moj/cpp/hearing/query/api/accesscontrol/hearing-query-api.drl +++ b/hearing-query/hearing-query-api/src/main/resources/uk/gov/moj/cpp/hearing/query/api/accesscontrol/hearing-query-api.drl @@ -15,6 +15,15 @@ rule "Query - API - hearing.get.hearings" $outcome.setSuccess(true); end +rule "Query - API - hearing.get.hearing-cases-for-day" + when + $outcome: Outcome(); + $action: Action(name == "hearing.get.hearing-cases-for-day"); + eval(userAndGroupProvider.isMemberOfAnyOfTheSuppliedGroups($action, "System Users")); + then + $outcome.setSuccess(true); +end + rule "Query - API - hearing.get.hearings-check-in" when $outcome: Outcome(); diff --git a/hearing-query/hearing-query-api/src/raml/hearing-query-api.raml b/hearing-query/hearing-query-api/src/raml/hearing-query-api.raml index 512687f2e..8d4179e14 100644 --- a/hearing-query/hearing-query-api/src/raml/hearing-query-api.raml +++ b/hearing-query/hearing-query-api/src/raml/hearing-query-api.raml @@ -244,6 +244,27 @@ protocols: [ HTTP, HTTPS ] example: !include json/hearing.get.hearings.json schema: !include json/schema/hearing.get.hearings.json +/hearing-cases-for-day: + get: + description: | + ... + (mapping): + responseType: application/vnd.hearing.get.hearing-cases-for-day+json + name: hearing.get.hearing-cases-for-day + ... + queryParameters: + date: + description: date of hearing in yyyy-MM-dd format + type: string + required: true + + responses: + 200: + description: OK + body: + application/vnd.hearing.get.hearing-cases-for-day+json: + example: !include json/hearing.get.hearing-cases-for-day.json + schema: !include json/schema/hearing.get.hearing-cases-for-day.json /hearings-check-in: get: diff --git a/hearing-query/hearing-query-api/src/raml/json/hearing.get.hearing-cases-for-day.json b/hearing-query/hearing-query-api/src/raml/json/hearing.get.hearing-cases-for-day.json new file mode 100644 index 000000000..df2d8f0f2 --- /dev/null +++ b/hearing-query/hearing-query-api/src/raml/json/hearing.get.hearing-cases-for-day.json @@ -0,0 +1,22 @@ +{ + "hearingCases": [ + { + "courtCentreId": "135cc630-f141-40b5-ae30-7615b0faa367", + "courtRoomId": "50168b64-ab8e-450f-9e90-feb7c71b83cd", + "hearingDate": "2026-07-16", + "hearingId": "394f3d42-2dfb-4e45-808a-b76a62f76438", + "prosecutionCases": [ + "378e4ea9-f759-4aef-af78-3a440f6b5d94" + ] + }, + { + "courtCentreId": "1a5af776-f775-4328-9d93-9ab333f2ca10", + "courtRoomId": "649502e5-184c-44c1-9a72-fc93e85a3ff0", + "hearingDate": "2026-07-16", + "hearingId": "740aff61-6492-4030-93d1-ac4291405379", + "prosecutionCases": [ + "03ede5fd-d72d-4769-aa69-5d28a831fdf3" + ] + } + ] +} \ No newline at end of file diff --git a/hearing-query/hearing-query-api/src/raml/json/schema/hearing.get.hearing-cases-for-day.json b/hearing-query/hearing-query-api/src/raml/json/schema/hearing.get.hearing-cases-for-day.json new file mode 100644 index 000000000..d2e6628b7 --- /dev/null +++ b/hearing-query/hearing-query-api/src/raml/json/schema/hearing.get.hearing-cases-for-day.json @@ -0,0 +1,53 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "http://justice.gov.uk/hearing/courts/get.hearing-cases-for-day.json", + "type": "object", + "properties": { + "hearingCases": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/hearingCase" + } + } + }, + "additionalProperties": false, + "definitions": { + "hearingCase": { + "type": "object", + "properties": { + "hearingId": { + "$ref": "http://justice.gov.uk/domain/core/common/definitions.json#/definitions/uuid" + }, + "courtCentreId": { + "$ref": "http://justice.gov.uk/domain/core/common/definitions.json#/definitions/uuid" + }, + "courtRoomId": { + "$ref": "http://justice.gov.uk/domain/core/common/definitions.json#/definitions/uuid" + }, + "hearingDate": { + "type": "string", + "format": "date" + }, + "prosecutionCases": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/caseSummary" + } + } + } + }, + "caseSummary": { + "type": "object", + "properties": { + "caseId": { + "$ref": "http://justice.gov.uk/domain/core/common/definitions.json#/definitions/uuid" + }, + "prosecutionCaseIdentifier": { + "$ref": "http://justice.gov.uk/core/courts/prosecutionCaseIdentifier.json" + } + } + } + } +} \ No newline at end of file diff --git a/hearing-query/hearing-query-api/src/test/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApiAccessControlTest.java b/hearing-query/hearing-query-api/src/test/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApiAccessControlTest.java index 4bd6177cb..1754b945a 100644 --- a/hearing-query/hearing-query-api/src/test/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApiAccessControlTest.java +++ b/hearing-query/hearing-query-api/src/test/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApiAccessControlTest.java @@ -23,6 +23,7 @@ public class HearingQueryApiAccessControlTest extends BaseDroolsAccessControlTes private static final String ACTION_NAME_GET_HEARING = "hearing.get.hearing"; private static final String ACTION_NAME_GET_HEARINGS = "hearing.get.hearings"; + private static final String ACTION_NAME_GET_HEARING_CASES_FOR_DAY = "hearing.get.hearing-cases-for-day"; private static final String ACTION_NAME_GET_HEARINGS_FOR_TODAY = "hearing.get.hearings-for-today"; private static final String ACTION_NAME_GET_DRAFT_RESULT = "hearing.get-draft-result"; private static final String ACTION_NAME_GET_RESULTS = "hearing.get-results"; @@ -72,6 +73,16 @@ public void shouldNotAllowUserInUnauthorisedGroupToGetHearingsByDateV2() { assertFailureOutcomeOnActionForTheSuppliedGroups(ACTION_NAME_GET_HEARINGS, "Listing Officers", "Court Clerks", "Legal Advisers", "Judiciary", "Court Associate", "Deputies", "DJMC", "Judge", "CPS", "Non CPS Prosecutors", "Advocates", "Defence Users", "Recorders", "Defence Lawyers", "Court Administrators"); } + @Test + public void shouldAllowUserInAuthorisedSystemUsersGroupToGetHearingCasesForDay() { + assertSuccessfulOutcomeOnActionForTheSuppliedGroups(ACTION_NAME_GET_HEARING_CASES_FOR_DAY, "System Users"); + } + + @Test + public void shouldNotAllowUserInUnauthorisedGroupToGetHearingCasesForDay() { + assertFailureOutcomeOnActionForTheSuppliedGroups(ACTION_NAME_GET_HEARING_CASES_FOR_DAY, "System Users"); + } + @Test public void shouldAllowUserInAuthorisedGroupToGetHearingsForToday() { assertSuccessfulOutcomeOnActionForTheSuppliedGroups(ACTION_NAME_GET_HEARINGS_FOR_TODAY, "Magistrates"); diff --git a/hearing-query/hearing-query-api/src/test/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApiTest.java b/hearing-query/hearing-query-api/src/test/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApiTest.java index 64fe5f911..0cfcf4241 100644 --- a/hearing-query/hearing-query-api/src/test/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApiTest.java +++ b/hearing-query/hearing-query-api/src/test/java/uk/gov/moj/cpp/hearing/query/api/HearingQueryApiTest.java @@ -28,11 +28,14 @@ import uk.gov.justice.core.courts.CrackedIneffectiveTrial; import uk.gov.justice.hearing.courts.GetHearings; +import uk.gov.justice.hearing.courts.HearingCasesForDay; import uk.gov.justice.services.common.converter.JsonObjectToObjectConverter; import uk.gov.justice.services.common.converter.ObjectToJsonObjectConverter; +import uk.gov.justice.services.core.accesscontrol.AccessControlViolationException; import uk.gov.justice.services.core.annotation.Handles; import uk.gov.justice.services.core.dispatcher.EnvelopePayloadTypeConverter; import uk.gov.justice.services.core.dispatcher.JsonEnvelopeRepacker; +import uk.gov.justice.services.core.featurecontrol.FeatureControlGuard; import uk.gov.justice.services.core.requester.Requester; import uk.gov.justice.services.messaging.Envelope; import uk.gov.justice.services.messaging.JsonEnvelope; @@ -140,6 +143,9 @@ public class HearingQueryApiTest { @Mock private Envelope mockGetHearingsEnvelope; + @Mock + private Envelope mockHearingCasesForDayEnvelope; + @Mock private Envelope mockSessionTimeResponse; @@ -212,6 +218,9 @@ public class HearingQueryApiTest { @Mock private ObjectToJsonObjectConverter objectToJsonObjectConverter; + @Mock + private FeatureControlGuard featureControlGuard; + @Mock private Permissions mockPermissions; @@ -794,6 +803,51 @@ public void shouldInitPIEventMapperCacheAndReturnCppHearingEventIds(){ assertThat(set.size(),is(32)); } + // ── findHearingCasesForDay ────────────────────────────────────────────────── + @Test + public void findHearingCasesForDay_shouldDelegateToViewAndReturnRepacked() { + final UUID userId = randomUUID(); + + final JsonEnvelope query = mock(JsonEnvelope.class, RETURNS_DEEP_STUBS); + when(query.metadata().userId()).thenReturn(Optional.of(userId.toString())); + + when(featureControlGuard.isFeatureEnabled("hearingCasesForDay")).thenReturn(true); + when(hearingQueryView.findHearingCasesForDay(eq(query))).thenReturn(mockHearingCasesForDayEnvelope); + when(mockEnvelopePayloadTypeConverter.convert(any(), any(Class.class))) + .thenReturn(mockJsonValueEnvelope); + when(mockJsonEnvelopeRepacker.repack(mockJsonValueEnvelope)).thenReturn(mockJsonEnvelope); + + final JsonEnvelope result = hearingQueryApi.findHearingCasesForDay(query); + + verify(hearingQueryView).findHearingCasesForDay(eq(query)); + verify(mockJsonEnvelopeRepacker).repack(mockJsonValueEnvelope); + assertThat(result, is(mockJsonEnvelope)); + } + + @Test + public void findHearingCasesForDay_shouldThrowBadRequestExceptionWhenNoUserIdPresent() { + final JsonEnvelope query = mock(JsonEnvelope.class, RETURNS_DEEP_STUBS); + when(query.metadata().userId()).thenReturn(Optional.empty()); + + assertThrows(BadRequestException.class, () -> hearingQueryApi.findHearingCasesForDay(query)); + + verify(featureControlGuard, never()).isFeatureEnabled(anyString()); + verify(hearingQueryView, never()).findHearingCasesForDay(any()); + } + + @Test + public void findHearingCasesForDay_shouldThrowAccessControlViolationExceptionWhenFeatureDisabled() { + final UUID userId = randomUUID(); + + final JsonEnvelope query = mock(JsonEnvelope.class, RETURNS_DEEP_STUBS); + when(query.metadata().userId()).thenReturn(Optional.of(userId.toString())); + when(featureControlGuard.isFeatureEnabled("hearingCasesForDay")).thenReturn(false); + + assertThrows(AccessControlViolationException.class, () -> hearingQueryApi.findHearingCasesForDay(query)); + + verify(hearingQueryView, never()).findHearingCasesForDay(any()); + } + // ── getHearingCheckIn ────────────────────────────────────────────────── @Test diff --git a/hearing-query/hearing-query-view/src/main/java/uk/gov/moj/cpp/hearing/query/view/HearingQueryView.java b/hearing-query/hearing-query-view/src/main/java/uk/gov/moj/cpp/hearing/query/view/HearingQueryView.java index 7ba571e18..6c41e9611 100644 --- a/hearing-query/hearing-query-view/src/main/java/uk/gov/moj/cpp/hearing/query/view/HearingQueryView.java +++ b/hearing-query/hearing-query-view/src/main/java/uk/gov/moj/cpp/hearing/query/view/HearingQueryView.java @@ -5,18 +5,19 @@ import static java.util.UUID.fromString; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; -import static uk.gov.justice.services.messaging.JsonObjects.createObjectBuilder; import static org.apache.commons.lang3.StringUtils.defaultIfEmpty; import static org.apache.commons.lang3.StringUtils.isEmpty; import static uk.gov.justice.services.core.annotation.Component.QUERY_VIEW; import static uk.gov.justice.services.core.enveloper.Enveloper.envelop; import static uk.gov.justice.services.messaging.JsonEnvelope.envelopeFrom; +import static uk.gov.justice.services.messaging.JsonObjects.createObjectBuilder; import static uk.gov.justice.services.messaging.JsonObjects.getString; import static uk.gov.justice.services.messaging.JsonObjects.getUUID; import uk.gov.justice.core.courts.CrackedIneffectiveTrial; import uk.gov.justice.core.courts.Defendant; import uk.gov.justice.hearing.courts.GetHearings; +import uk.gov.justice.hearing.courts.HearingCasesForDay; import uk.gov.justice.services.common.converter.JsonObjectToObjectConverter; import uk.gov.justice.services.common.converter.LocalDates; import uk.gov.justice.services.common.converter.ObjectToJsonValueConverter; @@ -63,7 +64,6 @@ import java.util.stream.Stream; import javax.inject.Inject; - import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonObjectBuilder; @@ -147,6 +147,16 @@ public Envelope findHearings(final JsonEnvelope envelope, .withMetadataFrom(envelope); } + public Envelope findHearingCasesForDay(final JsonEnvelope envelope) { + final JsonObject payload = envelope.payloadAsJsonObject(); + final LocalDate date = LocalDates.from(payload.getString(FIELD_DATE)); + + final HearingCasesForDay hearingCasesForDay = hearingService.getHearingCasesForDay(date); + return envelop(hearingCasesForDay) + .withName("hearing.get.hearing-cases-for-day") + .withMetadataFrom(envelope); + } + public Envelope getHearingCheckIn(final JsonEnvelope envelope, final List accessibleCasesAndApplicationIds, final boolean isDDJorRecorder) { diff --git a/hearing-query/hearing-query-view/src/main/java/uk/gov/moj/cpp/hearing/query/view/service/GetHearingCaseTransformer.java b/hearing-query/hearing-query-view/src/main/java/uk/gov/moj/cpp/hearing/query/view/service/GetHearingCaseTransformer.java new file mode 100644 index 000000000..f46c77c96 --- /dev/null +++ b/hearing-query/hearing-query-view/src/main/java/uk/gov/moj/cpp/hearing/query/view/service/GetHearingCaseTransformer.java @@ -0,0 +1,58 @@ +package uk.gov.moj.cpp.hearing.query.view.service; + +import static java.util.Collections.emptyList; +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; +import static java.util.stream.Collectors.toList; +import static org.apache.commons.collections.CollectionUtils.isNotEmpty; + +import uk.gov.justice.core.courts.Hearing; +import uk.gov.justice.core.courts.HearingDay; +import uk.gov.justice.core.courts.ProsecutionCase; +import uk.gov.justice.hearing.courts.HearingCases; + +import java.time.LocalDate; +import java.util.List; + +public class GetHearingCaseTransformer { + + public HearingCases.Builder hearingCases(final Hearing hearing, final LocalDate date) { + + return HearingCases.hearingCases() + .withHearingId(hearing.getId()) + .withCourtCentreId(hearing.getCourtCentre().getId()) + .withCourtRoomId(hearing.getCourtCentre().getRoomId()) + .withHearingDate(getHearingDate(hearing.getHearingDays(), date)) + .withProsecutionCases( + hearing.getProsecutionCases() == null ? emptyList() : + hearing.getProsecutionCases().stream() + .filter(pc -> shouldCaseBeIncluded(hearing, pc)) + .map(ProsecutionCase::getId) + .collect(toList()) + ); + } + + private String getHearingDate(final List hearingDays, final LocalDate date) { + if (isNotEmpty(hearingDays)) { + return hearingDays.stream() + .map(hd -> hd.getSittingDay().toLocalDate()) + .filter(date::equals) + .findFirst() + .map(LocalDate::toString) + .orElse(hearingDays.get(0).getSittingDay().toLocalDate().toString()); // defensive fallback; shouldn't hit since the repo already filtered on this date + } + return null; + } + + private boolean shouldCaseBeIncluded(final Hearing hearing, final ProsecutionCase pc) { + if (nonNull(hearing.getIsGroupProceedings()) && hearing.getIsGroupProceedings()) { + if (nonNull(pc.getIsGroupMaster()) && pc.getIsGroupMaster()) { + return true; + } else { + return isNull(pc.getIsGroupMember()) || !(pc.getIsGroupMember()); + } + } else { + return true; + } + } +} diff --git a/hearing-query/hearing-query-view/src/main/java/uk/gov/moj/cpp/hearing/query/view/service/HearingService.java b/hearing-query/hearing-query-view/src/main/java/uk/gov/moj/cpp/hearing/query/view/service/HearingService.java index 900a6801e..82614a007 100644 --- a/hearing-query/hearing-query-view/src/main/java/uk/gov/moj/cpp/hearing/query/view/service/HearingService.java +++ b/hearing-query/hearing-query-view/src/main/java/uk/gov/moj/cpp/hearing/query/view/service/HearingService.java @@ -29,6 +29,7 @@ import uk.gov.justice.core.courts.CourtApplication; import uk.gov.justice.core.courts.CrackedIneffectiveTrial; import uk.gov.justice.hearing.courts.GetHearings; +import uk.gov.justice.hearing.courts.HearingCasesForDay; import uk.gov.justice.hearing.courts.HearingSummaries; import uk.gov.justice.services.common.converter.JsonObjectToObjectConverter; import uk.gov.justice.services.common.converter.ObjectToJsonObjectConverter; @@ -169,6 +170,8 @@ public class HearingService { @Inject private GetHearingsTransformer getHearingTransformer; @Inject + private GetHearingCaseTransformer getHearingCaseTransformer; + @Inject private TimelineHearingSummaryHelper timelineHearingSummaryHelper; @Inject private HearingListXhibitResponseTransformer hearingListXhibitResponseTransformer; @@ -382,6 +385,26 @@ public GetHearings getHearings(final LocalDate date, final String startTime, .build(); } + @Transactional + public HearingCasesForDay getHearingCasesForDay(final LocalDate date) { + if (isNull(date)) { + return new HearingCasesForDay(null); + } + + final List hearingsForDay = hearingRepository.findHearings(date); + if (isEmpty(hearingsForDay)) { + return new HearingCasesForDay(null); + } + + return HearingCasesForDay.hearingCasesForDay() + .withHearingCases(hearingsForDay.stream() + .map(ha -> hearingJPAMapper.fromJPAMinimal(ha)) + .filter(ha -> isNotEmpty(ha.getProsecutionCases())) + .map(h -> getHearingCaseTransformer.hearingCases(h, date).build()) + .distinct() + .toList()) + .build(); + } @Transactional public GetHearings getHearingsForCheckIn(final LocalDate date, final UUID courtCentreId, final UUID roomId, diff --git a/hearing-query/hearing-query-view/src/test/java/uk/gov/moj/cpp/hearing/query/view/HearingQueryTest.java b/hearing-query/hearing-query-view/src/test/java/uk/gov/moj/cpp/hearing/query/view/HearingQueryTest.java index 0a63bb634..15b5a1b47 100644 --- a/hearing-query/hearing-query-view/src/test/java/uk/gov/moj/cpp/hearing/query/view/HearingQueryTest.java +++ b/hearing-query/hearing-query-view/src/test/java/uk/gov/moj/cpp/hearing/query/view/HearingQueryTest.java @@ -1,6 +1,5 @@ package uk.gov.moj.cpp.hearing.query.view; -import static com.google.common.io.Resources.getResource; import static com.jayway.jsonpath.matchers.JsonPathMatchers.withJsonPath; import static java.time.ZonedDateTime.now; import static java.util.Arrays.asList; @@ -11,8 +10,6 @@ import static java.util.Optional.of; import static java.util.UUID.fromString; import static java.util.UUID.randomUUID; -import static uk.gov.justice.services.messaging.JsonObjects.createArrayBuilder; -import static uk.gov.justice.services.messaging.JsonObjects.createObjectBuilder; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.is; @@ -32,7 +29,11 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static uk.gov.justice.core.courts.ApprovalType.CHANGE; +import static uk.gov.justice.hearing.courts.HearingCases.hearingCases; +import static uk.gov.justice.hearing.courts.HearingCasesForDay.hearingCasesForDay; import static uk.gov.justice.services.messaging.JsonEnvelope.envelopeFrom; +import static uk.gov.justice.services.messaging.JsonObjects.createArrayBuilder; +import static uk.gov.justice.services.messaging.JsonObjects.createObjectBuilder; import static uk.gov.justice.services.messaging.spi.DefaultJsonMetadata.metadataBuilder; import static uk.gov.justice.services.test.utils.core.enveloper.EnveloperFactory.createEnveloper; import static uk.gov.justice.services.test.utils.core.matchers.JsonEnvelopeMatcher.jsonEnvelope; @@ -54,6 +55,7 @@ import uk.gov.justice.core.courts.ProsecutionCase; import uk.gov.justice.core.courts.Target; import uk.gov.justice.hearing.courts.GetHearings; +import uk.gov.justice.hearing.courts.HearingCasesForDay; import uk.gov.justice.services.common.converter.JsonObjectToObjectConverter; import uk.gov.justice.services.common.converter.ObjectToJsonValueConverter; import uk.gov.justice.services.common.converter.StringToJsonObjectConverter; @@ -110,7 +112,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; - import javax.json.JsonArray; import javax.json.JsonObject; import javax.persistence.NoResultException; @@ -1062,6 +1063,22 @@ public void shouldFindHearings() { assertThat(hearings.metadata().name(), is("hearing.get.hearings")); } + @Test + public void findHearingCasesForDay() { + final LocalDate date = LocalDate.now(); + final JsonEnvelope envelope = envelopeFrom(metadataBuilder().withId(randomUUID()) + .withName("hearing.get.hearing-cases-for-day"), + createObjectBuilder() + .add("date", date.toString()) + .build()); + when(hearingService.getHearingCasesForDay(date)).thenReturn(hearingCasesForDay().withHearingCases(List.of(hearingCases().withHearingId(randomUUID()).build())).build()); + + final Envelope hearings = target.findHearingCasesForDay(envelope); + + assertThat(hearings.payload().getHearingCases().size(), is(1)); + assertThat(hearings.metadata().name(), is("hearing.get.hearing-cases-for-day")); + } + @Test public void shouldFindHearingsForToday() { final String userId = randomUUID().toString(); diff --git a/hearing-query/hearing-query-view/src/test/java/uk/gov/moj/cpp/hearing/query/view/service/GetHearingCaseTransformerTest.java b/hearing-query/hearing-query-view/src/test/java/uk/gov/moj/cpp/hearing/query/view/service/GetHearingCaseTransformerTest.java new file mode 100644 index 000000000..4d7c1a0b5 --- /dev/null +++ b/hearing-query/hearing-query-view/src/test/java/uk/gov/moj/cpp/hearing/query/view/service/GetHearingCaseTransformerTest.java @@ -0,0 +1,91 @@ +package uk.gov.moj.cpp.hearing.query.view.service; + +import static java.util.Collections.emptyList; +import static java.util.UUID.randomUUID; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static uk.gov.justice.core.courts.CourtCentre.courtCentre; +import static uk.gov.justice.core.courts.Hearing.hearing; +import static uk.gov.justice.core.courts.ProsecutionCase.prosecutionCase; +import static uk.gov.justice.core.courts.ProsecutionCaseIdentifier.prosecutionCaseIdentifier; + +import uk.gov.justice.core.courts.Hearing; +import uk.gov.justice.core.courts.HearingDay; +import uk.gov.justice.hearing.courts.HearingCases; + +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.Test; + +class GetHearingCaseTransformerTest { + + private final GetHearingCaseTransformer transformer = new GetHearingCaseTransformer(); + + @Test + void shouldTransformHearingWithNullProsecutionCasesAndHearingDate() { + final UUID hearingId = randomUUID(); + final UUID courtCentreId = randomUUID(); + final UUID roomId = randomUUID(); + final Hearing hearing = hearing().withId(hearingId) + .withCourtCentre(courtCentre().withId(courtCentreId).withRoomId(roomId).build()) + .withProsecutionCases(null) + .build(); + + final HearingCases result = transformer.hearingCases(hearing, LocalDate.now()).build(); + + assertThat(result.getHearingId(), equalTo(hearingId)); + assertThat(result.getCourtCentreId(), equalTo(courtCentreId)); + assertThat(result.getCourtRoomId(), equalTo(roomId)); + assertThat(result.getHearingDate(), is(nullValue())); + assertThat(result.getProsecutionCases(), is(emptyList())); + } + + @Test + void shouldTransformHearing() { + final UUID hearingId = randomUUID(); + final UUID courtCentreId = randomUUID(); + final UUID roomId = randomUUID(); + final UUID caseId = randomUUID(); + final String caseUrn = "caseUrn"; + final ZonedDateTime sittingDay = ZonedDateTime.now(); + final Hearing hearing = hearing().withId(hearingId) + .withCourtCentre(courtCentre().withId(courtCentreId).withRoomId(roomId).build()) + .withHearingDays(List.of(HearingDay.hearingDay().withSittingDay(sittingDay).build())) + .withProsecutionCases(List.of( + prosecutionCase().withId(caseId) + .withProsecutionCaseIdentifier(prosecutionCaseIdentifier().withCaseURN(caseUrn).build()) + .build() + )) + .build(); + + final HearingCases result = transformer.hearingCases(hearing, sittingDay.toLocalDate()).build(); + + assertThat(result.getHearingId(), equalTo(hearingId)); + assertThat(result.getCourtCentreId(), equalTo(courtCentreId)); + assertThat(result.getCourtRoomId(), equalTo(roomId)); + assertThat(result.getHearingDate(), is(LocalDate.now().toString())); + assertThat(result.getProsecutionCases().get(0), equalTo(caseId)); + } + + @Test + void shouldReturnHearingDateMatchingTheQueriedDayForMultiDayHearing() { + final ZonedDateTime today = ZonedDateTime.now(); + final ZonedDateTime tomorrow = today.plusDays(1); + final Hearing hearing = hearing().withId(randomUUID()) + .withCourtCentre(courtCentre().withId(randomUUID()).withRoomId(randomUUID()).build()) + .withHearingDays(List.of( + HearingDay.hearingDay().withSittingDay(today).build(), + HearingDay.hearingDay().withSittingDay(tomorrow).build())) + .withProsecutionCases(List.of()) + .build(); + + final HearingCases result = transformer.hearingCases(hearing, tomorrow.toLocalDate()).build(); + + assertThat(result.getHearingDate(), is(tomorrow.toLocalDate().toString())); + } +} \ No newline at end of file diff --git a/hearing-query/hearing-query-view/src/test/java/uk/gov/moj/cpp/hearing/query/view/service/HearingServiceTest.java b/hearing-query/hearing-query-view/src/test/java/uk/gov/moj/cpp/hearing/query/view/service/HearingServiceTest.java index 708a73858..e573ad8fc 100644 --- a/hearing-query/hearing-query-view/src/test/java/uk/gov/moj/cpp/hearing/query/view/service/HearingServiceTest.java +++ b/hearing-query/hearing-query-view/src/test/java/uk/gov/moj/cpp/hearing/query/view/service/HearingServiceTest.java @@ -6,10 +6,8 @@ import static java.nio.charset.Charset.defaultCharset; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; -import static java.util.Objects.isNull; import static java.util.UUID.randomUUID; import static java.util.stream.Collectors.toList; -import static uk.gov.justice.services.messaging.JsonObjects.createObjectBuilder; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.notNullValue; @@ -22,7 +20,6 @@ import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.iterableWithSize; -import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -46,6 +43,7 @@ import static uk.gov.justice.core.courts.Level.OFFENCE; import static uk.gov.justice.services.messaging.JsonEnvelope.envelopeFrom; import static uk.gov.justice.services.messaging.JsonEnvelope.metadataBuilder; +import static uk.gov.justice.services.messaging.JsonObjects.createObjectBuilder; import static uk.gov.justice.services.messaging.JsonObjects.getString; import static uk.gov.justice.services.test.utils.core.random.RandomGenerator.STRING; import static uk.gov.justice.services.test.utils.core.reflection.ReflectionUtil.setField; @@ -74,26 +72,26 @@ import static uk.gov.moj.cpp.hearing.test.matchers.ElementAtListMatcher.first; import uk.gov.justice.core.courts.Address; -import uk.gov.justice.core.courts.CrackedIneffectiveTrial; +import uk.gov.justice.core.courts.ApplicationStatus; import uk.gov.justice.core.courts.CourtApplication; -import uk.gov.justice.core.courts.CourtApplicationCase; import uk.gov.justice.core.courts.CourtApplicationParty; import uk.gov.justice.core.courts.CourtApplicationType; +import uk.gov.justice.core.courts.CrackedIneffectiveTrial; import uk.gov.justice.core.courts.DefendantCase; -import uk.gov.justice.core.courts.ApplicationStatus; import uk.gov.justice.core.courts.DelegatedPowers; import uk.gov.justice.core.courts.Gender; import uk.gov.justice.core.courts.Level; import uk.gov.justice.core.courts.MasterDefendant; -import uk.gov.justice.core.courts.Offence; import uk.gov.justice.core.courts.Organisation; import uk.gov.justice.core.courts.Person; import uk.gov.justice.core.courts.PersonDefendant; import uk.gov.justice.core.courts.Prompt; import uk.gov.justice.core.courts.ProsecutionCase; +import uk.gov.justice.core.courts.ProsecutionCaseIdentifier; import uk.gov.justice.core.courts.ResultLine; import uk.gov.justice.hearing.courts.CourtApplicationSummaries; import uk.gov.justice.hearing.courts.GetHearings; +import uk.gov.justice.hearing.courts.HearingCasesForDay; import uk.gov.justice.hearing.courts.HearingSummaries; import uk.gov.justice.services.common.converter.JsonObjectToObjectConverter; import uk.gov.justice.services.common.converter.ObjectToJsonObjectConverter; @@ -122,9 +120,8 @@ import uk.gov.moj.cpp.hearing.persist.NowsRepository; import uk.gov.moj.cpp.hearing.persist.entity.application.ApplicationDraftResult; import uk.gov.moj.cpp.hearing.persist.entity.ha.CourtCentre; -import uk.gov.moj.cpp.hearing.persist.entity.ha.DraftResult; -import uk.gov.moj.cpp.hearing.persist.entity.ha.Now; import uk.gov.moj.cpp.hearing.persist.entity.ha.Defendant; +import uk.gov.moj.cpp.hearing.persist.entity.ha.DraftResult; import uk.gov.moj.cpp.hearing.persist.entity.ha.Hearing; import uk.gov.moj.cpp.hearing.persist.entity.ha.HearingApplication; import uk.gov.moj.cpp.hearing.persist.entity.ha.HearingApplicationKey; @@ -132,6 +129,7 @@ import uk.gov.moj.cpp.hearing.persist.entity.ha.HearingEvent; import uk.gov.moj.cpp.hearing.persist.entity.ha.HearingSnapshotKey; import uk.gov.moj.cpp.hearing.persist.entity.ha.HearingYouthCourtDefendants; +import uk.gov.moj.cpp.hearing.persist.entity.ha.Now; import uk.gov.moj.cpp.hearing.persist.entity.ha.Nows; import uk.gov.moj.cpp.hearing.persist.entity.ha.NowsMaterial; import uk.gov.moj.cpp.hearing.persist.entity.ha.Target; @@ -149,7 +147,6 @@ import uk.gov.moj.cpp.hearing.query.view.response.hearingresponse.GetShareResultsV2Response; import uk.gov.moj.cpp.hearing.query.view.response.hearingresponse.HearingDetailsResponse; import uk.gov.moj.cpp.hearing.query.view.response.hearingresponse.NowListResponse; -import uk.gov.moj.cpp.hearing.query.view.response.hearingresponse.NowResponse; import uk.gov.moj.cpp.hearing.query.view.response.hearingresponse.ProsecutionCaseResponse; import uk.gov.moj.cpp.hearing.query.view.response.hearingresponse.TargetListResponse; import uk.gov.moj.cpp.hearing.query.view.response.hearingresponse.xhibit.CaseDetail; @@ -157,8 +154,8 @@ import uk.gov.moj.cpp.hearing.query.view.response.hearingresponse.xhibit.CourtRoom; import uk.gov.moj.cpp.hearing.query.view.response.hearingresponse.xhibit.CourtSite; import uk.gov.moj.cpp.hearing.query.view.response.hearingresponse.xhibit.CurrentCourtStatus; -import uk.gov.moj.cpp.hearing.query.view.service.userdata.UserDataService; import uk.gov.moj.cpp.hearing.query.view.service.ctl.ReferenceDataService; +import uk.gov.moj.cpp.hearing.query.view.service.userdata.UserDataService; import uk.gov.moj.cpp.hearing.repository.DocumentRepository; import uk.gov.moj.cpp.hearing.repository.DraftResultRepository; import uk.gov.moj.cpp.hearing.repository.HearingApplicationRepository; @@ -186,7 +183,6 @@ import java.util.Set; import java.util.UUID; - import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonString; @@ -250,6 +246,8 @@ public class HearingServiceTest { private DraftResultJPAMapper draftResultJPAMapper; @Mock private GetHearingsTransformer getHearingsTransformer; + @Spy + private GetHearingCaseTransformer getHearingCaseTransformer; @Mock private HearingListXhibitResponseTransformer hearingListXhibitResponseTransformer; @InjectMocks @@ -2718,6 +2716,57 @@ public void shouldReturnEmptyList_whenNoHearingsFoundForApplication() { assertTrue(result.isEmpty()); } + // ── findHearingCasesForDay ─────────────────────────────────────────────── + @Test + void getHearingCasesForDay_shouldReturnEmptyWhenDateIsNull() { + final HearingCasesForDay result = hearingService.getHearingCasesForDay(null); + + assertNull(result.getHearingCases()); + } + + @Test + void getHearingCasesForDay_shouldReturnEmptyWhenNoHearingsFoundForTheDate() { + final LocalDate date = LocalDate.now(); + when(hearingRepository.findHearings(date)).thenReturn(emptyList()); + + final HearingCasesForDay result = hearingService.getHearingCasesForDay(date); + + assertNull(result.getHearingCases()); + } + + @Test + void getHearingCasesForDay_shouldReturnHearingCasesForTheDate() { + final UUID courtCentreId = randomUUID(); + final UUID roomId = randomUUID(); + final UUID caseId = randomUUID(); + final String caseUrn = "CASE_URN"; + + final Hearing hearing = HearingTestUtils.buildHearing(); + final List hearings = asList(hearing); + + final LocalDate date = LocalDate.now(); + when(hearingRepository.findHearings(date)).thenReturn(hearings); + final uk.gov.justice.core.courts.Hearing hearingPojo = hearing() + .withId(hearing.getId()) + .withHearingDays(List.of(uk.gov.justice.core.courts.HearingDay.hearingDay().withSittingDay(ZonedDateTime.now()).build())) + .withCourtCentre(uk.gov.justice.core.courts.CourtCentre.courtCentre().withId(courtCentreId) + .withRoomId(roomId).build()) + .withProsecutionCases(singletonList(ProsecutionCase.prosecutionCase().withId(caseId) + .withProsecutionCaseIdentifier(ProsecutionCaseIdentifier.prosecutionCaseIdentifier().withCaseURN(caseUrn).build()) + .build())) + .build(); + when(hearingJPAMapper.fromJPAMinimal(hearing)).thenReturn(hearingPojo); + + final HearingCasesForDay result = hearingService.getHearingCasesForDay(date); + + assertNotNull(result.getHearingCases()); + assertThat(result.getHearingCases().get(0).getHearingId(), is(hearing.getId())); + assertThat(result.getHearingCases().get(0).getCourtCentreId(), is(courtCentreId)); + assertThat(result.getHearingCases().get(0).getCourtRoomId(), is(roomId)); + assertThat(result.getHearingCases().get(0).getProsecutionCases().get(0), is(caseId)); + assertThat(result.getHearingCases().get(0).getHearingDate(), is(LocalDate.now().toString())); + } + // ---- CHD-2687: display order of prosecution cases ----------------------------------------- @Test diff --git a/hearing-viewstore/hearing-viewstore-persistence/src/main/java/uk/gov/moj/cpp/hearing/mapping/HearingJPAMapper.java b/hearing-viewstore/hearing-viewstore-persistence/src/main/java/uk/gov/moj/cpp/hearing/mapping/HearingJPAMapper.java index 570950f3d..1e1c08897 100644 --- a/hearing-viewstore/hearing-viewstore-persistence/src/main/java/uk/gov/moj/cpp/hearing/mapping/HearingJPAMapper.java +++ b/hearing-viewstore/hearing-viewstore-persistence/src/main/java/uk/gov/moj/cpp/hearing/mapping/HearingJPAMapper.java @@ -181,6 +181,19 @@ public uk.gov.justice.core.courts.Hearing fromJPA(final Hearing entity) { .build(); } + public uk.gov.justice.core.courts.Hearing fromJPAMinimal(final Hearing entity) { + if (null == entity) { + return null; + } + + return uk.gov.justice.core.courts.Hearing.hearing() + .withId(entity.getId()) + .withHearingDays(hearingDayJPAMapper.fromJPA(entity.getHearingDays())) + .withCourtCentre(courtCentreJPAMapper.fromJPA(entity.getCourtCentre())) + .withProsecutionCases(prosecutionCaseJPAMapper.fromJPA(entity.getProsecutionCases())) + .build(); + } + public uk.gov.justice.core.courts.Hearing fromJPAWithCourtListRestrictions(final Hearing entity) { if (null == entity) { return null; diff --git a/hearing-viewstore/hearing-viewstore-persistence/src/main/java/uk/gov/moj/cpp/hearing/repository/HearingRepository.java b/hearing-viewstore/hearing-viewstore-persistence/src/main/java/uk/gov/moj/cpp/hearing/repository/HearingRepository.java index 33d0b204c..34c4f5ec8 100644 --- a/hearing-viewstore/hearing-viewstore-persistence/src/main/java/uk/gov/moj/cpp/hearing/repository/HearingRepository.java +++ b/hearing-viewstore/hearing-viewstore-persistence/src/main/java/uk/gov/moj/cpp/hearing/repository/HearingRepository.java @@ -48,6 +48,14 @@ public abstract List findHearingsByDateAndCourtCentreList(@QueryParam(" public abstract List findHearings(@QueryParam("date") final LocalDate date, @QueryParam("courtCentreId") final UUID courtCentreId); + @Query(value = "select h.*" + + "from ha_hearing_day d, ha_hearing h " + + "where h.id = d.hearing_id and d.date = :date " + + "and coalesce(d.is_cancelled,false) !=true " + + "and coalesce(h.is_box_hearing,false) != true " + + "and coalesce(h.is_vacated_trial,false) != true", isNative = true) + public abstract List findHearings(@QueryParam("date") final LocalDate date); + @Query(value = "SELECT distinct hearing " + "FROM Hearing hearing INNER JOIN hearing.hearingDays day INNER JOIN hearing.judicialRoles role " + "WHERE role.userId = :userId " + diff --git a/hearing-viewstore/hearing-viewstore-persistence/src/test/java/uk/gov/moj/cpp/hearing/repository/HearingRepositoryTest.java b/hearing-viewstore/hearing-viewstore-persistence/src/test/java/uk/gov/moj/cpp/hearing/repository/HearingRepositoryTest.java index 0534eaa9f..d48a83a73 100644 --- a/hearing-viewstore/hearing-viewstore-persistence/src/test/java/uk/gov/moj/cpp/hearing/repository/HearingRepositoryTest.java +++ b/hearing-viewstore/hearing-viewstore-persistence/src/test/java/uk/gov/moj/cpp/hearing/repository/HearingRepositoryTest.java @@ -186,6 +186,38 @@ public void shouldExcludeHearingFromListWhenHearingDayCancelledTrueAndFindHearin assertThat(hearingRepository.findHearings(hearingWithCancelledDays.getHearingDays().get(0).getSittingDay().toLocalDate(), hearingWithCancelledDays.getCourtCentre().getId()), empty()); } + @Test + public void shouldReturnNonEmptyListWhenFindHearingsForDayInvokedAndDataPresent() { + final uk.gov.justice.core.courts.Hearing hearing = hearings.get(0); + List hearingList = hearingRepository.findHearings(hearing.getHearingDays().get(0).getSittingDay().toLocalDate()); + assertThat(hearingList, hasItem(isBean(Hearing.class).with(Hearing::getId, is(hearing.getId())))); + assertThat(hearingList.get(0).getHearingDays(), hasItem(isBean(HearingDay.class).with(HearingDay::getHasSharedResults, is(true)))); + } + + @Test + public void shouldExcludeVacatedHearingFromListWhenVacatedTrueAndFindHearingsForDayInvoked() { + final uk.gov.justice.core.courts.Hearing vacatedHearing = addHearingWithVacatedStatus(Boolean.TRUE); + assertThat(hearingRepository.findHearings(vacatedHearing.getHearingDays().get(0).getSittingDay().toLocalDate()), empty()); + } + + @Test + public void shouldRetrieveHearingFromListWhenHearingDayCancelledNullOrFalseAndFindHearingsForDayInvoked() { + final uk.gov.justice.core.courts.Hearing hearingWithCancelledFalse = addHearingWithCancelledStatus(Boolean.FALSE); + List hearings = hearingRepository.findHearings(hearingWithCancelledFalse.getHearingDays().get(0).getSittingDay().toLocalDate()); + assertThat(hearings, hasItem(isBean(Hearing.class).with(Hearing::getId, is(hearingWithCancelledFalse.getId())))); + + final uk.gov.justice.core.courts.Hearing hearingWithCancelledNull = addHearingWithCancelledStatus(null); + hearings = hearingRepository.findHearings(hearingWithCancelledNull.getHearingDays().get(0).getSittingDay().toLocalDate()); + assertThat(hearings, hasItem(isBean(Hearing.class).with(Hearing::getId, is(hearingWithCancelledNull.getId())))); + } + + @Test + public void shouldExcludeHearingFromListWhenHearingDayCancelledTrueAndFindHearingsForDayInvoked() { + final uk.gov.justice.core.courts.Hearing hearingWithCancelledDays = addHearingWithCancelledStatus(true); + assertThat(hearingRepository.findHearings(hearingWithCancelledDays.getHearingDays().get(0).getSittingDay().toLocalDate()), empty()); + } + + @Test public void shouldFindAll() { assertEquals(hearings.size() + hearingsWithHearingDay.size(), hearingRepository.findAll().size()); diff --git a/pom.xml b/pom.xml index 545b2bd61..a0c4d8379 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ 17.103.95 17.0.1 17.104.81 - 17.0.275 + 17.0.279 2.2.11 2.6.3 5.7