mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-18 15:33:09 +00:00
Merge pull request #8175 from the-library-code/TLC-254_type_bind_d72
Type-bind for submission input (port from DSpace-CRIS 7)
This commit is contained in:
@@ -561,6 +561,15 @@ public class DCInput {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type bind list for use in determining whether
|
||||||
|
* to display this field in angular dynamic form building
|
||||||
|
* @return list of bound types
|
||||||
|
*/
|
||||||
|
public List<String> getTypeBindList() {
|
||||||
|
return typeBind;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify whether the current field contains an entity relationship
|
* Verify whether the current field contains an entity relationship
|
||||||
* This also implies a relationship type is defined for this field
|
* This also implies a relationship type is defined for this field
|
||||||
|
@@ -140,6 +140,7 @@
|
|||||||
<dc-qualifier>ispartofseries</dc-qualifier>
|
<dc-qualifier>ispartofseries</dc-qualifier>
|
||||||
<repeatable>true</repeatable>
|
<repeatable>true</repeatable>
|
||||||
<label>Series/Report No.</label>
|
<label>Series/Report No.</label>
|
||||||
|
<type-bind>Technical Report</type-bind>
|
||||||
<input-type>series</input-type>
|
<input-type>series</input-type>
|
||||||
<hint>Enter the series and number assigned to this item by your community.</hint>
|
<hint>Enter the series and number assigned to this item by your community.</hint>
|
||||||
<required></required>
|
<required></required>
|
||||||
|
@@ -155,6 +155,7 @@ public class SubmissionFormConverter implements DSpaceConverter<DCInputSet, Subm
|
|||||||
inputField.setInput(inputRest);
|
inputField.setInput(inputRest);
|
||||||
if (dcinput.isMetadataField()) {
|
if (dcinput.isMetadataField()) {
|
||||||
inputField.setSelectableMetadata(selectableMetadata);
|
inputField.setSelectableMetadata(selectableMetadata);
|
||||||
|
inputField.setTypeBind(dcinput.getTypeBindList());
|
||||||
}
|
}
|
||||||
if (dcinput.isRelationshipField()) {
|
if (dcinput.isRelationshipField()) {
|
||||||
selectableRelationship = getSelectableRelationships(dcinput);
|
selectableRelationship = getSelectableRelationships(dcinput);
|
||||||
|
@@ -83,6 +83,11 @@ public class SubmissionFormFieldRest {
|
|||||||
*/
|
*/
|
||||||
private List<LanguageFormField> languageCodes;
|
private List<LanguageFormField> languageCodes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of type bind value
|
||||||
|
*/
|
||||||
|
private List<String> typeBind;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter for {@link #selectableMetadata}
|
* Getter for {@link #selectableMetadata}
|
||||||
*
|
*
|
||||||
@@ -266,6 +271,14 @@ public class SubmissionFormFieldRest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getTypeBind() {
|
||||||
|
return typeBind;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypeBind(List<String> typeBind) {
|
||||||
|
this.typeBind = typeBind;
|
||||||
|
}
|
||||||
|
|
||||||
public SelectableRelationship getSelectableRelationship() {
|
public SelectableRelationship getSelectableRelationship() {
|
||||||
return selectableRelationship;
|
return selectableRelationship;
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,8 @@ import org.dspace.content.InProgressSubmission;
|
|||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.core.Utils;
|
import org.dspace.core.Utils;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe step for DSpace Spring Rest. Expose and allow patching of the in progress submission metadata. It is
|
* Describe step for DSpace Spring Rest. Expose and allow patching of the in progress submission metadata. It is
|
||||||
@@ -43,7 +45,11 @@ public class DescribeStep extends AbstractProcessingStep {
|
|||||||
|
|
||||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(DescribeStep.class);
|
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(DescribeStep.class);
|
||||||
|
|
||||||
|
// Input reader for form configuration
|
||||||
private DCInputsReader inputReader;
|
private DCInputsReader inputReader;
|
||||||
|
// Configuration service
|
||||||
|
private final ConfigurationService configurationService =
|
||||||
|
DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
|
|
||||||
public DescribeStep() throws DCInputsReaderException {
|
public DescribeStep() throws DCInputsReaderException {
|
||||||
inputReader = new DCInputsReader();
|
inputReader = new DCInputsReader();
|
||||||
@@ -64,8 +70,17 @@ public class DescribeStep extends AbstractProcessingStep {
|
|||||||
|
|
||||||
private void readField(InProgressSubmission obj, SubmissionStepConfig config, DataDescribe data,
|
private void readField(InProgressSubmission obj, SubmissionStepConfig config, DataDescribe data,
|
||||||
DCInputSet inputConfig) throws DCInputsReaderException {
|
DCInputSet inputConfig) throws DCInputsReaderException {
|
||||||
|
String documentTypeValue = "";
|
||||||
|
List<MetadataValue> documentType = itemService.getMetadataByMetadataString(obj.getItem(),
|
||||||
|
configurationService.getProperty("submit.type-bind.field", "dc.type"));
|
||||||
|
if (documentType.size() > 0) {
|
||||||
|
documentTypeValue = documentType.get(0).getValue();
|
||||||
|
}
|
||||||
for (DCInput[] row : inputConfig.getFields()) {
|
for (DCInput[] row : inputConfig.getFields()) {
|
||||||
for (DCInput input : row) {
|
for (DCInput input : row) {
|
||||||
|
// Is this input allowed for the document type, as per type bind config? If there is no type
|
||||||
|
// bind set, this is always true
|
||||||
|
boolean allowed = input.isAllowedFor(documentTypeValue);
|
||||||
|
|
||||||
List<String> fieldsName = new ArrayList<String>();
|
List<String> fieldsName = new ArrayList<String>();
|
||||||
if (input.isQualdropValue()) {
|
if (input.isQualdropValue()) {
|
||||||
@@ -91,6 +106,9 @@ public class DescribeStep extends AbstractProcessingStep {
|
|||||||
String[] metadataToCheck = Utils.tokenize(md.getMetadataField().toString());
|
String[] metadataToCheck = Utils.tokenize(md.getMetadataField().toString());
|
||||||
if (data.getMetadata().containsKey(
|
if (data.getMetadata().containsKey(
|
||||||
Utils.standardize(metadataToCheck[0], metadataToCheck[1], metadataToCheck[2], "."))) {
|
Utils.standardize(metadataToCheck[0], metadataToCheck[1], metadataToCheck[2], "."))) {
|
||||||
|
// If field is allowed by type bind, add value to existing field set, otherwise remove
|
||||||
|
// all values for this field
|
||||||
|
if (allowed) {
|
||||||
data.getMetadata()
|
data.getMetadata()
|
||||||
.get(Utils.standardize(md.getMetadataField().getMetadataSchema().getName(),
|
.get(Utils.standardize(md.getMetadataField().getMetadataSchema().getName(),
|
||||||
md.getMetadataField().getElement(),
|
md.getMetadataField().getElement(),
|
||||||
@@ -98,6 +116,12 @@ public class DescribeStep extends AbstractProcessingStep {
|
|||||||
"."))
|
"."))
|
||||||
.add(dto);
|
.add(dto);
|
||||||
} else {
|
} else {
|
||||||
|
data.getMetadata().remove(Utils.standardize(metadataToCheck[0], metadataToCheck[1],
|
||||||
|
metadataToCheck[2], "."));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Add values only if allowed by type bind
|
||||||
|
if (allowed) {
|
||||||
List<MetadataValueRest> listDto = new ArrayList<>();
|
List<MetadataValueRest> listDto = new ArrayList<>();
|
||||||
listDto.add(dto);
|
listDto.add(dto);
|
||||||
data.getMetadata()
|
data.getMetadata()
|
||||||
@@ -111,6 +135,7 @@ public class DescribeStep extends AbstractProcessingStep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPatchProcessing(Context context, HttpServletRequest currentRequest, InProgressSubmission source,
|
public void doPatchProcessing(Context context, HttpServletRequest currentRequest, InProgressSubmission source,
|
||||||
|
@@ -16,6 +16,7 @@ import org.apache.logging.log4j.Logger;
|
|||||||
import org.dspace.app.rest.model.ErrorRest;
|
import org.dspace.app.rest.model.ErrorRest;
|
||||||
import org.dspace.app.rest.repository.WorkspaceItemRestRepository;
|
import org.dspace.app.rest.repository.WorkspaceItemRestRepository;
|
||||||
import org.dspace.app.rest.submit.SubmissionService;
|
import org.dspace.app.rest.submit.SubmissionService;
|
||||||
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
import org.dspace.app.util.DCInput;
|
import org.dspace.app.util.DCInput;
|
||||||
import org.dspace.app.util.DCInputSet;
|
import org.dspace.app.util.DCInputSet;
|
||||||
import org.dspace.app.util.DCInputsReader;
|
import org.dspace.app.util.DCInputsReader;
|
||||||
@@ -25,6 +26,7 @@ import org.dspace.content.InProgressSubmission;
|
|||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.authority.service.MetadataAuthorityService;
|
import org.dspace.content.authority.service.MetadataAuthorityService;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute three validation check on fields validation:
|
* Execute three validation check on fields validation:
|
||||||
@@ -50,12 +52,20 @@ public class MetadataValidation extends AbstractValidation {
|
|||||||
|
|
||||||
private MetadataAuthorityService metadataAuthorityService;
|
private MetadataAuthorityService metadataAuthorityService;
|
||||||
|
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ErrorRest> validate(SubmissionService submissionService, InProgressSubmission obj,
|
public List<ErrorRest> validate(SubmissionService submissionService, InProgressSubmission obj,
|
||||||
SubmissionStepConfig config) throws DCInputsReaderException, SQLException {
|
SubmissionStepConfig config) throws DCInputsReaderException, SQLException {
|
||||||
|
|
||||||
List<ErrorRest> errors = new ArrayList<>();
|
List<ErrorRest> errors = new ArrayList<>();
|
||||||
|
String documentTypeValue = "";
|
||||||
DCInputSet inputConfig = getInputReader().getInputsByFormName(config.getId());
|
DCInputSet inputConfig = getInputReader().getInputsByFormName(config.getId());
|
||||||
|
List<MetadataValue> documentType = itemService.getMetadataByMetadataString(obj.getItem(),
|
||||||
|
configurationService.getProperty("submit.type-bind.field", "dc.type"));
|
||||||
|
if (documentType.size() > 0) {
|
||||||
|
documentTypeValue = documentType.get(0).getValue();
|
||||||
|
}
|
||||||
for (DCInput[] row : inputConfig.getFields()) {
|
for (DCInput[] row : inputConfig.getFields()) {
|
||||||
for (DCInput input : row) {
|
for (DCInput input : row) {
|
||||||
String fieldKey =
|
String fieldKey =
|
||||||
@@ -71,12 +81,21 @@ public class MetadataValidation extends AbstractValidation {
|
|||||||
for (int i = 1; i < inputPairs.size(); i += 2) {
|
for (int i = 1; i < inputPairs.size(); i += 2) {
|
||||||
String fullFieldname = input.getFieldName() + "." + (String) inputPairs.get(i);
|
String fullFieldname = input.getFieldName() + "." + (String) inputPairs.get(i);
|
||||||
List<MetadataValue> mdv = itemService.getMetadataByMetadataString(obj.getItem(), fullFieldname);
|
List<MetadataValue> mdv = itemService.getMetadataByMetadataString(obj.getItem(), fullFieldname);
|
||||||
|
// If the input is not allowed for this type, strip it from item metadata.
|
||||||
|
if (!input.isAllowedFor(documentTypeValue)) {
|
||||||
|
itemService.removeMetadataValues(ContextUtil.obtainCurrentRequestContext(),
|
||||||
|
obj.getItem(), mdv);
|
||||||
|
} else {
|
||||||
validateMetadataValues(mdv, input, config, isAuthorityControlled, fieldKey, errors);
|
validateMetadataValues(mdv, input, config, isAuthorityControlled, fieldKey, errors);
|
||||||
if (mdv.size() > 0 && input.isVisible(DCInput.SUBMISSION_SCOPE)) {
|
if (mdv.size() > 0 && input.isVisible(DCInput.SUBMISSION_SCOPE)) {
|
||||||
foundResult = true;
|
foundResult = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (input.isRequired() && ! foundResult) {
|
}
|
||||||
|
// If the input is required but not allowed for this type, and we removed, don't throw
|
||||||
|
// an error - this way, a field can be required for "Book" to which it is bound, but not
|
||||||
|
// other types. A user may have switched between types before a final deposit
|
||||||
|
if (input.isRequired() && !foundResult && input.isAllowedFor(documentTypeValue)) {
|
||||||
// for this required qualdrop no value was found, add to the list of error fields
|
// for this required qualdrop no value was found, add to the list of error fields
|
||||||
addError(errors, ERROR_VALIDATION_REQUIRED,
|
addError(errors, ERROR_VALIDATION_REQUIRED,
|
||||||
"/" + WorkspaceItemRestRepository.OPERATION_PATH_SECTIONS + "/" + config.getId() + "/" +
|
"/" + WorkspaceItemRestRepository.OPERATION_PATH_SECTIONS + "/" + config.getId() + "/" +
|
||||||
@@ -89,6 +108,12 @@ public class MetadataValidation extends AbstractValidation {
|
|||||||
|
|
||||||
for (String fieldName : fieldsName) {
|
for (String fieldName : fieldsName) {
|
||||||
List<MetadataValue> mdv = itemService.getMetadataByMetadataString(obj.getItem(), fieldName);
|
List<MetadataValue> mdv = itemService.getMetadataByMetadataString(obj.getItem(), fieldName);
|
||||||
|
if (!input.isAllowedFor(documentTypeValue)) {
|
||||||
|
itemService.removeMetadataValues(ContextUtil.obtainCurrentRequestContext(), obj.getItem(), mdv);
|
||||||
|
// Continue here, this skips the required check since we've just removed values that previously
|
||||||
|
// appeared, and the configuration already indicates this field shouldn't be included
|
||||||
|
continue;
|
||||||
|
}
|
||||||
validateMetadataValues(mdv, input, config, isAuthorityControlled, fieldKey, errors);
|
validateMetadataValues(mdv, input, config, isAuthorityControlled, fieldKey, errors);
|
||||||
if ((input.isRequired() && mdv.size() == 0) && input.isVisible(DCInput.SUBMISSION_SCOPE)) {
|
if ((input.isRequired() && mdv.size() == 0) && input.isVisible(DCInput.SUBMISSION_SCOPE)) {
|
||||||
// since this field is missing add to list of error
|
// since this field is missing add to list of error
|
||||||
@@ -124,6 +149,10 @@ public class MetadataValidation extends AbstractValidation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setConfigurationService(ConfigurationService configurationService) {
|
||||||
|
this.configurationService = configurationService;
|
||||||
|
}
|
||||||
|
|
||||||
public void setItemService(ItemService itemService) {
|
public void setItemService(ItemService itemService) {
|
||||||
this.itemService = itemService;
|
this.itemService = itemService;
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
<bean name="metadataValidation" class="org.dspace.app.rest.submit.step.validation.MetadataValidation"
|
<bean name="metadataValidation" class="org.dspace.app.rest.submit.step.validation.MetadataValidation"
|
||||||
scope="prototype">
|
scope="prototype">
|
||||||
<property name="name" value="submission-form"/>
|
<property name="name" value="submission-form"/>
|
||||||
|
<property name="configurationService" ref="org.dspace.services.ConfigurationService"/>
|
||||||
<property name="itemService" ref="org.dspace.content.ItemServiceImpl"/>
|
<property name="itemService" ref="org.dspace.content.ItemServiceImpl"/>
|
||||||
<property name="metadataAuthorityService" ref="org.dspace.content.authority.MetadataAuthorityServiceImpl"/>
|
<property name="metadataAuthorityService" ref="org.dspace.content.authority.MetadataAuthorityServiceImpl"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
@@ -11,6 +11,7 @@ import static org.hamcrest.Matchers.contains;
|
|||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||||
@@ -113,20 +114,20 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
||||||
// check the first two rows
|
// check the first two rows
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(
|
.andExpect(jsonPath("$.rows[0].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("name", "Author",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("name", "Author", null,
|
||||||
null, true,"Add an author", "dc.contributor.author"))))
|
null, true,"Add an author", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(
|
.andExpect(jsonPath("$.rows[1].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Title",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Title", null,
|
||||||
"You must enter a main title for this item.", false,
|
"You must enter a main title for this item.", false,
|
||||||
"Enter the main title of the item.", "dc.title"))))
|
"Enter the main title of the item.", "dc.title"))))
|
||||||
// check a row with multiple fields
|
// check a row with multiple fields
|
||||||
.andExpect(jsonPath("$.rows[3].fields",
|
.andExpect(jsonPath("$.rows[3].fields",
|
||||||
contains(
|
contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("date", "Date of Issue",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("date", "Date of Issue",
|
||||||
"You must enter at least the year.", false,
|
null, "You must enter at least the year.", false,
|
||||||
"Please give the date", "col-sm-4",
|
"Please give the date", "col-sm-4",
|
||||||
"dc.date.issued"),
|
"dc.date.issued"),
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Publisher",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Publisher", null,
|
||||||
null, false,"Enter the name of",
|
null, false,"Enter the name of",
|
||||||
"col-sm-8","dc.publisher"))))
|
"col-sm-8","dc.publisher"))))
|
||||||
;
|
;
|
||||||
@@ -144,18 +145,18 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(
|
.andExpect(jsonPath("$.rows[0].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("name", "Author",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("name", "Author", null,
|
||||||
null, true,"Add an author", "dc.contributor.author"))))
|
null, true,"Add an author", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(
|
.andExpect(jsonPath("$.rows[1].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Title",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Title", null,
|
||||||
"You must enter a main title for this item.", false,
|
"You must enter a main title for this item.", false,
|
||||||
"Enter the main title of the item.", "dc.title"))))
|
"Enter the main title of the item.", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[3].fields",contains(
|
.andExpect(jsonPath("$.rows[3].fields",contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("date", "Date of Issue",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("date", "Date of Issue", null,
|
||||||
"You must enter at least the year.", false,
|
"You must enter at least the year.", false,
|
||||||
"Please give the date", "col-sm-4",
|
"Please give the date", "col-sm-4",
|
||||||
"dc.date.issued"),
|
"dc.date.issued"),
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Publisher",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Publisher", null,
|
||||||
null, false,"Enter the name of",
|
null, false,"Enter the name of",
|
||||||
"col-sm-8","dc.publisher"))));
|
"col-sm-8","dc.publisher"))));
|
||||||
}
|
}
|
||||||
@@ -220,20 +221,20 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
// dc.subject fields with in separate rows all linked to an authority with different
|
// dc.subject fields with in separate rows all linked to an authority with different
|
||||||
// presentation modes (suggestion, name-lookup, lookup)
|
// presentation modes (suggestion, name-lookup, lookup)
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(
|
.andExpect(jsonPath("$.rows[0].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Author",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Author", null,
|
||||||
null, true,
|
null, true,
|
||||||
"Author field that can be associated with an authority providing suggestion",
|
"Author field that can be associated with an authority providing suggestion",
|
||||||
null, "dc.contributor.author", "SolrAuthorAuthority")
|
null, "dc.contributor.author", "SolrAuthorAuthority")
|
||||||
)))
|
)))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(
|
.andExpect(jsonPath("$.rows[1].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("lookup-name", "Editor",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("lookup-name", "Editor", null,
|
||||||
null, false,
|
null, false,
|
||||||
"Editor field that can be associated with an authority "
|
"Editor field that can be associated with an authority "
|
||||||
+ "providing the special name lookup",
|
+ "providing the special name lookup",
|
||||||
null, "dc.contributor.editor", "SolrEditorAuthority")
|
null, "dc.contributor.editor", "SolrEditorAuthority")
|
||||||
)))
|
)))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(
|
.andExpect(jsonPath("$.rows[2].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("lookup", "Subject",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("lookup", "Subject", null,
|
||||||
null, true,
|
null, true,
|
||||||
"Subject field that can be associated with an authority providing lookup",
|
"Subject field that can be associated with an authority providing lookup",
|
||||||
null, "dc.subject", "SolrSubjectAuthority")
|
null, "dc.subject", "SolrSubjectAuthority")
|
||||||
@@ -266,7 +267,7 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
||||||
// our test configuration include the dc.type field with a value pair in the 8th row
|
// our test configuration include the dc.type field with a value pair in the 8th row
|
||||||
.andExpect(jsonPath("$.rows[7].fields", contains(
|
.andExpect(jsonPath("$.rows[7].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("dropdown", "Type",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("dropdown", "Type", null,
|
||||||
null, true,
|
null, true,
|
||||||
"Select the type(s) of content of the item. To select more than one value in the " +
|
"Select the type(s) of content of the item. To select more than one value in the " +
|
||||||
"list, you may have to hold down the \"CTRL\" or \"Shift\" key.",
|
"list, you may have to hold down the \"CTRL\" or \"Shift\" key.",
|
||||||
@@ -275,6 +276,35 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findFieldWithTypeBindConfig() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/config/submissionforms/traditionalpageone"))
|
||||||
|
// The status has to be 200 OK
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
// We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
// Check that the JSON root matches the expected "traditionalpageone" input forms
|
||||||
|
.andExpect(jsonPath("$.id", is("traditionalpageone")))
|
||||||
|
.andExpect(jsonPath("$.name", is("traditionalpageone")))
|
||||||
|
.andExpect(jsonPath("$.type", is("submissionform")))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
|
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
||||||
|
// check a row with type-bind 'Technical Report'
|
||||||
|
.andExpect(jsonPath("$.rows[5].fields", contains(
|
||||||
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("series", "Series/Report No.",
|
||||||
|
"Technical Report", null, true,
|
||||||
|
"Enter the series and number assigned to this item by your community.",
|
||||||
|
"dc.relation.ispartofseries"))))
|
||||||
|
// check the same row with a NON-matching type-bind 'Article' (expect false)
|
||||||
|
.andExpect(((jsonPath("$.rows[5].fields", not(contains(
|
||||||
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("series", "Series/Report No.",
|
||||||
|
"Article", null, true,
|
||||||
|
"Enter the series and number assigned to this item by your community.",
|
||||||
|
"dc.relation.ispartofseries")))))));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findOpenRelationshipConfig() throws Exception {
|
public void findOpenRelationshipConfig() throws Exception {
|
||||||
String token = getAuthToken(admin.getEmail(), password);
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
@@ -352,14 +382,15 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Autore", "\u00C8" + " richiesto almeno un autore", true,
|
.matchFormFieldDefinition("name", "Autore", null,
|
||||||
|
"\u00C8" + " richiesto almeno un autore", true,
|
||||||
"Aggiungi un autore", "dc.contributor.author"))))
|
"Aggiungi un autore", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Titolo",
|
.matchFormFieldDefinition("onebox", "Titolo", null,
|
||||||
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
||||||
"Inserisci titolo principale di questo item", "dc.title"))))
|
"Inserisci titolo principale di questo item", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("dropdown", "Lingua", null, false,
|
.matchFormFieldDefinition("dropdown", "Lingua", null, null, false,
|
||||||
"Selezionare la lingua del contenuto principale dell'item."
|
"Selezionare la lingua del contenuto principale dell'item."
|
||||||
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
||||||
+ " Se il contenuto non ha davvero una lingua"
|
+ " Se il contenuto non ha davvero una lingua"
|
||||||
@@ -376,14 +407,14 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Автор", "Потрібно ввести хочаб одного автора!",
|
.matchFormFieldDefinition("name", "Автор", null, "Потрібно ввести хочаб одного автора!",
|
||||||
true, "Додати автора", "dc.contributor.author"))))
|
true, "Додати автора", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Заголовок",
|
.matchFormFieldDefinition("onebox", "Заголовок", null,
|
||||||
"Заговолок файла обов'язковий !", false,
|
"Заговолок файла обов'язковий !", false,
|
||||||
"Ввести основний заголовок файла", "dc.title"))))
|
"Ввести основний заголовок файла", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("dropdown", "Мова", null, false,
|
.matchFormFieldDefinition("dropdown", "Мова", null, null, false,
|
||||||
"Виберiть мову головного змiсту файлу, як що мови немає у списку, вибрати (Iнша)."
|
"Виберiть мову головного змiсту файлу, як що мови немає у списку, вибрати (Iнша)."
|
||||||
+ " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)",
|
+ " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)",
|
||||||
null, "dc.language.iso", "common_iso_languages"))));
|
null, "dc.language.iso", "common_iso_languages"))));
|
||||||
@@ -431,14 +462,15 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Autore", "\u00C8" + " richiesto almeno un autore", true,
|
.matchFormFieldDefinition("name", "Autore", null,
|
||||||
|
"\u00C8" + " richiesto almeno un autore", true,
|
||||||
"Aggiungi un autore", "dc.contributor.author"))))
|
"Aggiungi un autore", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Titolo",
|
.matchFormFieldDefinition("onebox", "Titolo", null,
|
||||||
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
||||||
"Inserisci titolo principale di questo item", "dc.title"))))
|
"Inserisci titolo principale di questo item", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("dropdown", "Lingua", null, false,
|
.matchFormFieldDefinition("dropdown", "Lingua", null, null, false,
|
||||||
"Selezionare la lingua del contenuto principale dell'item."
|
"Selezionare la lingua del contenuto principale dell'item."
|
||||||
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
||||||
+ " Se il contenuto non ha davvero una lingua"
|
+ " Se il contenuto non ha davvero una lingua"
|
||||||
@@ -455,14 +487,14 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Автор", "Потрібно ввести хочаб одного автора!",
|
.matchFormFieldDefinition("name", "Автор", null, "Потрібно ввести хочаб одного автора!",
|
||||||
true, "Додати автора", "dc.contributor.author"))))
|
true, "Додати автора", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Заголовок",
|
.matchFormFieldDefinition("onebox", "Заголовок", null,
|
||||||
"Заговолок файла обов'язковий !", false,
|
"Заговолок файла обов'язковий !", false,
|
||||||
"Ввести основний заголовок файла", "dc.title"))))
|
"Ввести основний заголовок файла", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("dropdown", "Мова", null, false,
|
.matchFormFieldDefinition("dropdown", "Мова", null, null, false,
|
||||||
"Виберiть мову головного змiсту файлу, як що мови немає у списку, вибрати (Iнша)."
|
"Виберiть мову головного змiсту файлу, як що мови немає у списку, вибрати (Iнша)."
|
||||||
+ " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)",
|
+ " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)",
|
||||||
null, "dc.language.iso", "common_iso_languages"))));
|
null, "dc.language.iso", "common_iso_languages"))));
|
||||||
@@ -505,14 +537,15 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Autore", "\u00C8" + " richiesto almeno un autore", true,
|
.matchFormFieldDefinition("name", "Autore", null,
|
||||||
|
"\u00C8" + " richiesto almeno un autore", true,
|
||||||
"Aggiungi un autore", "dc.contributor.author"))))
|
"Aggiungi un autore", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Titolo",
|
.matchFormFieldDefinition("onebox", "Titolo", null,
|
||||||
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
||||||
"Inserisci titolo principale di questo item", "dc.title"))))
|
"Inserisci titolo principale di questo item", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("dropdown", "Lingua", null, false,
|
.matchFormFieldDefinition("dropdown", "Lingua", null, null, false,
|
||||||
"Selezionare la lingua del contenuto principale dell'item."
|
"Selezionare la lingua del contenuto principale dell'item."
|
||||||
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
||||||
+ " Se il contenuto non ha davvero una lingua"
|
+ " Se il contenuto non ha davvero una lingua"
|
||||||
@@ -547,10 +580,10 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Autore", "\u00C8 richiesto almeno un autore", true,
|
.matchFormFieldDefinition("name", "Autore", null, "\u00C8 richiesto almeno un autore", true,
|
||||||
"Aggiungi un autore", "dc.contributor.author"))))
|
"Aggiungi un autore", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Titolo",
|
.matchFormFieldDefinition("onebox", "Titolo", null,
|
||||||
"\u00C8 necessario inserire un titolo principale per questo item", false,
|
"\u00C8 necessario inserire un titolo principale per questo item", false,
|
||||||
"Inserisci titolo principale di questo item", "dc.title"))));
|
"Inserisci titolo principale di questo item", "dc.title"))));
|
||||||
resetLocalesConfiguration();
|
resetLocalesConfiguration();
|
||||||
@@ -582,10 +615,10 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Autore", "\u00C8 richiesto almeno un autore", true,
|
.matchFormFieldDefinition("name", "Autore", null, "\u00C8 richiesto almeno un autore", true,
|
||||||
"Aggiungi un autore", "dc.contributor.author"))))
|
"Aggiungi un autore", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Titolo",
|
.matchFormFieldDefinition("onebox", "Titolo", null,
|
||||||
"\u00C8 necessario inserire un titolo principale per questo item", false,
|
"\u00C8 necessario inserire un titolo principale per questo item", false,
|
||||||
"Inserisci titolo principale di questo item", "dc.title"))));
|
"Inserisci titolo principale di questo item", "dc.title"))));
|
||||||
|
|
||||||
|
@@ -1935,6 +1935,141 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/**
|
||||||
|
* Test the update of metadata for fields configured with type-bind
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void patchUpdateMetadataWithBindTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
//1. A community-collection structure with one parent community with sub-community and two collections.
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
|
||||||
|
.withName("Sub Community")
|
||||||
|
.build();
|
||||||
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
|
||||||
|
.withTitle("Workspace Item 1")
|
||||||
|
.withIssueDate("2017-10-17")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.grantLicense()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//disable file upload mandatory
|
||||||
|
configurationService.setProperty("webui.submit.upload.required", false);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
// Try to add isPartOfSeries (type bound to technical report) - this should not work and instead we'll get
|
||||||
|
// no JSON path for that field
|
||||||
|
List<Operation> updateSeries = new ArrayList<Operation>();
|
||||||
|
List<Map<String, String>> seriesValues = new ArrayList<>();
|
||||||
|
Map<String, String> value = new HashMap<String, String>();
|
||||||
|
value.put("value", "New Series");
|
||||||
|
seriesValues.add(value);
|
||||||
|
updateSeries.add(new AddOperation("/sections/traditionalpageone/dc.relation.ispartofseries", seriesValues));
|
||||||
|
|
||||||
|
String patchBody = getPatchContent(updateSeries);
|
||||||
|
|
||||||
|
getClient(authToken).perform(patch("/api/submission/workspaceitems/" + witem.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should match an item with no series or type
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, null, null))));
|
||||||
|
|
||||||
|
// Verify that the metadata isn't in the workspace item
|
||||||
|
getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should match an item with no series or type
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, null, null))));
|
||||||
|
|
||||||
|
// Set the type to Technical Report confirm it worked
|
||||||
|
List<Operation> updateType = new ArrayList<>();
|
||||||
|
List<Map<String, String>> typeValues = new ArrayList<>();
|
||||||
|
value = new HashMap<String, String>();
|
||||||
|
value.put("value", "Technical Report");
|
||||||
|
typeValues.add(value);
|
||||||
|
updateType.add(new AddOperation("/sections/traditionalpageone/dc.type", typeValues));
|
||||||
|
patchBody = getPatchContent(updateType);
|
||||||
|
|
||||||
|
getClient(authToken).perform(patch("/api/submission/workspaceitems/" + witem.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should now match an item with the expected type and series
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, "Technical Report",
|
||||||
|
null))));
|
||||||
|
|
||||||
|
getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, "Technical Report",
|
||||||
|
null))));
|
||||||
|
|
||||||
|
// Another test, this time adding the series value should be successful and we'll see the value
|
||||||
|
patchBody = getPatchContent(updateSeries);
|
||||||
|
|
||||||
|
getClient(authToken).perform(patch("/api/submission/workspaceitems/" + witem.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should match an item with the expected series and type
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem,
|
||||||
|
"Technical Report", "New Series"))));
|
||||||
|
|
||||||
|
// Verify that the metadata isn't in the workspace item
|
||||||
|
getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should match an item with the expected series and type
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem,
|
||||||
|
"Technical Report", "New Series"))));
|
||||||
|
|
||||||
|
// One final update, to a different type, this should lose the series as we're back to a non-matching type
|
||||||
|
updateType = new ArrayList<>();
|
||||||
|
typeValues = new ArrayList<>();
|
||||||
|
value = new HashMap<String, String>();
|
||||||
|
value.put("value", "Article");
|
||||||
|
typeValues.add(value);
|
||||||
|
updateType.add(new AddOperation("/sections/traditionalpageone/dc.type", typeValues));
|
||||||
|
patchBody = getPatchContent(updateType);
|
||||||
|
|
||||||
|
getClient(authToken).perform(patch("/api/submission/workspaceitems/" + witem.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should NOT match an item with the series "New Series"
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, "Article",
|
||||||
|
null))));
|
||||||
|
|
||||||
|
getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, "Article",
|
||||||
|
null))));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void patchUpdateMetadataForbiddenTest() throws Exception {
|
public void patchUpdateMetadataForbiddenTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
@@ -10,6 +10,7 @@ package org.dspace.app.rest.matcher;
|
|||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
|
||||||
import static org.hamcrest.Matchers.allOf;
|
import static org.hamcrest.Matchers.allOf;
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
@@ -28,13 +29,15 @@ public class SubmissionFormFieldMatcher {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut for the
|
* Shortcut for the
|
||||||
* {@link SubmissionFormFieldMatcher#matchFormFieldDefinition(String, String, String, boolean, String, String, String, String)}
|
* {@link SubmissionFormFieldMatcher#matchFormFieldDefinition(String, String, String, String, boolean, String, String, String, String)}
|
||||||
* with a null style and vocabulary name
|
* with a null style and vocabulary name
|
||||||
*
|
*
|
||||||
* @param type
|
* @param type
|
||||||
* the expected input type
|
* the expected input type
|
||||||
* @param label
|
* @param label
|
||||||
* the expected label
|
* the expected label
|
||||||
|
* @param typeBind
|
||||||
|
* the expected type-bind field(s)
|
||||||
* @param mandatoryMessage
|
* @param mandatoryMessage
|
||||||
* the expected mandatoryMessage, can be null. If not empty the fiedl is expected to be flagged as
|
* the expected mandatoryMessage, can be null. If not empty the fiedl is expected to be flagged as
|
||||||
* mandatory
|
* mandatory
|
||||||
@@ -46,21 +49,23 @@ public class SubmissionFormFieldMatcher {
|
|||||||
* the expected metadata
|
* the expected metadata
|
||||||
* @return a Matcher for all the condition above
|
* @return a Matcher for all the condition above
|
||||||
*/
|
*/
|
||||||
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String mandatoryMessage,
|
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String typeBind,
|
||||||
boolean repeatable,
|
String mandatoryMessage, boolean repeatable,
|
||||||
String hints, String metadata) {
|
String hints, String metadata) {
|
||||||
return matchFormFieldDefinition(type, label, mandatoryMessage, repeatable, hints, null, metadata);
|
return matchFormFieldDefinition(type, label, typeBind, mandatoryMessage, repeatable, hints, null, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut for the
|
* Shortcut for the
|
||||||
* {@link SubmissionFormFieldMatcher#matchFormFieldDefinition(String, String, String, boolean, String, String, String, String)}
|
* {@link SubmissionFormFieldMatcher#matchFormFieldDefinition(String, String, String, String, boolean, String, String, String, String)}
|
||||||
* with a null controlled vocabulary
|
* with a null controlled vocabulary
|
||||||
*
|
*
|
||||||
* @param type
|
* @param type
|
||||||
* the expected input type
|
* the expected input type
|
||||||
* @param label
|
* @param label
|
||||||
* the expected label
|
* the expected label
|
||||||
|
* @param typeBind
|
||||||
|
* the expected type-bind field(s)
|
||||||
* @param mandatoryMessage
|
* @param mandatoryMessage
|
||||||
* the expected mandatoryMessage, can be null. If not empty the field is expected to be flagged as
|
* the expected mandatoryMessage, can be null. If not empty the field is expected to be flagged as
|
||||||
* mandatory
|
* mandatory
|
||||||
@@ -75,10 +80,10 @@ public class SubmissionFormFieldMatcher {
|
|||||||
* the expected metadata
|
* the expected metadata
|
||||||
* @return a Matcher for all the condition above
|
* @return a Matcher for all the condition above
|
||||||
*/
|
*/
|
||||||
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String mandatoryMessage,
|
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String typeBind,
|
||||||
boolean repeatable,
|
String mandatoryMessage, boolean repeatable, String hints, String style, String metadata) {
|
||||||
String hints, String style, String metadata) {
|
return matchFormFieldDefinition(type, label, typeBind, mandatoryMessage, repeatable, hints, style, metadata,
|
||||||
return matchFormFieldDefinition(type, label, mandatoryMessage, repeatable, hints, style, metadata, null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,6 +93,8 @@ public class SubmissionFormFieldMatcher {
|
|||||||
* the expected input type
|
* the expected input type
|
||||||
* @param label
|
* @param label
|
||||||
* the expected label
|
* the expected label
|
||||||
|
* @param typeBind
|
||||||
|
* the expected type-bind field(s)
|
||||||
* @param mandatoryMessage
|
* @param mandatoryMessage
|
||||||
* the expected mandatoryMessage, can be null. If not empty the field is expected to be flagged as
|
* the expected mandatoryMessage, can be null. If not empty the field is expected to be flagged as
|
||||||
* mandatory
|
* mandatory
|
||||||
@@ -100,18 +107,20 @@ public class SubmissionFormFieldMatcher {
|
|||||||
* missing
|
* missing
|
||||||
* @param metadata
|
* @param metadata
|
||||||
* the expected metadata
|
* the expected metadata
|
||||||
* @param controlled vocabulary
|
* @param controlledVocabulary
|
||||||
* the expected controlled vocabulary, can be null. If null the corresponding json path is expected to be
|
* the expected controlled vocabulary, can be null. If null the corresponding json path is expected to be
|
||||||
* missing
|
* missing
|
||||||
* @return a Matcher for all the condition above
|
* @return a Matcher for all the condition above
|
||||||
*/
|
*/
|
||||||
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String mandatoryMessage,
|
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String typeBind,
|
||||||
boolean repeatable, String hints, String style,
|
String mandatoryMessage, boolean repeatable,
|
||||||
String metadata, String controlledVocabulary) {
|
String hints, String style, String metadata,
|
||||||
|
String controlledVocabulary) {
|
||||||
return allOf(
|
return allOf(
|
||||||
// check each field definition
|
// check each field definition
|
||||||
hasJsonPath("$.input.type", is(type)),
|
hasJsonPath("$.input.type", is(type)),
|
||||||
hasJsonPath("$.label", containsString(label)),
|
hasJsonPath("$.label", containsString(label)),
|
||||||
|
typeBind != null ? hasJsonPath("$.typeBind", contains(typeBind)) : hasNoJsonPath("$.typeBind[0]"),
|
||||||
hasJsonPath("$.selectableMetadata[0].metadata", is(metadata)),
|
hasJsonPath("$.selectableMetadata[0].metadata", is(metadata)),
|
||||||
controlledVocabulary != null ? hasJsonPath("$.selectableMetadata[0].controlledVocabulary",
|
controlledVocabulary != null ? hasJsonPath("$.selectableMetadata[0].controlledVocabulary",
|
||||||
is(controlledVocabulary)) : hasNoJsonPath("$.selectableMetadata[0].controlledVocabulary"),
|
is(controlledVocabulary)) : hasNoJsonPath("$.selectableMetadata[0].controlledVocabulary"),
|
||||||
@@ -166,7 +175,7 @@ public class SubmissionFormFieldMatcher {
|
|||||||
hasJsonPath("$.selectableRelationship.filter", is(filter)),
|
hasJsonPath("$.selectableRelationship.filter", is(filter)),
|
||||||
hasJsonPath("$.selectableRelationship.searchConfiguration", is(searchConfiguration)),
|
hasJsonPath("$.selectableRelationship.searchConfiguration", is(searchConfiguration)),
|
||||||
hasJsonPath("$.selectableRelationship.nameVariants", is(String.valueOf(nameVariants))),
|
hasJsonPath("$.selectableRelationship.nameVariants", is(String.valueOf(nameVariants))),
|
||||||
matchFormFieldDefinition(type, label, mandatoryMessage, repeatable, hints, metadata));
|
matchFormFieldDefinition(type, label, null, mandatoryMessage, repeatable, hints, metadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -82,6 +82,30 @@ public class WorkspaceItemMatcher {
|
|||||||
matchLinks(witem));
|
matchLinks(witem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that the workspace item has the expected type and series values
|
||||||
|
* (used in type bind evaluation)
|
||||||
|
* @param witem the workspace item
|
||||||
|
* @param type the dc.type value eg. Technical Report
|
||||||
|
* @param series the series value eg. 11-23
|
||||||
|
* @return Matcher result
|
||||||
|
*/
|
||||||
|
public static Matcher matchItemWithTypeAndSeries(WorkspaceItem witem, String type, String series) {
|
||||||
|
return allOf(
|
||||||
|
// Check workspaceitem properties
|
||||||
|
matchProperties(witem),
|
||||||
|
// Check type appears or is null
|
||||||
|
type != null ?
|
||||||
|
hasJsonPath("$.sections.traditionalpageone['dc.type'][0].value", is(type)) :
|
||||||
|
hasNoJsonPath("$.sections.traditionalpageone['dc.type'][0].value"),
|
||||||
|
// Check series as it appears (for type bind testing)
|
||||||
|
series != null ?
|
||||||
|
hasJsonPath("$.sections.traditionalpageone['dc.relation.ispartofseries'][0].value", is(series)) :
|
||||||
|
hasNoJsonPath("$.sections.traditionalpageone['dc.relation.ispartofseries'][0].value"),
|
||||||
|
matchLinks(witem)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that the id and type are exposed
|
* Check that the id and type are exposed
|
||||||
*
|
*
|
||||||
|
@@ -936,6 +936,11 @@ metadata.hide.dc.description.provenance = true
|
|||||||
# Defaults to true; If set to 'false', submitter has option to skip upload
|
# Defaults to true; If set to 'false', submitter has option to skip upload
|
||||||
#webui.submit.upload.required = true
|
#webui.submit.upload.required = true
|
||||||
|
|
||||||
|
# Which field should be used for type-bind
|
||||||
|
# Defaults to 'dc.type'; If changing this value, you must also update the related
|
||||||
|
# dspace-angular environment configuration property submission.typeBind.field
|
||||||
|
#submit.type-bind.field = dc.type
|
||||||
|
|
||||||
#### Creative Commons settings ######
|
#### Creative Commons settings ######
|
||||||
|
|
||||||
# The url to the web service API
|
# The url to the web service API
|
||||||
@@ -1600,6 +1605,11 @@ request.item.type = all
|
|||||||
# Should all Request Copy emails go to the helpdesk instead of the item submitter?
|
# Should all Request Copy emails go to the helpdesk instead of the item submitter?
|
||||||
request.item.helpdesk.override = false
|
request.item.helpdesk.override = false
|
||||||
|
|
||||||
|
#------------------------------------------------------------------#
|
||||||
|
#------------------SUBMISSION CONFIGURATION------------------------#
|
||||||
|
#------------------------------------------------------------------#
|
||||||
|
# Field to use for type binding, default dc.type
|
||||||
|
submit.type-bind.field = dc.type
|
||||||
|
|
||||||
#------------------------------------------------------------------#
|
#------------------------------------------------------------------#
|
||||||
#-------------------MODULE CONFIGURATIONS--------------------------#
|
#-------------------MODULE CONFIGURATIONS--------------------------#
|
||||||
|
@@ -33,6 +33,7 @@ rest.projection.specificLevel.maxEmbed = 5
|
|||||||
rest.properties.exposed = plugin.named.org.dspace.curate.CurationTask
|
rest.properties.exposed = plugin.named.org.dspace.curate.CurationTask
|
||||||
rest.properties.exposed = google.analytics.key
|
rest.properties.exposed = google.analytics.key
|
||||||
rest.properties.exposed = versioning.item.history.include.submitter
|
rest.properties.exposed = versioning.item.history.include.submitter
|
||||||
|
rest.properties.exposed = submit.type-bind.field
|
||||||
|
|
||||||
#---------------------------------------------------------------#
|
#---------------------------------------------------------------#
|
||||||
# These configs are used by the deprecated REST (v4-6) module #
|
# These configs are used by the deprecated REST (v4-6) module #
|
||||||
|
Reference in New Issue
Block a user