diff --git a/src/main/java/org/folio/linked/data/service/resource/marc/ResourceMarcAuthorityServiceImpl.java b/src/main/java/org/folio/linked/data/service/resource/marc/ResourceMarcAuthorityServiceImpl.java index 748053b9..624ec5fe 100644 --- a/src/main/java/org/folio/linked/data/service/resource/marc/ResourceMarcAuthorityServiceImpl.java +++ b/src/main/java/org/folio/linked/data/service/resource/marc/ResourceMarcAuthorityServiceImpl.java @@ -125,15 +125,18 @@ private RequestProcessingException notFoundException(String srsId) { @Override public Long saveMarcAuthority(org.folio.ld.dictionary.model.Resource modelResource) { - var mapped = resourceModelMapper.toEntity(modelResource); - validateResource(mapped); - if (sameResourceExistsByIdAndSrsId(mapped)) { - return updateAuthority(mapped); + var resource = resourceModelMapper.toEntity(modelResource); + validateResource(resource); + + if (existsBySrsIdAndIdUnchanged(resource)) { + return updateAuthority(resource); } - if (resourceExistsBySrsId(mapped)) { - return replaceAuthority(mapped); + + if (existsBySrsId(resource)) { + return replaceAuthority(resource); } - return createAuthority(mapped); + + return createAuthority(resource); } private static void validateResource(Resource resource) { @@ -151,7 +154,7 @@ private static void logAndThrow(String message) { throw new IllegalArgumentException(message); } - private boolean sameResourceExistsByIdAndSrsId(Resource resource) { + private boolean existsBySrsIdAndIdUnchanged(Resource resource) { var id = resource.getId(); var srsId = resource.getFolioMetadata().getSrsId(); return resourceRepo.existsById(id) && getIdBySrsId(srsId).filter(id::equals).isPresent(); @@ -162,7 +165,7 @@ private Optional getIdBySrsId(String srsId) { .map(FolioMetadataRepository.IdOnly::getId); } - private boolean resourceExistsBySrsId(Resource resource) { + private boolean existsBySrsId(Resource resource) { return folioMetadataRepository.existsBySrsId(resource.getFolioMetadata().getSrsId()); } diff --git a/src/test/java/org/folio/linked/data/service/resource/marc/ResourceMarcAuthorityServiceIT.java b/src/test/java/org/folio/linked/data/service/resource/marc/ResourceMarcAuthorityServiceIT.java new file mode 100644 index 00000000..8b9d50ec --- /dev/null +++ b/src/test/java/org/folio/linked/data/service/resource/marc/ResourceMarcAuthorityServiceIT.java @@ -0,0 +1,86 @@ +package org.folio.linked.data.service.resource.marc; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.folio.ld.dictionary.PredicateDictionary.REPLACED_BY; +import static org.folio.linked.data.util.ResourceUtils.isPreferred; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Set; +import lombok.SneakyThrows; +import org.folio.ld.dictionary.ResourceTypeDictionary; +import org.folio.ld.dictionary.model.FolioMetadata; +import org.folio.ld.dictionary.model.Resource; +import org.folio.linked.data.e2e.base.IntegrationTest; +import org.folio.linked.data.test.resource.ResourceTestService; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +@IntegrationTest +class ResourceMarcAuthorityServiceIT { + @Autowired + private ResourceMarcAuthorityService resourceMarcAuthorityService; + @Autowired + private ObjectMapper objectMapper; + @Autowired + private ResourceTestService resourceTestService; + + @Test + @SneakyThrows + void testAuthorityPreferenceToggle_when_authority_is_reverted_back_to_original_state() { + var srsId = "src_id_01"; + + // save version 1 of the authority + var v1Resource = new Resource() + .setId(1L) + .setDoc(objectMapper.readTree("{}")) + .setTypes(Set.of(ResourceTypeDictionary.PERSON)) + .setLabel("label_01") + .setFolioMetadata(new FolioMetadata().setSrsId(srsId)); + + resourceMarcAuthorityService.saveMarcAuthority(v1Resource); + + // save version 2 of the authority + var v2Resource = new Resource() + .setId(2L) + .setDoc(v1Resource.getDoc()) + .setTypes(v1Resource.getTypes()) + .setLabel(v1Resource.getLabel()) + .setFolioMetadata(v1Resource.getFolioMetadata()); + + resourceMarcAuthorityService.saveMarcAuthority(v2Resource); + + var v1ResourceFromDb = resourceTestService.getResourceById("1", 1); + var v2ResourceFromDb = resourceTestService.getResourceById("2", 1); + assertResourceIsPreferred(v2ResourceFromDb); + assertResourceIsNotPreferred(v1ResourceFromDb); + assertReplacedBy(v1ResourceFromDb, v2ResourceFromDb); + + // Revert the authority back to the original (v1) version + resourceMarcAuthorityService.saveMarcAuthority(v1Resource); + + v1ResourceFromDb = resourceTestService.getResourceById("1", 1); + v2ResourceFromDb = resourceTestService.getResourceById("2", 1); + assertResourceIsPreferred(v1ResourceFromDb); + assertResourceIsNotPreferred(v2ResourceFromDb); + assertReplacedBy(v2ResourceFromDb, v1ResourceFromDb); + } + + private void assertResourceIsPreferred(org.folio.linked.data.model.entity.Resource resource) { + assertThat(resource.isActive()).isTrue(); + assertThat(isPreferred(resource)).isTrue(); + assertThat(resource.getOutgoingEdges()).isEmpty(); + } + + private void assertResourceIsNotPreferred(org.folio.linked.data.model.entity.Resource resource) { + assertThat(resource.isActive()).isFalse(); + assertThat(isPreferred(resource)).isFalse(); + } + + private void assertReplacedBy(org.folio.linked.data.model.entity.Resource resource, + org.folio.linked.data.model.entity.Resource replacedBy) { + assertThat(resource.getOutgoingEdges()).hasSize(1); + assertThat(resource.getOutgoingEdges()).allMatch( + edge -> edge.getPredicate().getUri().equals(REPLACED_BY.getUri()) && edge.getTarget().equals(replacedBy) + ); + } +}