diff --git a/pom.xml b/pom.xml
index 7b13e4cf7..ebcb08cea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,9 +66,9 @@
17.0.75
1.0.6
6.4.1
- 17.104.136
+ 17.104.137
17.104.3
- 17.104.176
+ 17.104.180
17.104.50
17.104.102
17.104.48
diff --git a/progression-command/progression-command-api/src/main/java/uk/gov/moj/cpp/progression/command/InitiateCourtApplicationProceedingsCommandApi.java b/progression-command/progression-command-api/src/main/java/uk/gov/moj/cpp/progression/command/InitiateCourtApplicationProceedingsCommandApi.java
index ecf798e9e..1c8ac5bbc 100644
--- a/progression-command/progression-command-api/src/main/java/uk/gov/moj/cpp/progression/command/InitiateCourtApplicationProceedingsCommandApi.java
+++ b/progression-command/progression-command-api/src/main/java/uk/gov/moj/cpp/progression/command/InitiateCourtApplicationProceedingsCommandApi.java
@@ -1,8 +1,13 @@
package uk.gov.moj.cpp.progression.command;
+import static java.util.Optional.empty;
+import static java.util.Optional.of;
+import static java.util.UUID.fromString;
+import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
import static uk.gov.justice.core.courts.LinkType.STANDALONE;
import static uk.gov.justice.services.core.annotation.Component.COMMAND_API;
import static uk.gov.justice.services.messaging.Envelope.metadataFrom;
+import static uk.gov.moj.cpp.progression.command.api.UserDetailsLoader.getAllowedHearingTypes;
import static uk.gov.moj.cpp.progression.command.api.UserDetailsLoader.isUserHasPermissionForApplicationTypeCode;
import uk.gov.justice.services.adapter.rest.exception.BadRequestException;
@@ -14,6 +19,9 @@
import uk.gov.justice.services.messaging.Envelope;
import uk.gov.justice.services.messaging.JsonEnvelope;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
import java.util.regex.Pattern;
import javax.inject.Inject;
@@ -24,6 +32,7 @@ public class InitiateCourtApplicationProceedingsCommandApi {
private static final Pattern URN_PATTERN = Pattern.compile("^[A-Z0-9]{11}$");
private static final String LINK_TYPE = "linkType";
+ public static final String COURT_APPLICATION = "courtApplication";
@Inject
private Sender sender;
@@ -38,17 +47,46 @@ public void initiateCourtApplicationProceedings(final JsonEnvelope command) {
throw new ForbiddenRequestException("User is not authorised to use this application type!");
}
- validateInputsForApplication(command.payloadAsJsonObject());
+ validateInputsForApplication(command);
this.sender.send(Envelope.envelopeFrom(metadataFrom(command.metadata()).withName("progression.command.initiate-court-proceedings-for-application").build(),
command.payloadAsJsonObject()));
}
- private void validateInputsForApplication(final JsonObject jsonObject) {
- final JsonObject courtApplication = jsonObject.getJsonObject("courtApplication");
+ private void validateDefaultHearingType(final JsonEnvelope command) {
+ final JsonObject payload = command.payloadAsJsonObject();
+ final JsonObject courtApplication = payload.getJsonObject(COURT_APPLICATION);
+ if (!standaloneApplication(courtApplication)) {
+ return;
+ }
+
+ final String applicationTypeId = courtApplication.getJsonObject("type").getString("id");
+ final List allowedHearingTypes = getAllowedHearingTypes(command.metadata(), requester, applicationTypeId);
+ if (isNotEmpty(allowedHearingTypes)) {
+ final Optional submittedHearingTypeId = submittedHearingTypeId(payload);
+ if (!submittedHearingTypeId.isPresent() || !allowedHearingTypes.contains(submittedHearingTypeId.get())) {
+ throw new BadRequestException("Hearing type must be one of the allowed hearing types for this application type!");
+ }
+ }
+ }
+
+ private Optional submittedHearingTypeId(final JsonObject payload) {
+ if (!payload.containsKey("courtHearing")) {
+ return empty();
+ }
+ final JsonObject courtHearing = payload.getJsonObject("courtHearing");
+ if (!courtHearing.containsKey("hearingType")) {
+ return empty();
+ }
+ return of(fromString(courtHearing.getJsonObject("hearingType").getString("id")));
+ }
+
+ private void validateInputsForApplication(final JsonEnvelope command) {
+ final JsonObject courtApplication = command.payloadAsJsonObject().getJsonObject(COURT_APPLICATION);
if (standaloneApplication(courtApplication) && courtApplication.containsKey("applicationReference") && isNotValidUrn(courtApplication.getString("applicationReference"))) {
throw new BadRequestException("Entered URN is not valid!");
}
+ validateDefaultHearingType(command);
}
private boolean standaloneApplication(final JsonObject courtApplication) {
@@ -60,7 +98,7 @@ private boolean isNotValidUrn(final String applicationReference) {
}
private boolean isUserNotAuthorised(final JsonEnvelope command) {
- final String applicationTypeCode = command.payloadAsJsonObject().getJsonObject("courtApplication").getJsonObject("type").getString("code");
+ final String applicationTypeCode = command.payloadAsJsonObject().getJsonObject(COURT_APPLICATION).getJsonObject("type").getString("code");
return !isUserHasPermissionForApplicationTypeCode(command.metadata(), requester, applicationTypeCode);
}
diff --git a/progression-command/progression-command-api/src/main/java/uk/gov/moj/cpp/progression/command/api/UserDetailsLoader.java b/progression-command/progression-command-api/src/main/java/uk/gov/moj/cpp/progression/command/api/UserDetailsLoader.java
index ea21b2c93..8fdd9812d 100644
--- a/progression-command/progression-command-api/src/main/java/uk/gov/moj/cpp/progression/command/api/UserDetailsLoader.java
+++ b/progression-command/progression-command-api/src/main/java/uk/gov/moj/cpp/progression/command/api/UserDetailsLoader.java
@@ -1,6 +1,7 @@
package uk.gov.moj.cpp.progression.command.api;
import static java.lang.String.format;
+import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static java.util.UUID.fromString;
import static javax.json.Json.createObjectBuilder;
@@ -9,6 +10,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import uk.gov.justice.services.core.requester.Requester;
import uk.gov.justice.services.messaging.Envelope;
import uk.gov.justice.services.messaging.JsonEnvelope;
@@ -20,12 +22,14 @@
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
+import javax.json.JsonString;
import javax.json.JsonValue;
public class UserDetailsLoader {
@@ -37,6 +41,8 @@ public class UserDetailsLoader {
public static final String TARGET = "target";
public static final String OBJECT = "object";
public static final String ACTION = "action";
+ public static final String ACTIVE = "active";
+ public static final String HEARING_TYPE = "HearingType";
public static final String ORGANISATION_ID = "organisationId";
public static final String ORGANISATION_NAME = "organisationName";
public static final String USER_ID_NOT_SUPPLIED_FOR_THE_USER_GROUPS_LOOK_UP = "User id Not Supplied for the UserGroups look up";
@@ -69,7 +75,7 @@ public List getPermissions(final Metadata metadata, final Requester
final JsonEnvelope requestEnvelope = envelopeFrom(metadataWithActionName, getOrganisationForUserRequest);
final Envelope response = requester.requestAsAdmin(requestEnvelope, JsonObject.class);
- if (!response.payload().containsKey(PERMISSIONS)) {
+ if (!response.payload().containsKey(PERMISSIONS)) {
return Collections.emptyList();
}
final JsonArray permissionsJsonArray = response.payload().getJsonArray(PERMISSIONS);
@@ -79,7 +85,7 @@ public List getPermissions(final Metadata metadata, final Requester
}
return permissionsJsonArray.stream()
- .map(p -> (JsonObject)p)
+ .map(p -> (JsonObject) p)
.map(permission ->
Permission.permission()
.withAction(JsonObjects.getString(permission, ACTION).orElse(null))
@@ -90,8 +96,49 @@ public List getPermissions(final Metadata metadata, final Requester
).collect(Collectors.toList());
}
+ public static List getAllowedHearingTypes(final Metadata metadata, final Requester requester, final String applicationTypeId) {
+ final JsonObject request = Json.createObjectBuilder()
+ .add(OBJECT, HEARING_TYPE)
+ .add(SOURCE, applicationTypeId)
+ .build();
+ final MetadataBuilder metadataWithActionName = Envelope.metadataFrom(metadata).withName("usersgroups.permissions");
+
+ final JsonEnvelope requestEnvelope = envelopeFrom(metadataWithActionName, request);
+ final Envelope response = requester.requestAsAdmin(requestEnvelope, JsonObject.class);
+
+ final JsonObject payload = response.payload();
+ if (isNull(payload) || !payload.containsKey(PERMISSIONS)) {
+ return Collections.emptyList();
+ }
+ final JsonArray permissionsJsonArray = payload.getJsonArray(PERMISSIONS);
+ if (isNull(permissionsJsonArray)) {
+ return Collections.emptyList();
+ }
+
+ return permissionsJsonArray.stream()
+ .map(p -> (JsonObject) p)
+ .filter(UserDetailsLoader::isActive)
+ .map(permission -> getNullableUUID(permission, TARGET))
+ .filter(Objects::nonNull)
+ .toList();
+ }
+
+ private static boolean isActive(final JsonObject permission) {
+ if (!permission.containsKey(ACTIVE)) {
+ return false;
+ }
+ final JsonValue value = permission.get(ACTIVE);
+ if (value.getValueType() == JsonValue.ValueType.TRUE) {
+ return true;
+ }
+ if (value.getValueType() == JsonValue.ValueType.STRING) {
+ return Boolean.parseBoolean(((JsonString) value).getString());
+ }
+ return false;
+ }
+
private static UUID getNullableUUID(final JsonObject permission, final String attribute) {
- final String uuidString = JsonObjects.getString( permission, attribute).orElse(null);
+ final String uuidString = JsonObjects.getString(permission, attribute).orElse(null);
if (nonNull(uuidString)) {
return fromString(uuidString);
} else {
@@ -110,7 +157,7 @@ protected UserOrganisationDetails getOrganisationDetailsForUser(final Envelope
final JsonEnvelope usersAndGroupsRequestEnvelope = envelopeFrom(requestEnvelope.metadata(), requestEnvelope.payload());
final Envelope response = requester.requestAsAdmin(usersAndGroupsRequestEnvelope, JsonObject.class);
final JsonObject organisationDetails = response.payload();
- if(nonNull(organisationDetails) && organisationDetails.containsKey(ORGANISATION_ID)) {
+ if (nonNull(organisationDetails) && organisationDetails.containsKey(ORGANISATION_ID)) {
return new UserOrganisationDetails(fromString(organisationDetails.getString(ORGANISATION_ID)),
organisationDetails.getString(ORGANISATION_NAME));
}
@@ -123,7 +170,7 @@ public boolean isPermitted(final JsonEnvelope query, final Requester requester)
.orElseThrow(() -> new IllegalStateException(USER_ID_NOT_SUPPLIED_FOR_THE_USER_GROUPS_LOOK_UP));
final UserOrganisationDetails organisationDetailsForUser = getOrganisationDetailsForUser(query, requester, userId);
final List permissions = getPermissions(query.metadata(), requester, query.payloadAsJsonObject().getString(DEFENDANT_ID));
- if(permissions.isEmpty()) {
+ if (permissions.isEmpty()) {
return false;
}
diff --git a/progression-command/progression-command-api/src/test/java/uk/gov/moj/cpp/progression/command/InitiateCourtApplicationProceedingsCommandApiTest.java b/progression-command/progression-command-api/src/test/java/uk/gov/moj/cpp/progression/command/InitiateCourtApplicationProceedingsCommandApiTest.java
index 37b03dfb3..ff5dca926 100644
--- a/progression-command/progression-command-api/src/test/java/uk/gov/moj/cpp/progression/command/InitiateCourtApplicationProceedingsCommandApiTest.java
+++ b/progression-command/progression-command-api/src/test/java/uk/gov/moj/cpp/progression/command/InitiateCourtApplicationProceedingsCommandApiTest.java
@@ -1,6 +1,7 @@
package uk.gov.moj.cpp.progression.command;
import static java.util.UUID.randomUUID;
+import static javax.json.Json.createArrayBuilder;
import static javax.json.Json.createObjectBuilder;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -22,7 +23,9 @@
import uk.gov.justice.services.messaging.spi.DefaultEnvelope;
import uk.gov.justice.services.messaging.spi.DefaultJsonEnvelopeProvider;
+import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -54,6 +57,7 @@ public void shouldInitialCourtProceedingsForCourtApplicationWhenNoApplicationRef
final Envelope queryResponseEnvelope = mock(Envelope.class);
when(queryResponseEnvelope.payload()).thenReturn(createObjectBuilder().add("hasPermission", true).build());
when(requester.request(any(), any())).thenReturn(queryResponseEnvelope);
+ stubEmptyPermissions();
initiateCourtApplicationProceedingsCommandApi.initiateCourtApplicationProceedings(commandEnvelope);
@@ -73,6 +77,7 @@ public void shouldInitialCourtProceedingsForCourtApplicationWhenApplicationRefer
.add("courtApplication", createObjectBuilder()
.add("id", randomUUID().toString())
.add("type", createObjectBuilder()
+ .add("id", randomUUID().toString())
.add("code", "anyCode")
.add("linkType", "STANDALONE"))
.add("applicationReference", validURN)
@@ -84,6 +89,7 @@ public void shouldInitialCourtProceedingsForCourtApplicationWhenApplicationRefer
final Envelope queryResponseEnvelope = mock(Envelope.class);
when(queryResponseEnvelope.payload()).thenReturn(createObjectBuilder().add("hasPermission", true).build());
when(requester.request(any(), any())).thenReturn(queryResponseEnvelope);
+ stubEmptyPermissions();
initiateCourtApplicationProceedingsCommandApi.initiateCourtApplicationProceedings(commandEnvelope);
@@ -227,11 +233,144 @@ public void shouldCallAddBreachApplication() {
assertThat(newCommand.payload(), equalTo(commandEnvelope.payloadAsJsonObject()));
}
+ @Test
+ public void shouldSendCommandWhenSubmittedHearingTypeIsAllowed() {
+ final String applicationTypeId = randomUUID().toString();
+ final String hearingTypeId = randomUUID().toString();
+ final JsonEnvelope commandEnvelope = buildStandaloneEnvelope(applicationTypeId, hearingTypeId);
+
+ stubHasPermission(true);
+ stubPermissions(allowedHearingTypePermissions(applicationTypeId, hearingTypeId));
+
+ initiateCourtApplicationProceedingsCommandApi.initiateCourtApplicationProceedings(commandEnvelope);
+
+ verify(sender, times(1)).send(envelopeCaptor.capture());
+ assertThat(envelopeCaptor.getValue().metadata().name(), is("progression.command.initiate-court-proceedings-for-application"));
+ }
+
+ @Test
+ public void shouldSendCommandWhenSubmittedHearingTypeIsOneOfMultipleAllowed() {
+ final String applicationTypeId = randomUUID().toString();
+ final String submittedHearingTypeId = randomUUID().toString();
+ final JsonEnvelope commandEnvelope = buildStandaloneEnvelope(applicationTypeId, submittedHearingTypeId);
+
+ stubHasPermission(true);
+ stubPermissions(allowedHearingTypePermissions(applicationTypeId,
+ randomUUID().toString(), submittedHearingTypeId, randomUUID().toString()));
+
+ initiateCourtApplicationProceedingsCommandApi.initiateCourtApplicationProceedings(commandEnvelope);
+
+ verify(sender, times(1)).send(envelopeCaptor.capture());
+ assertThat(envelopeCaptor.getValue().metadata().name(), is("progression.command.initiate-court-proceedings-for-application"));
+ }
+
+ @Test
+ public void shouldThrowBadRequestWhenSubmittedHearingTypeIsNotAllowed() {
+ final String applicationTypeId = randomUUID().toString();
+ final JsonEnvelope commandEnvelope = buildStandaloneEnvelope(applicationTypeId, randomUUID().toString());
+
+ stubHasPermission(true);
+ stubPermissions(allowedHearingTypePermissions(applicationTypeId, randomUUID().toString(), randomUUID().toString()));
+
+ assertThrows(BadRequestException.class, () -> initiateCourtApplicationProceedingsCommandApi.initiateCourtApplicationProceedings(commandEnvelope));
+ }
+
+ @Test
+ public void shouldThrowBadRequestWhenHearingTypeAbsentButAllowedHearingTypesExist() {
+ final String applicationTypeId = randomUUID().toString();
+ final JsonEnvelope commandEnvelope = buildStandaloneEnvelope(applicationTypeId, null);
+
+ stubHasPermission(true);
+ stubPermissions(allowedHearingTypePermissions(applicationTypeId, randomUUID().toString()));
+
+ assertThrows(BadRequestException.class, () -> initiateCourtApplicationProceedingsCommandApi.initiateCourtApplicationProceedings(commandEnvelope));
+ }
+
+ @Test
+ public void shouldSendCommandWhenNoAllowedHearingTypeMappingExists() {
+ final String applicationTypeId = randomUUID().toString();
+ final JsonEnvelope commandEnvelope = buildStandaloneEnvelope(applicationTypeId, randomUUID().toString());
+
+ stubHasPermission(true);
+ stubEmptyPermissions();
+
+ initiateCourtApplicationProceedingsCommandApi.initiateCourtApplicationProceedings(commandEnvelope);
+
+ verify(sender, times(1)).send(envelopeCaptor.capture());
+ assertThat(envelopeCaptor.getValue().metadata().name(), is("progression.command.initiate-court-proceedings-for-application"));
+ }
+
+ @Test
+ public void shouldNotEnforceHearingTypeForNonStandaloneApplication() {
+ final JsonObject payload = createObjectBuilder()
+ .add("courtApplication", createObjectBuilder()
+ .add("id", randomUUID().toString())
+ .add("type", createObjectBuilder()
+ .add("id", randomUUID().toString())
+ .add("code", "anyCode")
+ .add("linkType", "LINKED"))
+ .build())
+ .build();
+ final JsonEnvelope commandEnvelope = buildEnvelope(payload);
+
+ stubHasPermission(true);
+
+ initiateCourtApplicationProceedingsCommandApi.initiateCourtApplicationProceedings(commandEnvelope);
+
+ verify(sender, times(1)).send(envelopeCaptor.capture());
+ assertThat(envelopeCaptor.getValue().metadata().name(), is("progression.command.initiate-court-proceedings-for-application"));
+ }
+
+ private JsonEnvelope buildStandaloneEnvelope(final String applicationTypeId, final String hearingTypeId) {
+ final JsonObjectBuilder courtApplication = createObjectBuilder()
+ .add("id", randomUUID().toString())
+ .add("type", createObjectBuilder()
+ .add("id", applicationTypeId)
+ .add("code", "anyCode")
+ .add("linkType", "STANDALONE"));
+ final JsonObjectBuilder payload = createObjectBuilder().add("courtApplication", courtApplication);
+ if (hearingTypeId != null) {
+ payload.add("courtHearing", createObjectBuilder()
+ .add("hearingType", createObjectBuilder().add("id", hearingTypeId)));
+ }
+ return buildEnvelope(payload.build());
+ }
+
+ private JsonObject allowedHearingTypePermissions(final String source, final String... targets) {
+ final JsonArrayBuilder permissions = createArrayBuilder();
+ for (final String target : targets) {
+ permissions.add(createObjectBuilder()
+ .add("object", "HearingType")
+ .add("action", "Locked")
+ .add("active", true)
+ .add("source", source)
+ .add("target", target));
+ }
+ return createObjectBuilder().add("permissions", permissions).build();
+ }
+
+ private void stubHasPermission(final boolean value) {
+ final Envelope queryResponseEnvelope = mock(Envelope.class);
+ when(queryResponseEnvelope.payload()).thenReturn(createObjectBuilder().add("hasPermission", value).build());
+ when(requester.request(any(), any())).thenReturn(queryResponseEnvelope);
+ }
+
+ private void stubPermissions(final JsonObject permissionsPayload) {
+ final Envelope permissionsEnvelope = mock(Envelope.class);
+ when(permissionsEnvelope.payload()).thenReturn(permissionsPayload);
+ when(requester.requestAsAdmin(any(), any())).thenReturn(permissionsEnvelope);
+ }
+
+ private void stubEmptyPermissions() {
+ stubPermissions(createObjectBuilder().build());
+ }
+
private JsonEnvelope buildEnvelope() {
final JsonObject payload = createObjectBuilder()
.add("courtApplication", createObjectBuilder()
.add("id", randomUUID().toString())
.add("type", createObjectBuilder()
+ .add("id", randomUUID().toString())
.add("code", "anyCode")
.add("linkType", "STANDALONE"))
.build())
diff --git a/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/AbstractIT.java b/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/AbstractIT.java
index a179c7f70..c5fecb0dc 100644
--- a/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/AbstractIT.java
+++ b/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/AbstractIT.java
@@ -24,6 +24,7 @@
import static uk.gov.moj.cpp.progression.stub.SysDocGeneratorStub.stubAsyncDocumentGeneratorEndPoint;
import static uk.gov.moj.cpp.progression.stub.UnifiedSearchStub.stubUnifiedSearchQueryExactMatchWithEmptyResults;
import static uk.gov.moj.cpp.progression.stub.UnifiedSearchStub.stubUnifiedSearchQueryPartialMatch;
+import static uk.gov.moj.cpp.progression.stub.UsersAndGroupsStub.stubEmptyPermissionsQuery;
import static uk.gov.moj.cpp.progression.util.WireMockStubUtils.setupAsAuthorisedUser;
import static uk.gov.moj.cpp.progression.util.WireMockStubUtils.setupAsSystemUser;
import static uk.gov.moj.cpp.progression.util.WireMockStubUtils.setupHearingQueryStub;
@@ -103,6 +104,7 @@ protected static void defaultStubs() {
setupAsSystemUser(USER_ID_VALUE_AS_ADMIN);
setupUsersGroupQueryStub();
setupUsersGroupPermissionsForApplicationTypeStub(true);
+ stubEmptyPermissionsQuery();
stubQueryLocalJusticeArea("/restResource/referencedata.query.local-justice-areas.json");
stubQueryCourtsCodeData("/restResource/referencedata.query.local-justice-area-court-prosecutor-mapping-courts.json");
stubQueryOrganisationUnitsData("/restResource/referencedata.query.organisationunits.json");
diff --git a/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/CreateCourtApplicationIT.java b/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/CreateCourtApplicationIT.java
index 43baaa545..40d495f50 100644
--- a/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/CreateCourtApplicationIT.java
+++ b/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/CreateCourtApplicationIT.java
@@ -3,6 +3,8 @@
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.withJsonPath;
import static java.util.UUID.randomUUID;
+import static org.apache.http.HttpStatus.SC_BAD_REQUEST;
+import static org.apache.http.HttpStatus.SC_ACCEPTED;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
@@ -17,6 +19,7 @@
import static uk.gov.moj.cpp.progression.helper.PreAndPostConditionHelper.pollProsecutionCasesProgressionFor;
import static uk.gov.moj.cpp.progression.helper.QueueUtil.retrieveMessageBody;
import static uk.gov.moj.cpp.progression.stub.ListingStub.verifyPostListCourtHearing;
+import static uk.gov.moj.cpp.progression.stub.UsersAndGroupsStub.stubHearingTypePermission;
import static uk.gov.moj.cpp.progression.util.ReferProsecutionCaseToCrownCourtHelper.getProsecutionCaseMatchers;
import uk.gov.justice.services.integrationtest.utils.jms.JmsMessageConsumerClient;
@@ -26,6 +29,7 @@
import javax.json.JsonObject;
+import io.restassured.response.Response;
import org.hamcrest.Matcher;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -156,6 +160,28 @@ public void shouldPreserveOffencesWhenApplicationSourceIsMHAndCaseIsInactive() t
pollForApplication(applicationId, matchers);
}
+ @Test
+ public void shouldRejectStandaloneApplicationWhenHearingTypeIsNotAnAllowedHearingType() throws Exception {
+ // The standalone fixture carries applicationType id e857c8ea-... and hearingType id 8cdfd3da-...
+ final String standaloneApplicationTypeId = "e857c8ea-cd95-47d1-842f-2d618e77a9b5";
+
+ // Allowed hearing type for this application type differs from the one in the fixture,
+ // so the initiate-court-proceedings-for-application command must be rejected.
+ stubHearingTypePermission(standaloneApplicationTypeId, randomUUID().toString());
+
+ Response response = initiateCourtProceedingsForCourtApplication(randomUUID().toString(),
+ "applications/progression.initiate-court-proceedings-for-standalone-application.json");
+
+ assertThat(response.getStatusCode(), is(SC_BAD_REQUEST));
+
+ response = initiateCourtProceedingsForCourtApplication(randomUUID().toString(),
+ "applications/progression.initiate-court-proceedings-for-standalone-application.json");
+
+ stubHearingTypePermission(standaloneApplicationTypeId, "8cdfd3da-8900-42ca-9835-9f29d1e03cd6");
+
+ assertThat(response.getStatusCode(), is(SC_ACCEPTED));
+ }
+
private void verifyCourtApplicationCreatedEventPublished(final String applicationId) {
final Optional message = retrieveMessageBody(consumerForCourtApplicationCreated);
assertTrue(message.isPresent(), "Expected court-application-created event on JMS topic");
diff --git a/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/stub/UsersAndGroupsStub.java b/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/stub/UsersAndGroupsStub.java
index ff4e7860e..b7a7b59ec 100644
--- a/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/stub/UsersAndGroupsStub.java
+++ b/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/stub/UsersAndGroupsStub.java
@@ -178,4 +178,47 @@ public static void stubUserWithPermission(final String userId, final String body
.withBody(body)));
}
+ public static final String PERMISSIONS_QUERY = BASE_QUERY + "/permissions";
+ public static final String PERMISSIONS_QUERY_MEDIA_TYPE = "application/vnd.usersgroups.permissions+json";
+
+ /**
+ * Default stub for the usersgroups.permissions query, returning no permissions. Registered in
+ * {@code defaultStubs()} so that every command that now consults this query (e.g. the
+ * initiate-court-proceedings-for-application hearing-type validation) behaves as "no locked
+ * mapping" unless a test overrides it with {@link #stubLockedHearingTypePermission}.
+ */
+ public static void stubEmptyPermissionsQuery() {
+ stubFor(get(urlPathEqualTo(PERMISSIONS_QUERY))
+ .willReturn(aResponse().withStatus(OK.getStatusCode())
+ .withHeader(ID, randomUUID().toString())
+ .withHeader(CONTENT_TYPE, PERMISSIONS_QUERY_MEDIA_TYPE)
+ .withBody(Json.createObjectBuilder()
+ .add("permissions", Json.createArrayBuilder())
+ .build().toString())));
+ }
+
+ /**
+ * Stubs the usersgroups.permissions query to return a single active HearingType permission
+ * mapping the given application type ({@code source}) to the allowed hearing type ({@code target}).
+ */
+ public static void stubHearingTypePermission(final String source, final String target) {
+ final String body = Json.createObjectBuilder()
+ .add("permissions", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("permissionId", randomUUID().toString())
+ .add("object", "HearingType")
+ .add("action", "Locked")
+ .add("active", true)
+ .add("source", source)
+ .add("target", target)))
+ .build().toString();
+
+ removeStub(get(urlPathEqualTo(PERMISSIONS_QUERY)));
+ stubFor(get(urlPathEqualTo(PERMISSIONS_QUERY))
+ .willReturn(aResponse().withStatus(OK.getStatusCode())
+ .withHeader(ID, randomUUID().toString())
+ .withHeader(CONTENT_TYPE, PERMISSIONS_QUERY_MEDIA_TYPE)
+ .withBody(body)));
+ }
+
}