Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
b864f22
FPVTL-2022 : added Awaiting Information
ravidoki-hmcts Feb 3, 2026
d73feec
FPVTL-2022 - Initial changes for Awaiting Information Case
maddalihari Feb 3, 2026
24b0082
FPVTL-2022 - added awaiting information
ravidoki-hmcts Feb 6, 2026
d336590
FPVTL-2022 - added awaiting information
ravidoki-hmcts Feb 6, 2026
c95012d
FPVTL-2022 - added awaiting information tests for controller and service
Feb 9, 2026
682524c
Merge branch 'master' into FPVTL-2022
ravidoki-hmcts Feb 9, 2026
fcb3503
FPVTL-2022 - added awaiting information - tests
ravidoki-hmcts Feb 9, 2026
57087b6
FPVTL-2022 - added awaiting information tests for controller and service
Feb 9, 2026
2b14788
Merge remote-tracking branch 'origin/FPVTL-2022' into FPVTL-2022
Feb 9, 2026
78c23f6
FPVTL-2022 - added awaiting information tests for controller and service
Feb 9, 2026
525d5ab
FPVTL-2022 - added awaiting information tests for controller and service
Feb 9, 2026
144880c
FPVTL-2022 - added feature toggler
Feb 9, 2026
8a750ec
FPVTL-2022 - added awaiting information - added FS
ravidoki-hmcts Feb 10, 2026
7265b1d
FPVTL-2022 - added awaiting information - added FS
ravidoki-hmcts Feb 10, 2026
732de69
FPVTL-2022 - added awaiting information - added FS
ravidoki-hmcts Feb 10, 2026
d52259d
FPVTL-2022 - added feature toggler removed conditional on calss, used…
Feb 10, 2026
cfe3b9d
FPVTL-2022 - persist awaitingInformation in to case data
Feb 12, 2026
30c90aa
FPVTL-2022 added reasons for awaiting information
Feb 13, 2026
f19ab52
FPVTL-2022 - added awaiting information - added FS
ravidoki-hmcts Feb 17, 2026
9944db6
FPVTL-2022 - added awaiting information - added FS
ravidoki-hmcts Feb 17, 2026
61f4101
FPVTL-2022 - added awaiting information - added FS
ravidoki-hmcts Feb 17, 2026
3934862
FPVTL-2022 - added awaiting information - added FS
ravidoki-hmcts Feb 17, 2026
20d9f54
Merge branch 'master' into FPVTL-2022
srochani Feb 18, 2026
9aa90df
FPVTL-2022 - added awaiting information - added FS
ravidoki-hmcts Feb 19, 2026
be1e7ee
Merge remote-tracking branch 'origin/FPVTL-2022' into FPVTL-2022
ravidoki-hmcts Feb 19, 2026
14a06e7
FPVTL-2022 added tests for awaiting information details for summary tab
Feb 20, 2026
b9ba27e
FPVTL-2022 review comments
Feb 24, 2026
700c867
FPVTL-2022 - fixes as per comments
ravidoki-hmcts Feb 24, 2026
a262e62
Merge remote-tracking branch 'origin/FPVTL-2022' into FPVTL-2022
ravidoki-hmcts Feb 24, 2026
970a02f
FPVTL-2022 - fixes as per comments
ravidoki-hmcts Feb 24, 2026
1415228
FPVTL-2022 review comments
Feb 24, 2026
31c0a92
FPVTL-2022 review comments
Feb 25, 2026
7cafc9b
FPVTL-2022 review comments
Feb 25, 2026
a5d6134
FPVTL-2022 review comments
Feb 25, 2026
b5a5035
Merge remote-tracking branch 'origin/master' into FPVTL-2022
ravidoki-hmcts Feb 25, 2026
ac38882
FPVTL-2022 review comments
Feb 26, 2026
2f131ee
FPVTL-2022 review comments
Feb 26, 2026
d8355f9
FPVTL-2022 review date validation
Feb 26, 2026
770329c
FPVTL-2022 case event name change from Awaiting Information to Reques…
Mar 2, 2026
d3709fa
FPVTL-2022 case event name change from Awaiting Information to Reques…
Mar 2, 2026
38167ef
FPVTL-2022 case event name change from Awaiting Information to Reques…
Mar 4, 2026
3b724dd
FPVTL-2022 history Tab
Mar 6, 2026
211f397
FPVTL-2022 history Tab changes
Mar 11, 2026
1dae850
FPVTL-2022 history Tab changes
Mar 11, 2026
56c2a93
FPVTL-2085 Exit Awaiting Information (Manual Event) — Superuser Work…
Mar 17, 2026
5b3b0a0
FPVTL-2085 Exit Awaiting Information (Manual Event) — Superuser Work…
Mar 19, 2026
04db217
Merge branch 'master' of github.com:hmcts/prl-cos-api into FPVTL-2510…
bsgangapatnam Mar 26, 2026
c737c1e
adding Awating info for case issued
bsgangapatnam Mar 26, 2026
ca96a9e
refactor the callback controller for Case Issued
bsgangapatnam Mar 27, 2026
da0d184
FPVTL-2108 Populating HWF_APP_LIST when the case state AWAITING_INFOR…
tonymort Mar 26, 2026
c9b0c05
FPVTL-2108 On the about to submit stage of the HWF event, handling th…
tonymort Mar 29, 2026
0c5802c
Merge branch 'FPVTL-2510-fix' into FPVTL-2085
bsgangapatnam Mar 30, 2026
ddfbdd7
Fix NPE when validating respondent contact details (#3692)
jthmcts Mar 26, 2026
eccc9b1
Fix integration tests (#3681)
jthmcts Mar 26, 2026
17f9d1b
FPVTL-2431 - Update local env acr commands (#3686)
hisamuran-sun Mar 26, 2026
6937899
Revert "Revert "Fpvtl 2095 c100 policy changes (#3589)" (#3673)" (#3685)
srochani Mar 31, 2026
22d0544
Update dependency com.github.hmcts:ccd-config-generator to v6.7.2 (#3…
renovate[bot] Mar 31, 2026
7c2872d
Update dependency hashicorp/terraform to v1.14.8 (#3705)
renovate[bot] Mar 31, 2026
ccdc3d2
Update log4j2 monorepo to v2.25.4 (#3706)
renovate[bot] Mar 31, 2026
f7167b4
Merge branch 'master' into FPVTL-2085
maddalihari Apr 2, 2026
c943790
FPVTL-2085 fixed failing tests
Apr 2, 2026
477e40c
Merge remote-tracking branch 'origin/FPVTL-2085' into FPVTL-2085
Apr 2, 2026
42f77e9
FPVTL-2085 fixed failing tests
Apr 2, 2026
39f650c
FPVTL-2085 fixed failing tests
Apr 2, 2026
a509644
FPVTL-2085 fixed failing tests
Apr 2, 2026
28d4fb1
Merge branch 'master' into FPVTL-2085
maddalihari Apr 14, 2026
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
2 changes: 2 additions & 0 deletions charts/prl-cos/values.preview.template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,7 @@ java:
COMMON_DATA_API: http://rd-commondata-api-aat.service.core-compute-aat.internal
SEND_LETTER_URL: http://rpe-send-letter-service-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal
BARRISTER_FEATURE_ENABLED: true
AWAITING_INFORMATION_ENABLED: true
EXIT_AWAITING_INFORMATION_ENABLED: true
CAFCASS_DATE_TIME_FEATURE_ENABLED: true
APP_ENV: "preview"
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ public void testFl401AddCaseNumberWhenStateIsNotInSubmitted() throws Exception {
.contentType(APPLICATION_JSON)
.content(jsonRequest))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.isAddCaseNumberAdded").isEmpty())
.andExpect(jsonPath("$.data.isAddCaseNumberAdded").doesNotExist())
.andReturn();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package uk.gov.hmcts.reform.prl.controllers;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
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.ccd.client.model.CallbackRequest;
import uk.gov.hmcts.reform.ccd.client.model.CaseDetails;
import uk.gov.hmcts.reform.prl.enums.State;
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.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
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.SERVICE_AUTHORIZATION_HEADER;
import static uk.gov.hmcts.reform.prl.constants.PrlAppsConstants.STATE_FIELD;

@SpringBootTest
@RunWith(SpringRunner.class)
@ContextConfiguration
public class ExitAwaitingInformationControllerIntegrationTest {

private static final String AUTHORISATION_HEADER = "Authorization";
private static final String TEST_AUTH_TOKEN = "Bearer testAuthToken";
private static final String TEST_SERVICE_AUTH_TOKEN = "testServiceAuthToken";
private static final String URL = "/submit-exit-awaiting-information";
private static final long TEST_CASE_ID = 12345678L;

private MockMvc mockMvc;

@Autowired
private WebApplicationContext webApplicationContext;

@Autowired
private ObjectMapper objectMapper;

@MockBean
private AuthorisationService authorisationService;

@MockBean
private ExitAwaitingInformationService exitAwaitingInformationService;

@MockBean
private FeatureToggleService featureToggleService;

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

@Test
public void shouldSubmitExitAwaitingInformationSuccessfully() throws Exception {
when(authorisationService.isAuthorized(TEST_AUTH_TOKEN, TEST_SERVICE_AUTH_TOKEN)).thenReturn(true);
when(exitAwaitingInformationService.updateCase(any())).thenReturn(updatedCaseData());

mockMvc.perform(
post(URL)
.header(AUTHORISATION_HEADER, TEST_AUTH_TOKEN)
.header(SERVICE_AUTHORIZATION_HEADER, TEST_SERVICE_AUTH_TOKEN)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(validCallbackRequestJson()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.state").value(State.CASE_ISSUED.getValue()))
.andExpect(jsonPath("$.data.caseStatus.state").value(State.CASE_ISSUED.getLabel()))
.andExpect(jsonPath("$.data.existingField").value("existingValue"));

verify(exitAwaitingInformationService).updateCase(any());
}

@Test
public void shouldRejectSubmitExitAwaitingInformationWithoutAuthorizationHeader() throws Exception {
mockMvc.perform(
post(URL)
.header(SERVICE_AUTHORIZATION_HEADER, TEST_SERVICE_AUTH_TOKEN)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(validCallbackRequestJson()))
.andExpect(status().isBadRequest());
}

@Test
public void shouldRejectSubmitExitAwaitingInformationWithoutServiceAuthorizationHeader() throws Exception {
mockMvc.perform(
post(URL)
.header(AUTHORISATION_HEADER, TEST_AUTH_TOKEN)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(validCallbackRequestJson()))
.andExpect(status().isBadRequest());
}

@Test
public void shouldRejectSubmitExitAwaitingInformationWithUnauthorizedTokens() throws Exception {
when(authorisationService.isAuthorized(TEST_AUTH_TOKEN, TEST_SERVICE_AUTH_TOKEN)).thenReturn(false);

ServletException exception = assertThrows(ServletException.class, () -> mockMvc.perform(
post(URL)
.header(AUTHORISATION_HEADER, TEST_AUTH_TOKEN)
.header(SERVICE_AUTHORIZATION_HEADER, TEST_SERVICE_AUTH_TOKEN)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(validCallbackRequestJson())));

assertNotNull(exception.getCause());
assertEquals("Invalid Client", exception.getCause().getMessage());
}

private String validCallbackRequestJson() throws Exception {
Map<String, Object> caseData = new HashMap<>();
caseData.put("existingField", "existingValue");

CallbackRequest callbackRequest = CallbackRequest.builder()
.eventId("submit-exit-awaiting-information")
.caseDetails(CaseDetails.builder()
.id(TEST_CASE_ID)
.state(State.AWAITING_INFORMATION.getValue())
.data(caseData)
.build())
.caseDetailsBefore(CaseDetails.builder()
.id(TEST_CASE_ID)
.state(State.AWAITING_INFORMATION.getValue())
.data(new HashMap<>(caseData))
.build())
.build();

return objectMapper.writeValueAsString(callbackRequest);
}

private Map<String, Object> updatedCaseData() {
Map<String, Object> caseData = new HashMap<>();
caseData.put("existingField", "existingValue");
caseData.put(STATE_FIELD, State.CASE_ISSUED.getValue());
caseData.put(CASE_STATUS, Map.of("state", State.CASE_ISSUED.getLabel()));
return caseData;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package uk.gov.hmcts.reform.prl.controllers;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
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.ccd.client.model.CallbackRequest;
import uk.gov.hmcts.reform.ccd.client.model.CaseDetails;
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.FeatureToggleService;
import uk.gov.hmcts.reform.prl.services.RequestFurtherInformationService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
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.SERVICE_AUTHORIZATION_HEADER;

@SpringBootTest
@RunWith(SpringRunner.class)
@ContextConfiguration
public class RequestFurtherInformationControllerIntegrationTest {

private static final String AUTHORISATION_HEADER = "Authorization";
private static final String TEST_AUTH_TOKEN = "Bearer testAuthToken";
private static final String TEST_SERVICE_AUTH_TOKEN = "testServiceAuthToken";
private static final String SUBMIT_URL = "/submit-request-further-information";
private static final String VALIDATE_URL = "/validate-request-further-information";
private static final long TEST_CASE_ID = 12345678L;

private MockMvc mockMvc;

@Autowired
private WebApplicationContext webApplicationContext;

@Autowired
private ObjectMapper objectMapper;

@MockBean
private AuthorisationService authorisationService;

@MockBean
private RequestFurtherInformationService requestFurtherInformationService;

@MockBean
private FeatureToggleService featureToggleService;

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

@Test
public void shouldSubmitAwaitingInformationSuccessfully() throws Exception {
when(authorisationService.isAuthorized(TEST_AUTH_TOKEN, TEST_SERVICE_AUTH_TOKEN)).thenReturn(true);
when(requestFurtherInformationService.addToCase(any())).thenReturn(submittedCaseData());

mockMvc.perform(
post(SUBMIT_URL)
.header(AUTHORISATION_HEADER, TEST_AUTH_TOKEN)
.header(SERVICE_AUTHORIZATION_HEADER, TEST_SERVICE_AUTH_TOKEN)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(validCallbackRequestJson()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.id").value(TEST_CASE_ID))
.andExpect(jsonPath("$.data.caseStatus.state").value("Awaiting information"))
.andExpect(jsonPath("$.data.applicantName").value("John Doe"))
.andExpect(jsonPath("$.data.respondentName").value("Jane Doe"));

verify(requestFurtherInformationService).addToCase(any());
}

@Test
public void shouldRejectSubmitAwaitingInformationWithoutAuthorizationHeader() throws Exception {
mockMvc.perform(
post(SUBMIT_URL)
.header(SERVICE_AUTHORIZATION_HEADER, TEST_SERVICE_AUTH_TOKEN)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(validCallbackRequestJson()))
.andExpect(status().isBadRequest());
}

@Test
public void shouldRejectSubmitAwaitingInformationWithoutServiceAuthorizationHeader() throws Exception {
mockMvc.perform(
post(SUBMIT_URL)
.header(AUTHORISATION_HEADER, TEST_AUTH_TOKEN)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(validCallbackRequestJson()))
.andExpect(status().isBadRequest());
}

@Test
public void shouldRejectSubmitAwaitingInformationWithUnauthorizedTokens() throws Exception {
when(authorisationService.isAuthorized(TEST_AUTH_TOKEN, TEST_SERVICE_AUTH_TOKEN)).thenReturn(false);

ServletException exception = assertThrows(ServletException.class, () -> mockMvc.perform(
post(SUBMIT_URL)
.header(AUTHORISATION_HEADER, TEST_AUTH_TOKEN)
.header(SERVICE_AUTHORIZATION_HEADER, TEST_SERVICE_AUTH_TOKEN)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(validCallbackRequestJson())));

assertNotNull(exception.getCause());
assertEquals("Invalid Client", exception.getCause().getMessage());
}

@Test
public void shouldValidateAwaitingInformationSuccessfully() throws Exception {
when(requestFurtherInformationService.validate(any(CallbackRequest.class))).thenReturn(new ArrayList<>());

mockMvc.perform(
post(VALIDATE_URL)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(validCallbackRequestJson()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.errors").isArray())
.andExpect(jsonPath("$.errors").isEmpty());
}

@Test
public void shouldValidateAwaitingInformationWithErrors() throws Exception {
when(requestFurtherInformationService.validate(any(CallbackRequest.class)))
.thenReturn(List.of("Please enter a future date"));

mockMvc.perform(
post(VALIDATE_URL)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(validCallbackRequestJson()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.errors[0]").value("Please enter a future date"));
}

@Test
public void shouldReturnEmptyValidationErrorsWhenFeatureToggleDisabled() throws Exception {
when(featureToggleService.isAwaitingInformationEnabled()).thenReturn(false);

mockMvc.perform(
post(VALIDATE_URL)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(validCallbackRequestJson()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.errors").isArray())
.andExpect(jsonPath("$.errors").isEmpty());
}

@Test
public void shouldRejectValidationWithoutContentType() throws Exception {
mockMvc.perform(
post(VALIDATE_URL)
.content(validCallbackRequestJson()))
.andExpect(status().isUnsupportedMediaType());
}

private String validCallbackRequestJson() throws Exception {
Map<String, Object> caseData = new HashMap<>();
caseData.put("id", TEST_CASE_ID);
caseData.put("reviewDate", "2030-01-01");
caseData.put("existingField", "existingValue");

CallbackRequest callbackRequest = CallbackRequest.builder()
.eventId("request-further-information")
.caseDetails(CaseDetails.builder()
.id(TEST_CASE_ID)
.state("AWAITING_INFORMATION")
.data(caseData)
.build())
.caseDetailsBefore(CaseDetails.builder()
.id(TEST_CASE_ID)
.state("CASE_ISSUED")
.data(new HashMap<>(caseData))
.build())
.build();

return objectMapper.writeValueAsString(callbackRequest);
}

private Map<String, Object> submittedCaseData() {
Map<String, Object> caseData = new HashMap<>();
caseData.put("id", TEST_CASE_ID);
caseData.put("applicantName", "John Doe");
caseData.put("respondentName", "Jane Doe");
caseData.put(CASE_STATUS, CaseStatus.builder().state("Awaiting information").build());
return caseData;
}
}
Loading