diff --git a/service/build.gradle b/service/build.gradle index 389a06161a9..82000eb71c9 100644 --- a/service/build.gradle +++ b/service/build.gradle @@ -416,6 +416,7 @@ dependencies { contractTestImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: versions.junit_jupiter contractTestRuntimeOnly group: 'org.junit.platform', name: 'junit-platform-commons', version: '1.8.2' contractTestImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.13.5' + contractTestImplementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.13.5' contractTestImplementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign', version: '4.1.1' contractTestImplementation group: 'org.springframework.cloud', name: 'spring-cloud-netflix-ribbon', version: '2.2.10.RELEASE' contractTestImplementation group: 'com.netflix.ribbon', name: 'ribbon-core', version: '2.7.18' diff --git a/service/src/contractTest/java/uk/gov/hmcts/reform/ObjectMapperContractTestConfig.java b/service/src/contractTest/java/uk/gov/hmcts/reform/ObjectMapperContractTestConfig.java new file mode 100644 index 00000000000..52054486141 --- /dev/null +++ b/service/src/contractTest/java/uk/gov/hmcts/reform/ObjectMapperContractTestConfig.java @@ -0,0 +1,21 @@ +package uk.gov.hmcts.reform; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ObjectMapperContractTestConfig { + + @Bean + public ObjectMapper objectMapper() { + return JsonMapper.builder() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .addModule(new JavaTimeModule()) + .build(); + } + +} diff --git a/service/src/contractTest/java/uk/gov/hmcts/reform/am/client/RoleAssignmentServiceConsumerApplication.java b/service/src/contractTest/java/uk/gov/hmcts/reform/am/client/RoleAssignmentServiceConsumerApplication.java new file mode 100644 index 00000000000..c9e4fea8af8 --- /dev/null +++ b/service/src/contractTest/java/uk/gov/hmcts/reform/am/client/RoleAssignmentServiceConsumerApplication.java @@ -0,0 +1,12 @@ +package uk.gov.hmcts.reform.am.client; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients(basePackages = { + "uk.gov.hmcts.reform.am.client" +}) + +public class RoleAssignmentServiceConsumerApplication { +} diff --git a/service/src/contractTest/java/uk/gov/hmcts/reform/am/client/RoleAssignmentServiceConsumerTest.java b/service/src/contractTest/java/uk/gov/hmcts/reform/am/client/RoleAssignmentServiceConsumerTest.java new file mode 100644 index 00000000000..818f443eba3 --- /dev/null +++ b/service/src/contractTest/java/uk/gov/hmcts/reform/am/client/RoleAssignmentServiceConsumerTest.java @@ -0,0 +1,141 @@ +package uk.gov.hmcts.reform.am.client; + +import au.com.dius.pact.consumer.dsl.DslPart; +import au.com.dius.pact.consumer.dsl.PactDslWithProvider; +import au.com.dius.pact.consumer.junit5.PactConsumerTestExt; +import au.com.dius.pact.consumer.junit5.PactTestFor; +import au.com.dius.pact.core.model.RequestResponsePact; +import au.com.dius.pact.core.model.annotations.Pact; +import au.com.dius.pact.core.model.annotations.PactFolder; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.HttpStatus; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import uk.gov.hmcts.reform.am.model.AssignmentRequest; +import uk.gov.hmcts.reform.am.model.GrantType; +import uk.gov.hmcts.reform.am.model.RoleAssignment; +import uk.gov.hmcts.reform.am.model.RoleAssignmentRequestResource; +import uk.gov.hmcts.reform.am.model.RoleCategory; +import uk.gov.hmcts.reform.am.model.RoleRequest; +import uk.gov.hmcts.reform.am.model.RoleType; + +import java.io.IOException; +import java.time.ZonedDateTime; +import java.util.List; +import java.util.Map; + +import static io.pactfoundation.consumer.dsl.LambdaDsl.newJsonBody; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +@ExtendWith(PactConsumerTestExt.class) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@PactTestFor(providerName = "am_roleAssignment_createAssignment", port = "8894") +@PactFolder("pacts") +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = RoleAssignmentServiceConsumerApplication.class) +@TestPropertySource(properties = "am_role_assignment.api.url=localhost:8894") +public class RoleAssignmentServiceConsumerTest { + + private static final String SERVICE_AUTH_TOKEN = "someServiceAuthToken"; + private static final String AUTHORIZATION_TOKEN = "Bearer some-access-token"; + + @Autowired + ObjectMapper objectMapper; + + @Autowired + AmApi amApi; + + private final ZonedDateTime now = ZonedDateTime.now(); + + // create + @Pact(provider = "am_roleAssignment_createAssignment", consumer = "fpl_ccdConfiguration") + public RequestResponsePact generatePactFragmentForCreate(PactDslWithProvider builder) throws IOException { + // @formatter:off + return builder + .given("The assignment request is valid with one requested role and replaceExisting flag as false") + .uponReceiving("A request to add a role") + .method("POST") + .path("/am/role-assignments") + .headers("Content-Type", "application/json") + .body(objectMapper.writeValueAsString(buildAssignmentRequest())) + .willRespondWith() + .status(HttpStatus.SC_CREATED) + .headers(Map.of( + "Content-Type", "application/vnd.uk.gov.hmcts.role-assignment-service.create-assignments+json")) + .body(buildCreateResponsePactDsl()) + .toPact(); + } + + @Test + @PactTestFor(pactMethod = "generatePactFragmentForCreate") + public void verifyAssignRole() { + RoleAssignmentRequestResource res = amApi.createRoleAssignment(AUTHORIZATION_TOKEN, + SERVICE_AUTH_TOKEN, buildAssignmentRequest()); + + assertThat(res.getRoleAssignmentResponse().getRequestedRoles()).asList().hasSize(1); + assertThat(res.getRoleAssignmentResponse().getRequestedRoles().get(0).getStatus()).isEqualTo("APPROVED"); + } + + private AssignmentRequest buildAssignmentRequest() { + return AssignmentRequest.builder() + .roleRequest(RoleRequest.builder() + .assignerId("assignerId") + .process("fpl-case-service") + .reference("reference") + .replaceExisting(false) + .build()) + .requestedRoles(List.of( + RoleAssignment.builder() + .actorId("actorId") + .actorIdType("IDAM") + .beginTime(now) + .endTime(now.plusDays(1)) + .attributes(Map.of("jurisdiction", "PUBLICLAW", "caseId", "1234567890123456")) + .grantType(GrantType.STANDARD) + .readOnly(false) + .roleName("allocated-judge") + .roleType(RoleType.CASE) + .roleCategory(RoleCategory.JUDICIAL) + .build() + )) + .build(); + } + + protected DslPart buildCreateResponsePactDsl() { + return newJsonBody(ob -> ob + .object("roleAssignmentResponse", pa -> pa + .array("requestedRoles", ra -> ra + .object(r -> r + .stringType("actorId", "actorId") + .stringType("actorIdType", "IDAM") + .stringType("roleName", "allocated-judge") + .stringType("roleType", "CASE") + .stringType("classification", "PUBLIC") + .stringType("grantType", "STANDARD") + .stringType("roleCategory", "JUDICIAL") + .object("attributes", at -> at + .stringType("jurisdiction", "PUBLICLAW") + .stringType("caseId", "1234567890123456")) + .booleanType("readOnly", false) + .stringType("status", "APPROVED") + .decimalType("beginTime", "endTime") + ) + ) + .object("roleRequest", rr -> rr + .stringType("assignerId", "assignerId") + .stringType("process", "process") + .stringType("reference", "reference") + .booleanType("replaceExisting", false) + )) + ).build(); + } + + // query + + // delete +} diff --git a/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleAssignment.java b/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleAssignment.java index c8a116f2f74..48604ef09ce 100644 --- a/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleAssignment.java +++ b/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleAssignment.java @@ -5,6 +5,7 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; import java.time.ZonedDateTime; import java.util.List; @@ -15,6 +16,7 @@ @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @AllArgsConstructor +@NoArgsConstructor public class RoleAssignment { private String id; diff --git a/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleAssignmentRequestResource.java b/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleAssignmentRequestResource.java index fe65a43c134..813106b8aae 100644 --- a/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleAssignmentRequestResource.java +++ b/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleAssignmentRequestResource.java @@ -4,10 +4,12 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import lombok.extern.jackson.Jacksonized; @Data @Builder @NoArgsConstructor +@Jacksonized @AllArgsConstructor public class RoleAssignmentRequestResource { diff --git a/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleRequest.java b/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleRequest.java index f3205861dfc..482f539eefc 100644 --- a/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleRequest.java +++ b/service/src/main/java/uk/gov/hmcts/reform/am/model/RoleRequest.java @@ -1,10 +1,16 @@ package uk.gov.hmcts.reform.am.model; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.jackson.Jacksonized; @Data @Builder +@NoArgsConstructor +@Jacksonized +@AllArgsConstructor public class RoleRequest { private String assignerId;