diff --git a/api/agencyservice.yaml b/api/agencyservice.yaml index 9da69b31..35ab4208 100644 --- a/api/agencyservice.yaml +++ b/api/agencyservice.yaml @@ -15,7 +15,7 @@ paths: parameters: - name: postcode in: query - required: true + required: false description: The postcode the user entered schema: type: string diff --git a/src/main/java/de/caritas/cob/agencyservice/api/controller/AgencyController.java b/src/main/java/de/caritas/cob/agencyservice/api/controller/AgencyController.java index 41692cb3..bb50d200 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/controller/AgencyController.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/controller/AgencyController.java @@ -8,6 +8,7 @@ import de.caritas.cob.agencyservice.generated.api.controller.AgenciesApi; import io.swagger.annotations.Api; import java.util.List; +import java.util.Optional; import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; @@ -38,14 +39,14 @@ public class AgencyController implements AgenciesApi { */ @Override public ResponseEntity> getAgencies( - @RequestParam String postcode, @RequestParam Integer consultingType, + @RequestParam Integer consultingType, @RequestParam(required = false) String postcode, @RequestParam(value = "topicId", required = false) Integer topicId, @RequestParam(value = "age", required = false) Integer age, @RequestParam(value = "gender", required = false) String gender, @RequestParam(value = "counsellingRelation", required = false) String counsellingRelation ) { - var agencies = agencyService.getAgencies(postcode, consultingType, + var agencies = agencyService.getAgencies(Optional.ofNullable(postcode), consultingType, ofNullable(topicId), ofNullable(age), ofNullable(gender), ofNullable(counsellingRelation)); return !CollectionUtils.isEmpty(agencies) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/AgencyRepository.java b/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/AgencyRepository.java index 5bd07630..dce30e15 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/AgencyRepository.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/AgencyRepository.java @@ -4,7 +4,6 @@ import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; /** @@ -15,10 +14,10 @@ public interface AgencyRepository extends JpaRepository { String AND_WITH_BRACKET = "AND ("; String SELECT_WITH_TOPICS = "SELECT a.*, :tenantId FROM agency a " - + "INNER JOIN agency_postcode_range r ON a.id = r.agency_id " + + "LEFT JOIN agency_postcode_range r ON a.id = r.agency_id " + "INNER JOIN agency_topic at ON a.id = at.agency_id " - + "WHERE (CAST(:postcode AS INT) BETWEEN CAST(SUBSTR(r.postcode_from, 1, :length) AS int) " - + "AND CAST(SUBSTR(r.postcode_to, 1, :length) AS int)) " + "AND a.is_offline = false " + + "WHERE (:postcode is NULL OR ((CAST(:postcode AS INT) BETWEEN CAST(SUBSTR(r.postcode_from, 1, :length) AS int) " + + "AND CAST(SUBSTR(r.postcode_to, 1, :length) AS int)))) " + "AND a.is_offline = false " + "AND (:type is NULL OR a.consulting_type = :type) " + "AND at.topic_id = :topicId " + AND_WITH_BRACKET @@ -32,10 +31,10 @@ public interface AgencyRepository extends JpaRepository { + "AND a.delete_date IS NULL "; String SELECT_WITHOUT_TOPICS = "SELECT a.*, :tenantId FROM agency a " - + "INNER JOIN agency_postcode_range r ON a.id = r.agency_id " + + "LEFT JOIN agency_postcode_range r ON a.id = r.agency_id " + "WHERE " - + "(CAST(:postcode AS INT) BETWEEN CAST(SUBSTR(r.postcode_from, 1, :length) AS int) " - + "AND CAST(SUBSTR(r.postcode_to, 1, :length) AS int)) " + "AND a.is_offline = false " + + "(:postcode is NULL OR ((CAST(:postcode AS INT) BETWEEN CAST(SUBSTR(r.postcode_from, 1, :length) AS int) " + + "AND CAST(SUBSTR(r.postcode_to, 1, :length) AS int)))) " + "AND a.is_offline = false " + "AND (:type is NULL OR a.consulting_type = :type) " + AND_WITH_BRACKET + " (:age IS NULL) OR (a.age_from <= :age)" diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencySearch.java b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencySearch.java index 0331c9b6..c2bc11cf 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencySearch.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencySearch.java @@ -8,7 +8,7 @@ @Data public class AgencySearch { - private String postCode; + private Optional postCode; private Optional consultingTypeId; private Optional topicId; private Optional age; diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java index fff09489..834a99a0 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java @@ -103,7 +103,7 @@ public List getAgencies(int consultingTypeId) { } - public List getAgencies(String postCode, int consultingTypeId, + public List getAgencies(Optional postCode, int consultingTypeId, Optional topicId) { return getAgencies(postCode, consultingTypeId, topicId, Optional.empty(), Optional.empty(), Optional.empty()); } @@ -116,17 +116,19 @@ public List getAgencies(String postCode, int consultingTy * @param consultingTypeId the consulting type used for filtering agencies * @return a list containing regarding agencies */ - public List getAgencies(String postCode, int consultingTypeId, + public List getAgencies(Optional postCode, + Integer consultingTypeId, Optional topicId, Optional age, Optional gender, Optional counsellingRelation) { var consultingTypeSettings = retrieveConsultingTypeSettings( consultingTypeId); - - if (doesPostCodeNotMatchMinSize(postCode, consultingTypeSettings)) { + if (postCode.isPresent() && doesPostCodeNotMatchMinSize(postCode.get(), + consultingTypeSettings)) { return Collections.emptyList(); } + var agencies = findAgencies(postCode, getConsultingTypeIdForSearch(consultingTypeId), topicId, age, gender, counsellingRelation); Collections.shuffle(agencies); @@ -147,7 +149,7 @@ private Optional getConsultingTypeIdForSearch(int consultingTypeId) { return multitenancyWithSingleDomain ? Optional.empty() : Optional.of(consultingTypeId); } - private List findAgencies(String postCode, Optional consultingTypeId, + private List findAgencies(Optional postCode, Optional consultingTypeId, Optional optionalTopicId, Optional age, Optional gender, Optional counsellingRelation) { @@ -175,8 +177,8 @@ private List findAgencies(String postCode, Optional consultingT private List findAgencies(AgencySearch agencySearch) { try { return getAgencyRepositoryForSearch() - .searchWithoutTopic(agencySearch.getPostCode(), - agencySearch.getPostCode().length(), agencySearch.getConsultingTypeId().orElse(null), + .searchWithoutTopic(agencySearch.getPostCode().orElse(null), + agencySearch.getPostCode().orElse("").length(), agencySearch.getConsultingTypeId().orElse(null), agencySearch.getAge().orElse(null), agencySearch.getGender().orElse(null), agencySearch.getCounsellingRelation().orElse(null), @@ -238,7 +240,7 @@ public ExtendedConsultingTypeResponseDTO retrieveConsultingTypeSettings(int cons private List findAgenciesWithTopic(AgencySearch agencySearch) { try { return getAgencyRepositoryForSearch() - .searchWithTopic(agencySearch.getPostCode(), agencySearch.getPostCode().length(), + .searchWithTopic(agencySearch.getPostCode().orElse(null), agencySearch.getPostCode().orElse("").length(), agencySearch.getConsultingTypeId().orElse(null), agencySearch.getTopicId().orElseThrow(), agencySearch.getAge().orElse(null), agencySearch.getGender().orElse(null), diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerIT.java index 34c2d59f..f6ae2b9d 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerIT.java @@ -80,7 +80,7 @@ class AgencyControllerIT { @Test void getAgencies_Should_ReturnNoContent_When_ServiceReturnsEmptyList() throws Exception { - when(agencyService.getAgencies(Mockito.anyString(), Mockito.anyInt(), Mockito.any(Optional.class), Mockito.any(Optional.class), Mockito.any(Optional.class), Mockito.any(Optional.class))) + when(agencyService.getAgencies(Mockito.any(Optional.class), Mockito.anyInt(), Mockito.any(Optional.class), Mockito.any(Optional.class), Mockito.any(Optional.class), Mockito.any(Optional.class))) .thenReturn(null); mvc.perform( @@ -112,11 +112,11 @@ void getAgencies_Should_ReturnBadRequest_When_ConsultingTypeParamIsInvalid() } @Test - void getAgencies_Should_ReturnBadRequest_When_PostcodeParamIsNotProvided() + void getAgencies_Should_ReturnRespondWith2XXResponseCode_When_PostcodeParamIsNotProvided() throws Exception { mvc.perform(get(PATH_GET_LIST_OF_AGENCIES + "?" + VALID_CONSULTING_TYPE_QUERY) - .accept(MediaType.APPLICATION_JSON)).andExpect(status().isBadRequest()); + .accept(MediaType.APPLICATION_JSON)).andExpect(status().isNoContent()); } @Test @@ -133,7 +133,7 @@ void getAgencies_Should_ReturnListAndOk_When_ServiceReturnsList() throws Excepti List agencies = new ArrayList<>(); agencies.add(FULL_AGENCY_RESPONSE_DTO); - when(agencyService.getAgencies(Mockito.anyString(), Mockito.anyInt(), Mockito.any(Optional.class), Mockito.any(Optional.class), Mockito.any(Optional.class), Mockito.any(Optional.class))) + when(agencyService.getAgencies(Mockito.any(Optional.class), Mockito.anyInt(), Mockito.any(Optional.class), Mockito.any(Optional.class), Mockito.any(Optional.class), Mockito.any(Optional.class))) .thenReturn(agencies); mvc.perform( @@ -143,7 +143,7 @@ void getAgencies_Should_ReturnListAndOk_When_ServiceReturnsList() throws Excepti .andExpect(status().isOk()) .andExpect(jsonPath("[0].name").value(AGENCY_RESPONSE_DTO.getName())); - verify(agencyService, atLeastOnce()).getAgencies(Mockito.anyString(), + verify(agencyService, atLeastOnce()).getAgencies(Mockito.any(Optional.class), Mockito.anyInt(), Mockito.any(Optional.class), Mockito.any(Optional.class), Mockito.any(Optional.class), Mockito.any(Optional.class)); } diff --git a/src/test/java/de/caritas/cob/agencyservice/api/repository/agency/AgencyRepositoryIT.java b/src/test/java/de/caritas/cob/agencyservice/api/repository/agency/AgencyRepositoryIT.java index 2685e6bd..f0db961d 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/repository/agency/AgencyRepositoryIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/repository/agency/AgencyRepositoryIT.java @@ -55,6 +55,14 @@ void searchWithoutTopic_Should_findAgencyByPostcodeAndConsultingType() { assertThat(agencyList).hasSize(2); } + @Test + void searchWithoutTopic_Should_findAgencyByOnlyConsultingTypeSkippingPostCodeFiltering() { + // given, when + var agencyList = agencyRepository.searchWithoutTopic(null, 5, 0, null, null, null, 1L); + // then + assertThat(agencyList).hasSize(104); + } + @Test void searchWithTopic_Should_findAgencyByPostcodeAndConsultingTypeAndTopicId() { @@ -66,6 +74,14 @@ void searchWithTopic_Should_findAgencyByPostcodeAndConsultingTypeAndTopicId() { assertThat(agencyList.get(0).getAgencyTopics()).extracting("topicId").containsExactly(0L, 1L); } + @Test + void searchWithTopic_Should_findAgencyConsultingTypeAndTopicIdSkippingPostCode() { + // given, when + var agencyList = agencyRepository.searchWithTopic(null, 5, 0, 1, null, null, null, 1L); + // then + assertThat(agencyList).hasSize(2); + } + @Test void searchWithTopic_Should_findAgencyByPostcodeAndConsultingTypeAndTopicId_When_ConsultingTypeIsNotProvided() { // given, when diff --git a/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceITBase.java b/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceITBase.java index ac337d1d..f51fdb95 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceITBase.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceITBase.java @@ -40,7 +40,7 @@ public void getAgencies_Should_returnMatchingAgencies_When_postcodeAndConsulting String postCode = "88662"; List resultAgencies = agencyService - .getAgencies(postCode, CONSULTING_TYPE_PREGNANCY, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()); + .getAgencies(Optional.of(postCode), CONSULTING_TYPE_PREGNANCY, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()); assertThat(resultAgencies, hasSize(1)); FullAgencyResponseDTO resultAgency = resultAgencies.get(0); diff --git a/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceTenantAwareTest.java b/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceTenantAwareTest.java index ada39cc0..cfcfa262 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceTenantAwareTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceTenantAwareTest.java @@ -77,7 +77,7 @@ public void getAgencies_Should_throwBadRequestException_When_topicIdNotProvidedA restrictedTenantDTO); // when - this.agencyService.getAgencies("12123", 1, Optional.empty()); + this.agencyService.getAgencies(Optional.of("12123"), 1, Optional.empty()); // then verify(agencyRepository).searchWithTopic("12123", 5, 1, 2, null, @@ -99,7 +99,7 @@ public void getAgencies_Should_searchByTopicId_When_topicIdProvidedAndFeatureEna restrictedTenantDTO); // when - this.agencyService.getAgencies("12123", 1, Optional.of(2), Optional.empty(), Optional.empty(), Optional.empty()); + this.agencyService.getAgencies(Optional.of("12123"), 1, Optional.of(2), Optional.empty(), Optional.empty(), Optional.empty()); // then verify(agencyRepository).searchWithTopic("12123", 5, 1, 2, null, diff --git a/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceTest.java b/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceTest.java index 51d77be9..e4aa639b 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/service/AgencyServiceTest.java @@ -49,6 +49,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Optional; +import javax.swing.text.html.Option; import org.hamcrest.collection.IsEmptyCollection; import org.jeasy.random.EasyRandom; import org.junit.After; @@ -117,7 +118,7 @@ public void getListOfAgencies_Should_ReturnServiceExceptionAndLogDatabaseError_O private void callGetAgencies() { Optional emptyTopicIds = Optional.empty(); try { - agencyService.getAgencies(VALID_POSTCODE, CONSULTING_TYPE_SUCHT, emptyTopicIds); + agencyService.getAgencies(Optional.of(VALID_POSTCODE), CONSULTING_TYPE_SUCHT, emptyTopicIds); fail("Expected exception: ServiceException"); } catch (InternalServerErrorException internalServerErrorException) { assertTrue("Excepted ServiceException thrown", true); @@ -163,9 +164,9 @@ public void getListOfAgencies_Should_ReturnListOfFullAgencyResponseDTO_WhenDBSel when(consultingTypeManager.getConsultingTypeSettings(Mockito.anyInt())) .thenReturn(CONSULTING_TYPE_SETTINGS_WITH_WHITESPOT_AGENCY); - assertThat(agencyService.getAgencies(VALID_POSTCODE, CONSULTING_TYPE_SUCHT, Optional.empty()), + assertThat(agencyService.getAgencies(Optional.of(VALID_POSTCODE), CONSULTING_TYPE_SUCHT, Optional.empty()), everyItem(instanceOf(FullAgencyResponseDTO.class))); - assertThat(agencyService.getAgencies(VALID_POSTCODE, CONSULTING_TYPE_SUCHT, Optional.empty())) + assertThat(agencyService.getAgencies(Optional.of(VALID_POSTCODE), CONSULTING_TYPE_SUCHT, Optional.empty())) .extracting(POSTCODE).contains(POSTCODE); } @@ -181,7 +182,7 @@ public void getListOfAgencies_Should_ReturnWhiteSpotAgency_WhenNoAgencyFoundForG when(consultingTypeManager.getConsultingTypeSettings(Mockito.anyInt())) .thenReturn(CONSULTING_TYPE_SETTINGS_WITH_WHITESPOT_AGENCY); - assertThat(agencyService.getAgencies(VALID_POSTCODE, CONSULTING_TYPE_SUCHT, Optional.empty())) + assertThat(agencyService.getAgencies(Optional.of(VALID_POSTCODE), CONSULTING_TYPE_SUCHT, Optional.empty())) .extracting(FIELD_AGENCY_ID).contains(AGENCY_ID); } @@ -194,7 +195,7 @@ public void getListOfAgencies_Should_ReturnEmptyList_WhenNoAgencyFoundForGivenPo when(consultingTypeManager.getConsultingTypeSettings(Mockito.anyInt())) .thenReturn(CONSULTING_TYPE_SETTINGS_WITHOUT_WHITESPOT_AGENCY); - assertThat(agencyService.getAgencies(VALID_POSTCODE, CONSULTING_TYPE_SUCHT, Optional.empty()), + assertThat(agencyService.getAgencies(Optional.of(VALID_POSTCODE), CONSULTING_TYPE_SUCHT, Optional.empty()), IsEmptyCollection.empty()); } @@ -205,7 +206,7 @@ public void getListOfAgencies_Should_ReturnEmptyList_When_PostcodeSizeIsSmallerT when(consultingTypeManager.getConsultingTypeSettings(Mockito.anyInt())) .thenReturn(CONSULTING_TYPE_SETTINGS_EMIGRATION); - assertThat(agencyService.getAgencies(VALID_POSTCODE, CONSULTING_TYPE_EMIGRATION, Optional.empty()), + assertThat(agencyService.getAgencies(Optional.of(VALID_POSTCODE), CONSULTING_TYPE_EMIGRATION, Optional.empty()), IsEmptyCollection.empty()); } @@ -268,7 +269,7 @@ public void getAgencies_Should_ThrowInternalServerError_When_MissingConsultingTy when(consultingTypeManager.getConsultingTypeSettings(anyInt())) .thenThrow(new MissingConsultingTypeException("")); - agencyService.getAgencies("", 0, Optional.empty()); + agencyService.getAgencies(Optional.of(""), 0, Optional.empty()); } @Test @@ -310,7 +311,7 @@ public void getAgencies_Should_throwBadRequestException_When_TopicIdNotProvidedA when(tenantService.getRestrictedTenantDataForSingleTenant()).thenReturn(restrictedTenantDTO); // when - this.agencyService.getAgencies("12123", 1, Optional.empty()); + this.agencyService.getAgencies(Optional.of("12123"), 1, Optional.empty()); } @Test @@ -326,7 +327,7 @@ public void getAgencies_Should_searchByTopicId_When_TopicIdProvidedAndFeatureEna when(tenantService.getRestrictedTenantDataForSingleTenant()).thenReturn(restrictedTenantDTO); // when - this.agencyService.getAgencies("12123", 1, Optional.of(2)); + this.agencyService.getAgencies(Optional.of("12123"), 1, Optional.of(2)); // then verify(agencyRepository).searchWithTopic("12123", 5, 1, 2, AGE, GENDER, COUNSELLING_RELATION,