From 945f813cd0e7f841d82f686b6830218f6bc310ca Mon Sep 17 00:00:00 2001 From: aitestmate Date: Thu, 2 Jul 2026 00:41:25 +0000 Subject: [PATCH 1/2] [chore] [mod-dcb] unit tests --- .../impl/ShadowLocationServiceImplTest.java | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/src/test/java/org/folio/dcb/service/impl/ShadowLocationServiceImplTest.java b/src/test/java/org/folio/dcb/service/impl/ShadowLocationServiceImplTest.java index 71f1b077..3b0ab767 100644 --- a/src/test/java/org/folio/dcb/service/impl/ShadowLocationServiceImplTest.java +++ b/src/test/java/org/folio/dcb/service/impl/ShadowLocationServiceImplTest.java @@ -48,6 +48,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpServerErrorException.InternalServerError; +import static org.mockito.ArgumentMatchers.eq; @ExtendWith(MockitoExtension.class) class ShadowLocationServiceImplTest { @@ -374,6 +375,153 @@ void createShadowLocations_negative_serviceExceptionThrown() { .hasMessage("Failed to create shadow locations"); } + @Test + void createShadowLocations_positive_partialExistenceHierarchyReuse() { + // TestMate-34ec793e0eaae755ccfec6a1494f9d1b + // Given + when(dcbFeatureProperties.isFlexibleCirculationRulesEnabled()).thenReturn(true); + when(dcbEntityServiceFacade.findOrCreateServicePoint()).thenReturn(servicePoint()); + when(locationUnitClient.findInstitutionsByQuery(agencySql(), true, 10, 0)).thenReturn(asSinglePage(institution())); + when(locationUnitClient.findCampusesByQuery(agencySql(), true, 10, 0)).thenReturn(empty()); + when(locationUnitClient.findLibrariesByQuery(agencySql(), true, 10, 0)).thenReturn(empty()); + when(locationsClient.findLocationByQuery(locationSql(), true, 10, 0)).thenReturn(empty()); + when(locationUnitClient.createCampus(luCaptor.capture())).then(returningFirstArgument()); + when(locationUnitClient.createLibrary(luCaptor.capture())).then(returningFirstArgument()); + when(locationsClient.createLocation(locCaptor.capture())).then(returningFirstArgument()); + var refreshRequest = refreshRequest(List.of(dcbLocation()), emptyList()); + // When + var result = dcbHubLocationService.createShadowLocations(refreshRequest); + // Then + assertThat(result).isEqualTo(new RefreshShadowLocationResponse() + .addLocationsItem(refreshLocationStatus(SUCCESS)) + .locationUnits(new RefreshLocationUnitsStatus() + .addInstitutionsItem(refreshAgencyStatus(SKIPPED)) + .addCampusesItem(refreshAgencyStatus(SUCCESS)) + .addLibrariesItem(refreshAgencyStatus(SUCCESS)))); + verify(locationUnitClient, never()).createInstitution(any()); + verify(locationUnitClient).createCampus(any()); + verify(locationUnitClient).createLibrary(any()); + verify(locationsClient).createLocation(any()); + LocationUnit capturedCampus = luCaptor.getAllValues().stream() + .filter(lu -> lu.getInstitutionId() != null && lu.getCampusId() == null) + .findFirst() + .orElseThrow(); + assertThat(capturedCampus.getInstitutionId()).isEqualTo(INSTITUTION_ID); + } + + @Test + void createShadowLocations_positive_combinedRequestGrouping() { + // TestMate-94fcb8ae859525449cb6b22ac8ffa5f8 + // Given + String loc1Name = "Location 1"; + String loc1Code = "LOC-1"; + String loc2Name = "Location 2"; + String loc2Code = "LOC-2"; + String loc1Sql = CqlQuery.exactMatchByNameAndCode(loc1Name, loc1Code).getQuery(); + String loc2Sql = CqlQuery.exactMatchByNameAndCode(loc2Name, loc2Code).getQuery(); + when(dcbFeatureProperties.isFlexibleCirculationRulesEnabled()).thenReturn(true); + when(dcbEntityServiceFacade.findOrCreateServicePoint()).thenReturn(servicePoint()); + when(locationUnitClient.findInstitutionsByQuery(agencySql(), true, 10, 0)).thenReturn(empty()); + when(locationUnitClient.findCampusesByQuery(agencySql(), true, 10, 0)).thenReturn(empty()); + when(locationUnitClient.findLibrariesByQuery(agencySql(), true, 10, 0)).thenReturn(empty()); + when(locationsClient.findLocationByQuery(loc1Sql, true, 10, 0)).thenReturn(empty()); + when(locationsClient.findLocationByQuery(loc2Sql, true, 10, 0)).thenReturn(empty()); + when(locationUnitClient.createInstitution(luCaptor.capture())).then(returningFirstArgument()); + when(locationUnitClient.createCampus(luCaptor.capture())).then(returningFirstArgument()); + when(locationUnitClient.createLibrary(luCaptor.capture())).then(returningFirstArgument()); + when(locationsClient.createLocation(locCaptor.capture())).then(returningFirstArgument()); + var agency = dcbAgency(); + var location1 = dcbLocation(loc1Name, loc1Code, agency); + var location2 = dcbLocation(loc2Name, loc2Code, agency); + var refreshRequest = refreshRequest(List.of(location1, location2), List.of()); + // When + var result = dcbHubLocationService.createShadowLocations(refreshRequest); + // Then + assertThat(result).isEqualTo(new RefreshShadowLocationResponse() + .addLocationsItem(refreshLocationStatus(SUCCESS).code(loc1Code)) + .addLocationsItem(refreshLocationStatus(SUCCESS).code(loc2Code)) + .locationUnits(new RefreshLocationUnitsStatus() + .addInstitutionsItem(refreshAgencyStatus(SUCCESS)) + .addCampusesItem(refreshAgencyStatus(SUCCESS)) + .addLibrariesItem(refreshAgencyStatus(SUCCESS)))); + verify(locationUnitClient, times(1)).createInstitution(any()); + verify(locationUnitClient, times(1)).createCampus(any()); + verify(locationUnitClient, times(1)).createLibrary(any()); + verify(locationsClient, times(2)).createLocation(any()); + List capturedLocations = locCaptor.getAllValues(); + assertThat(capturedLocations) + .extracting(Location::getCode, Location::getName) + .containsExactlyInAnyOrder( + org.assertj.core.groups.Tuple.tuple(loc1Code, loc1Name), + org.assertj.core.groups.Tuple.tuple(loc2Code, loc2Name) + ); + String sharedInstitutionId = capturedLocations.get(0).getInstitutionId(); + String sharedCampusId = capturedLocations.get(0).getCampusId(); + String sharedLibraryId = capturedLocations.get(0).getLibraryId(); + assertThat(capturedLocations.get(1).getInstitutionId()).isEqualTo(sharedInstitutionId); + assertThat(capturedLocations.get(1).getCampusId()).isEqualTo(sharedCampusId); + assertThat(capturedLocations.get(1).getLibraryId()).isEqualTo(sharedLibraryId); + } + + @Test + void createShadowLocations_positive_partialSuccessMultipleAgencies() { + // TestMate-f3af2b8f3b8782a468074ae1dee25408 + // Given + String agency1Name = "Agency Fail"; + String agency1Code = "AG-FAIL"; + String agency2Name = "Agency Success"; + String agency2Code = "AG-SUCCESS"; + String agency1Sql = CqlQuery.exactMatchByNameAndCode(agency1Name, agency1Code).getQuery(); + String agency2Sql = CqlQuery.exactMatchByNameAndCode(agency2Name, agency2Code).getQuery(); + when(dcbFeatureProperties.isFlexibleCirculationRulesEnabled()).thenReturn(true); + when(dcbEntityServiceFacade.findOrCreateServicePoint()).thenReturn(servicePoint()); + when(locationUnitClient.findInstitutionsByQuery(agency1Sql, true, 10, 0)).thenReturn(empty()); + when(locationUnitClient.createInstitution(any())).thenAnswer(invocation -> { + LocationUnit lu = invocation.getArgument(0); + if (agency1Code.equals(lu.getCode())) { + throw badRequestError("/institutions"); + } + return lu; + }); + when(locationUnitClient.findInstitutionsByQuery(agency2Sql, true, 10, 0)).thenReturn(empty()); + when(locationUnitClient.findCampusesByQuery(agency2Sql, true, 10, 0)).thenReturn(empty()); + when(locationUnitClient.findLibrariesByQuery(agency2Sql, true, 10, 0)).thenReturn(empty()); + when(locationsClient.findLocationByQuery(agency2Sql, true, 10, 0)).thenReturn(empty()); + when(locationUnitClient.createCampus(luCaptor.capture())).then(returningFirstArgument()); + when(locationUnitClient.createLibrary(luCaptor.capture())).then(returningFirstArgument()); + when(locationsClient.createLocation(locCaptor.capture())).then(returningFirstArgument()); + var agency1 = new DcbAgency().name(agency1Name).code(agency1Code); + var agency2 = new DcbAgency().name(agency2Name).code(agency2Code); + var refreshRequest = refreshRequest(emptyList(), List.of(agency1, agency2)); + // When + var result = dcbHubLocationService.createShadowLocations(refreshRequest); + // Then + assertThat(result.getLocationUnits().getInstitutions()) + .extracting(RefreshLocationStatus::getCode, RefreshLocationStatus::getStatus) + .containsExactlyInAnyOrder( + org.assertj.core.groups.Tuple.tuple(agency1Code, ERROR), + org.assertj.core.groups.Tuple.tuple(agency2Code, SUCCESS) + ); + assertThat(result.getLocationUnits().getCampuses()) + .extracting(RefreshLocationStatus::getCode, RefreshLocationStatus::getStatus) + .containsExactlyInAnyOrder( + org.assertj.core.groups.Tuple.tuple(agency1Code, SKIPPED), + org.assertj.core.groups.Tuple.tuple(agency2Code, SUCCESS) + ); + assertThat(result.getLocations()) + .extracting(RefreshLocationStatus::getCode, RefreshLocationStatus::getStatus) + .containsExactlyInAnyOrder( + org.assertj.core.groups.Tuple.tuple(agency1Code, SKIPPED), + org.assertj.core.groups.Tuple.tuple(agency2Code, SUCCESS) + ); + verify(locationUnitClient, times(2)).createInstitution(any()); + verify(locationUnitClient, times(1)).createCampus(any()); + verify(locationsClient, times(1)).createLocation(any()); + assertThat(locCaptor.getAllValues()) + .extracting(Location::getCode, Location::getName) + .containsExactly(org.assertj.core.groups.Tuple.tuple(agency2Code, agency2Name)); + } + private static ShadowLocationRefreshBody refreshRequest(List locations, List agencies) { return new ShadowLocationRefreshBody() .locations(locations) From 81ba98f9ac942fe961ef1ac68d3d992be2c8bb20 Mon Sep 17 00:00:00 2001 From: Pavel Filippov Date: Thu, 2 Jul 2026 10:44:03 +0300 Subject: [PATCH 2/2] chore(unit-tests): Update tests to follow codestyle --- .../impl/ShadowLocationServiceImplTest.java | 87 ++++++++----------- 1 file changed, 37 insertions(+), 50 deletions(-) diff --git a/src/test/java/org/folio/dcb/service/impl/ShadowLocationServiceImplTest.java b/src/test/java/org/folio/dcb/service/impl/ShadowLocationServiceImplTest.java index 3b0ab767..0a084675 100644 --- a/src/test/java/org/folio/dcb/service/impl/ShadowLocationServiceImplTest.java +++ b/src/test/java/org/folio/dcb/service/impl/ShadowLocationServiceImplTest.java @@ -10,6 +10,7 @@ import static org.folio.dcb.domain.dto.RefreshLocationStatusType.ERROR; import static org.folio.dcb.domain.dto.RefreshLocationStatusType.SKIPPED; import static org.folio.dcb.domain.dto.RefreshLocationStatusType.SUCCESS; +import static org.folio.dcb.utils.CqlQuery.exactMatchByNameAndCode; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -35,7 +36,6 @@ import org.folio.dcb.integration.invstorage.model.Location; import org.folio.dcb.integration.invstorage.model.LocationUnit; import org.folio.dcb.service.entities.DcbEntityServiceFacade; -import org.folio.dcb.utils.CqlQuery; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -48,7 +48,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpServerErrorException.InternalServerError; -import static org.mockito.ArgumentMatchers.eq; @ExtendWith(MockitoExtension.class) class ShadowLocationServiceImplTest { @@ -375,10 +374,9 @@ void createShadowLocations_negative_serviceExceptionThrown() { .hasMessage("Failed to create shadow locations"); } - @Test + @Test void createShadowLocations_positive_partialExistenceHierarchyReuse() { // TestMate-34ec793e0eaae755ccfec6a1494f9d1b - // Given when(dcbFeatureProperties.isFlexibleCirculationRulesEnabled()).thenReturn(true); when(dcbEntityServiceFacade.findOrCreateServicePoint()).thenReturn(servicePoint()); when(locationUnitClient.findInstitutionsByQuery(agencySql(), true, 10, 0)).thenReturn(asSinglePage(institution())); @@ -389,9 +387,9 @@ void createShadowLocations_positive_partialExistenceHierarchyReuse() { when(locationUnitClient.createLibrary(luCaptor.capture())).then(returningFirstArgument()); when(locationsClient.createLocation(locCaptor.capture())).then(returningFirstArgument()); var refreshRequest = refreshRequest(List.of(dcbLocation()), emptyList()); - // When + var result = dcbHubLocationService.createShadowLocations(refreshRequest); - // Then + assertThat(result).isEqualTo(new RefreshShadowLocationResponse() .addLocationsItem(refreshLocationStatus(SUCCESS)) .locationUnits(new RefreshLocationUnitsStatus() @@ -409,16 +407,15 @@ void createShadowLocations_positive_partialExistenceHierarchyReuse() { assertThat(capturedCampus.getInstitutionId()).isEqualTo(INSTITUTION_ID); } - @Test + @Test void createShadowLocations_positive_combinedRequestGrouping() { // TestMate-94fcb8ae859525449cb6b22ac8ffa5f8 - // Given - String loc1Name = "Location 1"; - String loc1Code = "LOC-1"; - String loc2Name = "Location 2"; - String loc2Code = "LOC-2"; - String loc1Sql = CqlQuery.exactMatchByNameAndCode(loc1Name, loc1Code).getQuery(); - String loc2Sql = CqlQuery.exactMatchByNameAndCode(loc2Name, loc2Code).getQuery(); + var loc1Name = "Location 1"; + var loc1Code = "LOC-1"; + var loc2Name = "Location 2"; + var loc2Code = "LOC-2"; + var loc1Sql = exactMatchByNameAndCode(loc1Name, loc1Code).getQuery(); + var loc2Sql = exactMatchByNameAndCode(loc2Name, loc2Code).getQuery(); when(dcbFeatureProperties.isFlexibleCirculationRulesEnabled()).thenReturn(true); when(dcbEntityServiceFacade.findOrCreateServicePoint()).thenReturn(servicePoint()); when(locationUnitClient.findInstitutionsByQuery(agencySql(), true, 10, 0)).thenReturn(empty()); @@ -434,9 +431,9 @@ void createShadowLocations_positive_combinedRequestGrouping() { var location1 = dcbLocation(loc1Name, loc1Code, agency); var location2 = dcbLocation(loc2Name, loc2Code, agency); var refreshRequest = refreshRequest(List.of(location1, location2), List.of()); - // When + var result = dcbHubLocationService.createShadowLocations(refreshRequest); - // Then + assertThat(result).isEqualTo(new RefreshShadowLocationResponse() .addLocationsItem(refreshLocationStatus(SUCCESS).code(loc1Code)) .addLocationsItem(refreshLocationStatus(SUCCESS).code(loc2Code)) @@ -448,41 +445,38 @@ void createShadowLocations_positive_combinedRequestGrouping() { verify(locationUnitClient, times(1)).createCampus(any()); verify(locationUnitClient, times(1)).createLibrary(any()); verify(locationsClient, times(2)).createLocation(any()); - List capturedLocations = locCaptor.getAllValues(); + var capturedLocations = locCaptor.getAllValues(); assertThat(capturedLocations) .extracting(Location::getCode, Location::getName) - .containsExactlyInAnyOrder( - org.assertj.core.groups.Tuple.tuple(loc1Code, loc1Name), - org.assertj.core.groups.Tuple.tuple(loc2Code, loc2Name) - ); - String sharedInstitutionId = capturedLocations.get(0).getInstitutionId(); - String sharedCampusId = capturedLocations.get(0).getCampusId(); - String sharedLibraryId = capturedLocations.get(0).getLibraryId(); + .containsExactlyInAnyOrder(tuple(loc1Code, loc1Name), tuple(loc2Code, loc2Name)); + var sharedInstitutionId = capturedLocations.get(0).getInstitutionId(); + var sharedCampusId = capturedLocations.get(0).getCampusId(); + var sharedLibraryId = capturedLocations.get(0).getLibraryId(); assertThat(capturedLocations.get(1).getInstitutionId()).isEqualTo(sharedInstitutionId); assertThat(capturedLocations.get(1).getCampusId()).isEqualTo(sharedCampusId); assertThat(capturedLocations.get(1).getLibraryId()).isEqualTo(sharedLibraryId); } - @Test + @Test void createShadowLocations_positive_partialSuccessMultipleAgencies() { // TestMate-f3af2b8f3b8782a468074ae1dee25408 - // Given - String agency1Name = "Agency Fail"; - String agency1Code = "AG-FAIL"; - String agency2Name = "Agency Success"; - String agency2Code = "AG-SUCCESS"; - String agency1Sql = CqlQuery.exactMatchByNameAndCode(agency1Name, agency1Code).getQuery(); - String agency2Sql = CqlQuery.exactMatchByNameAndCode(agency2Name, agency2Code).getQuery(); + var agency1Name = "Agency Fail"; + var agency1Code = "AG-FAIL"; + var agency2Name = "Agency Success"; + var agency2Code = "AG-SUCCESS"; + var agency1Sql = exactMatchByNameAndCode(agency1Name, agency1Code).getQuery(); when(dcbFeatureProperties.isFlexibleCirculationRulesEnabled()).thenReturn(true); when(dcbEntityServiceFacade.findOrCreateServicePoint()).thenReturn(servicePoint()); when(locationUnitClient.findInstitutionsByQuery(agency1Sql, true, 10, 0)).thenReturn(empty()); when(locationUnitClient.createInstitution(any())).thenAnswer(invocation -> { - LocationUnit lu = invocation.getArgument(0); + var lu = invocation.getArgument(0); if (agency1Code.equals(lu.getCode())) { throw badRequestError("/institutions"); } return lu; }); + + var agency2Sql = exactMatchByNameAndCode(agency2Name, agency2Code).getQuery(); when(locationUnitClient.findInstitutionsByQuery(agency2Sql, true, 10, 0)).thenReturn(empty()); when(locationUnitClient.findCampusesByQuery(agency2Sql, true, 10, 0)).thenReturn(empty()); when(locationUnitClient.findLibrariesByQuery(agency2Sql, true, 10, 0)).thenReturn(empty()); @@ -493,33 +487,26 @@ void createShadowLocations_positive_partialSuccessMultipleAgencies() { var agency1 = new DcbAgency().name(agency1Name).code(agency1Code); var agency2 = new DcbAgency().name(agency2Name).code(agency2Code); var refreshRequest = refreshRequest(emptyList(), List.of(agency1, agency2)); - // When + var result = dcbHubLocationService.createShadowLocations(refreshRequest); - // Then assertThat(result.getLocationUnits().getInstitutions()) .extracting(RefreshLocationStatus::getCode, RefreshLocationStatus::getStatus) - .containsExactlyInAnyOrder( - org.assertj.core.groups.Tuple.tuple(agency1Code, ERROR), - org.assertj.core.groups.Tuple.tuple(agency2Code, SUCCESS) - ); + .containsExactlyInAnyOrder(tuple(agency1Code, ERROR), tuple(agency2Code, SUCCESS)); + assertThat(result.getLocationUnits().getCampuses()) .extracting(RefreshLocationStatus::getCode, RefreshLocationStatus::getStatus) - .containsExactlyInAnyOrder( - org.assertj.core.groups.Tuple.tuple(agency1Code, SKIPPED), - org.assertj.core.groups.Tuple.tuple(agency2Code, SUCCESS) - ); + .containsExactlyInAnyOrder(tuple(agency1Code, SKIPPED), tuple(agency2Code, SUCCESS)); + assertThat(result.getLocations()) .extracting(RefreshLocationStatus::getCode, RefreshLocationStatus::getStatus) - .containsExactlyInAnyOrder( - org.assertj.core.groups.Tuple.tuple(agency1Code, SKIPPED), - org.assertj.core.groups.Tuple.tuple(agency2Code, SUCCESS) - ); + .containsExactlyInAnyOrder(tuple(agency1Code, SKIPPED), tuple(agency2Code, SUCCESS)); + verify(locationUnitClient, times(2)).createInstitution(any()); verify(locationUnitClient, times(1)).createCampus(any()); verify(locationsClient, times(1)).createLocation(any()); assertThat(locCaptor.getAllValues()) .extracting(Location::getCode, Location::getName) - .containsExactly(org.assertj.core.groups.Tuple.tuple(agency2Code, agency2Name)); + .containsExactly(tuple(agency2Code, agency2Name)); } private static ShadowLocationRefreshBody refreshRequest(List locations, List agencies) { @@ -549,11 +536,11 @@ private static ServicePointRequest servicePoint() { } private static String agencySql() { - return CqlQuery.exactMatchByNameAndCode(AGENCY_NAME, AGENCY_CODE).getQuery(); + return exactMatchByNameAndCode(AGENCY_NAME, AGENCY_CODE).getQuery(); } private static String locationSql() { - return CqlQuery.exactMatchByNameAndCode(LOCATION_NAME, LOCATION_CODE).getQuery(); + return exactMatchByNameAndCode(LOCATION_NAME, LOCATION_CODE).getQuery(); } private static Answer returningFirstArgument() {