Skip to content
Open
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
Expand Up @@ -46,6 +46,7 @@

import javax.inject.Inject;

import com.fasterxml.jackson.databind.JsonNode;
import org.slf4j.Logger;

@SuppressWarnings({"squid:S1067", "pmd:NullAssignment", "java:S107"})
Expand Down Expand Up @@ -330,16 +331,31 @@ private List<Hearing> enrichAllCourtSchedulerHearingIdsIntoHearings(final List<I
hearingIds.forEach(id -> {
final Hearing hearing = hearingsById.get(id.hearingId());
if (hearing != null) {
hearing.setHearingDate(id.hearingDate());
hearing.setHearingDayCount(id.hearingDayCount());
hearing.setHearingDayPosition(id.hearingDayPosition());
enrichedHearings.add(hearing);
// A multi-day hearing yields one IdResponse per day, all sharing the same hearingId.
// Build a separate flattened hearing per day so that setting the day fields here - and
// the converter later mutating the properties JSON in place - cannot overwrite the
// other days of the same hearing.
enrichedHearings.add(flattenHearingForDay(hearing, id));
}
});

return enrichedHearings;
}

/**
* Produces an independent flattened hearing for a single hearing-day. The response for this path
* is rendered from the hearing's {@code properties} JSON (plus the flattened day fields), so the
* properties node is deep-copied to keep each day's rendering isolated from the others.
*/
private Hearing flattenHearingForDay(final Hearing source, final IdResponse id) {
final JsonNode propertiesCopy = source.getProperties() == null ? null : source.getProperties().deepCopy();
final Hearing hearingForDay = new Hearing(source.getId(), propertiesCopy);
hearingForDay.setHearingDate(id.hearingDate());
hearingForDay.setHearingDayCount(id.hearingDayCount());
hearingForDay.setHearingDayPosition(id.hearingDayPosition());
return hearingForDay;
}

private boolean isMags(final String jurisdictionType) {
return JurisdictionType.MAGISTRATES.name().equalsIgnoreCase(jurisdictionType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,75 @@ public void searchMagistratesHearings() {
assertThat(results.metadata().name(), is("listing.search.hearings"));
}

@Test
public void multiDayHearingShouldKeepPerDayPositionAndScheduleId() {
final UUID hearingId = randomUUID();
final UUID schedule1 = randomUUID();
final UUID schedule2 = randomUUID();

final String propsJson = "{ \"allocated\":\"true\", \"startDate\": \"2026-07-20\", "
+ "\"courtRoomId\": \"6e424105-55f4-4e1a-bb9e-6ffbae3f7c18\", "
+ "\"courtApplications\" : [{}] , \"listedCases\" : [{}], "
+ "\"hearingDays\" : [{\"hearingDate\": \"2026-07-20\"}, {\"hearingDate\": \"2026-07-21\"}] }";
final Hearing hearing = new Hearing(hearingId, JacksonUtil.toJsonNode(propsJson));
hearing.setAllocated(true);
hearing.setTotalCount(2L);

// one hearing, two hearing days -> two IdResponses sharing the same hearingId
final List<IdResponse> hearingIds = new ArrayList<>();
hearingIds.add(new IdResponse(hearingId, schedule1, parse("2026-07-20"), 2, 1));
hearingIds.add(new IdResponse(hearingId, schedule2, parse("2026-07-21"), 2, 2));
final HearingIdsResponse response = new HearingIdsResponse(hearingIds, 2, 1);

when(courtSchedulerServiceAdapter
.getCourtSchedulerHearings(
OU_CODE,
Optional.of(COURT_SESSION),
COURT_ROOM_ID.toString(),
SEARCH_DATE.toString(),
SEARCH_DATE.toString(),
Optional.empty(),
Optional.of(BUSINESS_TYPE),
Optional.of(JURISDICTION_TYPE.toString()),
"ADULT,YOUTH", 50, 1)).thenReturn(response);

when(hearingRepository.findAllCourtSchedulerHearingByIds(anyList())).thenReturn(newArrayList(hearing));

final JsonEnvelope query = envelopeFrom(
metadataBuilder().withId(randomUUID()).withName("event.name"),
createObjectBuilder()
.add(ALLOCATED_QUERY_PARAMETER, ALLOCATED)
.add(OU_CODE_QUERY_PARAMETER, OU_CODE)
.add(COURT_SESSION_QUERY_PARAMETER, COURT_SESSION.toString())
.add(COURT_ROOM_QUERY_PARAMETER, COURT_ROOM_ID.toString())
.add(JURISDICTION_TYPE_QUERY_PARAMETER, JURISDICTION_TYPE.toString())
.add(START_DATE_QUERY_PARAMETER, SEARCH_DATE.toString())
.add(END_DATE_QUERY_PARAMETER, SEARCH_DATE.toString())
.add(BUSINESS_TYPE_QUERY_PARAMETER, BUSINESS_TYPE.toString())
.add(PAGE_SIZE, "50")
.add(PAGE_NUMBER, "1")
.build());

final JsonEnvelope results = rangeSearchQuery.rangeSearchCourtCalendar(query);
final JsonArray hearingsArr = results.payloadAsJsonObject().getJsonArray("hearings");

assertThat(hearingsArr.size(), is(2));

// Day 1 of 2 - its own position, date and court schedule id
final JsonObject firstDay = hearingsArr.getJsonObject(0);
assertThat(firstDay.getInt("hearingDayPosition"), is(1));
assertThat(firstDay.getJsonArray("hearingDays").size(), is(1));
assertThat(firstDay.getJsonArray("hearingDays").getJsonObject(0).getString("hearingDate"), is("2026-07-20"));
assertThat(firstDay.getJsonArray("hearingDays").getJsonObject(0).getString("courtScheduleId"), is(schedule1.toString()));

// Day 2 of 2 - must NOT be overwritten by day 1 (or vice versa)
final JsonObject secondDay = hearingsArr.getJsonObject(1);
assertThat(secondDay.getInt("hearingDayPosition"), is(2));
assertThat(secondDay.getJsonArray("hearingDays").size(), is(1));
assertThat(secondDay.getJsonArray("hearingDays").getJsonObject(0).getString("hearingDate"), is("2026-07-21"));
assertThat(secondDay.getJsonArray("hearingDays").getJsonObject(0).getString("courtScheduleId"), is(schedule2.toString()));
}


@Test
public void searchHearingsWithDateRangeWithAllParametersProvidedWithoutPagination() {
Expand Down
Loading