Skip to content

Commit

Permalink
ADOP-2566: Set up migratecase event for migration tool (#958)
Browse files Browse the repository at this point in the history
* ADOP-2566: Set up migratecase event for migration tool

* remove unused object

* Fix checkstyle

* Update MigrateCase.java

* name migration

* update function generics

* refactor duplicate code, move caseworker event tests into the right package

* Add migrate-case tests, refactor some unnecessary constants

* ADOP-2566: Update tests, remove ADOP-test migration

* rename func

* test migration demo

* Revert test migration

---------

Co-authored-by: Daniel Catchpole <daniel.catchpole@justice.gov.uk>
  • Loading branch information
qasimnawaz-moj and DanCatchpole authored Dec 3, 2024
1 parent cc8a7be commit fb45491
Show file tree
Hide file tree
Showing 24 changed files with 381 additions and 797 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package uk.gov.hmcts.reform.adoption.adoptioncase.event;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import uk.gov.hmcts.ccd.sdk.api.CCDConfig;
import uk.gov.hmcts.ccd.sdk.api.CaseDetails;
import uk.gov.hmcts.ccd.sdk.api.ConfigBuilder;
import uk.gov.hmcts.ccd.sdk.api.callback.AboutToStartOrSubmitResponse;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.CaseData;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.State;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.UserRole;

import java.util.Map;
import java.util.function.Consumer;

import static uk.gov.hmcts.reform.adoption.adoptioncase.model.State.AwaitingPayment;
import static uk.gov.hmcts.reform.adoption.adoptioncase.model.State.Draft;
import static uk.gov.hmcts.reform.adoption.adoptioncase.model.State.LaSubmitted;
import static uk.gov.hmcts.reform.adoption.adoptioncase.model.State.Submitted;
import static uk.gov.hmcts.reform.adoption.adoptioncase.model.UserRole.SYSTEM_UPDATE;
import static uk.gov.hmcts.reform.adoption.adoptioncase.model.access.Permissions.CREATE_READ_UPDATE_DELETE;

@Slf4j
@Component
public class MigrateCase implements CCDConfig<CaseData, State, UserRole> {

public static final String MIGRATE_CASE = "migrate-case";

// Note - keep "ADOP-log", it is useful for triggering an "event" without updating data
private final Map<String, Consumer<CaseDetails<CaseData, State>>> migrations = Map.of(
"ADOP-log", this::runLog
);

@Override
public void configure(final ConfigBuilder<CaseData, State, UserRole> configBuilder) {

configBuilder
.event(MIGRATE_CASE)
.forStates(Draft, AwaitingPayment, Submitted, LaSubmitted)
.name("Migrate case")
.description("Migrate case")
.retries(120, 120)
.grant(CREATE_READ_UPDATE_DELETE, SYSTEM_UPDATE)
.aboutToSubmitCallback(this::aboutToSubmit);
}

public AboutToStartOrSubmitResponse<CaseData, State> aboutToSubmit(CaseDetails<CaseData, State> details,
CaseDetails<CaseData, State> beforeDetails) {
CaseData data = details.getData();
String migrationId = data.getMigrationId();
Long id = details.getId();

log.info("Migration {id = {}, case reference = {}} started", migrationId, id);

if (!migrations.containsKey(migrationId)) {
throw new RuntimeException("No migration mapped to " + migrationId);
}

migrations.get(migrationId).accept(details);

log.info("Migration {id = {}, case reference = {}} finished", migrationId, id);

State state = details.getState();

data.setMigrationId(null);
return AboutToStartOrSubmitResponse.<CaseData, State>builder()
.data(data)
.state(state)
.build();
}

private void runLog(CaseDetails<CaseData, State> caseDetails) {
log.info("Logging migration on case {}", caseDetails.getId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
@AllArgsConstructor
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class)
@Builder
@Builder(toBuilder = true)
public class Applicant {

@CCD(label = "First names")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import lombok.AllArgsConstructor;
import lombok.Builder;
Expand All @@ -22,6 +23,7 @@
import uk.gov.hmcts.reform.adoption.adoptioncase.model.access.DefaultAccess;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.access.SystemUpdateAccess;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.access.SystemUpdateCollectionAccess;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.access.SystemUpdateOnlyAccess;
import uk.gov.hmcts.reform.adoption.document.DocumentType;
import uk.gov.hmcts.reform.adoption.document.model.AdoptionDocument;
import uk.gov.hmcts.reform.adoption.document.model.AdoptionUploadDocument;
Expand Down Expand Up @@ -805,6 +807,13 @@ public class CaseData {

private YesOrNo seekFurtherInformationAdopOrLaSelected;

@JsonInclude(JsonInclude.Include.NON_NULL)
@CCD(
label = "Migration ID",
access = {SystemUpdateOnlyAccess.class }
)
private String migrationId;

public String getNameOfCourtFirstHearing() {
if (Objects.nonNull(familyCourtName)) {
return familyCourtName;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package uk.gov.hmcts.reform.adoption.adoptioncase.model.access;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;
import uk.gov.hmcts.ccd.sdk.api.HasAccessControl;
import uk.gov.hmcts.ccd.sdk.api.HasRole;
import uk.gov.hmcts.ccd.sdk.api.Permission;

import static uk.gov.hmcts.reform.adoption.adoptioncase.model.UserRole.SYSTEM_UPDATE;

public class SystemUpdateOnlyAccess implements HasAccessControl {
@Override
public SetMultimap<HasRole, Permission> getGrants() {
SetMultimap<HasRole, Permission> grants = HashMultimap.create();
grants.putAll(SYSTEM_UPDATE, Permissions.CREATE_READ_UPDATE_DELETE);

return grants;
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
package uk.gov.hmcts.reform.adoption.caseworker.event;
package uk.gov.hmcts.reform.adoption.adoptioncase.caseworker.event;

import com.google.common.collect.ImmutableSet;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
import uk.gov.hmcts.ccd.sdk.ConfigBuilderImpl;
import uk.gov.hmcts.ccd.sdk.ResolvedCCDConfig;
import uk.gov.hmcts.ccd.sdk.api.CaseDetails;
import uk.gov.hmcts.ccd.sdk.api.Event;
import uk.gov.hmcts.ccd.sdk.api.HasRole;
import uk.gov.hmcts.reform.adoption.adoptioncase.event.CaseWorkerAllocateJudge;
import uk.gov.hmcts.reform.adoption.adoptioncase.event.EventTest;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.CaseData;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.State;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.UserRole;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.platform.commons.util.ReflectionUtils.findMethod;
import static uk.gov.hmcts.reform.adoption.adoptioncase.event.CaseWorkerAllocateJudge.CASEWORKER_ALLOCATE_JUDGE;
import static uk.gov.hmcts.reform.adoption.testutil.TestDataHelper.caseData;

@ExtendWith(MockitoExtension.class)
public class CaseWorkerAllocateJudgeTest {
public class CaseWorkerAllocateJudgeTest extends EventTest {

@InjectMocks
CaseWorkerAllocateJudge caseWorkerAllocateJudge;
Expand All @@ -43,33 +36,6 @@ void shouldAddConfigurationToConfigBuilder() {
.contains(CASEWORKER_ALLOCATE_JUDGE);
}


public static ConfigBuilderImpl<CaseData, State, UserRole> createCaseDataConfigBuilder() {
return new ConfigBuilderImpl<>(new ResolvedCCDConfig<>(
CaseData.class,
State.class,
UserRole.class,
new HashMap<>(),
ImmutableSet.copyOf(State.class.getEnumConstants())));
}


@SuppressWarnings({"unchecked"})
public static <T, S, R extends HasRole> Map<String, Event<T, R, S>> getEventsFrom(
final ConfigBuilderImpl<T, S, R> configBuilder) {

return (Map<String, Event<T, R, S>>) findMethod(ConfigBuilderImpl.class, "getEvents")
.map(method -> {
try {
method.setAccessible(true);
return method.invoke(configBuilder);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new AssertionError("Unable to invoke ConfigBuilderImpl.class method getEvents", e);
}
})
.orElseThrow(() -> new AssertionError("Unable to find ConfigBuilderImpl.class method getEvents"));
}

private CaseDetails<CaseData, State> getCaseDetails() {
final var details = new CaseDetails<CaseData, State>();
final var data = caseData();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
package uk.gov.hmcts.reform.adoption.adoptioncase.caseworker.event;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableSet;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import uk.gov.hmcts.ccd.sdk.ConfigBuilderImpl;
import uk.gov.hmcts.ccd.sdk.ResolvedCCDConfig;
import uk.gov.hmcts.ccd.sdk.api.CaseDetails;
import uk.gov.hmcts.ccd.sdk.api.Event;
import uk.gov.hmcts.ccd.sdk.api.HasRole;
import uk.gov.hmcts.ccd.sdk.api.callback.AboutToStartOrSubmitResponse;
import uk.gov.hmcts.ccd.sdk.type.DynamicList;
import uk.gov.hmcts.ccd.sdk.type.DynamicListElement;
import uk.gov.hmcts.ccd.sdk.type.ListValue;
import uk.gov.hmcts.ccd.sdk.type.YesOrNo;
import uk.gov.hmcts.reform.adoption.adoptioncase.event.EventTest;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.ApplyingWith;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.CaseData;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.ManageHearingDetails;
Expand All @@ -27,10 +25,7 @@
import uk.gov.hmcts.reform.adoption.adoptioncase.model.State;
import uk.gov.hmcts.reform.adoption.adoptioncase.model.UserRole;
import uk.gov.hmcts.reform.adoption.document.CaseDataDocumentService;
import uk.gov.hmcts.reform.idam.client.models.User;
import uk.gov.hmcts.reform.idam.client.models.UserDetails;

import java.lang.reflect.InvocationTargetException;
import java.time.Clock;
import java.time.Instant;
import java.time.LocalDate;
Expand All @@ -46,15 +41,13 @@
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.platform.commons.util.ReflectionUtils.findMethod;
import static org.mockito.Mockito.when;
import static uk.gov.hmcts.reform.adoption.adoptioncase.caseworker.event.CaseWorkerManageHearing.CASEWORKER_MANAGE_HEARING;
import static uk.gov.hmcts.reform.adoption.adoptioncase.search.CaseFieldsConstants.BLANK_SPACE;
import static uk.gov.hmcts.reform.adoption.testutil.TestConstants.TEST_AUTHORIZATION_TOKEN;
import static uk.gov.hmcts.reform.adoption.testutil.TestDataHelper.caseData;

@ExtendWith(MockitoExtension.class)
class CaseWorkerManageHearingTest {
class CaseWorkerManageHearingTest extends EventTest {


@InjectMocks
Expand Down Expand Up @@ -339,41 +332,4 @@ private CaseDetails<CaseData, State> getCaseDetailsForHearing() {
details.setId(1L);
return details;
}


public static ConfigBuilderImpl<CaseData, State, UserRole> createCaseDataConfigBuilder() {
return new ConfigBuilderImpl<>(new ResolvedCCDConfig<>(
CaseData.class,
State.class,
UserRole.class,
new HashMap<>(),
ImmutableSet.copyOf(State.class.getEnumConstants())
));
}

@SuppressWarnings({"unchecked"})
public static <T, S, R extends HasRole> Map<String, Event<T, R, S>> getEventsFrom(
final ConfigBuilderImpl<T, S, R> configBuilder) {

return (Map<String, Event<T, R, S>>) findMethod(ConfigBuilderImpl.class, "getEvents")
.map(method -> {
try {
method.setAccessible(true);
return method.invoke(configBuilder);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new AssertionError("Unable to invoke ConfigBuilderImpl.class method getEvents", e);
}
})
.orElseThrow(() -> new AssertionError("Unable to find ConfigBuilderImpl.class method getEvents"));
}

private User getCaseworkerUser() {
UserDetails userDetails = UserDetails
.builder()
.forename("testFname")
.surname("testSname")
.build();

return new User(TEST_AUTHORIZATION_TOKEN, userDetails);
}
}
Loading

0 comments on commit fb45491

Please sign in to comment.