Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/release-notes/11783-Curation-Status-fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
In prior versions of Dataverse, publishing a dataset via the superuser only update-current-version option would not set the current curation status (if enabled/used) to none/empty and, in v6.7, would not maintain the curation status history. These issues are now resolved and the update current version option works the same as normal publication of a new version w.r.t. curation status.
2 changes: 1 addition & 1 deletion doc/sphinx-guides/source/container/app-image.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ For now, stale images will be kept on Docker Hub indefinitely.
| Example: :substitution-code:`|nextVersion|-noble`
| Summary: Rolling tag, equivalent to ``unstable`` for current development cycle.
Will roll over to the rolling production tag after a Dataverse release.
| Discussion: Perhaps you are eager to starting testing features of an upcoming version (e.g. |nextVersion|) in a staging environment. You select the :substitution-code:`|nextVersion|-noble` tag (as opposed to ``unstable``) because you want to stay on |nextVersion| rather switching to the version **after that** when a release is made (which would happen if you had selected the ``unstable`` tag). Also, when the next release comes out (|nextVersion| in this example), you would stay on the :substitution-code:`|nextVersion|-noble` tag, which is the same tag that someone would use who wants the final release of |nextVersion|. (See "Rolling Production", above.)
| Discussion: Perhaps you are eager to start testing features of an upcoming version (e.g. |nextVersion|) in a staging environment. You select the :substitution-code:`|nextVersion|-noble` tag (as opposed to ``unstable``) because you want to stay on |nextVersion| rather than switching to the version **after that** when a release is made (which would happen if you had selected the ``unstable`` tag). Also, when the next release comes out (|nextVersion| in this example), you would stay on the :substitution-code:`|nextVersion|-noble` tag, which is the same tag that someone would use who wants the final release of |nextVersion|. (See "Rolling Production", above.)

**NOTE**: In these tags for development usage, the version number will always be 1 minor version ahead of existing Dataverse releases.
Example: Assume Dataverse ``6.x`` is released, ``6.(x+1)`` is underway.
Expand Down
2 changes: 1 addition & 1 deletion modules/container-base/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ provides in-depth information about content, building, tuning and so on for this
**Where to get help and ask questions:**

IQSS will not offer support on how to deploy or run it. Please reach out to the community for help on using it.
You can join the Community Chat on Matrix at https://chat.dataverse.org and https://groups.google.com/g/dataverse-community
You can join the Community Chat at https://chat.dataverse.org and https://groups.google.com/g/dataverse-community
to ask for help and guidance.

## Supported Image Tags
Expand Down
2 changes: 1 addition & 1 deletion modules/container-configbaker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ provides information about this image.
**Where to get help and ask questions:**

IQSS will not offer support on how to deploy or run it. Please reach out to the community for help on using it.
You can join the Community Chat on Matrix at https://chat.dataverse.org and https://groups.google.com/g/dataverse-community
You can join the Community Chat at https://chat.dataverse.org and https://groups.google.com/g/dataverse-community
to ask for help and guidance.

## Supported Image Tags
Expand Down
2 changes: 1 addition & 1 deletion src/main/docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ for more details on tunable settings, locations, etc.
**Where to get help and ask questions:**

IQSS will not offer support on how to deploy or run it. Please reach out to the community for help on using it.
You can join the Community Chat on Matrix at https://chat.dataverse.org and https://groups.google.com/g/dataverse-community
You can join the Community Chat at https://chat.dataverse.org and https://groups.google.com/g/dataverse-community
to ask for help and guidance.

## Supported Image Tags
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/edu/harvard/iq/dataverse/api/Datasets.java
Original file line number Diff line number Diff line change
Expand Up @@ -2609,7 +2609,7 @@ public Response getCurationStatus(@Context ContainerRequestContext crc,
canSeeStatus = permissionSvc.requestOn(createDataverseRequest(user), ds).has(Permission.PublishDataset);
}

if (dsv.isDraft() && (canSeeStatus)) {
if (canSeeStatus) {
List<CurationStatus> statuses = includeHistory ? dsv.getCurationStatuses() : Collections.singletonList(dsv.getCurrentCurationStatus());
if (includeHistory) {
JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import edu.harvard.iq.dataverse.DatasetField;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.TermsOfUseAndAccess;
import edu.harvard.iq.dataverse.CurationStatus;
import edu.harvard.iq.dataverse.DataFile;
import edu.harvard.iq.dataverse.FileMetadata;
import edu.harvard.iq.dataverse.RoleAssignment;
Expand All @@ -27,6 +28,8 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.lang3.StringUtils;

/**
*
* @author qqmyers
Expand Down Expand Up @@ -73,7 +76,7 @@ public Dataset execute(CommandContext ctxt) throws CommandException {
newTerms.setDatasetVersion(updateVersion);
updateVersion.setTermsOfUseAndAccess(newTerms);

//Creation Note
//Version Note
updateVersion.setVersionNote(newVersion.getVersionNote());

// Clear unnecessary terms relationships ....
Expand All @@ -96,6 +99,24 @@ public Dataset execute(CommandContext ctxt) throws CommandException {
updateVersion.getWorkflowComments().addAll(newComments);
}

// Transfer curation status entries from draft to published version
List<CurationStatus> draftCurationStatuses = newVersion.getCurationStatuses();
if (draftCurationStatuses != null && !draftCurationStatuses.isEmpty()) {
for (CurationStatus cs : draftCurationStatuses) {
// Update the dataset version reference
//This call sets the version in the curationstatus object as well
updateVersion.addCurationStatus(cs);
}
// Clear the list from the draft version
newVersion.getCurationStatuses().clear();
}

// Add a new empty curation status to clear the status in the published version (as done in the FinalizeDatasetPublicationCommand)
CurationStatus status = updateVersion.getCurrentCurationStatus();
if (status != null && StringUtils.isNotBlank(status.getLabel())) {
updateVersion.addCurationStatus(new CurationStatus(null, updateVersion, getRequest().getAuthenticatedUser()));
}

// we have to merge to update the database but not flush because
// we don't want to create two draft versions!
Dataset tempDataset = getDataset();
Expand Down Expand Up @@ -201,7 +222,7 @@ public Dataset execute(CommandContext ctxt) throws CommandException {
// This can be corrected by running the update PID API later, but who will look in the log?
// With the change to not use the DeleteDatasetVersionCommand above and other
// fixes, this error may now cleanly restore the initial state
// with the draft and last published versions unchanged, but this has not yet bee tested.
// with the draft and last published versions unchanged, but this has not yet been tested.
// (Alternately this could move to onSuccess if we intend it to stay non-fatal.)
logger.log(Level.WARNING, "Curate Published DatasetVersion: exception while updating PID metadata:{0}", ex.getMessage());
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/webapp/dataset.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@
#{bundle['dataset.curationStatusMenu']} <span class="caret"></span>
</button>
<ul class="dropdown-menu multi-level pull-right text-left">
<ui:fragment rendered="#{(not empty DatasetPage.allowedCurationStatuses) and DatasetPage.canPublishDataset()}">
<ui:fragment rendered="#{(not empty DatasetPage.allowedCurationStatuses) and DatasetPage.canPublishDataset() and version.draft}">
<li class="dropdown-submenu pull-left">
<a tabindex="0">#{bundle['dataset.changestatus']}</a>
<ul class="dropdown-menu">
Expand Down
64 changes: 62 additions & 2 deletions src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -3875,6 +3875,8 @@ public void testCurationStatusAPIs() {
createDataverseResponse.prettyPrint();
String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse);

UtilIT.publishDataverseViaNativeApi(dataverseAlias, apiToken).then().assertThat().statusCode(OK.getStatusCode());

Response setCurationLabelSets = UtilIT.setSetting(SettingsServiceBean.Key.AllowedCurationLabels, "{\"StandardProcess\":[\"Author contacted\", \"Privacy Review\", \"Awaiting paper publication\", \"Final Approval\"],\"AlternateProcess\":[\"State 1\",\"State 2\",\"State 3\"]}");
setCurationLabelSets.then().assertThat()
.statusCode(OK.getStatusCode());
Expand All @@ -3885,7 +3887,7 @@ public void testCurationStatusAPIs() {
Response setDataverseCurationLabelSetResponse = UtilIT.setDataverseCurationLabelSet(dataverseAlias, apiToken, "AlternateProcess");
setDataverseCurationLabelSetResponse.then().assertThat().statusCode(FORBIDDEN.getStatusCode());

Response makeSuperUser = UtilIT.makeSuperUser(username);
Response makeSuperUser = UtilIT.setSuperuserStatus(username, true);
assertEquals(200, makeSuperUser.getStatusCode());

//Non-existent option
Expand Down Expand Up @@ -3944,8 +3946,66 @@ public void testCurationStatusAPIs() {
Response setInvalidStatus = UtilIT.setDatasetCurationLabel(datasetId, apiToken, "Invalid Status");
setInvalidStatus.then().assertThat().statusCode(BAD_REQUEST.getStatusCode());

// Publish the dataset
UtilIT.publishDatasetViaNativeApi(datasetId, "major", apiToken).then().assertThat()
.statusCode(OK.getStatusCode());

// Verify that the current curation label is now empty after publishing
Response getStatusAfterPublish = UtilIT.getDatasetCurationStatus(datasetId, apiToken, false);
getStatusAfterPublish.then().assertThat().statusCode(OK.getStatusCode());
JsonObject statusAfterPublish = Json.createReader(new StringReader(getStatusAfterPublish.body().asString())).readObject();
JsonObject dataObject = statusAfterPublish.getJsonObject("data");
assertFalse(dataObject.containsKey("label"), "Curation label should be empty after publishing");

//Cause a new draft version
String jsonLDTerms = "{\"https://dataverse.org/schema/core#fileTermsOfAccess\":{\"https://dataverse.org/schema/core#dataAccessPlace\":\"Somewhere\"}}";
Response updateTerms = UtilIT.updateDatasetJsonLDMetadata(datasetId, apiToken, jsonLDTerms, true);
updateTerms.then().assertThat()
.statusCode(OK.getStatusCode());

// Add a new valid curation label
Response setNewStatus = UtilIT.setDatasetCurationLabel(datasetId, apiToken, "State 2");
setNewStatus.then().assertThat().statusCode(OK.getStatusCode());

// Verify the label was set
Response getStatusAfterSet = UtilIT.getDatasetCurationStatus(datasetId, apiToken, false);
getStatusAfterSet.then().assertThat().statusCode(OK.getStatusCode());
JsonObject statusAfterSet = Json.createReader(new StringReader(getStatusAfterSet.body().asString())).readObject();
JsonObject dataInSecondDraft = statusAfterSet.getJsonObject("data");
assertEquals("State 2", dataInSecondDraft.getString("label"), "Curation label should be set to State 2");

// Publish the dataset again using updatecurrent as superuser
Response updateCurrentResponse = UtilIT.publishDatasetViaNativeApi(datasetId, "updatecurrent", apiToken);
updateCurrentResponse.then().assertThat().statusCode(OK.getStatusCode());

// Verify that the current curation label is now empty after updatecurrent
Response getStatusAfterUpdateCurrent = UtilIT.getDatasetCurationStatus(datasetId, apiToken, false);
getStatusAfterUpdateCurrent.then().assertThat().statusCode(OK.getStatusCode());
JsonObject statusAfterUpdateCurrent = Json.createReader(new StringReader(getStatusAfterUpdateCurrent.body().asString())).readObject();
JsonObject dataAfterUpdateCurrent = statusAfterUpdateCurrent.getJsonObject("data");
assertFalse(dataAfterUpdateCurrent.containsKey("label"), "Curation label should be empty after updatecurrent");

// Verify that the history contains the previously added label
Response getHistoryAfterUpdateCurrent = UtilIT.getDatasetCurationStatus(datasetId, apiToken, true);
getHistoryAfterUpdateCurrent.then().assertThat().statusCode(OK.getStatusCode());

// Extract the data array from the response
JsonObject responseObj = Json.createReader(new StringReader(getHistoryAfterUpdateCurrent.body().asString())).readObject();
JsonArray historyAfterUpdateCurrent = responseObj.getJsonArray("data");

// Verify history contains the State 2 label
boolean foundState2 = false;
for (int i = 0; i < historyAfterUpdateCurrent.size(); i++) {
JsonObject entry = historyAfterUpdateCurrent.getJsonObject(i);
if (entry.containsKey("label") && "State 2".equals(entry.getString("label"))) {
foundState2 = true;
break;
}
}
assertTrue(foundState2, "History should contain the State 2 label after updatecurrent");

// Clean up
Response deleteDatasetResponse = UtilIT.deleteDatasetViaNativeApi(datasetId, apiToken);
Response deleteDatasetResponse = UtilIT.destroyDataset(datasetId, apiToken);
assertEquals(200, deleteDatasetResponse.getStatusCode());

Response deleteDataverseResponse = UtilIT.deleteDataverse(dataverseAlias, apiToken);
Expand Down