Skip to content

Commit

Permalink
DMP-2623: Case Document Generation (#1622)
Browse files Browse the repository at this point in the history
  • Loading branch information
mario-paniccia authored Jun 27, 2024
1 parent 0e22c6a commit 0031d72
Show file tree
Hide file tree
Showing 63 changed files with 2,161 additions and 18 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ def coverageExclusions = [
'**/uk/gov/hmcts/darts/audit/api**',
'**/uk/gov/hmcts/darts/event/api**',
'**/uk/gov/hmcts/darts/audiorequests/api**',
'**/uk/gov/hmcts/darts/casedocument/template**',
]

jacocoTestReport {
Expand Down Expand Up @@ -458,6 +459,8 @@ dependencies {
testImplementation 'io.github.hakky54:logcaptor:2.9.3'
testImplementation 'org.testcontainers:testcontainers:1.19.8'

testImplementation group: 'org.jeasy', name: 'easy-random-core', version: '5.0.0'

compileJava.dependsOn = openApiGenerateTaskList
}

Expand Down
4 changes: 4 additions & 0 deletions lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copy the below annotations from the instance variables to the constructor
# see https://github.com/rzwitserloot/lombok/issues/745
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Value

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import uk.gov.hmcts.darts.common.entity.CourtCaseEntity;
import uk.gov.hmcts.darts.common.repository.CaseRepository;
import uk.gov.hmcts.darts.testutils.IntegrationBase;
import uk.gov.hmcts.darts.testutils.stubs.CourtCaseStub;

import java.time.OffsetDateTime;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

class CaseRepositoryIntTest extends IntegrationBase {
Expand Down Expand Up @@ -43,4 +48,93 @@ void testFindByIsRetentionUpdatedTrueAndRetentionRetriesLessThan() {
assertThat(result).hasSize(1);
assertThat(result.get(0).getId()).isEqualTo(matchingCase.getId());
}

@Test
void testFindCasesNeedingCaseDocumentGeneratedPaged() {
// given
caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(true);
courtCase.setCaseClosedTimestamp(OffsetDateTime.now().minusDays(27));
});

var matchingCase1 = caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(true);
courtCase.setCaseClosedTimestamp(OffsetDateTime.now().minusDays(28));
});

var matchingCase2 = caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(true);
courtCase.setCaseClosedTimestamp(OffsetDateTime.now().minusDays(29));
});

caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(true);
courtCase.setCaseClosedTimestamp(OffsetDateTime.now().minusDays(29));
});

var courtCaseWithCaseDocument = caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(true);
courtCase.setCaseClosedTimestamp(OffsetDateTime.now().minusDays(29));
});
dartsDatabase.getCaseDocumentStub().createCaseDocumentEntity(courtCaseWithCaseDocument, courtCaseWithCaseDocument.getCreatedBy());

caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(false);
});

// when
List<CourtCaseEntity> result = caseRepository.findCasesNeedingCaseDocumentGenerated(
OffsetDateTime.now().minusDays(28), Pageable.ofSize(2));

// then
assertThat(result).hasSize(2);
assertThat(result.get(0).getId()).isEqualTo(matchingCase1.getId());
assertThat(result.get(1).getId()).isEqualTo(matchingCase2.getId());
}

@Test
void testFindCasesNeedingCaseDocumentGeneratedUnpaged() {
// given
caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(true);
courtCase.setCaseClosedTimestamp(OffsetDateTime.now().minusDays(27));
});

var courtCaseWithCaseDocument = caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(true);
courtCase.setCaseClosedTimestamp(OffsetDateTime.now().minusDays(29));
});
dartsDatabase.getCaseDocumentStub().createAndSaveCaseDocumentEntity(courtCaseWithCaseDocument);

caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(false);
});

var matchingCase1 = caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(true);
courtCase.setCaseClosedTimestamp(OffsetDateTime.now().minusDays(28));
});

var matchingCase2 = caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(true);
courtCase.setCaseClosedTimestamp(OffsetDateTime.now().minusDays(29));
});

var matchingCase3 = caseStub.createAndSaveCourtCase(courtCase -> {
courtCase.setClosed(true);
courtCase.setCaseClosedTimestamp(OffsetDateTime.now().minusDays(29));
});

assertThat(dartsDatabase.getCaseRepository().findAll()).hasSize(6);

// when
List<CourtCaseEntity> result = caseRepository.findCasesNeedingCaseDocumentGenerated(
OffsetDateTime.now().minusDays(28), Pageable.unpaged());

// then
assertThat(result).hasSize(3);
assertThat(result.get(0).getId()).isEqualTo(matchingCase1.getId());
assertThat(result.get(1).getId()).isEqualTo(matchingCase2.getId());
assertThat(result.get(2).getId()).isEqualTo(matchingCase3.getId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import uk.gov.hmcts.darts.task.runner.impl.CloseUnfinishedTranscriptionsAutomatedTask;
import uk.gov.hmcts.darts.task.runner.impl.DailyListAutomatedTask;
import uk.gov.hmcts.darts.task.runner.impl.ExternalDataStoreDeleterAutomatedTask;
import uk.gov.hmcts.darts.task.runner.impl.GenerateCaseDocumentAutomatedTask;
import uk.gov.hmcts.darts.task.runner.impl.InboundAudioDeleterAutomatedTask;
import uk.gov.hmcts.darts.task.runner.impl.InboundToUnstructuredAutomatedTask;
import uk.gov.hmcts.darts.task.runner.impl.OutboundAudioDeleterAutomatedTask;
Expand Down Expand Up @@ -95,10 +96,7 @@ class AutomatedTaskServiceTest extends IntegrationPerClassBase {
private UnstructuredAudioDeleterProcessor unstructuredAudioDeleterProcessor;

@Autowired
private AutomatedTaskProcessorFactory unstructuredToArmProcessor;

@Autowired
private AutomatedTaskProcessorFactory armResponseFilesProcessor;
private AutomatedTaskProcessorFactory taskProcessorFactory;

@Autowired
private CleanupArmResponseFilesService cleanupArmResponseFilesService;
Expand Down Expand Up @@ -559,7 +557,7 @@ void givenConfiguredTasksUpdateCronAndResetCronForUnstructuredToArmAutomatedTask
automatedTaskRepository,
lockProvider,
automatedTaskConfigurationProperties,
unstructuredToArmProcessor,
taskProcessorFactory,
logApi
);

Expand Down Expand Up @@ -593,7 +591,7 @@ void givenConfiguredTaskCancelUnstructuredToArmAutomatedTask() {
automatedTaskRepository,
lockProvider,
automatedTaskConfigurationProperties,
unstructuredToArmProcessor,
taskProcessorFactory,
logApi
);

Expand All @@ -620,7 +618,7 @@ void givenConfiguredTasksUpdateCronAndResetCronForProcessArmResponseFilesAutomat
automatedTaskRepository,
lockProvider,
automatedTaskConfigurationProperties,
armResponseFilesProcessor,
taskProcessorFactory,
logApi
);

Expand Down Expand Up @@ -652,7 +650,7 @@ void givenConfiguredTaskCancelProcessArmResponseFilesAutomatedTask() {
automatedTaskRepository,
lockProvider,
automatedTaskConfigurationProperties,
armResponseFilesProcessor,
taskProcessorFactory,
logApi
);

Expand Down Expand Up @@ -789,6 +787,65 @@ void givenConfiguredTaskCancelCloseOldCasesAutomatedTask() {
automatedTaskService.reloadTaskByName(automatedTask.getTaskName());
}

@Test
void givenConfiguredTaskGenerateCaseDocumentAutomatedTask() {
AutomatedTask automatedTask =
new GenerateCaseDocumentAutomatedTask(
automatedTaskRepository,
lockProvider,
automatedTaskConfigurationProperties,
taskProcessorFactory,
logApi
);

Optional<AutomatedTaskEntity> originalAutomatedTaskEntity =
automatedTaskService.getAutomatedTaskEntityByTaskName(automatedTask.getTaskName());
log.info("TEST - Original task {} cron expression {}", automatedTask.getTaskName(),
originalAutomatedTaskEntity.get().getCronExpression()
);

automatedTaskService.updateAutomatedTaskCronExpression(automatedTask.getTaskName(), "*/9 * * * * *");

Set<ScheduledTask> scheduledTasks = scheduledTaskHolder.getScheduledTasks();
displayTasks(scheduledTasks);

Optional<AutomatedTaskEntity> updatedAutomatedTaskEntity =
automatedTaskService.getAutomatedTaskEntityByTaskName(automatedTask.getTaskName());
log.info("TEST - Updated task {} cron expression {}", automatedTask.getTaskName(),
updatedAutomatedTaskEntity.get().getCronExpression()
);
assertEquals(originalAutomatedTaskEntity.get().getTaskName(), updatedAutomatedTaskEntity.get().getTaskName());
assertNotEquals(originalAutomatedTaskEntity.get().getCronExpression(), updatedAutomatedTaskEntity.get().getCronExpression());

automatedTaskService.updateAutomatedTaskCronExpression(
automatedTask.getTaskName(), originalAutomatedTaskEntity.get().getCronExpression());
}

@Test
void givenConfiguredTaskCancelGenerateCaseDocumentAutomatedTask() {
AutomatedTask automatedTask =
new GenerateCaseDocumentAutomatedTask(
automatedTaskRepository,
lockProvider,
automatedTaskConfigurationProperties,
taskProcessorFactory,
logApi
);

Set<ScheduledTask> scheduledTasks = scheduledTaskHolder.getScheduledTasks();
displayTasks(scheduledTasks);

boolean mayInterruptIfRunning = false;
boolean taskCancelled = automatedTaskService.cancelAutomatedTask(
automatedTask.getTaskName(),
mayInterruptIfRunning
);
assertTrue(taskCancelled);

log.info("About to reload task {}", automatedTask.getTaskName());
automatedTaskService.reloadTaskByName(automatedTask.getTaskName());
}


@Test
void canUpdatedCronForDailyListHouseKeepingTask() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package uk.gov.hmcts.darts.task.service;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import uk.gov.hmcts.darts.casedocument.service.GenerateCaseDocumentSingleCaseProcessor;
import uk.gov.hmcts.darts.common.entity.CaseDocumentEntity;
import uk.gov.hmcts.darts.common.entity.CourtCaseEntity;
import uk.gov.hmcts.darts.common.entity.ExternalObjectDirectoryEntity;
import uk.gov.hmcts.darts.common.entity.MediaEntity;
import uk.gov.hmcts.darts.common.entity.UserAccountEntity;
import uk.gov.hmcts.darts.common.repository.AnnotationRepository;
import uk.gov.hmcts.darts.common.repository.CaseDocumentRepository;
import uk.gov.hmcts.darts.common.repository.CaseRepository;
import uk.gov.hmcts.darts.common.repository.ExternalObjectDirectoryRepository;
import uk.gov.hmcts.darts.common.repository.HearingRepository;
import uk.gov.hmcts.darts.common.repository.UserAccountRepository;
import uk.gov.hmcts.darts.testutils.IntegrationBase;

import java.time.OffsetDateTime;
import java.util.List;

import static java.time.ZoneOffset.UTC;
import static org.assertj.core.api.Assertions.assertThat;
import static uk.gov.hmcts.darts.common.enums.ExternalLocationTypeEnum.ARM;
import static uk.gov.hmcts.darts.common.enums.ObjectRecordStatusEnum.ARM_DROP_ZONE;

class GenerateCaseDocumentProcessorIntTest extends IntegrationBase {

private static final OffsetDateTime DT_2025 = OffsetDateTime.of(2025, 1, 1, 1, 0, 0, 0, UTC);

@SpyBean
CaseRepository caseRepository;
@SpyBean
CaseDocumentRepository caseDocumentRepository;
@SpyBean
ExternalObjectDirectoryRepository eodRepository;
@Autowired
UserAccountRepository userAccountRepository;
@Autowired
AnnotationRepository annotationRepository;
@Autowired
GenerateCaseDocumentSingleCaseProcessor processor;
@Autowired
HearingRepository hearingRepository;

@Test
void testGenerateCaseDocument() {
// given
givenBearerTokenExists("[email protected]");
UserAccountEntity testUser = dartsDatabase.getUserAccountStub().getIntegrationTestUserAccountEntity();

CourtCaseEntity courtCase = dartsDatabase.getCourtCaseStub().createAndSaveCourtCaseWithHearings(createdCourtCase -> {
createdCourtCase.setRetentionUpdated(true);
createdCourtCase.setRetentionRetries(1);
createdCourtCase.setClosed(true);
});

List<MediaEntity> medias = dartsDatabase.getMediaStub().createAndSaveSomeMedias();
var hearing = courtCase.getHearings().get(0);
hearing.addMedia(medias.get(0));

hearingRepository.save(hearing);
dartsDatabase.getCaseRetentionStub().createCaseRetentionObject(courtCase, DT_2025);

dartsDatabase.getExternalObjectDirectoryStub().createAndSaveEod(medias.get(0), ARM_DROP_ZONE, ARM, eod -> { });

var annotation = dartsDatabase.getAnnotationStub().createAndSaveAnnotationEntityWith(testUser, "TestAnnotation", hearing);
annotationRepository.save(annotation);

// when
processor.processGenerateCaseDocument(courtCase.getId());

// then
List<CaseDocumentEntity> caseDocumentEntities = caseDocumentRepository.findByCourtCase(courtCase);
assertThat(caseDocumentEntities.size()).isEqualTo(1);
CaseDocumentEntity caseDocument = caseDocumentEntities.get(0);
assertThat(caseDocument.getCourtCase().getId()).isEqualTo(courtCase.getId());

List<ExternalObjectDirectoryEntity> eodCaseDocument = eodRepository.findByCaseDocument(caseDocument);
assertThat(eodCaseDocument.size()).isEqualTo(1);
}

private static void givenBearerTokenExists(String email) {
Jwt jwt = Jwt.withTokenValue("test")
.header("alg", "RS256")
.claim("emails", List.of(email))
.build();
SecurityContextHolder.getContext().setAuthentication(new JwtAuthenticationToken(jwt));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import jakarta.transaction.Transactional;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.jeasy.random.EasyRandom;
import org.jeasy.random.EasyRandomParameters;
import org.jeasy.random.randomizers.range.IntegerRangeRandomizer;
import org.springframework.stereotype.Component;
import uk.gov.hmcts.darts.common.entity.CaseDocumentEntity;
import uk.gov.hmcts.darts.common.entity.CourtCaseEntity;
Expand All @@ -19,6 +22,7 @@
public class CaseDocumentStub {

private final CaseDocumentRepository caseDocumentRepository;
private final UserAccountStub userAccountStub;

@Transactional
public CaseDocumentEntity createAndSaveCaseDocumentEntity(CourtCaseEntity courtCaseEntity, UserAccountEntity uploadedBy) {
Expand All @@ -27,6 +31,14 @@ public CaseDocumentEntity createAndSaveCaseDocumentEntity(CourtCaseEntity courtC
return caseDocumentEntity;
}

@Transactional
public CaseDocumentEntity createAndSaveCaseDocumentEntity(CourtCaseEntity courtCaseEntity) {
UserAccountEntity testUser = userAccountStub.getIntegrationTestUserAccountEntity();
CaseDocumentEntity caseDocumentEntity = createCaseDocumentEntity(courtCaseEntity, testUser);
caseDocumentEntity = caseDocumentRepository.save(caseDocumentEntity);
return caseDocumentEntity;
}

public CaseDocumentEntity createCaseDocumentEntity(CourtCaseEntity courtCaseEntity, UserAccountEntity uploadedBy) {
CaseDocumentEntity caseDocumentEntity = new CaseDocumentEntity();
caseDocumentEntity.setCourtCase(courtCaseEntity);
Expand All @@ -40,4 +52,14 @@ public CaseDocumentEntity createCaseDocumentEntity(CourtCaseEntity courtCaseEnti
caseDocumentEntity.setLastModifiedBy(uploadedBy);
return caseDocumentEntity;
}

public CaseDocumentEntity createCaseDocumentWithRandomValues() {
EasyRandomParameters parameters = new EasyRandomParameters()
.randomize(Integer.class, new IntegerRangeRandomizer(1, 100))
.collectionSizeRange(1, 1)
.overrideDefaultInitialization(true);

EasyRandom generator = new EasyRandom(parameters);
return generator.nextObject(CaseDocumentEntity.class);
}
}
Loading

0 comments on commit 0031d72

Please sign in to comment.