Skip to content

Commit

Permalink
#6752 add validator to test for empty DS
Browse files Browse the repository at this point in the history
  • Loading branch information
sekmiller committed Sep 3, 2021
1 parent 2225313 commit 60e7209
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 6 deletions.
10 changes: 10 additions & 0 deletions scripts/search/tests/data/emptyDataset.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"datasetVersion": {
"metadataBlocks": {
"citation": {
"fields": [
]
}
}
}
}
15 changes: 14 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
@Table(indexes = {@Index(columnList="dataset_id")},
uniqueConstraints = @UniqueConstraint(columnNames = {"dataset_id,versionnumber,minorversionnumber"}))
@ValidateVersionNote(versionNote = "versionNote", versionState = "versionState")
@ValidateDatasetVersion
public class DatasetVersion implements Serializable {

private static final Logger logger = Logger.getLogger(DatasetVersion.class.getCanonicalName());
Expand Down Expand Up @@ -1616,6 +1617,18 @@ public Set<ConstraintViolation> validate() {

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

Set<ConstraintViolation<DatasetVersion>> constraintViolationsdsv = validator.validate(this);
//Validating that the dataset version has fields at all
//should only be an issue for uploaded datasets
if(!constraintViolationsdsv.isEmpty()){
for (ConstraintViolation<DatasetVersion> constraintViolation : constraintViolationsdsv) {
returnSet.add(constraintViolation);
break; // currently only support one message, so we can break out of the loop after the first constraint violation
}
return returnSet;
}

for (DatasetField dsf : this.getFlatDatasetFields()) {
dsf.setValidationMessage(null); // clear out any existing validation message
Set<ConstraintViolation<DatasetField>> constraintViolations = validator.validate(dsf);
Expand Down Expand Up @@ -1959,5 +1972,5 @@ public String getJsonLd() {
public String getLocaleLastUpdateTime() {
return DateUtil.formatDate(new Timestamp(lastUpdateTime.getTime()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package edu.harvard.iq.dataverse;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
*
* @author skraffmi
*/
public class DatasetVersionValidator implements ConstraintValidator<ValidateDatasetVersion, DatasetVersion> {

@Override
public void initialize(final ValidateDatasetVersion constraintAnnotation) {

}

@Override
public boolean isValid(DatasetVersion t, ConstraintValidatorContext cvc) {
return isHasDatasetFields(t, null);
}

public static boolean isHasDatasetFields(DatasetVersion t, ConstraintValidatorContext context) {
return !t.getFlatDatasetFields().isEmpty();
}
}
32 changes: 32 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/ValidateDatasetVersion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package edu.harvard.iq.dataverse;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;
/**
*
* @author skraffmi
*/
@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = {DatasetVersionValidator.class})
@Documented
public @interface ValidateDatasetVersion {
String message() default "Failed Validation Dataset Version";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

}
9 changes: 7 additions & 2 deletions src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetFieldType;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.DatasetVersionValidator;
import edu.harvard.iq.dataverse.Dataverse;
import edu.harvard.iq.dataverse.DataverseFacet;
import edu.harvard.iq.dataverse.DataverseContact;
Expand Down Expand Up @@ -241,18 +242,22 @@ public Response createDataset(String jsonBody, @PathParam("identifier") String p
ds.setOwner(owner);

if (ds.getVersions().isEmpty()) {
return badRequest("Please provide initial version in the dataset json");
return badRequest(BundleUtil.getStringFromBundle("dataverses.api.create.dataset.error.mustIncludeVersion"));
}

if (!ds.getFiles().isEmpty() && !u.isSuperuser()){
return badRequest("Only a superuser may add files via this api");
return badRequest(BundleUtil.getStringFromBundle("dataverses.api.create.dataset.error.superuserFiles"));
}

// clean possible version metadata
DatasetVersion version = ds.getVersions().get(0);
version.setMinorVersionNumber(null);
version.setVersionNumber(null);
version.setVersionState(DatasetVersion.VersionState.DRAFT);

if (!DatasetVersionValidator.isHasDatasetFields(version, null)){
return badRequest(BundleUtil.getStringFromBundle("dataverses.api.create.dataset.error.mustIncludeFields"));
}

ds.setAuthority(null);
ds.setIdentifier(null);
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/propertyFiles/Bundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2406,6 +2406,9 @@ dataverses.api.move.dataverse.error.metadataBlock=Dataverse metadata block is no
dataverses.api.move.dataverse.error.dataverseLink=Dataverse is linked to target dataverse or one of its parents.
dataverses.api.move.dataverse.error.datasetLink=Dataset is linked to target dataverse or one of its parents.
dataverses.api.move.dataverse.error.forceMove=Please use the parameter ?forceMove=true to complete the move. This will remove anything from the dataverse that is not compatible with the target dataverse.
dataverses.api.create.dataset.error.mustIncludeFields=Dataset must include fields
dataverses.api.create.dataset.error.mustIncludeVersion=Please provide initial version in the dataset json
dataverses.api.create.dataset.error.superuserFiles=Only a superuser may add files via this api

#Access.java
access.api.allowRequests.failure.noDataset=Could not find Dataset with id: {0}
Expand Down
22 changes: 22 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,28 @@ public void testAddUpdateDatasetViaNativeAPI() {
publishDataset = UtilIT.publishDatasetViaNativeApi(datasetPersistentId, "major", apiToken);
//"Delete metadata failed: " + updateField.getDatasetFieldType().getDisplayName() + ": " + displayValue + " not found."
}

@Test
public void testAddEmptyDatasetViaNativeAPI() {

Response createUser = UtilIT.createRandomUser();
createUser.prettyPrint();
String username = UtilIT.getUsernameFromResponse(createUser);
String apiToken = UtilIT.getApiTokenFromResponse(createUser);

Response createDataverseResponse = UtilIT.createRandomDataverse(apiToken);
createDataverseResponse.prettyPrint();
String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse);

String pathToJsonFile = "scripts/search/tests/data/emptyDataset.json";
Response createDatasetResponse = UtilIT.createDatasetViaNativeApi(dataverseAlias, pathToJsonFile, apiToken);
createDatasetResponse.prettyPrint();

createDatasetResponse.then().assertThat()
.statusCode(BAD_REQUEST.getStatusCode())
.body("message", equalTo("Dataset must include fields"));

}

/**
* This test requires the root dataverse to be published to pass.
Expand Down
19 changes: 19 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,13 @@
import org.hamcrest.Matcher;
import static com.jayway.restassured.path.xml.XmlPath.from;
import static com.jayway.restassured.RestAssured.given;
import edu.harvard.iq.dataverse.DatasetField;
import edu.harvard.iq.dataverse.DatasetFieldConstant;
import edu.harvard.iq.dataverse.DatasetFieldType;
import edu.harvard.iq.dataverse.DatasetFieldValue;
import edu.harvard.iq.dataverse.util.StringUtil;
import java.io.StringReader;
import java.util.Collections;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
Expand Down Expand Up @@ -2667,4 +2672,18 @@ public static Response recreateDatasetJsonLD(String apiToken, String dataverseAl
.post("/api/dataverses/" + dataverseAlias +"/datasets");
return response;
}

public static DatasetField createTitleField(String value) {
return constructPrimitive(DatasetFieldConstant.title, value);
}

private static DatasetField constructPrimitive(String fieldName, String value) {
DatasetField field = new DatasetField();
field.setDatasetFieldType(
new DatasetFieldType(fieldName, DatasetFieldType.FieldType.TEXT, false));
field.setDatasetFieldValues(
Collections.singletonList(
new DatasetFieldValue(field, value)));
return field;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package edu.harvard.iq.dataverse.engine.command.impl;

import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetField;
import edu.harvard.iq.dataverse.DatasetServiceBean;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.DvObject;
import edu.harvard.iq.dataverse.api.UtilIT;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.mocks.MocksFactory;
import static edu.harvard.iq.dataverse.mocks.MocksFactory.*;
import edu.harvard.iq.dataverse.engine.TestCommandContext;
import edu.harvard.iq.dataverse.engine.TestDataverseEngine;
import edu.harvard.iq.dataverse.engine.command.exception.IllegalCommandException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
Expand Down Expand Up @@ -42,10 +46,16 @@ public void testSimpleVersionAddition() throws Exception {
dsvInitial.setMinorVersionNumber(0l);
dsvInitial.setVersionNumber(1l);

List<DatasetField> fields = new ArrayList<>();
//adding title to pass new validation - fields required
fields.add(UtilIT.createTitleField("Title"));
dsvInitial.setDatasetFields(fields);

// Create version to be added
DatasetVersion dsvNew = new DatasetVersion();
dsvNew.setVersionState(DatasetVersion.VersionState.DRAFT);

dsvNew.setDatasetFields(fields);

// Execute
CreateDatasetVersionCommand sut = new CreateDatasetVersionCommand( makeRequest(), ds, dsvNew );

Expand Down Expand Up @@ -89,6 +99,8 @@ public DatasetServiceBean datasets() {

testEngine.submit(sut);
}




static class MockDatasetServiceBean extends DatasetServiceBean {
Expand All @@ -103,5 +115,5 @@ public DatasetVersion storeVersion(DatasetVersion dsv) {
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import edu.harvard.iq.dataverse.DataFile;
import edu.harvard.iq.dataverse.DataTable;
import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetField;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.FileMetadata;
import edu.harvard.iq.dataverse.api.UtilIT;
import edu.harvard.iq.dataverse.mocks.MocksFactory;
import static edu.harvard.iq.dataverse.mocks.MocksFactory.makeDataset;
import java.io.IOException;
Expand Down Expand Up @@ -565,7 +567,11 @@ public void testDirectoryLabels() {
fileMetadata.setLabel("foo.png");
fileMetadata.setDirectoryLabel("/has/leading/slash");
datasetVersion.getFileMetadatas().add(fileMetadata);

List<DatasetField> fields = new ArrayList<>();
//adding fields for validation
fields.add(UtilIT.createTitleField("Title"));
datasetVersion.setDatasetFields(fields);

//We are programmatically stripping of leading and trailing slashes
Set<ConstraintViolation> violations1 = datasetVersion.validate();
assertEquals(0, violations1.size());
Expand Down

0 comments on commit 60e7209

Please sign in to comment.