diff --git a/doc/sphinx-guides/source/_static/api/dataverse-complete.json b/doc/sphinx-guides/source/_static/api/dataverse-complete.json new file mode 100644 index 00000000000..d5e92d1f1fc --- /dev/null +++ b/doc/sphinx-guides/source/_static/api/dataverse-complete.json @@ -0,0 +1,15 @@ +{ + "name": "Scientific Research", + "alias": "science", + "dataverseContacts": [ + { + "contactEmail": "pi@example.edu" + }, + { + "contactEmail": "student@example.edu" + } + ], + "affiliation": "Scientific Research University", + "description": "We do all the science.", + "dataverseType": "LABORATORY" +} diff --git a/doc/sphinx-guides/source/_static/api/dataverse-minimal.json b/doc/sphinx-guides/source/_static/api/dataverse-minimal.json new file mode 100644 index 00000000000..10086749825 --- /dev/null +++ b/doc/sphinx-guides/source/_static/api/dataverse-minimal.json @@ -0,0 +1,9 @@ +{ + "name": "Scientific Research", + "alias": "science", + "dataverseContacts": [ + { + "contactEmail": "pi@example.edu" + } + ] +} diff --git a/doc/sphinx-guides/source/_static/installation/files/etc/maintenance/HarvardShield_RGB.png b/doc/sphinx-guides/source/_static/installation/files/etc/maintenance/HarvardShield_RGB.png new file mode 100644 index 00000000000..f8fd03c2aa8 Binary files /dev/null and b/doc/sphinx-guides/source/_static/installation/files/etc/maintenance/HarvardShield_RGB.png differ diff --git a/doc/sphinx-guides/source/_static/installation/files/etc/maintenance/maintenance.xhtml b/doc/sphinx-guides/source/_static/installation/files/etc/maintenance/maintenance.xhtml new file mode 100644 index 00000000000..78b6100c9eb --- /dev/null +++ b/doc/sphinx-guides/source/_static/installation/files/etc/maintenance/maintenance.xhtml @@ -0,0 +1,118 @@ + + + + + Harvard Dataverse + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Harvard Dataverse +
+
+ A collaboration with Harvard Library, Harvard University IT, and IQSS +
+
+
+
+
+
+

We apologize for the service interruption.

+

The Harvard Dataverse is currently undergoing maintenance. At this time both the application and APIs are not able to be used. However, the datasets stored in the Harvard Dataverse are fine and not impacted by this maintenance.

+

If you have any comments, questions or concerns, please reach out to support@dataverse.org.

+
+
+ + + diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 16da2e4c6dc..cee78e37896 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -12,11 +12,24 @@ Endpoints Dataverses ~~~~~~~~~~~ -Generates a new dataverse under ``$id``. Expects a json content describing the dataverse. +Generates a new dataverse under ``$id``. Expects a JSON content describing the dataverse, as in the example below. If ``$id`` is omitted, a root dataverse is created. ``$id`` can either be a dataverse id (long) or a dataverse alias (more robust). :: POST http://$SERVER/api/dataverses/$id?key=$apiKey +The following JSON example can be `downloaded <../_static/api/dataverse-complete.json>`_ and modified to create dataverses to suit your needs. The fields ``name``, ``alias``, and ``dataverseContacts`` are required. The controlled vocabulary for ``dataverseType`` is + +- ``JOURNALS`` +- ``LABORATORY`` +- ``ORGANIZATIONS_INSTITUTIONS`` +- ``RESEARCHERS`` +- ``RESEARCH_GROUP`` +- ``RESEARCH_PROJECTS`` +- ``TEACHING_COURSES`` +- ``UNCATEGORIZED`` + +.. literalinclude:: ../_static/api/dataverse-complete.json + View data about the dataverse identified by ``$id``. ``$id`` can be the id number of the dataverse, its alias, or the special value ``:root``. :: GET http://$SERVER/api/dataverses/$id diff --git a/doc/sphinx-guides/source/installation/administration.rst b/doc/sphinx-guides/source/installation/administration.rst index 59cf11652a3..b2f908bd8f1 100644 --- a/doc/sphinx-guides/source/installation/administration.rst +++ b/doc/sphinx-guides/source/installation/administration.rst @@ -67,6 +67,13 @@ https://github.com/IQSS/dataverse/issues/2595 contains some information on enabl There is a database table called ``actionlogrecord`` that captures events that may be of interest. See https://github.com/IQSS/dataverse/issues/2729 for more discussion around this table. +Maintenance +---------- + +When you have scheduled down time for your production servers, we provide a `sample maintenance page <../_static/installation/files/etc/maintenance/maintenance.xhtml>`_ for you to use. To download, right-click and select "Save Link As". + +The maintenance page is intended to be a static page served by Apache to provide users with a nicer, more informative experience when the site is unavailable. + User Administration ------------------- diff --git a/doc/sphinx-guides/source/user/dataverse-management.rst b/doc/sphinx-guides/source/user/dataverse-management.rst index bac42305119..b3a1d7e95f1 100755 --- a/doc/sphinx-guides/source/user/dataverse-management.rst +++ b/doc/sphinx-guides/source/user/dataverse-management.rst @@ -12,7 +12,7 @@ to manage the settings described in this guide. Create a Dataverse (Within the "Root" Dataverse) =================================================== -Creating a dataverse is easy but first you must be a registered user (see Create Account). +Creating a dataverse is easy but first you must be a registered user (see :doc:`/user/account`). #. Once you are logged in click on the "Add Data" button and in the dropdown menu select "New Dataverse". #. Once on the "New Dataverse" page fill in the following fields: @@ -22,7 +22,7 @@ Creating a dataverse is easy but first you must be a registered user (see Create * **Affiliation**: Add any Affiliation that can be associated to this particular dataverse (e.g., project name, institute name, department name, journal name, etc). This is automatically filled out if you have added an affiliation for your user account. * **Description**: Provide a description of this dataverse. This will display on the home page of your dataverse and in the search result list. The description field supports certain HTML tags (, ,
,
, , ,
,
,
, ,
,

-

, , , ,
  • ,
      ,

      ,

      , , , , , , 
        ). * **Category**: Select a category that best describes the type of dataverse this will be. For example, if this is a dataverse for an individual researcher's datasets, select Researcher. If this is a dataverse for an institution, select Organization & Institution. - * **Choose the sets of Metadata Elements for datasets in this dataverse**: by default the metadata elements will be from the host dataverse that this new dataverse is created in. Dataverse offers metadata standards for multiple domains. To learn more about the metadata standards in Dataverse please check out the appendix (insert link here) + * **Choose the sets of Metadata Elements for datasets in this dataverse**: by default the metadata elements will be from the host dataverse that this new dataverse is created in. Dataverse offers metadata standards for multiple domains. To learn more about the metadata standards in Dataverse please check out the :doc:`/user/appendix`. * **Select facets for this dataverse**: by default the facets that will appear on your dataverse landing page will be from the host dataverse that this new dataverse was created in. The facets are simply metadata fields that can be used to help others easily find dataverses and datasets within this dataverse. You can select as many facets as you would like. #. Selected metadata elements are also used to pick which metadata fields you would like to use for creating templates for your datasets. Metadata fields can be hidden, or selected as required or optional. Once you have selected all the fields you would like to use, you can create your template(s) after you finish creating your dataverse. #. Click "Create Dataverse" button and you're done! @@ -92,19 +92,24 @@ Permissions When you access a dataverse's permissions page, you will see there are three sections: Permissions, Users/Groups, and Roles. |image2| + Clicking on Permissions will bring you to this page: + |image3| + By clicking on the Edit Access button, you are able to change the settings allowing no one or anyone to add either dataverses or datasets to a dataverse. + |image4| + The Edit Access pop up allows you to also select if someone adding a dataset to this dataverse should be allowed to publish it (Curator role) or if the dataset will be submitted to the administrator of this dataverse to be reviewed then published (Contributor role). These Access settings can be changed at any time. Assign Role ----------------------- -You can also give access to a Dataverse user to allow them to access an unpublished dataverse as well as other roles. To do this, click on the Assign Roles to Users/Groups button in the Users/Groups section. You can also give multiple users the same role at one time. +You can also give access to a Dataverse user to allow them to access an unpublished dataverse as well as other roles. To do this, click on the Assign Roles to Users/Groups button in the Users/Groups section. You can also give multiple users the same role at one time. This roles can be removed at any time. + |image5| -|image6| -This roles can be removed at any time. +|image6| .. _dataset-templates: @@ -176,10 +181,15 @@ is made public, it can no longer be unpublished. .. |image1| image:: ./img/Dataverse-Diagram.png .. |image2| image:: ./img/dvperms1.png + :class: img-responsive .. |image3| image:: ./img/dv2.png + :class: img-responsive .. |image4| image:: ./img/dv3.png + :class: img-responsive .. |image5| image:: ./img/dv4.png + :class: img-responsive .. |image6| image:: ./img/dv5.png + :class: img-responsive diff --git a/scripts/installer/install b/scripts/installer/install index 071b8e7558b..1c0289feb21 100755 --- a/scripts/installer/install +++ b/scripts/installer/install @@ -807,7 +807,7 @@ else print TMPCMD $sql_command; close TMPCMD; - my $psql_commandline = $psql_exec . "/psql -h " . $CONFIG_DEFAULTS{'POSTGRES_SERVER'} . " -U postgres -d postgres -f /tmp/pgcmd.$$.tmp >/dev/null 2>&1"; + my $psql_commandline = $psql_admin_exec . "/psql -h " . $CONFIG_DEFAULTS{'POSTGRES_SERVER'} . " -U postgres -d postgres -f /tmp/pgcmd.$$.tmp >/dev/null 2>&1"; my $out = qx($psql_commandline 2>&1); my $exitcode = $?; @@ -829,8 +829,8 @@ else print "\nCreating Postgres database:\n"; my $psql_command = - $psql_admin_exec - . "/createdb -h " . $CONFIG_DEFAULTS{'POSTGRES_SERVER'} . " -U postgres " + $psql_exec + . "/createdb -h " . $CONFIG_DEFAULTS{'POSTGRES_SERVER'} . " -U $CONFIG_DEFAULTS{'POSTGRES_USER'} " . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} . " --owner=" . $CONFIG_DEFAULTS{'POSTGRES_USER'}; diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java b/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java index 8c495b65a0b..9a71ae7c4c9 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java @@ -130,6 +130,25 @@ public Response addDataverse( String body, @PathParam("identifier") String paren d = execCommand( new CreateDataverseCommand(d, createDataverseRequest(u), null, null) ); return createdResponse( "/dataverses/"+d.getAlias(), json(d) ); } catch ( WrappedResponse ww ) { + Throwable cause = ww.getCause(); + StringBuilder sb = new StringBuilder(); + while (cause.getCause() != null) { + cause = cause.getCause(); + if (cause instanceof ConstraintViolationException) { + ConstraintViolationException constraintViolationException = (ConstraintViolationException) cause; + for (ConstraintViolation violation : constraintViolationException.getConstraintViolations()) { + sb.append(" Invalid value: <<<").append(violation.getInvalidValue()).append(">>> for ") + .append(violation.getPropertyPath()).append(" at ") + .append(violation.getLeafBean()).append(" - ") + .append(violation.getMessage()); + } + } + } + String error = sb.toString(); + if (!error.isEmpty()) { + LOGGER.log(Level.INFO, error); + return ww.refineResponse(error); + } return ww.getResponse(); } catch (EJBException ex) { diff --git a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java index ce9b66c81b5..dde1d63bd0e 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java @@ -78,6 +78,13 @@ public void setLenient(boolean lenient) { public Dataverse parseDataverse(JsonObject jobj) throws JsonParseException { Dataverse dv = new Dataverse(); + /** + * @todo Instead of this getMandatoryString method we should run the + * String through ConstraintValidator. See EMailValidatorTest and + * EMailValidator for examples. That way we can check not only if it's + * required or not but other bean validation rules such as "must match + * this regex". + */ dv.setAlias(getMandatoryString(jobj, "alias")); dv.setName(getMandatoryString(jobj, "name")); dv.setDescription(jobj.getString("description", null)); @@ -102,7 +109,16 @@ public Dataverse parseDataverse(JsonObject jobj) throws JsonParseException { dv.setDataverseTheme(theme); theme.setDataverse(dv); } - + + dv.setDataverseType(Dataverse.DataverseType.UNCATEGORIZED); // default + if (jobj.containsKey("dataverseType")) { + for (Dataverse.DataverseType dvtype : Dataverse.DataverseType.values()) { + if (dvtype.name().equals(jobj.getString("dataverseType"))) { + dv.setDataverseType(dvtype); + } + } + } + /* We decided that subject is not user set, but gotten from the subject of the dataverse's datasets - leavig this code in for now, in case we need to go back to it at some point diff --git a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java index 5a2c1575f98..d006a74ef8c 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java @@ -173,40 +173,42 @@ public static JsonArrayBuilder rolesToJson( List role ) { } return bld; } - - public static JsonObjectBuilder json( DataverseRole role ) { - JsonObjectBuilder bld = jsonObjectBuilder() - .add("alias", role.getAlias()) - .add("name", role.getName()) - .add("permissions", json(role.permissions())) - .add("description", role.getDescription()); - if ( role.getId() != null ) bld.add("id", role.getId() ); - if ( role.getOwner()!=null && role.getOwner().getId()!=null ) bld.add("ownerId", role.getOwner().getId()); - - return bld; - } - - public static JsonObjectBuilder json( Dataverse dv ) { - JsonObjectBuilder bld = jsonObjectBuilder() - .add("id", dv.getId() ) - .add("alias", dv.getAlias()) - .add("name", dv.getName()) - .add("affiliation", dv.getAffiliation()) - .add("dataverseContacts", json(dv.getDataverseContacts())) - .add("permissionRoot", dv.isPermissionRoot()) - .add("description", dv.getDescription()); - if ( dv.getOwner() != null ) { - bld.add("ownerId", dv.getOwner().getId()); - } - if ( dv.getCreateDate() != null ) { - bld.add("creationDate", Util.getDateTimeFormat().format(dv.getCreateDate())); - } - if ( dv.getCreator() != null ) { - bld.add("creator",json(dv.getCreator())); - } - - return bld; - } + + public static JsonObjectBuilder json(DataverseRole role) { + JsonObjectBuilder bld = jsonObjectBuilder() + .add("alias", role.getAlias()) + .add("name", role.getName()) + .add("permissions", json(role.permissions())) + .add("description", role.getDescription()); + if (role.getId() != null) { + bld.add("id", role.getId()); + } + if (role.getOwner() != null && role.getOwner().getId() != null) { + bld.add("ownerId", role.getOwner().getId()); + } + return bld; + } + + public static JsonObjectBuilder json(Dataverse dv) { + JsonObjectBuilder bld = jsonObjectBuilder() + .add("id", dv.getId()) + .add("alias", dv.getAlias()) + .add("name", dv.getName()) + .add("affiliation", dv.getAffiliation()) + .add("dataverseContacts", json(dv.getDataverseContacts())) + .add("permissionRoot", dv.isPermissionRoot()) + .add("description", dv.getDescription()); + if (dv.getOwner() != null) { + bld.add("ownerId", dv.getOwner().getId()); + } + if (dv.getCreateDate() != null) { + bld.add("creationDate", Util.getDateTimeFormat().format(dv.getCreateDate())); + } + if (dv.getCreator() != null) { + bld.add("creator", json(dv.getCreator())); + } + return bld; + } public static JsonArrayBuilder json(List dataverseContacts) { JsonArrayBuilder bld = Json.createArrayBuilder(); diff --git a/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java b/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java index 2d243e9bb50..9d4e82b125b 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java @@ -2,39 +2,39 @@ import com.jayway.restassured.RestAssured; import com.jayway.restassured.response.Response; +import edu.harvard.iq.dataverse.Dataverse; +import java.io.FileNotFoundException; +import java.io.FileReader; import java.util.logging.Logger; -import org.junit.AfterClass; +import javax.json.Json; +import javax.json.JsonObject; +import javax.ws.rs.core.Response.Status; +import static javax.ws.rs.core.Response.Status.CREATED; +import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; +import static javax.ws.rs.core.Response.Status.OK; import org.junit.BeforeClass; import org.junit.Test; import static junit.framework.Assert.assertEquals; +import static org.hamcrest.CoreMatchers.equalTo; public class DataversesIT { private static final Logger logger = Logger.getLogger(DataversesIT.class.getCanonicalName()); - private static String username1; - private static String apiToken1; - private static String dataverseAlias1; - private static String dataverseAlias2; - @BeforeClass public static void setUpClass() { - RestAssured.baseURI = UtilIT.getRestAssuredBaseUri(); - - Response createUserResponse = UtilIT.createRandomUser(); -// createUserResponse.prettyPrint(); - assertEquals(200, createUserResponse.getStatusCode()); - - apiToken1 = UtilIT.getApiTokenFromResponse(createUserResponse); - username1 = UtilIT.getUsernameFromResponse(createUserResponse); - } @Test public void testAttemptToCreateDuplicateAlias() throws Exception { - Response createDataverse1Response = UtilIT.createRandomDataverse(apiToken1); + Response createUser = UtilIT.createRandomUser(); +// createUser.prettyPrint(); + String username = UtilIT.getUsernameFromResponse(createUser); + String apiToken = UtilIT.getApiTokenFromResponse(createUser); + + Response createDataverse1Response = UtilIT.createRandomDataverse(apiToken); if (createDataverse1Response.getStatusCode() != 201) { // purposefully using println here to the error shows under "Test Results" in Netbeans System.out.println("A workspace for testing (a dataverse) couldn't be created in the root dataverse. The output was:\n\n" + createDataverse1Response.body().asString()); @@ -44,37 +44,96 @@ public void testAttemptToCreateDuplicateAlias() throws Exception { } assertEquals(201, createDataverse1Response.getStatusCode()); - dataverseAlias1 = UtilIT.getAliasFromResponse(createDataverse1Response); - dataverseAlias2 = dataverseAlias1.toUpperCase(); + String dataverseAlias1 = UtilIT.getAliasFromResponse(createDataverse1Response); + String dataverseAlias2 = dataverseAlias1.toUpperCase(); logger.info("Attempting to creating dataverse with alias '" + dataverseAlias2 + "' (uppercase version of existing '" + dataverseAlias1 + "' dataverse, should fail)..."); - Response attemptToCreateDataverseWithDuplicateAlias = UtilIT.createDataverse(dataverseAlias2, apiToken1); + String category = null; + Response attemptToCreateDataverseWithDuplicateAlias = UtilIT.createDataverse(dataverseAlias2, category, apiToken); attemptToCreateDataverseWithDuplicateAlias.prettyPrint(); assertEquals(400, attemptToCreateDataverseWithDuplicateAlias.getStatusCode()); logger.info("Deleting dataverse " + dataverseAlias1); - Response deleteDataverse1Response = UtilIT.deleteDataverse(dataverseAlias1, apiToken1); + Response deleteDataverse1Response = UtilIT.deleteDataverse(dataverseAlias1, apiToken); deleteDataverse1Response.prettyPrint(); assertEquals(200, deleteDataverse1Response.getStatusCode()); logger.info("Checking response code for attempting to delete a non-existent dataverse."); - Response attemptToDeleteDataverseThatShouldNotHaveBeenCreated = UtilIT.deleteDataverse(dataverseAlias2, apiToken1); + Response attemptToDeleteDataverseThatShouldNotHaveBeenCreated = UtilIT.deleteDataverse(dataverseAlias2, apiToken); attemptToDeleteDataverseThatShouldNotHaveBeenCreated.prettyPrint(); assertEquals(404, attemptToDeleteDataverseThatShouldNotHaveBeenCreated.getStatusCode()); } - @AfterClass - public static void tearDownClass() { - boolean disabled = false; + @Test + public void testDataverseCategory() { + Response createUser = UtilIT.createRandomUser(); + createUser.prettyPrint(); + String username = UtilIT.getUsernameFromResponse(createUser); + String apiToken = UtilIT.getApiTokenFromResponse(createUser); + + Response createDataverseWithoutCategory = UtilIT.createRandomDataverse(apiToken); + createDataverseWithoutCategory.prettyPrint(); + createDataverseWithoutCategory.then().assertThat() + .body("data.dataverseType", equalTo("UNCATEGORIZED")) + .statusCode(Status.CREATED.getStatusCode()); + + String alias1 = UtilIT.getRandomIdentifier(); + String category1 = Dataverse.DataverseType.LABORATORY.toString(); + Response createDataverseWithCategory = UtilIT.createDataverse(alias1, category1, apiToken); + createDataverseWithCategory.prettyPrint(); + createDataverseWithCategory.then().assertThat() + .body("data.dataverseType", equalTo("LABORATORY")) + .statusCode(Status.CREATED.getStatusCode()); + + String alias2 = UtilIT.getRandomIdentifier(); + String madeUpCategory = "madeUpCategory"; + Response createDataverseWithInvalidCategory = UtilIT.createDataverse(alias2, madeUpCategory, apiToken); + createDataverseWithInvalidCategory.prettyPrint(); + createDataverseWithInvalidCategory.then().assertThat() + .body("data.dataverseType", equalTo("UNCATEGORIZED")) + .statusCode(Status.CREATED.getStatusCode()); + + String alias3 = UtilIT.getRandomIdentifier(); + String category3 = Dataverse.DataverseType.LABORATORY.toString().toLowerCase(); + Response createDataverseWithLowerCaseCategory = UtilIT.createDataverse(alias3, category3, apiToken); + createDataverseWithLowerCaseCategory.prettyPrint(); + createDataverseWithLowerCaseCategory.then().assertThat() + .body("data.dataverseType", equalTo("UNCATEGORIZED")) + .statusCode(Status.CREATED.getStatusCode()); - if (disabled) { - return; - } + } - Response deleteUser1Response = UtilIT.deleteUser(username1); - deleteUser1Response.prettyPrint(); - assertEquals(200, deleteUser1Response.getStatusCode()); + @Test + public void testMinimalDataverse() throws FileNotFoundException { + Response createUser = UtilIT.createRandomUser(); + createUser.prettyPrint(); + String username = UtilIT.getUsernameFromResponse(createUser); + String apiToken = UtilIT.getApiTokenFromResponse(createUser); + JsonObject dvJson; + FileReader reader = new FileReader("doc/sphinx-guides/source/_static/api/dataverse-minimal.json"); + dvJson = Json.createReader(reader).readObject(); + Response create = UtilIT.createDataverse(dvJson, apiToken); + create.prettyPrint(); + create.then().assertThat().statusCode(CREATED.getStatusCode()); + Response deleteDataverse = UtilIT.deleteDataverse("science", apiToken); + deleteDataverse.prettyPrint(); + deleteDataverse.then().assertThat().statusCode(OK.getStatusCode()); + } + @Test + public void testNotEnoughJson() { + Response createUser = UtilIT.createRandomUser(); + createUser.prettyPrint(); + String username = UtilIT.getUsernameFromResponse(createUser); + String apiToken = UtilIT.getApiTokenFromResponse(createUser); + Response createFail = UtilIT.createDataverse(Json.createObjectBuilder().add("name", "notEnough").add("alias", "notEnough").build(), apiToken); + createFail.prettyPrint(); + createFail.then().assertThat() + /** + * @todo We really don't want Dataverse to throw a 500 error + * when not enough JSON is supplied to create a dataverse. + */ + .statusCode(INTERNAL_SERVER_ERROR.getStatusCode()); } } diff --git a/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java b/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java index 5cc8bb17ddb..ae5f8ec7182 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java @@ -73,7 +73,6 @@ public class SearchIT { private static TestUser homer; private static TestUser ned; private static TestUser clancy; - private static final String categoryTestDataverse = "categoryTestDataverse"; private static final String dvForPermsTesting = "dvForPermsTesting"; private static String dataset1; private static String dataset2; @@ -89,7 +88,6 @@ public class SearchIT { private static final boolean disableTestPermsonRootDv = false; private static final boolean disableTestPermsOnNewDv = false; private static final boolean homerPublishesVersion2AfterDeletingFile = false; - private static final boolean disableTestCategory = false; private Stopwatch timer; private boolean haveToUseCurlForUpload = false; @@ -731,40 +729,6 @@ public void homerPublishesVersion2AfterDeletingFile() throws InterruptedExceptio } - @Ignore - @Test - public void dataverseCategory() { - - if (disableTestCategory) { - return; - } - - Response enableNonPublicSearch = enableSetting(SettingsServiceBean.Key.SearchApiNonPublicAllowed); - assertEquals(200, enableNonPublicSearch.getStatusCode()); - - /** - * Unfortunately, it appears that the ability to specify the category of - * a dataverse when creating it is a GUI-only feature. It can't - * currently be done via the API, to our knowledge. You also can't tell - * from the API which category was persisted but it always seems to be - * "UNCATEGORIZED" - */ - TestDataverse dataverseToCreate = new TestDataverse(categoryTestDataverse, categoryTestDataverse, Dataverse.DataverseType.ORGANIZATIONS_INSTITUTIONS); - Response createDvResponse = createDataverse(dataverseToCreate, homer); - assertEquals(201, createDvResponse.getStatusCode()); - - TestSearchQuery query = new TestSearchQuery(categoryTestDataverse); - Response searchResponse = search(query, homer); -// searchResponse.prettyPrint(); - JsonPath jsonPath = JsonPath.from(searchResponse.body().asString()); - String category = jsonPath.get("data.facets." + SearchFields.DATAVERSE_CATEGORY).toString(); - String msg = "category: " + category; - assertEquals("category: [null]", msg); - - Response disableNonPublicSearch = deleteSetting(SettingsServiceBean.Key.SearchApiNonPublicAllowed); - assertEquals(200, disableNonPublicSearch.getStatusCode()); - } - @AfterClass public static void cleanup() { @@ -805,11 +769,6 @@ public static void cleanup() { assertEquals(200, destroyDataset.getStatusCode()); } - if (!disableTestCategory) { - Response deleteCategoryDataverseResponse = deleteDataverse(categoryTestDataverse, homer); - assertEquals(200, deleteCategoryDataverseResponse.getStatusCode()); - } - if (!disableTestPermsOnNewDv) { Response deleteDvResponse = deleteDataverse(dvForPermsTesting, homer); assertEquals(200, deleteDvResponse.getStatusCode()); diff --git a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java index fa097182407..b177713a734 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java @@ -20,7 +20,9 @@ import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import static com.jayway.restassured.RestAssured.given; import static com.jayway.restassured.path.xml.XmlPath.from; +import java.math.BigDecimal; import java.util.List; +import javax.json.JsonValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -85,7 +87,7 @@ private static String getRandomUsername() { return "user" + getRandomIdentifier().substring(0, 8); } - private static String getRandomIdentifier() { + public static String getRandomIdentifier() { return UUID.randomUUID().toString().substring(0, 8); } @@ -133,7 +135,7 @@ public static Response getServiceDocument(String apiToken) { return response; } - static Response createDataverse(String alias, String apiToken) { + static Response createDataverse(String alias, String category, String apiToken) { JsonArrayBuilder contactArrayBuilder = Json.createArrayBuilder(); contactArrayBuilder.add(Json.createObjectBuilder().add("contactEmail", getEmailFromUserName(getRandomIdentifier()))); JsonArrayBuilder subjectArrayBuilder = Json.createArrayBuilder(); @@ -143,6 +145,8 @@ static Response createDataverse(String alias, String apiToken) { .add("name", alias) .add("dataverseContacts", contactArrayBuilder) .add("dataverseSubjects", subjectArrayBuilder) + // don't send "dataverseType" if category is null, must be a better way + .add(category != null ? "dataverseType" : "notTheKeyDataverseType", category != null ? category : "whatever") .build(); Response createDataverseResponse = given() .body(dvData.toString()).contentType(ContentType.JSON) @@ -150,9 +154,17 @@ static Response createDataverse(String alias, String apiToken) { return createDataverseResponse; } + static Response createDataverse(JsonObject dvData, String apiToken) { + Response createDataverseResponse = given() + .body(dvData.toString()).contentType(ContentType.JSON) + .when().post("/api/dataverses/:root?key=" + apiToken); + return createDataverseResponse; + } + static Response createRandomDataverse(String apiToken) { String alias = getRandomIdentifier(); - return createDataverse(alias, apiToken); + String category = null; + return createDataverse(alias, category, apiToken); } static Response showDataverseContents(String alias, String apiToken) { diff --git a/src/test/java/edu/harvard/iq/dataverse/util/json/JsonParserTest.java b/src/test/java/edu/harvard/iq/dataverse/util/json/JsonParserTest.java index c7491e34615..e4660760a95 100644 --- a/src/test/java/edu/harvard/iq/dataverse/util/json/JsonParserTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/util/json/JsonParserTest.java @@ -22,6 +22,7 @@ import edu.harvard.iq.dataverse.authorization.users.GuestUser; import edu.harvard.iq.dataverse.engine.command.DataverseRequest; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; +import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -236,19 +237,25 @@ public void testPrimitiveRepeatesFieldRoundTrip() throws JsonParseException { public void testParseCompleteDataverse() throws JsonParseException { JsonObject dvJson; - try (InputStream jsonFile = ClassLoader.getSystemResourceAsStream("json/complete-dataverse.json")) { - InputStreamReader reader = new InputStreamReader(jsonFile, "UTF-8"); + try (FileReader reader = new FileReader("doc/sphinx-guides/source/_static/api/dataverse-complete.json")) { dvJson = Json.createReader(reader).readObject(); Dataverse actual = sut.parseDataverse(dvJson); - assertEquals("testDv", actual.getName()); - assertEquals("testAlias", actual.getAlias()); - assertEquals("Test-Driven University", actual.getAffiliation()); - assertEquals("test Description.", actual.getDescription()); + assertEquals("Scientific Research", actual.getName()); + assertEquals("science", actual.getAlias()); + assertEquals("Scientific Research University", actual.getAffiliation()); + assertEquals("We do all the science.", actual.getDescription()); + assertEquals("LABORATORY", actual.getDataverseType().toString()); assertEquals(2, actual.getDataverseContacts().size()); - assertEquals("test@example.com,test@example.org", actual.getContactEmails()); + assertEquals("pi@example.edu,student@example.edu", actual.getContactEmails()); assertEquals(0, actual.getDataverseContacts().get(0).getDisplayOrder()); assertEquals(1, actual.getDataverseContacts().get(1).getDisplayOrder()); - assertTrue(actual.isPermissionRoot()); + /** + * The JSON does not specify "permissionRoot" because it's a no-op + * so we don't want to document it in the API Guide. It's a no-op + * because as of fb7e65f (4.0) all dataverses have permissionRoot + * hard coded to true. + */ + assertFalse(actual.isPermissionRoot()); } catch (IOException ioe) { throw new JsonParseException("Couldn't read test file", ioe); } @@ -266,6 +273,7 @@ public void testParseThemeDataverse() throws JsonParseException { assertEquals("testAlias", actual.getAlias()); assertEquals("Test-Driven University", actual.getAffiliation()); assertEquals("test Description.", actual.getDescription()); + assertEquals("UNCATEGORIZED", actual.getDataverseType().toString()); assertEquals("gray", actual.getDataverseTheme().getBackgroundColor()); assertEquals("red", actual.getDataverseTheme().getLinkColor()); assertEquals("http://www.cnn.com", actual.getDataverseTheme().getLinkUrl()); @@ -297,6 +305,7 @@ public void testParseMinimalDataverse() throws JsonParseException { Dataverse actual = sut.parseDataverse(dvJson); assertEquals("testDv", actual.getName()); assertEquals("testAlias", actual.getAlias()); + assertEquals("UNCATEGORIZED", actual.getDataverseType().toString()); assertTrue(actual.getDataverseContacts().isEmpty()); assertEquals("", actual.getContactEmails()); assertFalse(actual.isPermissionRoot()); diff --git a/src/test/resources/json/complete-dataverse.json b/src/test/resources/json/complete-dataverse.json deleted file mode 100644 index 98679af44ff..00000000000 --- a/src/test/resources/json/complete-dataverse.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "testDv", - "alias": "testAlias", - "affiliation": "Test-Driven University", - "dataverseContacts": [ - { - "contactEmail": "test@example.com" - }, - { - "contactEmail": "test@example.org" - } - ], - "permissionRoot": true, - "description": "test Description." -}