From 0efb26424c9fc67a921625a05bca1dcf60026c6c Mon Sep 17 00:00:00 2001 From: Jan van Mansum Date: Mon, 9 Dec 2024 11:04:32 +0100 Subject: [PATCH] Started implementing tests for the sword examples. --- pom.xml | 22 +++- .../core/dansbag/DansConversionFixture.java | 111 ++++++++++++++++++ .../dansbag/DansDepositConverterTest.java | 27 ++++- 3 files changed, 154 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 8303407..b80ce15 100644 --- a/pom.xml +++ b/pom.xml @@ -37,10 +37,11 @@ nl.knaw.dans.dvingest.DdDataverseIngestApplication 0.2.0 1.0.0 + 1.0.0 - scm:git:ssh://github.com/DANS-KNAW/dd-dataverse-ingest + scm:git:ssh://github.com/DANS-KNAW/${project.artifactId} HEAD @@ -216,6 +217,7 @@ maven-dependency-plugin + compile-dependencies initialize unpack @@ -237,6 +239,24 @@ + + test-dependencies + generate-test-resources + + unpack + + + + + nl.knaw.dans + dd-dans-sword2-examples + ${dd-dans-sword2-examples.version} + ${project.build.directory}/test + example-bags/** + + + + diff --git a/src/test/java/nl/knaw/dans/dvingest/core/dansbag/DansConversionFixture.java b/src/test/java/nl/knaw/dans/dvingest/core/dansbag/DansConversionFixture.java index 366319f..a41a6eb 100644 --- a/src/test/java/nl/knaw/dans/dvingest/core/dansbag/DansConversionFixture.java +++ b/src/test/java/nl/knaw/dans/dvingest/core/dansbag/DansConversionFixture.java @@ -23,7 +23,13 @@ import nl.knaw.dans.dvingest.core.dansbag.xml.XmlReader; import nl.knaw.dans.dvingest.core.dansbag.xml.XmlReaderImpl; import nl.knaw.dans.dvingest.core.service.DataverseService; +import nl.knaw.dans.lib.dataverse.model.dataset.CompoundMultiValueField; +import nl.knaw.dans.lib.dataverse.model.dataset.ControlledMultiValueField; +import nl.knaw.dans.lib.dataverse.model.dataset.ControlledSingleValueField; import nl.knaw.dans.lib.dataverse.model.dataset.License; +import nl.knaw.dans.lib.dataverse.model.dataset.MetadataField; +import nl.knaw.dans.lib.dataverse.model.dataset.PrimitiveMultiValueField; +import nl.knaw.dans.lib.dataverse.model.dataset.PrimitiveSingleValueField; import nl.knaw.dans.lib.util.MappingLoader; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.BeforeEach; @@ -31,13 +37,23 @@ import java.net.URI; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Set; import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; public abstract class DansConversionFixture extends TestDirFixture { protected final DataverseService dataverseServiceMock = Mockito.mock(DataverseService.class); @@ -81,4 +97,99 @@ private Map licenses(String... uri) { } return licenses; } + + protected Path createValidDeposit(String validExample, String depositDir) throws Exception { + var deposit = testDir.resolve(depositDir); + Files.createDirectory(deposit); + // Create deposit.properties + var props = new Properties(); + props.setProperty("state.label", "SUBMITTED"); + props.setProperty("state.description", "Deposit is submitted"); + props.setProperty("deposit.origin", "SWORD"); + props.setProperty("creation.timestamp", DateTimeFormatter.ISO_INSTANT + .withZone(ZoneId.of("UTC")) + .format(Instant.now())); + props.setProperty("depositor.userId", "jdoe"); + try (var out = Files.newBufferedWriter(deposit.resolve("deposit.properties"))) { + props.store(out, null); + } + FileUtils.copyDirectoryToDirectory(Paths.get("target/test/example-bags/valid").resolve(validExample).toFile(), deposit.toFile()); + return deposit; + } + + protected void assertPrimitiveSinglevalueFieldContainsValue(List fields, String typeName, String value) { + assertThat(fields) + .filteredOn(f -> typeName.equals(f.getTypeName())) + .map(f -> (PrimitiveSingleValueField) f).extracting(PrimitiveSingleValueField::getValue) + .containsExactly(value); + } + + protected void assertPrimitiveMultiValueFieldContainsValues(List fields, String typeName, String... values) { + assertThat(fields) + .filteredOn(f -> typeName.equals(f.getTypeName())) + .map(f -> (PrimitiveMultiValueField) f).extracting(PrimitiveMultiValueField::getValue) + .containsExactly(List.of(values)); + } + + protected void assertControlledSingleValueFieldContainsValue(List fields, String typeName, String value) { + assertThat(fields) + .filteredOn(f -> typeName.equals(f.getTypeName())) + .map(f -> (ControlledSingleValueField) f).extracting(ControlledSingleValueField::getValue) + .containsExactly(value); + } + + protected void assertControlledMultiValueFieldContainsValues(List fields, String typeName, String... values) { + assertThat(fields) + .filteredOn(f -> typeName.equals(f.getTypeName())) + .map(f -> (ControlledMultiValueField) f).extracting(ControlledMultiValueField::getValue) + .containsExactly(List.of(values)); + } + + protected void assertCompoundMultiValueFieldContainsValues(List fields, String typeName, List> expectedValues) { + var filteredFields = fields.stream() + .filter(f -> typeName.equals(f.getTypeName())) + .map(f -> (CompoundMultiValueField) f) + .toList(); + + assertThat(filteredFields).as("Field not found: " + typeName).isNotEmpty(); + assertThat(filteredFields).as("Field appearing more than once: " + typeName).hasSize(1); + + var actualValues = filteredFields.get(0).getValue(); + assertThat(actualValues).as("Different number of actual and expected values: " + actualValues.size() + " vs " + expectedValues.size()).hasSize(expectedValues.size()); + + List> actualValuesList = new ArrayList<>(); + for (var actualValue : actualValues) { + var actualValueMap = actualValue.entrySet().stream() + .map(e -> Map.entry(e.getKey(), e.getValue().getValue())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + actualValuesList.add(actualValueMap); + } + + assertThat(actualValuesList).containsExactlyInAnyOrderElementsOf(expectedValues); + + } + + @SafeVarargs + protected final void assertCompoundMultiValueFieldContainsValues2(List fields, String typeName, Map... expectedValues) { + var filteredFields = fields.stream() + .filter(f -> typeName.equals(f.getTypeName())) + .map(f -> (CompoundMultiValueField) f) + .toList(); + + assertThat(filteredFields).as("Field not found: " + typeName).isNotEmpty(); + assertThat(filteredFields).as("Field appearing more than once: " + typeName).hasSize(1); + + var actualValues = filteredFields.get(0).getValue(); + assertThat(actualValues).as("Different number of actual and expected values: " + actualValues.size() + " vs " + expectedValues.length).hasSize(expectedValues.length); + + List> actualValuesList = new ArrayList<>(); + for (var actualValue : actualValues) { + var actualValueMap = actualValue.entrySet().stream() + .map(e -> Map.entry(e.getKey(), e.getValue().getValue())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + actualValuesList.add(actualValueMap); + } + + assertThat(actualValuesList).containsExactlyInAnyOrderElementsOf(List.of(expectedValues)); + } } diff --git a/src/test/java/nl/knaw/dans/dvingest/core/dansbag/DansDepositConverterTest.java b/src/test/java/nl/knaw/dans/dvingest/core/dansbag/DansDepositConverterTest.java index 9b1f370..236ead9 100644 --- a/src/test/java/nl/knaw/dans/dvingest/core/dansbag/DansDepositConverterTest.java +++ b/src/test/java/nl/knaw/dans/dvingest/core/dansbag/DansDepositConverterTest.java @@ -17,12 +17,13 @@ import nl.knaw.dans.dvingest.core.service.YamlService; import nl.knaw.dans.dvingest.core.service.YamlServiceImpl; +import nl.knaw.dans.lib.dataverse.model.dataset.Dataset; import nl.knaw.dans.lib.dataverse.model.user.AuthenticatedUser; -import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import java.nio.file.Paths; +import java.util.List; +import java.util.Map; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; @@ -34,20 +35,36 @@ public class DansDepositConverterTest extends DansConversionFixture { @Test public void run_converts_dans_sword_all_mappings_example_to_dataverse_ingest_deposit() throws Exception { // Given - FileUtils.copyDirectoryToDirectory(Paths.get("src/test/resources/unit-test/d0919038-9866-49e8-986a-bcef54ae7566").toFile(), testDir.toFile()); - var depositDir = testDir.resolve("d0919038-9866-49e8-986a-bcef54ae7566"); - var deposit = dansBagDepositReader.readDeposit(depositDir); + var depositDir = createValidDeposit("all-mappings", "00000000-0000-0000-0000-000000000001"); var authenticatedUser = new AuthenticatedUser(); authenticatedUser.setFirstName("John"); authenticatedUser.setLastName("Doe"); authenticatedUser.setEmail("jdoe@foo.com"); + authenticatedUser.setDisplayName("John Doe"); Mockito.when(dataverseServiceMock.getUserById(Mockito.anyString())).thenReturn(Optional.of(authenticatedUser)); + var deposit = dansBagDepositReader.readDeposit(depositDir); // When new DansDepositConverter(deposit, null, mappingService, yamlService).run(); // Then assertThat(deposit.getBagDir().resolve("dataset.yml")).exists(); + var datasetYml = yamlService.readYaml(deposit.getBagDir().resolve("dataset.yml"), Dataset.class); + var citationBlockFields = datasetYml.getDatasetVersion().getMetadataBlocks().get("citation").getFields(); + // Find the metadata field with property typeName = "title" + assertPrimitiveSinglevalueFieldContainsValue(citationBlockFields, "title", "A bag containing examples for each mapping rule"); + assertPrimitiveMultiValueFieldContainsValues(citationBlockFields, "alternativeTitle", "DCTERMS title 1"); + assertCompoundMultiValueFieldContainsValues2(citationBlockFields, "datasetContact", Map.of( + "datasetContactName", "John Doe", + "datasetContactEmail", "jdoe@foo.com" + )); + assertCompoundMultiValueFieldContainsValues2(citationBlockFields, "otherId", + Map.of("otherIdAgency", "", "otherIdValue", "DCTERMS_ID001"), + Map.of("otherIdAgency", "", "otherIdValue", "DC_ID002"), + Map.of("otherIdAgency", "", "otherIdValue", "DCTERMS_ID003"), + Map.of("otherIdAgency", "TESTPREFIX", "otherIdValue", "1234")); + + } }