From 30b130ee32b88b23c3b9b2f87ffd61bbf4a38395 Mon Sep 17 00:00:00 2001 From: Russell Dodd Date: Wed, 22 May 2024 12:22:15 +0100 Subject: [PATCH] PO-314: Initial coding to support Result ref-data --- .../ResultControllerIntegrationTest.java | 30 ++++++++++++++--- .../{develop => }/ResultController.java | 24 ++++++++++++-- .../reference/ResultReferenceDataResults.java | 32 +++++++++++++++++++ .../projection/ResultReferenceData.java | 5 +++ .../opal/repository/jpa/ResultSpecs.java | 15 +++++++++ .../opal/service/opal/ResultService.java | 30 +++++++++++++++++ .../{develop => }/ResultControllerTest.java | 27 ++++++++++++++-- .../opal/service/opal/ResultServiceTest.java | 29 +++++++++++++++++ 8 files changed, 182 insertions(+), 10 deletions(-) rename src/integrationTest/java/uk/gov/hmcts/opal/controllers/{develop => }/ResultControllerIntegrationTest.java (84%) rename src/main/java/uk/gov/hmcts/opal/controllers/{develop => }/ResultController.java (63%) create mode 100644 src/main/java/uk/gov/hmcts/opal/dto/reference/ResultReferenceDataResults.java create mode 100644 src/main/java/uk/gov/hmcts/opal/entity/projection/ResultReferenceData.java rename src/test/java/uk/gov/hmcts/opal/controllers/{develop => }/ResultControllerTest.java (64%) diff --git a/src/integrationTest/java/uk/gov/hmcts/opal/controllers/develop/ResultControllerIntegrationTest.java b/src/integrationTest/java/uk/gov/hmcts/opal/controllers/ResultControllerIntegrationTest.java similarity index 84% rename from src/integrationTest/java/uk/gov/hmcts/opal/controllers/develop/ResultControllerIntegrationTest.java rename to src/integrationTest/java/uk/gov/hmcts/opal/controllers/ResultControllerIntegrationTest.java index bb08706e..d24130a8 100644 --- a/src/integrationTest/java/uk/gov/hmcts/opal/controllers/develop/ResultControllerIntegrationTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/opal/controllers/ResultControllerIntegrationTest.java @@ -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; @@ -11,6 +11,7 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.opal.dto.search.ResultSearchDto; import uk.gov.hmcts.opal.entity.ResultEntity; +import uk.gov.hmcts.opal.entity.projection.ResultReferenceData; import uk.gov.hmcts.opal.service.opal.ResultService; import static java.util.Collections.singletonList; @@ -40,7 +41,7 @@ void testGetResultById() throws Exception { when(resultService.getResult(1L)).thenReturn(resultEntity); - mockMvc.perform(get("/dev/result/1")) + mockMvc.perform(get("/api/result/1")) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.resultId").value(1)) @@ -73,7 +74,7 @@ void testGetResultById() throws Exception { void testGetResultById_WhenResultDoesNotExist() throws Exception { when(resultService.getResult(2L)).thenReturn(null); - mockMvc.perform(get("/dev/result/2")) + mockMvc.perform(get("/api/result/2")) .andExpect(status().isNoContent()); } @@ -83,7 +84,7 @@ void testPostResultsSearch() throws Exception { when(resultService.searchResults(any(ResultSearchDto.class))).thenReturn(singletonList(resultEntity)); - mockMvc.perform(post("/dev/result/search") + mockMvc.perform(post("/api/result/search") .contentType(MediaType.APPLICATION_JSON) .content("{\"criteria\":\"value\"}")) .andExpect(status().isOk()) @@ -115,12 +116,31 @@ void testPostResultsSearch() throws Exception { @Test void testPostResultsSearch_WhenResultDoesNotExist() throws Exception { - mockMvc.perform(post("/dev/result/search") + mockMvc.perform(post("/api/result/search") .contentType(MediaType.APPLICATION_JSON) .content("{\"criteria\":\"2\"}")) .andExpect(status().isNoContent()); } + + @Test + void testGetEnforcerRefData() throws Exception { + ResultReferenceData refData = new ResultReferenceData("result-id-001", "Result Title", + "Result Tittle Cy", "FINAL"); + + when(resultService.getReferenceData(any())).thenReturn(singletonList(refData)); + + mockMvc.perform(get("/api/result/ref-data") + .header("authorization", "Bearer some_value")) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.count").value(1)) + .andExpect(jsonPath("$.refData[0].resultId").value("result-id-001")) + .andExpect(jsonPath("$.refData[0].resultTitle").value("Result Title")) + .andExpect(jsonPath("$.refData[0].resultTitleCy").value("Result Tittle Cy")) + .andExpect(jsonPath("$.refData[0].resultType").value("FINAL")); + } + private ResultEntity createResultEntity() { return ResultEntity.builder() .resultId("1") diff --git a/src/main/java/uk/gov/hmcts/opal/controllers/develop/ResultController.java b/src/main/java/uk/gov/hmcts/opal/controllers/ResultController.java similarity index 63% rename from src/main/java/uk/gov/hmcts/opal/controllers/develop/ResultController.java rename to src/main/java/uk/gov/hmcts/opal/controllers/ResultController.java index 67b74068..97f5c526 100644 --- a/src/main/java/uk/gov/hmcts/opal/controllers/develop/ResultController.java +++ b/src/main/java/uk/gov/hmcts/opal/controllers/ResultController.java @@ -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; @@ -12,25 +12,33 @@ 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.ResultReferenceDataResults; import uk.gov.hmcts.opal.dto.search.ResultSearchDto; import uk.gov.hmcts.opal.entity.ResultEntity; +import uk.gov.hmcts.opal.entity.projection.ResultReferenceData; import uk.gov.hmcts.opal.service.ResultServiceInterface; +import uk.gov.hmcts.opal.service.opal.ResultService; import java.util.List; +import java.util.Optional; import static uk.gov.hmcts.opal.util.HttpUtil.buildResponse; @RestController -@RequestMapping("/dev/result") +@RequestMapping("/api/result") @Slf4j(topic = "ResultController") @Tag(name = "Result Controller") public class ResultController { private final ResultServiceInterface resultService; - public ResultController(@Qualifier("resultServiceProxy") ResultServiceInterface resultService) { + private final ResultService opalResultService; + + public ResultController(@Qualifier("resultServiceProxy") ResultServiceInterface resultService, + ResultService opalResultService) { this.resultService = resultService; + this.opalResultService = opalResultService; } @GetMapping(value = "/{resultId}") @@ -54,5 +62,15 @@ public ResponseEntity> postResultsSearch(@RequestBody ResultS return buildResponse(response); } + @GetMapping(value = {"/ref-data", "/ref-data/", "/ref-data/{filter}"}) + @Operation(summary = "Returns MajorCreditors as reference data with an optional filter applied") + public ResponseEntity getResultRefData( + @PathVariable Optional filter) { + log.info(":GET:getMajorCreditorRefData: filter string: {}", filter); + + List refData = opalResultService.getReferenceData(filter); + log.info(":GET:getMajorCreditorRefData: major creditor reference data count: {}", refData.size()); + return ResponseEntity.ok(ResultReferenceDataResults.builder().refData(refData).build()); + } } diff --git a/src/main/java/uk/gov/hmcts/opal/dto/reference/ResultReferenceDataResults.java b/src/main/java/uk/gov/hmcts/opal/dto/reference/ResultReferenceDataResults.java new file mode 100644 index 00000000..211835f5 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/opal/dto/reference/ResultReferenceDataResults.java @@ -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.ResultReferenceData; + +import java.util.List; +import java.util.Optional; + +@Builder +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class ResultReferenceDataResults { + private Integer count; + private List refData; + + public static class ResultReferenceDataResultsBuilder { + public ResultReferenceDataResults.ResultReferenceDataResultsBuilder refData( + List refData) { + this.refData = refData; + return this.count(Optional.ofNullable(refData).map(List::size).orElse(0)); + } + + private ResultReferenceDataResults.ResultReferenceDataResultsBuilder count(Integer count) { + this.count = count; + return this; + } + } +} diff --git a/src/main/java/uk/gov/hmcts/opal/entity/projection/ResultReferenceData.java b/src/main/java/uk/gov/hmcts/opal/entity/projection/ResultReferenceData.java new file mode 100644 index 00000000..1dd36e4f --- /dev/null +++ b/src/main/java/uk/gov/hmcts/opal/entity/projection/ResultReferenceData.java @@ -0,0 +1,5 @@ +package uk.gov.hmcts.opal.entity.projection; + +public record ResultReferenceData(String resultId, String resultTitle, String resultTitleCy, String resultType) { + +} diff --git a/src/main/java/uk/gov/hmcts/opal/repository/jpa/ResultSpecs.java b/src/main/java/uk/gov/hmcts/opal/repository/jpa/ResultSpecs.java index f9f8a68a..53f58639 100644 --- a/src/main/java/uk/gov/hmcts/opal/repository/jpa/ResultSpecs.java +++ b/src/main/java/uk/gov/hmcts/opal/repository/jpa/ResultSpecs.java @@ -5,6 +5,8 @@ import uk.gov.hmcts.opal.entity.ResultEntity; import uk.gov.hmcts.opal.entity.ResultEntity_; +import java.util.Optional; + public class ResultSpecs extends EntitySpecs { public Specification findBySearchCriteria(ResultSearchDto criteria) { @@ -21,6 +23,12 @@ public Specification findBySearchCriteria(ResultSearchDto criteria )); } + public Specification referenceDataFilter(Optional filter) { + return Specification.allOf(specificationList( + filter.filter(s -> !s.isBlank()).map(this::likeAnyResult) + )); + } + public static Specification equalsResultId(String resultId) { return (root, query, builder) -> builder.equal(root.get(ResultEntity_.resultId), resultId); } @@ -79,4 +87,11 @@ public static Specification likeUserEntries(String userEntries) { userEntries); } + public Specification likeAnyResult(String filter) { + return Specification.anyOf( + likeResultId(filter), + likeResultTitle(filter), + likeResultTitleCy(filter) + ); + } } diff --git a/src/main/java/uk/gov/hmcts/opal/service/opal/ResultService.java b/src/main/java/uk/gov/hmcts/opal/service/opal/ResultService.java index ba746fb7..53925ee1 100644 --- a/src/main/java/uk/gov/hmcts/opal/service/opal/ResultService.java +++ b/src/main/java/uk/gov/hmcts/opal/service/opal/ResultService.java @@ -3,16 +3,21 @@ import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.cache.annotation.Cacheable; 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.ResultSearchDto; +import uk.gov.hmcts.opal.entity.ResultEntity_; import uk.gov.hmcts.opal.entity.ResultEntity; +import uk.gov.hmcts.opal.entity.projection.ResultReferenceData; import uk.gov.hmcts.opal.repository.ResultRepository; import uk.gov.hmcts.opal.repository.jpa.ResultSpecs; import uk.gov.hmcts.opal.service.ResultServiceInterface; import java.util.List; +import java.util.Optional; @Service @RequiredArgsConstructor @@ -37,4 +42,29 @@ public List searchResults(ResultSearchDto criteria) { return page.getContent(); } + @Cacheable( + cacheNames = "resultReferenceDataCache", + key = "#filter.orElse('noFilter')" + ) + public List getReferenceData(Optional filter) { + + Sort nameSort = Sort.by(Sort.Direction.ASC, ResultEntity_.RESULT_TITLE); + + Page page = resultRepository + .findBy(specs.referenceDataFilter(filter), + ffq -> ffq + .sortBy(nameSort) + .page(Pageable.unpaged())); + + return page.getContent().stream().map(this::toRefData).toList(); + } + + private ResultReferenceData toRefData(ResultEntity entity) { + return new ResultReferenceData( + entity.getResultId(), + entity.getResultTitle(), + entity.getResultTitleCy(), + entity.getResultType() + ); + } } diff --git a/src/test/java/uk/gov/hmcts/opal/controllers/develop/ResultControllerTest.java b/src/test/java/uk/gov/hmcts/opal/controllers/ResultControllerTest.java similarity index 64% rename from src/test/java/uk/gov/hmcts/opal/controllers/develop/ResultControllerTest.java rename to src/test/java/uk/gov/hmcts/opal/controllers/ResultControllerTest.java index f3e3d401..1a5f6f6a 100644 --- a/src/test/java/uk/gov/hmcts/opal/controllers/develop/ResultControllerTest.java +++ b/src/test/java/uk/gov/hmcts/opal/controllers/ResultControllerTest.java @@ -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; @@ -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.ResultController; +import uk.gov.hmcts.opal.dto.reference.ResultReferenceDataResults; import uk.gov.hmcts.opal.dto.search.ResultSearchDto; import uk.gov.hmcts.opal.entity.ResultEntity; +import uk.gov.hmcts.opal.entity.projection.ResultReferenceData; import uk.gov.hmcts.opal.service.opal.ResultService; import java.util.List; +import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; @@ -63,4 +65,25 @@ void testSearchResults_Success() { verify(resultService, times(1)).searchResults(any()); } + @Test + void testGetResultsRefData_Success() { + // Arrange + ResultReferenceData refData = new ResultReferenceData("result-id-001", "Result Title", + "Result Tittle Cy", "FINAL"); + List refDataList = List.of(refData); + + when(resultService.getReferenceData(any())).thenReturn(refDataList); + + // Act + Optional filter = Optional.empty(); + ResponseEntity response = resultController + .getResultRefData(filter); + + // Assert + assertEquals(HttpStatus.OK, response.getStatusCode()); + ResultReferenceDataResults refDataResults = response.getBody(); + assertEquals(1, refDataResults.getCount()); + assertEquals(refDataList, refDataResults.getRefData()); + verify(resultService, times(1)).getReferenceData(any()); + } } diff --git a/src/test/java/uk/gov/hmcts/opal/service/opal/ResultServiceTest.java b/src/test/java/uk/gov/hmcts/opal/service/opal/ResultServiceTest.java index 5f3394b1..365eb1b3 100644 --- a/src/test/java/uk/gov/hmcts/opal/service/opal/ResultServiceTest.java +++ b/src/test/java/uk/gov/hmcts/opal/service/opal/ResultServiceTest.java @@ -13,9 +13,11 @@ import org.springframework.data.repository.query.FluentQuery; import uk.gov.hmcts.opal.dto.search.ResultSearchDto; import uk.gov.hmcts.opal.entity.ResultEntity; +import uk.gov.hmcts.opal.entity.projection.ResultReferenceData; import uk.gov.hmcts.opal.repository.ResultRepository; import java.util.List; +import java.util.Optional; import java.util.function.Function; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -68,5 +70,32 @@ void testSearchResults() { } + @SuppressWarnings("unchecked") + @Test + void testResultsReferenceData() { + // Arrange + FluentQuery.FetchableFluentQuery ffq = Mockito.mock(FluentQuery.FetchableFluentQuery.class); + when(ffq.sortBy(any())).thenReturn(ffq); + ResultEntity entity = ResultEntity.builder().build(); + Page mockPage = new PageImpl<>(List.of(entity), Pageable.unpaged(), 999L); + when(resultRepository.findBy(any(Specification.class), any())).thenAnswer(iom -> { + iom.getArgument(1, Function.class).apply(ffq); + return mockPage; + }); + + // Act + List result = resultService.getReferenceData(Optional.empty()); + + ResultReferenceData refData = new ResultReferenceData( + entity.getResultId(), + entity.getResultTitle(), + entity.getResultTitleCy(), + entity.getResultType() + ); + + // Assert + assertEquals(List.of(refData), result); + + } }