Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional doi fixes #1909

Merged
merged 3 commits into from
Dec 16, 2024
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
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
Changes
=======

Version v16.5.1 (released 2024-12-16)

- pids: add manage permission to be able to manage DOIs
- deposit: fix validation check when user needs a DOI and DOI is optional

Version v16.5.0 (released 2024-12-16)

- pids: add support for optional DOI
Expand Down
2 changes: 1 addition & 1 deletion invenio_rdm_records/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@

from .ext import InvenioRDMRecords

__version__ = "16.5.0"
__version__ = "16.5.1"

__all__ = ("__version__", "InvenioRDMRecords")
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@ class PublishButtonComponent extends Component {
handlePublish = (event, handleSubmit, publishWithoutCommunity) => {
const { setSubmitContext } = this.context;
const { formik, raiseDOINeededButNotReserved, isDOIRequired } = this.props;
const noINeedOne = formik?.values?.noINeedOne;
const noINeedDOI = formik?.values?.noINeedDOI;
// Check for explicit DOI reservation via the "GET DOI button" only when DOI is
// optional in the instance's settings. If it is required, backend will automatically
// mint one even if it was not explicitly reserved
const shouldCheckForExplicitDOIReservation =
isDOIRequired !== undefined && // isDOIRequired is undefined when no value was provided from Invenio-app-rdm
!isDOIRequired &&
noINeedOne &&
noINeedDOI &&
Object.keys(formik?.values?.pids).length === 0;
if (shouldCheckForExplicitDOIReservation) {
const errors = {
pids: {
doi: i18next.t("DOI is needed. Please click on the button to reserve it."),
doi: i18next.t("DOI is needed. You need to reserve a DOI before publishing."),
},
};
formik.setErrors(errors);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,14 +497,14 @@ class CustomPIDField extends Component {
form.setFieldValue("pids", {});
if (!required) {
// We set the
form.setFieldValue("noINeedOne", true);
form.setFieldValue("noINeedDOI", true);
}
} else if (userSelectedNoNeed) {
form.setFieldValue("pids", {});
form.setFieldValue("noINeedOne", false);
form.setFieldValue("noINeedDOI", false);
} else {
this.onExternalIdentifierChanged("");
form.setFieldValue("noINeedOne", false);
form.setFieldValue("noINeedDOI", false);
}
form.setFieldError(fieldPath, false);
this.setState({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
RESERVE_PID_STARTED,
RESERVE_PID_SUCCEEDED,
SET_COMMUNITY,
SET_DOI_NEEDED,
} from "../types";

async function changeURLAfterCreation(draftURL) {
Expand Down Expand Up @@ -152,6 +153,16 @@ export const save = (draft) => {
type: DRAFT_SAVE_SUCCEEDED,
payload: { data: response.data },
});

if (draft.noINeedDOI) {
// Save the choice that user selected that DOI is needed. This is used to validate
// if user has reserved a DOI before clicking publish. This check is valid when
// DOI is optional
dispatch({
type: SET_DOI_NEEDED,
payload: { noINeedDOI: draft.noINeedDOI },
});
}
};
};

Expand Down Expand Up @@ -344,3 +355,12 @@ export const changeSelectedCommunity = (community) => {
});
};
};

export const setDOINeeded = (value) => {
return async (dispatch) => {
dispatch({
type: SET_DOI_NEEDED,
payload: { noINeedDOI: value },
});
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
RESERVE_PID_STARTED,
RESERVE_PID_SUCCEEDED,
SET_COMMUNITY,
SET_DOI_NEEDED,
} from "../types";

export class DepositStatus {
Expand Down Expand Up @@ -332,13 +333,21 @@ const depositReducer = (state = {}, action) => {
},
};
}

return {
...state,
record: recordCopy,
editorState: computeDepositState(recordCopy, action.payload.community),
};
}
case SET_DOI_NEEDED: {
const recordCopy = {
...state.record,
};
return {
...state,
record: { ...recordCopy, ...action.payload },
};
}
default:
return state;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export const DISCARD_PID_STARTED = "DISCARD_PID_STARTED";
export const DISCARD_PID_SUCCEEDED = "DISCARD_PID_SUCCEEDED";
export const DISCARD_PID_FAILED = "DISCARD_PID_FAILED";

export const SET_DOI_NEEDED = "SET_DOI_NEEDED";

// Files
export const FILE_UPLOAD_ADDED = "FILE_UPLOAD_ADDED";
export const FILE_UPLOAD_IN_PROGRESS = "FILE_UPLOAD_IN_PROGRESS";
Expand Down
8 changes: 6 additions & 2 deletions invenio_rdm_records/services/components/pids.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ def update_draft(self, identity, data=None, record=None, errors=None):

# if DOI is not required in an instance check validate allowed providers
# for each record version
if "doi" not in required_schemes:
doi_required = "doi" in required_schemes
can_manage_dois = self.service.check_permission(identity, "pid_manage")
if not doi_required and not can_manage_dois:
previous_published = self.service.record_cls.get_latest_published_by_parent(
record.parent
)
Expand Down Expand Up @@ -149,7 +151,9 @@ def publish(self, identity, draft=None, record=None):

# if DOI is not required in an instance check validate allowed providers
# for each record version
if "doi" not in required_schemes:
doi_required = "doi" in required_schemes
can_manage_dois = self.service.check_permission(identity, "pid_manage")
if not doi_required and not can_manage_dois:
# if a doi was ever minted for the parent record then we always require one
# for any version of the record that will be published
if draft.parent.get("pids", {}).get("doi"):
Expand Down
1 change: 1 addition & 0 deletions invenio_rdm_records/services/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class RDMRecordPermissionPolicy(RecordPermissionPolicy):
can_pid_update = can_review
can_pid_discard = can_review
can_pid_delete = can_review
can_pid_manage = [SystemProcess()]

#
# Actions
Expand Down
39 changes: 39 additions & 0 deletions tests/services/test_rdm_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from copy import deepcopy

import pytest
from invenio_access.permissions import system_identity

from invenio_rdm_records.proxies import current_rdm_records
from invenio_rdm_records.services.errors import (
Expand Down Expand Up @@ -172,6 +173,44 @@ def test_publish_public_record_versions_managed_doi_no_doi(
running_app.app.config["RDM_PERSISTENT_IDENTIFIERS"]["doi"]["required"] = True


def test_edit_published_record_change_doi_when_optional(
running_app, search_clear, minimal_record, verified_user
):
running_app.app.config["RDM_PERSISTENT_IDENTIFIERS"]["doi"]["required"] = False
verified_user_identity = verified_user.identity
service = current_rdm_records.records_service
# Publish without DOI
draft = service.create(verified_user_identity, minimal_record)
record = service.publish(id_=draft.id, identity=verified_user_identity)
assert "doi" not in record._record.pids
assert "doi" not in record._record.parent.pids

# create a new version with no DOI
draft = service.new_version(verified_user_identity, record.id)
draft_data = deepcopy(draft.data)
draft_data["metadata"]["publication_date"] = "2023-01-01"

draft = service.update_draft(verified_user_identity, draft.id, data=draft_data)
record = service.publish(id_=draft.id, identity=verified_user_identity)
assert "doi" not in record._record.pids
assert "doi" not in record._record.parent.pids

# edit the new published version and change the DOI to locally managed with
# system user
draft = service.edit(system_identity, record.id)
draft = service.pids.create(system_identity, draft.id, "doi")
draft_data = deepcopy(draft.data)
draft_data["metadata"]["publication_date"] = "2023-01-01"
draft = service.update_draft(system_identity, draft.id, data=draft_data)

record = service.publish(id_=draft.id, identity=system_identity)
assert "doi" in record._record.pids
assert "doi" in record._record.parent.pids

# Reset the running_app config for next tests
running_app.app.config["RDM_PERSISTENT_IDENTIFIERS"]["doi"]["required"] = True


def test_publish_public_record_with_default_doi(
running_app, search_clear, minimal_record, uploader
):
Expand Down
Loading