diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index 3be005a252d..437c42ba8b3 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -52,6 +52,8 @@ uniqueConstraints = @UniqueConstraint(columnNames = {"dataset_id,versionnumber,minorversionnumber"})) public class DatasetVersion implements Serializable { + private static final Logger logger = Logger.getLogger(DatasetVersion.class.getCanonicalName()); + /** * Convenience comparator to compare dataset versions by their version number. * The draft version is considered the latest. @@ -1034,6 +1036,26 @@ public Set validate() { } } } + List dsvfileMetadatas = this.getFileMetadatas(); + if (dsvfileMetadatas != null) { + for (FileMetadata fileMetadata : dsvfileMetadatas) { + Set> constraintViolations = validator.validate(fileMetadata); + if (constraintViolations.size() > 0) { + // currently only support one message + ConstraintViolation violation = constraintViolations.iterator().next(); + /** + * @todo How can we expose this more detailed message + * containing the invalid value to the user? + */ + String message = "Constraint violation found in FileMetadata. " + + violation.getMessage() + " " + + "The invalid value is \"" + violation.getInvalidValue().toString() + "\"."; + logger.info(message); + returnSet.add(violation); + break; // currently only support one message, so we can break out of the loop after the first constraint violation + } + } + } return returnSet; } } diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetCommand.java index 25d2231708a..3a8973c7845 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetCommand.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetCommand.java @@ -100,6 +100,7 @@ public Dataset execute(CommandContext ctxt) throws CommandException { String validationFailedString = "Validation failed:"; for (ConstraintViolation constraintViolation : constraintViolations) { validationFailedString += " " + constraintViolation.getMessage(); + validationFailedString += " Invalid value: '" + constraintViolation.getInvalidValue() + "'."; } throw new IllegalCommandException(validationFailedString, this); } diff --git a/src/test/java/edu/harvard/iq/dataverse/api/FileMetadataIT.java b/src/test/java/edu/harvard/iq/dataverse/api/FileMetadataIT.java index 8f243451c68..3f279de4c2f 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/FileMetadataIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/FileMetadataIT.java @@ -32,8 +32,10 @@ import java.util.UUID; import static com.jayway.restassured.RestAssured.given; +import static javax.ws.rs.core.Response.Status.BAD_REQUEST; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.fail; +import static org.hamcrest.CoreMatchers.equalTo; /** * FileMetadata Integration Tests @@ -138,15 +140,18 @@ public void testJsonParserWithDirectoryLabels() { try { // try to create a dataset with directory labels that contain both leading and trailing file separators - Response resp = given() + Response shouldFailDueToLeadingAndTrailingSeparators = given() .header(keyString, token) .body(IOUtils.toString(classLoader.getResourceAsStream( "json/complete-dataset-with-files-invalid-directory-labels.json"))) .contentType("application/json") .post("/api/dataverses/" + testName + "/datasets"); - // this request should fail since a @Pattern constraint exists in FileMetadata to prevent this - assertEquals(resp.getStatusCode(), 500); - + shouldFailDueToLeadingAndTrailingSeparators.prettyPrint(); + shouldFailDueToLeadingAndTrailingSeparators.then().assertThat() + // Note that the JSON under test actually exercises leading too but only the first (trailing) is exercised here. + .body("message", equalTo("Validation failed: Directory Name cannot contain leading or trailing file separators. Invalid value: 'data/subdir1/'.")) + .statusCode(BAD_REQUEST.getStatusCode()); + // create dataset and set id dsId = given() .header(keyString, token) diff --git a/src/test/java/edu/harvard/iq/dataverse/ingest/IngestServiceBeanHelperTest.java b/src/test/java/edu/harvard/iq/dataverse/ingest/IngestServiceBeanHelperTest.java index 09d0b045b6c..20099d654fd 100644 --- a/src/test/java/edu/harvard/iq/dataverse/ingest/IngestServiceBeanHelperTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/ingest/IngestServiceBeanHelperTest.java @@ -20,6 +20,8 @@ import java.util.List; import static edu.harvard.iq.dataverse.mocks.MocksFactory.makeDataset; +import java.util.Set; +import javax.validation.ConstraintViolation; /** * Tests against IngestServiceBean helper methods. @@ -367,4 +369,40 @@ public void testCheckForDuplicateFileNamesTabular() throws Exception { assertEquals(file2NameAltered, true); } + @Test + public void testDirectoryLabels() { + + DatasetVersion datasetVersion = new DatasetVersion(); + FileMetadata fileMetadata = new FileMetadata(); + fileMetadata.setLabel("foo.png"); + fileMetadata.setDirectoryLabel("/has/leading/slash"); + datasetVersion.getFileMetadatas().add(fileMetadata); + + Set violations1 = datasetVersion.validate(); + assertEquals(1, violations1.size()); + ConstraintViolation violation1 = violations1.iterator().next(); + assertEquals("Directory Name cannot contain leading or trailing file separators.", violation1.getMessage()); + + // reset + datasetVersion.setFileMetadatas(new ArrayList<>()); + Set violations2 = datasetVersion.validate(); + assertEquals(0, violations2.size()); + + fileMetadata.setDirectoryLabel("has/trailing/slash/"); + datasetVersion.getFileMetadatas().add(fileMetadata); + Set violations3 = datasetVersion.validate(); + assertEquals(1, violations3.size()); + assertEquals("Directory Name cannot contain leading or trailing file separators.", violations3.iterator().next().getMessage()); + + // reset + datasetVersion.setFileMetadatas(new ArrayList<>()); + Set violations4 = datasetVersion.validate(); + assertEquals(0, violations4.size()); + + fileMetadata.setDirectoryLabel("just/right"); + datasetVersion.getFileMetadatas().add(fileMetadata); + Set violations5 = datasetVersion.validate(); + assertEquals(0, violations5.size()); + } + }