Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -272,6 +280,38 @@ public void shouldRetrieveApplicationWithCourtOrderHearingForTodayForLoggedOnUse
);
}

@Test
public void shouldRetrieveHearingCasesForDayForSystemUser() {
final UUID userId = randomUUID();
setupAsSystemUser(userId);
stubUsersAndGroupsUserRoles(getLoggedInUser());
final ImmutableMap<String, Boolean> 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<GetHearings> resultMatcher) {
final RequestParams requestParams = requestParams(getURL("hearing.get.hearings-for-today"), "application/vnd.hearing.get.hearings-for-today+json")
.withHeader(HeaderConstants.USER_ID, userId)
Expand All @@ -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<HearingCasesForDay> 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<ResponseData> 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<CourtApplication> courtApplicationList) {
final UUID prosecutionCaseId = randomUUID();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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) {

Expand All @@ -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<String> 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<HearingCasesForDay> envelope = this.hearingQueryView.findHearingCasesForDay(query);
return getJsonEnvelope(envelope);
}

@Handles("hearing.get.hearings-check-in")
public JsonEnvelope getHearingCheckIn(final JsonEnvelope query) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
21 changes: 21 additions & 0 deletions hearing-query/hearing-query-api/src/raml/hearing-query-api.raml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
]
}
]
}
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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");
Expand Down
Loading
Loading