Skip to content

Commit

Permalink
BugFix: Lazy load case documents (#1335)
Browse files Browse the repository at this point in the history
* Lazy load case documents

* Fix test by mocking hearingEntityInitService

* Fix test
  • Loading branch information
Obsiye authored Feb 6, 2025
1 parent a4838ad commit 86f6eac
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public class CourtCaseController {
private final AuthenticationHelper authenticationHelper;
private final CaseProgressService caseProgressService;
private final HearingNotesService hearingNotesService;
private final CourtCaseResponseMapper courtCaseResponseMapper;

@Autowired
public CourtCaseController(CourtCaseService courtCaseService,
Expand All @@ -91,6 +92,7 @@ public CourtCaseController(CourtCaseService courtCaseService,
AuthenticationHelper authenticationHelper,
CaseProgressService caseProgressService,
HearingNotesService hearingNotesService,
CourtCaseResponseMapper courtCaseResponseMapper,
@Value("${feature.flags.enable-cacheable-case-list:true}") boolean enableCacheableCaseList) {
this.courtCaseService = courtCaseService;
this.offenderMatchService = offenderMatchService;
Expand All @@ -100,6 +102,7 @@ public CourtCaseController(CourtCaseService courtCaseService,
this.authenticationHelper = authenticationHelper;
this.caseProgressService = caseProgressService;
this.hearingNotesService = hearingNotesService;
this.courtCaseResponseMapper = courtCaseResponseMapper;
}

@Operation(description = "Gets the court case data by hearing id and defendant id.")
Expand Down Expand Up @@ -386,7 +389,7 @@ public CaseListResponse getCaseList(
private CourtCaseResponse buildCourtCaseResponseForCaseIdAndDefendantId(HearingEntity hearingEntity, String defendantId, List<CaseProgressHearing> caseHearings) {
final var offenderMatchesCount = offenderMatchService.getMatchCountByCaseIdAndDefendant(hearingEntity.getCaseId(), defendantId)
.orElse(0);
return CourtCaseResponseMapper.mapFrom(hearingEntity, defendantId, offenderMatchesCount, caseHearings);
return courtCaseResponseMapper.mapFrom(hearingEntity, defendantId, offenderMatchesCount, caseHearings);
}

private CourtCaseResponse buildCourtCaseResponse(HearingEntity hearingEntity) {
Expand All @@ -412,6 +415,6 @@ private List<CourtCaseResponse> buildCourtCaseResponses(HearingEntity hearingEnt
private CourtCaseResponse buildCourtCaseResponse(HearingEntity hearingEntity, LocalDate hearingDate, HearingDefendantEntity hearingDefendantEntity) {
final var defendant = Optional.ofNullable(hearingDefendantEntity).map(HearingDefendantEntity::getDefendant).orElseThrow();
var matchCount = offenderMatchService.getMatchCountByCaseIdAndDefendant(hearingEntity.getCaseId(), defendant.getDefendantId()).orElse(0);
return CourtCaseResponseMapper.mapFrom(hearingEntity, hearingDefendantEntity, matchCount, hearingDate);
return courtCaseResponseMapper.mapFrom(hearingEntity, hearingDefendantEntity, matchCount, hearingDate);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package uk.gov.justice.probation.courtcaseservice.controller.mapper;

import lombok.extern.slf4j.Slf4j;
import org.hibernate.Hibernate;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import uk.gov.justice.probation.courtcaseservice.controller.model.CaseCommentResponse;
import uk.gov.justice.probation.courtcaseservice.controller.model.CaseDocumentResponse;
import uk.gov.justice.probation.courtcaseservice.controller.model.CaseMarker;
Expand All @@ -12,6 +13,7 @@
import uk.gov.justice.probation.courtcaseservice.controller.model.OffenceResponse;
import uk.gov.justice.probation.courtcaseservice.controller.model.PhoneNumber;
import uk.gov.justice.probation.courtcaseservice.jpa.entity.*;
import uk.gov.justice.probation.courtcaseservice.service.HearingEntityInitService;
import uk.gov.justice.probation.courtcaseservice.service.model.CaseProgressHearing;

import java.time.LocalDate;
Expand All @@ -23,9 +25,13 @@
import java.util.stream.Collectors;

@Slf4j
@Service
public class CourtCaseResponseMapper {

public static CourtCaseResponse mapFrom(HearingEntity hearingEntity, String defendantId, int matchCount, List<CaseProgressHearing> caseHearings) {
@Autowired
public HearingEntityInitService hearingEntityInitService;

public CourtCaseResponse mapFrom(HearingEntity hearingEntity, String defendantId, int matchCount, List<CaseProgressHearing> caseHearings) {
// Core case-based
final var builder = CourtCaseResponse.builder()
.hearings(caseHearings);
Expand All @@ -46,19 +52,17 @@ public static CourtCaseResponse mapFrom(HearingEntity hearingEntity, String defe
return builder.build();
}

private static List<CaseDocumentResponse> mapCaseDocuments(HearingEntity hearingEntity, String defendantId) {
private List<CaseDocumentResponse> mapCaseDocuments(HearingEntity hearingEntity, String defendantId) {
hearingEntityInitService.initializeCaseDocuments(hearingEntity);
return hearingEntity.getCourtCase().getCaseDefendant(defendantId)
.map(caseDefendantEntity -> {
Hibernate.initialize(caseDefendantEntity.getDocuments());
return caseDefendantEntity.getDocuments();
})
.map(CaseDefendantEntity::getDocuments)
.map(caseDefendantDocumentEntities -> caseDefendantDocumentEntities.stream()
.map(doc -> new CaseDocumentResponse(doc.getDocumentId(),doc.getCreated(), new CaseDocumentResponse.FileResponse(doc.getDocumentName(), 0)))
.collect(Collectors.toList())
).orElse(Collections.emptyList());
}

public static CourtCaseResponse mapFrom(HearingEntity hearingEntity, HearingDefendantEntity defendantEntity, int matchCount, LocalDate hearingDate) {
public CourtCaseResponse mapFrom(HearingEntity hearingEntity, HearingDefendantEntity defendantEntity, int matchCount, LocalDate hearingDate) {
// Core case-based
final var builder = CourtCaseResponse.builder();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ public Optional<HearingEntity> findByIdAndInitHearingDefendants(Long id) {
return hearing;
}

@Transactional
public HearingEntity initializeCaseDocuments(HearingEntity hearing) {
Hibernate.initialize(hearing.getCourtCase().getCaseDefendants());
hearing.getCourtCase().getCaseDefendants().forEach(caseDefendantEntity -> Hibernate.initialize(caseDefendantEntity.getDocuments()));
return hearing;
}

@Transactional
public Optional<HearingEntity> findByHearingIdAndInitHearingNotes(String hearingId, String defendantId) {
var hearing = hearingRepository.findByHearingIdAndHearingDefendantsDefendantIdAndDeletedFalse(hearingId, defendantId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import uk.gov.justice.probation.courtcaseservice.client.model.DeliusOffenderDetail
import uk.gov.justice.probation.courtcaseservice.client.model.ProbationStatus
import uk.gov.justice.probation.courtcaseservice.jpa.entity.OffenderEntity
import uk.gov.justice.probation.courtcaseservice.jpa.entity.OffenderProbationStatus
import uk.gov.justice.probation.courtcaseservice.jpa.repository.DefendantRepository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.kotlin.MockingKt;
import org.springframework.http.HttpHeaders;
import org.springframework.web.context.request.WebRequest;
import reactor.core.publisher.Mono;
import uk.gov.justice.probation.courtcaseservice.controller.mapper.CourtCaseResponseMapper;
import uk.gov.justice.probation.courtcaseservice.controller.model.CaseCommentRequest;
import uk.gov.justice.probation.courtcaseservice.controller.model.CaseCommentResponse;
import uk.gov.justice.probation.courtcaseservice.controller.model.CaseListResponse;
Expand All @@ -19,13 +20,7 @@
import uk.gov.justice.probation.courtcaseservice.controller.model.HearingSearchRequest;
import uk.gov.justice.probation.courtcaseservice.jpa.entity.*;
import uk.gov.justice.probation.courtcaseservice.security.AuthAwareAuthenticationToken;
import uk.gov.justice.probation.courtcaseservice.service.AuthenticationHelper;
import uk.gov.justice.probation.courtcaseservice.service.CaseCommentsService;
import uk.gov.justice.probation.courtcaseservice.service.CaseProgressService;
import uk.gov.justice.probation.courtcaseservice.service.CourtCaseService;
import uk.gov.justice.probation.courtcaseservice.service.HearingNotesService;
import uk.gov.justice.probation.courtcaseservice.service.OffenderMatchService;
import uk.gov.justice.probation.courtcaseservice.service.OffenderUpdateService;
import uk.gov.justice.probation.courtcaseservice.service.*;
import uk.gov.justice.probation.courtcaseservice.service.model.CaseProgressHearing;
import uk.gov.justice.probation.courtcaseservice.service.model.HearingSearchFilter;

Expand Down Expand Up @@ -83,6 +78,10 @@ class CourtCaseControllerTest {
private CaseProgressService caseProgressService;
@Mock
private HearingNotesService hearingNotesService;
@Mock
private HearingEntityInitService hearingEntityInitService;
@InjectMocks
private CourtCaseResponseMapper courtCaseResponseMapper;

private CourtCaseController courtCaseController;
private final HearingEntity hearingEntity = HearingEntity.builder()
Expand Down Expand Up @@ -110,7 +109,7 @@ class CourtCaseControllerTest {
@BeforeEach
public void setUp() {
courtCaseController = new CourtCaseController(courtCaseService, offenderMatchService,
offenderUpdateService, caseCommentsService, authenticationHelper, caseProgressService, hearingNotesService, true);
offenderUpdateService, caseCommentsService, authenticationHelper, caseProgressService, hearingNotesService, courtCaseResponseMapper, true);
}

@Test
Expand Down Expand Up @@ -303,7 +302,7 @@ void whenListIsNotModified_thenReturn() {
@Test
void givenCacheableCaseListDisabled_whenListIsNotModified_thenReturnFullList() {
final var nonCachingController = new CourtCaseController(courtCaseService,
offenderMatchService, offenderUpdateService, caseCommentsService, authenticationHelper, caseProgressService, hearingNotesService, false);
offenderMatchService, offenderUpdateService, caseCommentsService, authenticationHelper, caseProgressService, hearingNotesService, courtCaseResponseMapper, false);

final var courtCaseEntity = this.hearingEntity.withHearingDefendants(List.of(EntityHelper.aHearingDefendantEntity()))
.withHearingDays(Collections.singletonList(EntityHelper.aHearingDayEntity()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import org.junit.jupiter.api.BeforeEach;
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.justice.probation.courtcaseservice.controller.model.CourtCaseResponse;
import uk.gov.justice.probation.courtcaseservice.controller.model.HearingOutcomeResponse;
import uk.gov.justice.probation.courtcaseservice.controller.model.OffenceResponse;
Expand Down Expand Up @@ -29,6 +33,7 @@
import uk.gov.justice.probation.courtcaseservice.jpa.entity.Sex;
import uk.gov.justice.probation.courtcaseservice.jpa.entity.SourceType;
import uk.gov.justice.probation.courtcaseservice.jpa.entity.VerdictEntity;
import uk.gov.justice.probation.courtcaseservice.service.HearingEntityInitService;
import uk.gov.justice.probation.courtcaseservice.service.HearingOutcomeType;
import uk.gov.justice.probation.courtcaseservice.service.model.CaseProgressHearing;

Expand All @@ -43,11 +48,12 @@
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import static uk.gov.justice.probation.courtcaseservice.jpa.entity.EntityHelper.DEFENDANT_ADDRESS;
import static uk.gov.justice.probation.courtcaseservice.jpa.entity.EntityHelper.HEARING_ID;
import static uk.gov.justice.probation.courtcaseservice.jpa.entity.EntityHelper.aDefendantOffence;


@ExtendWith(MockitoExtension.class)
class CourtCaseResponseMapperTest {

private static final long ID = 1234L;
Expand Down Expand Up @@ -84,6 +90,13 @@ class CourtCaseResponseMapperTest {
private static String DOCUMENT_ID = "document-id-one";
private static String DOCUMENT_NAME = "document-name-one.pdf";
private HearingEntity hearingEntity;

@Mock
private HearingEntityInitService hearingEntityInitService;

@InjectMocks
private CourtCaseResponseMapper courtCaseResponseMapper;

private final AddressPropertiesEntity addressPropertiesEntity = AddressPropertiesEntity.builder()
.line1("27")
.line2("Elm Place")
Expand All @@ -104,7 +117,6 @@ class CourtCaseResponseMapperTest {

@BeforeEach
void setUp() {

var hearings = Arrays.asList(
HearingDayEntity.builder()
.day(HEARING_DATE)
Expand Down Expand Up @@ -166,7 +178,7 @@ void givenSeparateDefendant_whenMap_thenReturnMultipleResponses() {
.offences(singletonList(defendantOffence))
.build();

var courtCaseResponse = CourtCaseResponseMapper.mapFrom(hearingEntity, defendantEntity, 3, HEARING_DATE);
var courtCaseResponse = courtCaseResponseMapper.mapFrom(hearingEntity, defendantEntity, 3, HEARING_DATE);

assertCaseFields(courtCaseResponse, null, SourceType.COMMON_PLATFORM);
assertHearingFields(courtCaseResponse);
Expand Down Expand Up @@ -212,15 +224,15 @@ void givenSeparateDefendant_whenMap_thenReturnMultipleResponses() {

@Test
void givenMultipleDefendants_whenMapByDefendantId_thenReturnCorrectDefendant() {
when(hearingEntityInitService.initializeCaseDocuments(hearingEntity)).thenReturn(hearingEntity);

var newName = NamePropertiesEntity.builder().surname("PRESLEY").forename1("Elvis").build();
var defendant1 = buildDefendant(newName, OffenderEntity.builder().crn("D99999").build());
var defendant2 = EntityHelper.aHearingDefendantEntity(DEFENDANT_ID);

var courtCase = hearingEntity.withHearingDefendants(List.of(defendant1, defendant2));


var response = CourtCaseResponseMapper.mapFrom(courtCase, "bd1f71e5-939b-4580-8354-7d6061a58032", 5, caseProgressHearings);
var response = courtCaseResponseMapper.mapFrom(courtCase, "bd1f71e5-939b-4580-8354-7d6061a58032", 5, caseProgressHearings);

assertCaseFields(response);
assertThat(response.getNumberOfPossibleMatches()).isEqualTo(5);
Expand All @@ -232,6 +244,7 @@ void givenMultipleDefendants_whenMapByDefendantId_thenReturnCorrectDefendant() {

@Test
void givenDefendantWithOffender_whenMapByDefendantId_thenReturnFieldsFromOffender() {
when(hearingEntityInitService.initializeCaseDocuments(hearingEntity)).thenReturn(hearingEntity);

final var name = NamePropertiesEntity.builder().surname("TICKELL").forename1("Katherine").build();
final OffenderEntity offender = OffenderEntity.builder().crn("W99999")
Expand All @@ -246,7 +259,7 @@ void givenDefendantWithOffender_whenMapByDefendantId_thenReturnFieldsFromOffende

var courtCase = hearingEntity.withHearingDefendants(List.of(defendant));

var response = CourtCaseResponseMapper.mapFrom(courtCase, "bd1f71e5-939b-4580-8354-7d6061a58032", 5, caseProgressHearings);
var response = courtCaseResponseMapper.mapFrom(courtCase, "bd1f71e5-939b-4580-8354-7d6061a58032", 5, caseProgressHearings);

assertThat(response.getProbationStatus()).isEqualTo("Previously known");
assertThat(response.getCrn()).isEqualTo("W99999");
Expand Down Expand Up @@ -275,7 +288,7 @@ void shouldMapHearingOutcomeFields() {

var hearingEntityUpdated = hearingEntity.withHearingDefendants(List.of(defendant));

var response = CourtCaseResponseMapper.mapFrom(hearingEntityUpdated, "bd1f71e5-939b-4580-8354-7d6061a58032", 5, caseProgressHearings);
var response = courtCaseResponseMapper.mapFrom(hearingEntityUpdated, "bd1f71e5-939b-4580-8354-7d6061a58032", 5, caseProgressHearings);

assertThat(response.getHearings().get(0).getHearingOutcome().getHearingOutcomeType()).isEqualTo(HearingOutcomeType.REPORT_REQUESTED);
}
Expand All @@ -290,7 +303,7 @@ void shouldMapCaseDocumentsFields() {

courtCase.getCaseDefendants().get(0).createDocument(DOCUMENT_ID, DOCUMENT_NAME);

var response = CourtCaseResponseMapper.mapFrom(hearing, EntityHelper.DEFENDANT_ID, 5, caseProgressHearings);
var response = courtCaseResponseMapper.mapFrom(hearing, EntityHelper.DEFENDANT_ID, 5, caseProgressHearings);

var caseDocument = response.getFiles().get(0);
assertThat(caseDocument.getId()).isEqualTo(DOCUMENT_ID);
Expand Down

0 comments on commit 86f6eac

Please sign in to comment.