Skip to content

Commit

Permalink
Add LJA Reference Data Endpoint & infrastructure code
Browse files Browse the repository at this point in the history
  • Loading branch information
RustyHMCTS committed May 8, 2024
1 parent 1a489de commit f04cef8
Show file tree
Hide file tree
Showing 12 changed files with 214 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package uk.gov.hmcts.opal.controllers.develop;
package uk.gov.hmcts.opal.controllers;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public ResponseEntity<List<BusinessUnitEntity>> postBusinessUnitsSearch(
}

@GetMapping(value = {"/ref-data", "/ref-data/", "/ref-data/{filter}"})
@Operation(summary = "Returns Business Units as reference data with an option filter applied")
@Operation(summary = "Returns Business Units as reference data with an optional filter applied")
public ResponseEntity<BusinessUnitReferenceDataResults> getBusinessUnitRefData(
@PathVariable Optional<String> filter) {
log.info(":GET:getBusinessUnitRefData: query: \n{}", filter);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package uk.gov.hmcts.opal.controllers.develop;
package uk.gov.hmcts.opal.controllers;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand All @@ -12,11 +12,15 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import uk.gov.hmcts.opal.dto.reference.LjaReferenceDataResults;
import uk.gov.hmcts.opal.dto.search.LocalJusticeAreaSearchDto;
import uk.gov.hmcts.opal.entity.LocalJusticeAreaEntity;
import uk.gov.hmcts.opal.entity.projection.LjaReferenceData;
import uk.gov.hmcts.opal.service.LocalJusticeAreaServiceInterface;
import uk.gov.hmcts.opal.service.opal.LocalJusticeAreaService;

import java.util.List;
import java.util.Optional;

import static uk.gov.hmcts.opal.util.HttpUtil.buildResponse;

Expand All @@ -29,9 +33,13 @@ public class LocalJusticeAreaController {

private final LocalJusticeAreaServiceInterface localJusticeAreaService;

private final LocalJusticeAreaService opalLocalJusticeAreaService;

public LocalJusticeAreaController(
@Qualifier("localJusticeAreaService") LocalJusticeAreaServiceInterface localJusticeAreaService) {
@Qualifier("localJusticeAreaService") LocalJusticeAreaServiceInterface localJusticeAreaService,
LocalJusticeAreaService opalLocalJusticeAreaService) {
this.localJusticeAreaService = localJusticeAreaService;
this.opalLocalJusticeAreaService = opalLocalJusticeAreaService;
}

@GetMapping(value = "/{localJusticeAreaId}")
Expand All @@ -56,5 +64,15 @@ public ResponseEntity<List<LocalJusticeAreaEntity>> postLocalJusticeAreasSearch(
return buildResponse(response);
}

@GetMapping(value = {"/ref-data", "/ref-data/", "/ref-data/{filter}"})
@Operation(summary = "Returns Local Justice Area as reference data with an optional filter applied")
public ResponseEntity<LjaReferenceDataResults> getLocalJusticeAreaRefData(
@PathVariable Optional<String> filter) {
log.info(":GET:getLocalJusticeAreaRefData: query: \n{}", filter);

List<LjaReferenceData> refData = opalLocalJusticeAreaService.getReferenceData(filter);

log.info(":GET:getLocalJusticeAreaRefData: local justice area reference data count: {}", refData.size());
return ResponseEntity.ok(LjaReferenceDataResults.builder().refData(refData).build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public ResponseEntity<List<OffenceEntity>> postOffencesSearch(@RequestBody Offen
}

@GetMapping(value = {"/ref-data", "/ref-data/", "/ref-data/{filter}"})
@Operation(summary = "Returns Offences as reference data with an option filter applied")
@Operation(summary = "Returns Offences as reference data with an optional filter applied")
public ResponseEntity<OffenceReferenceDataResults> getOffenceRefData(@PathVariable Optional<String> filter) {
log.info(":GET:getOffenceRefData: query: \n{}", filter);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package uk.gov.hmcts.opal.dto.reference;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import uk.gov.hmcts.opal.entity.projection.LjaReferenceData;

import java.util.List;
import java.util.Optional;

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class LjaReferenceDataResults {
private Integer count;
private List<LjaReferenceData> refData;

public static class LjaReferenceDataResultsBuilder {
public LjaReferenceDataResultsBuilder refData(
List<LjaReferenceData> refData) {
this.refData = refData;
return this.count(Optional.ofNullable(refData).map(List::size).orElse(0));
}

private LjaReferenceDataResultsBuilder count(Integer count) {
this.count = count;
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
public class LocalJusticeAreaSearchDto extends AddressSearch implements ToJsonString {

private String localJusticeAreaId;

private String ljaCode;
}
17 changes: 17 additions & 0 deletions src/main/java/uk/gov/hmcts/opal/entity/LocalJusticeAreaEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import java.time.LocalDateTime;

@Data
@Entity
@EqualsAndHashCode(callSuper = true)
Expand All @@ -34,4 +38,17 @@ public class LocalJusticeAreaEntity extends AddressEntity {
@Column(name = "local_justice_area_id", nullable = false)
private Short localJusticeAreaId;

@Column(name = "lja_code", length = 4)
private String ljaCode;

@Column(name = "address_line_4", length = 35)
private String addressLine4;

@Column(name = "address_line_5", length = 35)
private String addressLine5;

@Column(name = "end_date")
@Temporal(TemporalType.TIMESTAMP)
private LocalDateTime endDate;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package uk.gov.hmcts.opal.entity.projection;

public interface LjaReferenceData {

Short getLocalJusticeAreaId();

String getLjaCode();

String getName();

String getAddressLine1();

String getPostcode();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,48 @@
import uk.gov.hmcts.opal.entity.LocalJusticeAreaEntity;
import uk.gov.hmcts.opal.entity.LocalJusticeAreaEntity_;

import java.time.LocalDateTime;
import java.util.Optional;

public class LocalJusticeAreaSpecs extends AddressSpecs<LocalJusticeAreaEntity> {

public Specification<LocalJusticeAreaEntity> findBySearchCriteria(LocalJusticeAreaSearchDto criteria) {
return Specification.allOf(specificationList(
findByAddressCriteria(criteria),
notBlank(criteria.getLjaCode()).map(LocalJusticeAreaSpecs::likeLjaCode),
notBlank(criteria.getLocalJusticeAreaId()).map(LocalJusticeAreaSpecs::equalsLocalJusticeAreaId)
));
}

public Specification<LocalJusticeAreaEntity> referenceDataFilter(Optional<String> filter) {
return Specification.allOf(specificationList(
Optional.of(LocalDateTime.now()).map(LocalJusticeAreaSpecs::endDateGreaterThenEqualToDate),
filter.filter(s -> !s.isBlank()).map(this::likeAnyLocalJusticeArea)
));
}

public static Specification<LocalJusticeAreaEntity> equalsLocalJusticeAreaId(String localJusticeAreaId) {
return (root, query, builder) -> builder.equal(root.get(LocalJusticeAreaEntity_.localJusticeAreaId),
localJusticeAreaId);
}

public static Specification<LocalJusticeAreaEntity> likeLjaCode(String ljaCode) {
return (root, query, builder) ->
likeWildcardPredicate(root.get(LocalJusticeAreaEntity_.ljaCode), builder, ljaCode);
}

public Specification<LocalJusticeAreaEntity> likeAnyLocalJusticeArea(String filter) {
return Specification.anyOf(
likeLjaCode(filter),
likeName(filter),
likePostcode(filter)
);
}

public static Specification<LocalJusticeAreaEntity> endDateGreaterThenEqualToDate(LocalDateTime expiryDate) {
return (root, query, builder) -> builder.or(
builder.isNull(root.get(LocalJusticeAreaEntity_.endDate)),
builder.greaterThanOrEqualTo(root.get(LocalJusticeAreaEntity_.endDate), expiryDate)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import uk.gov.hmcts.opal.dto.search.LocalJusticeAreaSearchDto;
import uk.gov.hmcts.opal.entity.LocalJusticeAreaEntity;
import uk.gov.hmcts.opal.entity.LocalJusticeAreaEntity_;
import uk.gov.hmcts.opal.entity.projection.LjaReferenceData;
import uk.gov.hmcts.opal.repository.LocalJusticeAreaRepository;
import uk.gov.hmcts.opal.repository.jpa.LocalJusticeAreaSpecs;
import uk.gov.hmcts.opal.service.LocalJusticeAreaServiceInterface;

import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
Expand All @@ -37,4 +41,17 @@ public List<LocalJusticeAreaEntity> searchLocalJusticeAreas(LocalJusticeAreaSear
return page.getContent();
}

public List<LjaReferenceData> getReferenceData(Optional<String> filter) {

Sort nameSort = Sort.by(Sort.Direction.ASC, LocalJusticeAreaEntity_.NAME);

Page<LjaReferenceData> page = localJusticeAreaRepository
.findBy(specs.referenceDataFilter(filter),
ffq -> ffq
.sortBy(nameSort)
.as(LjaReferenceData.class)
.page(Pageable.unpaged()));

return page.getContent();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package uk.gov.hmcts.opal.controllers.develop;
package uk.gov.hmcts.opal.controllers;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand All @@ -7,12 +7,14 @@
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import uk.gov.hmcts.opal.controllers.develop.LocalJusticeAreaController;
import uk.gov.hmcts.opal.dto.reference.LjaReferenceDataResults;
import uk.gov.hmcts.opal.dto.search.LocalJusticeAreaSearchDto;
import uk.gov.hmcts.opal.entity.LocalJusticeAreaEntity;
import uk.gov.hmcts.opal.entity.projection.LjaReferenceData;
import uk.gov.hmcts.opal.service.opal.LocalJusticeAreaService;

import java.util.List;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
Expand Down Expand Up @@ -65,4 +67,56 @@ void testSearchLocalJusticeAreas_Success() {
verify(localJusticeAreaService, times(1)).searchLocalJusticeAreas(any());
}


@Test
void testGetLocalJusticeAreasRefData_Success() {
// Arrange
LjaReferenceData entity = createLjaReferenceData();
List<LjaReferenceData> localJusticeAreaList = List.of(entity);

when(localJusticeAreaService.getReferenceData(any())).thenReturn(localJusticeAreaList);

// Act
Optional<String> filter = Optional.empty();
ResponseEntity<LjaReferenceDataResults> response = localJusticeAreaController
.getLocalJusticeAreaRefData(filter);

// Assert
assertEquals(HttpStatus.OK, response.getStatusCode());
LjaReferenceDataResults refDataResults = response.getBody();
assertEquals(1, refDataResults.getCount());
assertEquals(localJusticeAreaList, refDataResults.getRefData());
verify(localJusticeAreaService, times(1)).getReferenceData(any());
}

private LjaReferenceData createLjaReferenceData() {
return new LjaReferenceData() {

@Override
public Short getLocalJusticeAreaId() {
return (short)1;
}

@Override
public String getLjaCode() {
return "MAIN";
}

@Override
public String getName() {
return "Local Justice Area Main";
}

@Override
public String getAddressLine1() {
return "No.1 The Old Bailey";
}

@Override
public String getPostcode() {
return "BB1 1BB";
}
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
import org.springframework.data.repository.query.FluentQuery;
import uk.gov.hmcts.opal.dto.search.LocalJusticeAreaSearchDto;
import uk.gov.hmcts.opal.entity.LocalJusticeAreaEntity;
import uk.gov.hmcts.opal.entity.projection.LjaReferenceData;
import uk.gov.hmcts.opal.repository.LocalJusticeAreaRepository;

import java.util.List;
import java.util.Optional;
import java.util.function.Function;

import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -70,5 +72,27 @@ void testSearchLocalJusticeAreas() {

}

@SuppressWarnings("unchecked")
@Test
void testLocalJusticeAreasReferenceData() {
// Arrange
FluentQuery.FetchableFluentQuery ffq = Mockito.mock(FluentQuery.FetchableFluentQuery.class);
when(ffq.as(any())).thenReturn(ffq);
when(ffq.sortBy(any())).thenReturn(ffq);

LocalJusticeAreaEntity localJAEntity = LocalJusticeAreaEntity.builder().build();
Page<LocalJusticeAreaEntity> mockPage = new PageImpl<>(List.of(localJAEntity), Pageable.unpaged(), 999L);
when(localJusticeAreaRepository.findBy(any(Specification.class), any())).thenAnswer(iom -> {
iom.getArgument(1, Function.class).apply(ffq);
return mockPage;
});

// Act
List<LjaReferenceData> result = localJusticeAreaService.getReferenceData(Optional.empty());

// Assert
assertEquals(List.of(localJAEntity), result);

}

}

0 comments on commit f04cef8

Please sign in to comment.