diff --git a/doc/release-notes/12699-CurateCommand updates.md b/doc/release-notes/12699-CurateCommand updates.md new file mode 100644 index 00000000000..f3f5eb23718 --- /dev/null +++ b/doc/release-notes/12699-CurateCommand updates.md @@ -0,0 +1,3 @@ +## Updates to the "Update Current Version" Publishing Option +This release fixes a bug in the Update Current Version functionality that would cause it to fail if the submit for review/ return to author functionality had been used with the dataset. +It also assures that people who contributed to the draft are added to the list of people who contributed to the published version being updated (which was not done previously). diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index 4bff7150b97..bf028b13675 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -183,11 +183,11 @@ public enum VersionState { private String jsonLd; @OneToMany(mappedBy="datasetVersion", cascade={CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST}) - private List datasetVersionUsers; + private List datasetVersionUsers = new ArrayList<>(); // Is this the right mapping and cascading for when the workflowcomments table is being used for objects other than DatasetVersion? @OneToMany(mappedBy = "datasetVersion", cascade={CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST}) - private List workflowComments; + private List workflowComments = new ArrayList<>(); /* * As of v6.7, the NULLS LAST part of the annotation below appears to not be working. Explicit sorting has been added in the getCurationStatuses() method. The annotation is kept since, if it does work @@ -2167,6 +2167,16 @@ public void removeCurationStatus(CurationStatus curationStatus) { curationStatus.setDatasetVersion(null); } + public void addWorkflowComment(WorkflowComment comment) { + comment.setDatasetVersion(this); + workflowComments.add(comment); + } + + public void addDatasetVersionUser(DatasetVersionUser dvu) { + dvu.setDatasetVersion(this); + datasetVersionUsers.add(dvu); + } + public CurationStatus getCurationStatusAsOfDate(Date date) { if (curationStatuses == null || curationStatuses.isEmpty()) { return null; diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CuratePublishedDatasetVersionCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CuratePublishedDatasetVersionCommand.java index 1c57a9d4647..73d6ee6206f 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CuratePublishedDatasetVersionCommand.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CuratePublishedDatasetVersionCommand.java @@ -14,6 +14,7 @@ import edu.harvard.iq.dataverse.Dataset; import edu.harvard.iq.dataverse.DatasetField; import edu.harvard.iq.dataverse.DatasetVersion; +import edu.harvard.iq.dataverse.DatasetVersionUser; import edu.harvard.iq.dataverse.TermsOfUseAndAccess; import edu.harvard.iq.dataverse.CurationStatus; import edu.harvard.iq.dataverse.DataFile; @@ -91,12 +92,38 @@ public Dataset execute(CommandContext ctxt) throws CommandException { //Also set the fileaccessrequest boolean on the dataset to match the new terms getDataset().setFileAccessRequest(updateVersion.getTermsOfUseAndAccess().isFileAccessRequest()); + + // Transfer workflow comments from draft to published version List newComments = newVersion.getWorkflowComments(); - if (newComments!=null && newComments.size() >0) { - for(WorkflowComment wfc: newComments) { - wfc.setDatasetVersion(updateVersion); + if (newComments != null && newComments.size() > 0) { + for (WorkflowComment wfc : newComments) { + updateVersion.addWorkflowComment(wfc); + } + newVersion.getWorkflowComments().clear(); + } + + // Transfer DatasetVersionUser entries from draft to published version + if (newVersion.getDatasetVersionUsers() != null && !newVersion.getDatasetVersionUsers().isEmpty()) { + for (Iterator it = newVersion.getDatasetVersionUsers().iterator(); it.hasNext();) { + DatasetVersionUser dvu = it.next(); + boolean found = false; + for (DatasetVersionUser existingDvu : updateVersion.getDatasetVersionUsers()) { + if (existingDvu.getAuthenticatedUser().equals(dvu.getAuthenticatedUser())) { + if (dvu.getLastUpdateDate().after(existingDvu.getLastUpdateDate())) { + existingDvu.setLastUpdateDate(dvu.getLastUpdateDate()); + } + found = true; + break; + } + } + if (found) { + it.remove(); + ctxt.em().remove(dvu); + } else { + updateVersion.addDatasetVersionUser(dvu); + it.remove(); + } } - updateVersion.getWorkflowComments().addAll(newComments); } // Transfer curation status entries from draft to published version @@ -232,11 +259,6 @@ public Dataset execute(CommandContext ctxt) throws CommandException { updateDatasetUser(ctxt); - // ToDo - see if there are other DatasetVersionUser entries unique to the draft - // version that should be moved to the last published version - // As this command is intended for minor fixes, often done by the person pushing - // the update-current-version button, this is probably a minor issue. - return savedDataset; } diff --git a/src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java b/src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java index 1e1aad484e4..3a3bf390506 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java @@ -4246,6 +4246,15 @@ public void testUpdateDatasetTermsOfAccess() throws IOException { + private Response updateDatasetMetadataUnique(String datasetPid, String pathToJsonFile, String title, String apiToken) { + String json = UtilIT.getDatasetJson(pathToJsonFile).replace("newTitle", title); + return given() + .header(API_TOKEN_HTTP_HEADER, apiToken) + .body(json) + .contentType("application/json") + .put("/api/datasets/:persistentId/versions/" + DS_VERSION_DRAFT + "?persistentId=" + datasetPid); + } + @Test public void testCuratePublishedDatasetVersionCommand() throws IOException { Response createUser = UtilIT.createRandomUser(); @@ -4255,6 +4264,12 @@ public void testCuratePublishedDatasetVersionCommand() throws IOException { String apiToken = UtilIT.getApiTokenFromResponse(createUser); String username = UtilIT.getUsernameFromResponse(createUser); + // Create another user to test the "found" case during curation + Response createUser2 = UtilIT.createRandomUser(); + String apiToken2 = UtilIT.getApiTokenFromResponse(createUser2); + String username2 = UtilIT.getUsernameFromResponse(createUser2); + UtilIT.setSuperuserStatus(username2, true).then().assertThat().statusCode(OK.getStatusCode()); + String pathToJsonFile = "doc/sphinx-guides/source/_static/api/dataset-update-metadata.json"; Response createDataverse = UtilIT.createRandomDataverse(apiToken); createDataverse.prettyPrint(); @@ -4358,7 +4373,8 @@ public void testCuratePublishedDatasetVersionCommand() throws IOException { editDDIResponse.prettyPrint(); assertEquals(200, editDDIResponse.getStatusCode()); - + // Add username2 to the draft before it is published as major version + updateDatasetMetadataUnique(datasetPid, pathToJsonFile, "Title Published", apiToken2).then().assertThat().statusCode(OK.getStatusCode()); UtilIT.publishDataverseViaNativeApi(dataverseAlias, apiToken).then().assertThat().statusCode(OK.getStatusCode()); UtilIT.publishDatasetViaNativeApi(datasetId, "major", apiToken).then().assertThat().statusCode(OK.getStatusCode()); @@ -4369,12 +4385,24 @@ public void testCuratePublishedDatasetVersionCommand() throws IOException { .statusCode(OK.getStatusCode()) .body("data.latestVersion.files[0].label", equalTo("dct.tab")); - String pathToJsonFile = "doc/sphinx-guides/source/_static/api/dataset-update-metadata.json"; - Response updateTitle = UtilIT.updateDatasetMetadataViaNative(datasetPid, pathToJsonFile, apiToken); - updateTitle.prettyPrint(); - updateTitle.then().assertThat() - .statusCode(OK.getStatusCode()); + updateDatasetMetadataUnique(datasetPid, pathToJsonFile, "Title Draft 1", apiToken).then().assertThat().statusCode(OK.getStatusCode()); + // Add a workflow comment to the draft + UtilIT.submitDatasetForReview(datasetPid, apiToken).then().assertThat().statusCode(OK.getStatusCode()); + JsonObjectBuilder curatorComment = JsonUtil.createObjectBuilder(); + curatorComment.add("reasonForReturn", "Please fix the metadata."); + UtilIT.returnDatasetToAuthor(datasetPid, curatorComment.build(), apiToken).then().assertThat().statusCode(OK.getStatusCode()); + + // Add another DatasetVersionUser by having another superuser edit the draft + // username2 is already in the published version (found = true), username3 is new (found = false) + Response createUser3 = UtilIT.createRandomUser(); + String apiToken3 = UtilIT.getApiTokenFromResponse(createUser3); + String username3 = UtilIT.getUsernameFromResponse(createUser3); + UtilIT.setSuperuserStatus(username3, true).then().assertThat().statusCode(OK.getStatusCode()); + + updateDatasetMetadataUnique(datasetPid, pathToJsonFile, "Title Draft 2", apiToken2).then().assertThat().statusCode(OK.getStatusCode()); + updateDatasetMetadataUnique(datasetPid, pathToJsonFile, "Title Draft 3", apiToken3).then().assertThat().statusCode(OK.getStatusCode()); + // shouldn't be able to update current unless you're a super user UtilIT.publishDatasetViaNativeApi(datasetId, "updatecurrent", apiToken).then().assertThat().statusCode(FORBIDDEN.getStatusCode()); @@ -4391,6 +4419,15 @@ public void testCuratePublishedDatasetVersionCommand() throws IOException { getDatasetJsonAfterUpdate.then().assertThat() .statusCode(OK.getStatusCode()); + // Check that the DatasetVersionUsers were transferred/updated by checking the contributors list + Response getCompareSummary = UtilIT.getCompareSummary(datasetId, apiToken); + getCompareSummary.prettyPrint(); + getCompareSummary.then().assertThat() + .statusCode(OK.getStatusCode()) + .body("data[0].contributors", org.hamcrest.Matchers.containsString(username)) + .body("data[0].contributors", org.hamcrest.Matchers.containsString(username2)) + .body("data[0].contributors", org.hamcrest.Matchers.containsString(username3)); + //Check that the draft version is gone Response getDraft1 = UtilIT.getDatasetVersion(datasetPid, DS_VERSION_DRAFT, apiToken); getDraft1.then().assertThat() 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 1c1d7116dc3..83f25fb9c26 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java @@ -2414,6 +2414,13 @@ static Response nativeGet(Integer datasetId, String apiToken) { return response; } + static Response getCompareSummary(Integer datasetId, String apiToken) { + Response response = given() + .header(API_TOKEN_HTTP_HEADER, apiToken) + .get("/api/datasets/" + datasetId + "/versions/compareSummary"); + return response; + } + static Response privateUrlGet(Integer datasetId, String apiToken) { Response response = given() .header(API_TOKEN_HTTP_HEADER, apiToken)