Skip to content
Closed
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
@@ -0,0 +1,125 @@
package uk.gov.hmcts.reform.prl.controllers;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;
import uk.gov.hmcts.reform.prl.ResourceLoader;
import uk.gov.hmcts.reform.prl.models.complextypes.tab.summarytab.summary.CaseStatus;
import uk.gov.hmcts.reform.prl.services.AuthorisationService;
import uk.gov.hmcts.reform.prl.services.ExitAwaitingInformationService;
import uk.gov.hmcts.reform.prl.services.FeatureToggleService;

import java.util.HashMap;
import java.util.Map;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
import static uk.gov.hmcts.reform.prl.constants.PrlAppsConstants.CASE_STATUS;
import static uk.gov.hmcts.reform.prl.constants.PrlAppsConstants.STATE_FIELD;

@SpringBootTest(properties = {
"feature.toggle.exitAwaitingInformationEnabled=true"
})
@RunWith(SpringRunner.class)
@ContextConfiguration
public class ExitAwaitingInformationControllerIntegrationTest {

private static final String AUTHORISATION_HEADER = "Authorization";
private static final String SERVICE_AUTHORISATION_HEADER = "Service-Authorization";
private static final String TEST_AUTH_TOKEN = "Bearer testAuthToken";
private static final String TEST_SERVICE_AUTH_TOKEN = "testServiceAuthToken";

private MockMvc mockMvc;

@Autowired
private WebApplicationContext webApplicationContext;

@MockBean
private AuthorisationService authorisationService;

@MockBean
private ExitAwaitingInformationService exitAwaitingInformationService;

@MockBean
private FeatureToggleService featureToggleService;

@Before
public void setUp() {
this.mockMvc = webAppContextSetup(webApplicationContext).build();
when(featureToggleService.isExitAwaitingInformationEnabled()).thenReturn(true);
}

private Map<String, Object> createMockCaseData() {
Map<String, Object> caseData = new HashMap<>();
caseData.put("id", 12345678L);
caseData.put(STATE_FIELD, "CASE_ISSUED");
caseData.put(CASE_STATUS, CaseStatus.builder().state("Case Issued").build());
return caseData;
}

@Test
public void shouldSubmitExitAwaitingInformationSuccessfully() throws Exception {
String url = "/submit-exit-awaiting-information";
String jsonRequest = ResourceLoader.loadJson("CallbackRequest.json");

when(authorisationService.isAuthorized(any(), any())).thenReturn(true);
when(exitAwaitingInformationService.updateCase(any())).thenReturn(createMockCaseData());

mockMvc.perform(
post(url)
.header(AUTHORISATION_HEADER, TEST_AUTH_TOKEN)
.header(SERVICE_AUTHORISATION_HEADER, TEST_SERVICE_AUTH_TOKEN)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(jsonRequest))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.id").value(12345678))
.andExpect(jsonPath("$.data.state").value("CASE_ISSUED"))
.andReturn();
}

@Test
public void shouldRejectSubmitExitAwaitingInformationWithoutAuthorizationHeader() throws Exception {
String url = "/submit-exit-awaiting-information";
String jsonRequest = ResourceLoader.loadJson("CallbackRequest.json");

mockMvc.perform(
post(url)
.header(SERVICE_AUTHORISATION_HEADER, TEST_SERVICE_AUTH_TOKEN)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(jsonRequest))
.andExpect(status().isBadRequest())
.andReturn();
}

@Test
public void shouldRejectSubmitExitAwaitingInformationWithUnauthorizedTokens() throws Exception {
String url = "/submit-exit-awaiting-information";
String jsonRequest = ResourceLoader.loadJson("CallbackRequest.json");

when(authorisationService.isAuthorized(any(), any())).thenReturn(false);

mockMvc.perform(
post(url)
.header(AUTHORISATION_HEADER, "invalidToken")
.header(SERVICE_AUTHORISATION_HEADER, "invalidServiceToken")
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(jsonRequest))
.andExpect(status().isInternalServerError())
.andReturn();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,7 @@ public class PrlAppsConstants {
public static final String FETCH_FEE_ERROR = "Error while fetching fee details for application type: ";
public static final String ENGLISH = "en";
public static final String WELSH = "cy";
public static final String EXIT_AWAITING_INFORMATION_DETAILS = "exitAwaitingInformationDetails";


public static final String MIAM_ERROR_WELSH = "Ni allwch wneud y cais hwn oni bai bod y ceisydd naill ai wedi mynychu"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package uk.gov.hmcts.reform.prl.controllers;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse;
import uk.gov.hmcts.reform.ccd.client.model.CallbackRequest;
import uk.gov.hmcts.reform.prl.constants.PrlAppsConstants;
import uk.gov.hmcts.reform.prl.services.AuthorisationService;
import uk.gov.hmcts.reform.prl.services.ExitAwaitingInformationService;
import uk.gov.hmcts.reform.prl.services.FeatureToggleService;

import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static uk.gov.hmcts.reform.prl.constants.PrlAppsConstants.INVALID_CLIENT;

@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ExitAwaitingInformationController {

private final ExitAwaitingInformationService exitAwaitingInformationService;
private final AuthorisationService authorisationService;
private final FeatureToggleService featureToggleService;

@PostMapping(path = "/submit-exit-awaiting-information", consumes = APPLICATION_JSON, produces = APPLICATION_JSON)
@Operation(description = "Exit awaiting information callback to update case data and set case status")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Callback processed.",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = AboutToStartOrSubmitCallbackResponse.class))),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content)})
@SecurityRequirement(name = "Bearer Authentication")
public AboutToStartOrSubmitCallbackResponse submitExitAwaitingInformation(
@RequestHeader(HttpHeaders.AUTHORIZATION) @Parameter(hidden = true) String authorisation,
@RequestHeader(PrlAppsConstants.SERVICE_AUTHORIZATION_HEADER) String s2sToken,
@RequestBody CallbackRequest callbackRequest
) {
log.info("Submitting exit awaiting information for case: {}",
callbackRequest.getCaseDetails().getId());

if (authorisationService.isAuthorized(authorisation, s2sToken)
&& featureToggleService.isExitAwaitingInformationEnabled()) {
var caseDataUpdated = exitAwaitingInformationService.updateCase(callbackRequest);
return AboutToStartOrSubmitCallbackResponse.builder().data(caseDataUpdated).build();
}
throw new RuntimeException(INVALID_CLIENT);
}

}
3 changes: 2 additions & 1 deletion src/main/java/uk/gov/hmcts/reform/prl/enums/CaseEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ public enum CaseEvent {
REVIEW_ADDITIONAL_APPLICATION("reviewAdditionalApplication"),
CLOSE_REVIEW_RA_REQUEST_TASK("closeReviewRARequestTask"),
REQUEST_FURTHER_INFORMATION("requestFurtherInformation"),
REQUEST_FURTHER_INFORMATION_HISTORY("requestFurtherInformationHistory");
REQUEST_FURTHER_INFORMATION_HISTORY("requestFurtherInformationHistory"),
EXIT_AWAITING_INFORMATION("exitAwaitingInformation");

private final String value;

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/uk/gov/hmcts/reform/prl/enums/State.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public enum State {
PROCEEDS_IN_HERITAGE_SYSTEM("PROCEEDS_IN_HERITAGE_SYSTEM",
"Proceeding in offline mode in familyman system"),
AWAITING_INFORMATION("AWAITING_INFORMATION",
"Awaiting information");
"Awaiting information"),
EXIT_AWAITING_INFORMATION("EXIT_AWAITING_INFORMATION",
"Exit Awaiting information");

private final String value;
private final String label;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package uk.gov.hmcts.reform.prl.enums.awaitinginformation;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.RequiredArgsConstructor;
import uk.gov.hmcts.reform.prl.enums.CustomEnumSerializer;

import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Stream;

@RequiredArgsConstructor
@JsonSerialize(using = CustomEnumSerializer.class)
public enum ExitAwaitingInformationReasonEnum {

CASE_ISSUED("CASE_ISSUED", "Case Issued"),
GATE_KEEPING("GATE_KEEPING", "Gate Keeping"),
SUBMITTED_NOT_PAID("SUBMITTED_NOT_PAID", "Pending"),
SUBMITTED_PAID("SUBMITTED_PAID", "Submitted");

private final String value;
private final String label;

ExitAwaitingInformationReasonEnum(String value) {
this.value = value;
this.label = value;
}

public static ExitAwaitingInformationReasonEnum fromValue(final String value) {
return tryFromValue(value)
.orElseThrow(() -> new NoSuchElementException("Unable to map " + value + " to a case state"));
}

public static Optional<ExitAwaitingInformationReasonEnum> tryFromValue(final String value) {
return Stream.of(values())
.filter(state -> state.value.equalsIgnoreCase(value))
.findFirst();
}

@JsonValue
public String getLabel() {
return label;
}

@JsonCreator
public static ExitAwaitingInformationReasonEnum getValue(String key) {
return ExitAwaitingInformationReasonEnum.valueOf(key);
}
}
3 changes: 2 additions & 1 deletion src/main/java/uk/gov/hmcts/reform/prl/models/Features.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ public enum Features {
IS_BARRISTER_FEATURE_ENABLED("barristerFeatureEnabled"),
IS_CAFCASS_DATE_TIME_FEATURE_ENABLED("cafcassDateTimeFeatureEnabled"),
IS_OS_COURT_LOOKUP_ENABLED("osCourtLookupEnabled"),
IS_AWAITING_INFORMATION_ENABLED("awaitingInformationEnabled");
IS_AWAITING_INFORMATION_ENABLED("awaitingInformationEnabled"),
IS_EXIT_AWAITING_INFORMATION_ENABLED("exitAwaitingInformationEnabled");

private final String name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package uk.gov.hmcts.reform.prl.models.dto.ccd;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import uk.gov.hmcts.reform.prl.enums.State;

@Data
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class ExitAwaitingInformation {
@JsonProperty("exitAwaitingInformationTargetState")
private State exitAwaitingInformationTargetState;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package uk.gov.hmcts.reform.prl.services;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Builder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import uk.gov.hmcts.reform.ccd.client.model.CallbackRequest;
import uk.gov.hmcts.reform.prl.models.complextypes.tab.summarytab.summary.CaseStatus;
import uk.gov.hmcts.reform.prl.models.dto.ccd.ExitAwaitingInformation;

import java.util.Map;

import static uk.gov.hmcts.reform.prl.constants.PrlAppsConstants.CASE_STATUS;
import static uk.gov.hmcts.reform.prl.constants.PrlAppsConstants.EXIT_AWAITING_INFORMATION_DETAILS;
import static uk.gov.hmcts.reform.prl.constants.PrlAppsConstants.STATE_FIELD;

@Slf4j
@Builder
@RequiredArgsConstructor
@Service
public class ExitAwaitingInformationService {

private final FeatureToggleService featureToggleService;
private final ObjectMapper objectMapper;

public Map<String, Object> updateCase(CallbackRequest callbackRequest) {
var caseDataUpdated = callbackRequest.getCaseDetails().getData();
var exitAwaitingInformation = getExitAwaitingInformation(caseDataUpdated);
var targetState = exitAwaitingInformation.getExitAwaitingInformationTargetState();

caseDataUpdated.put(STATE_FIELD, targetState.getValue());
caseDataUpdated.put(
CASE_STATUS, CaseStatus.builder()
.state(targetState.getLabel())
.build()
);
log.info(
"Updated '{}' field for case {} to {}",
CASE_STATUS, callbackRequest.getCaseDetails().getId(), targetState.getLabel()
);
return caseDataUpdated;
}

private ExitAwaitingInformation getExitAwaitingInformation(Map<String, Object> caseData) {
return objectMapper.convertValue(
caseData.get(EXIT_AWAITING_INFORMATION_DETAILS),
ExitAwaitingInformation.class
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,8 @@ public boolean isOsCourtLookupFeatureEnabled() {
public boolean isAwaitingInformationEnabled() {
return isFeatureEnabled(Features.IS_AWAITING_INFORMATION_ENABLED);
}

public boolean isExitAwaitingInformationEnabled() {
return isFeatureEnabled(Features.IS_EXIT_AWAITING_INFORMATION_ENABLED);
}
}
1 change: 1 addition & 0 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ feature:
cafcassDateTimeFeatureEnabled: ${CAFCASS_DATE_TIME_FEATURE_ENABLED:false}
osCourtLookupEnabled: ${OS_COURT_LOOKUP_ENABLED:false}
awaitingInformationEnabled: ${AWAITING_INFORMATION_ENABLED:false}
exitAwaitingInformationEnabled: ${EXIT_AWAITING_INFORMATION_ENABLED:false}

xui:
url: ${XUI_URL:https://manage-case.aat.platform.hmcts.net/cases/case-details}
Expand Down
Loading