Merge pull request #10540 from atmire/fix-issue-10536_relation-field-requiredissue-main

Fix issue 10536 relation field required issue
This commit is contained in:
Tim Donohue
2025-09-12 14:05:07 -05:00
committed by GitHub
5 changed files with 324 additions and 25 deletions

View File

@@ -30,6 +30,7 @@
<name-map collection-entity-type="CustomEntityType" submission-name="entitytypetest"/> <name-map collection-entity-type="CustomEntityType" submission-name="entitytypetest"/>
<name-map collection-handle="123456789/test-duplicate-detection" submission-name="test-duplicate-detection"/> <name-map collection-handle="123456789/test-duplicate-detection" submission-name="test-duplicate-detection"/>
<name-map collection-handle="123456789/collection-test-patch" submission-name="publicationTestPatch"/> <name-map collection-handle="123456789/collection-test-patch" submission-name="publicationTestPatch"/>
<name-map collection-handle="123456789/enforced-relation" submission-name="enforcedRelation"/>
</submission-map> </submission-map>
@@ -200,6 +201,13 @@
<processing-class>org.dspace.app.rest.submit.step.UploadStep</processing-class> <processing-class>org.dspace.app.rest.submit.step.UploadStep</processing-class>
<type>upload</type> <type>upload</type>
</step-definition> </step-definition>
<step-definition id="publicationStep" mandatory="true">
<heading>submit.progressbar.describe.stepone</heading>
<processing-class>org.dspace.app.rest.submit.step.DescribeStep</processing-class>
<type>submission-form</type>
</step-definition>
</step-definitions> </step-definitions>
<!-- The submission-definitions map lays out the detailed definition of --> <!-- The submission-definitions map lays out the detailed definition of -->
@@ -305,6 +313,10 @@
<step id="traditionalpageone"/> <step id="traditionalpageone"/>
</submission-process> </submission-process>
<submission-process name="enforcedRelation">
<step id="publicationStep"></step>
</submission-process>
<submission-process name="publicationTestPatch"> <submission-process name="publicationTestPatch">
<step id="collection" /> <step id="collection" />
<step id="traditionalpageone" /> <step id="traditionalpageone" />

View File

@@ -465,6 +465,24 @@ it, please enter the types and the actual numbers or codes.</hint>
</row> </row>
</form> </form>
<form name="publicationStep">
<row>
<relation-field>
<relationship-type>isAuthorOfPublication</relationship-type>
<search-configuration>person</search-configuration>
<repeatable>true</repeatable>
<label>Author</label>
<hint>Enter the author's name (Family name, Given names).</hint>
<externalsources>orcid</externalsources>
<required>true</required>
<!-- You may choose to validate author names via a Regular Expression if it's appropriate for
your institution. The below regex requires a comma to be present in the author field.
However, this is disabled by default to support organizations as authors, etc. -->
<!--<regex>\w+(,)+\w+</regex>-->
</relation-field>
</row>
</form>
</form-definitions> </form-definitions>

View File

@@ -23,9 +23,15 @@ import org.dspace.app.util.DCInputsReader;
import org.dspace.app.util.DCInputsReaderException; import org.dspace.app.util.DCInputsReaderException;
import org.dspace.app.util.SubmissionStepConfig; import org.dspace.app.util.SubmissionStepConfig;
import org.dspace.content.InProgressSubmission; import org.dspace.content.InProgressSubmission;
import org.dspace.content.Item;
import org.dspace.content.MetadataValue; import org.dspace.content.MetadataValue;
import org.dspace.content.RelationshipType;
import org.dspace.content.authority.service.MetadataAuthorityService; import org.dspace.content.authority.service.MetadataAuthorityService;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.ItemService; import org.dspace.content.service.ItemService;
import org.dspace.content.service.RelationshipService;
import org.dspace.content.service.RelationshipTypeService;
import org.dspace.core.Context;
import org.dspace.services.ConfigurationService; import org.dspace.services.ConfigurationService;
/** /**
@@ -54,6 +60,11 @@ public class MetadataValidation extends AbstractValidation {
private ConfigurationService configurationService; private ConfigurationService configurationService;
private RelationshipTypeService relationshipTypeService =
ContentServiceFactory.getInstance().getRelationshipTypeService();
private RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
@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 {
@@ -147,11 +158,42 @@ public class MetadataValidation extends AbstractValidation {
} }
} }
} }
relationshipRequiredFieldCheck(ContextUtil.obtainCurrentRequestContext(), obj.getItem(), input, errors,
config);
} }
} }
return errors; return errors;
} }
/**
* Checks if the relation type exists on the item. If not, sets the error state.
*
* @param context the current context
* @param item item in the submission
* @param input input field
* @param errors List holding all errors
* @param config submission step config
* @throws SQLException
*/
private void relationshipRequiredFieldCheck(Context context, Item item, DCInput input, List<ErrorRest> errors,
SubmissionStepConfig config) throws SQLException {
if (input.isRelationshipField() && input.isRequired()) {
String relationshipType = input.getRelationshipType();
if (itemService.getMetadataByMetadataString(item, "relation." + relationshipType).isEmpty()) {
List<RelationshipType> relationTypes =
relationshipTypeService.findByLeftwardOrRightwardTypeName(context, relationshipType);
for (RelationshipType relationType : relationTypes) {
if (!relationshipService.findByItemAndRelationshipType(context, item, relationType).isEmpty()) {
return;
}
}
addError(errors, ERROR_VALIDATION_REQUIRED,
"/" + WorkspaceItemRestRepository.OPERATION_PATH_SECTIONS + "/" + config.getId() + "/" +
input.getFieldName());
}
}
}
private void validateMetadataValues(List<MetadataValue> mdv, DCInput input, SubmissionStepConfig config, private void validateMetadataValues(List<MetadataValue> mdv, DCInput input, SubmissionStepConfig config,
boolean isAuthorityControlled, String fieldKey, boolean isAuthorityControlled, String fieldKey,

View File

@@ -68,13 +68,13 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
//The configuration file for the test env includes 6 forms //The configuration file for the test env includes 6 forms
.andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", equalTo(10))) .andExpect(jsonPath("$.page.totalElements", equalTo(11)))
.andExpect(jsonPath("$.page.totalPages", equalTo(1))) .andExpect(jsonPath("$.page.totalPages", equalTo(1)))
.andExpect(jsonPath("$.page.number", is(0))) .andExpect(jsonPath("$.page.number", is(0)))
.andExpect( .andExpect(
jsonPath("$._links.self.href", Matchers.startsWith(REST_SERVER_URL + "config/submissionforms"))) jsonPath("$._links.self.href", Matchers.startsWith(REST_SERVER_URL + "config/submissionforms")))
//The array of submissionforms should have a size of 8 //The array of submissionforms should have a size of 11
.andExpect(jsonPath("$._embedded.submissionforms", hasSize(equalTo(10)))) .andExpect(jsonPath("$._embedded.submissionforms", hasSize(equalTo(11))))
; ;
} }
@@ -85,12 +85,12 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", equalTo(10))) .andExpect(jsonPath("$.page.totalElements", equalTo(11)))
.andExpect(jsonPath("$.page.totalPages", equalTo(1))) .andExpect(jsonPath("$.page.totalPages", equalTo(1)))
.andExpect(jsonPath("$.page.number", is(0))) .andExpect(jsonPath("$.page.number", is(0)))
.andExpect(jsonPath("$._links.self.href", Matchers.startsWith(REST_SERVER_URL .andExpect(jsonPath("$._links.self.href", Matchers.startsWith(REST_SERVER_URL
+ "config/submissionforms"))) + "config/submissionforms")))
.andExpect(jsonPath("$._embedded.submissionforms", hasSize(equalTo(10)))); .andExpect(jsonPath("$._embedded.submissionforms", hasSize(equalTo(11))));
} }
@Test @Test
@@ -697,10 +697,10 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
Matchers.containsString("page=1"), Matchers.containsString("size=2")))) Matchers.containsString("page=1"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf( .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"), Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=4"), Matchers.containsString("size=2")))) Matchers.containsString("page=5"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalElements", equalTo(10))) .andExpect(jsonPath("$.page.totalElements", equalTo(11)))
.andExpect(jsonPath("$.page.totalPages", equalTo(5))) .andExpect(jsonPath("$.page.totalPages", equalTo(6)))
.andExpect(jsonPath("$.page.number", is(0))); .andExpect(jsonPath("$.page.number", is(0)));
getClient(tokenAdmin).perform(get("/api/config/submissionforms") getClient(tokenAdmin).perform(get("/api/config/submissionforms")
@@ -724,10 +724,10 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
Matchers.containsString("page=2"), Matchers.containsString("size=2")))) Matchers.containsString("page=2"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf( .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"), Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=4"), Matchers.containsString("size=2")))) Matchers.containsString("page=5"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalElements", equalTo(10))) .andExpect(jsonPath("$.page.totalElements", equalTo(11)))
.andExpect(jsonPath("$.page.totalPages", equalTo(5))) .andExpect(jsonPath("$.page.totalPages", equalTo(6)))
.andExpect(jsonPath("$.page.number", is(1))); .andExpect(jsonPath("$.page.number", is(1)));
getClient(tokenAdmin).perform(get("/api/config/submissionforms") getClient(tokenAdmin).perform(get("/api/config/submissionforms")
@@ -735,8 +735,8 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
.param("page", "2")) .param("page", "2"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.submissionforms[0].id", is("test-outside-submission-hidden"))) .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("publicationStep")))
.andExpect(jsonPath("$._embedded.submissionforms[1].id", is("qualdroptest"))) .andExpect(jsonPath("$._embedded.submissionforms[1].id", is("test-outside-submission-hidden")))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf( .andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"), Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=0"), Matchers.containsString("size=2")))) Matchers.containsString("page=0"), Matchers.containsString("size=2"))))
@@ -748,10 +748,10 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
Matchers.containsString("page=2"), Matchers.containsString("size=2")))) Matchers.containsString("page=2"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf( .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"), Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=4"), Matchers.containsString("size=2")))) Matchers.containsString("page=5"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalElements", equalTo(10))) .andExpect(jsonPath("$.page.totalElements", equalTo(11)))
.andExpect(jsonPath("$.page.totalPages", equalTo(5))) .andExpect(jsonPath("$.page.totalPages", equalTo(6)))
.andExpect(jsonPath("$.page.number", is(2))); .andExpect(jsonPath("$.page.number", is(2)));
getClient(tokenAdmin).perform(get("/api/config/submissionforms") getClient(tokenAdmin).perform(get("/api/config/submissionforms")
@@ -759,8 +759,8 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
.param("page", "3")) .param("page", "3"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.submissionforms[0].id", is("traditionalpagetwo"))) .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("qualdroptest")))
.andExpect(jsonPath("$._embedded.submissionforms[1].id", is("sampleauthority"))) .andExpect(jsonPath("$._embedded.submissionforms[1].id", is("traditionalpagetwo")))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf( .andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"), Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=0"), Matchers.containsString("size=2")))) Matchers.containsString("page=0"), Matchers.containsString("size=2"))))
@@ -772,10 +772,10 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
Matchers.containsString("page=3"), Matchers.containsString("size=2")))) Matchers.containsString("page=3"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf( .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"), Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=4"), Matchers.containsString("size=2")))) Matchers.containsString("page=5"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalElements", equalTo(10))) .andExpect(jsonPath("$.page.totalElements", equalTo(11)))
.andExpect(jsonPath("$.page.totalPages", equalTo(5))) .andExpect(jsonPath("$.page.totalPages", equalTo(6)))
.andExpect(jsonPath("$.page.number", is(3))); .andExpect(jsonPath("$.page.number", is(3)));
getClient(tokenAdmin).perform(get("/api/config/submissionforms") getClient(tokenAdmin).perform(get("/api/config/submissionforms")
@@ -783,7 +783,8 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
.param("page", "4")) .param("page", "4"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.submissionforms[0].id", is("traditionalpageone"))) .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("sampleauthority")))
.andExpect(jsonPath("$._embedded.submissionforms[1].id", is("traditionalpageone")))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf( .andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"), Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=0"), Matchers.containsString("size=2")))) Matchers.containsString("page=0"), Matchers.containsString("size=2"))))
@@ -795,10 +796,33 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
Matchers.containsString("page=4"), Matchers.containsString("size=2")))) Matchers.containsString("page=4"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf( .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"), Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=4"), Matchers.containsString("size=2")))) Matchers.containsString("page=5"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalElements", equalTo(10))) .andExpect(jsonPath("$.page.totalElements", equalTo(11)))
.andExpect(jsonPath("$.page.totalPages", equalTo(5))) .andExpect(jsonPath("$.page.totalPages", equalTo(6)))
.andExpect(jsonPath("$.page.number", is(4))); .andExpect(jsonPath("$.page.number", is(4)));
getClient(tokenAdmin).perform(get("/api/config/submissionforms")
.param("size", "2")
.param("page", "5"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.submissionforms[0].id", is("typebindtest")))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=0"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=4"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=5"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=5"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalElements", equalTo(11)))
.andExpect(jsonPath("$.page.totalPages", equalTo(6)))
.andExpect(jsonPath("$.page.number", is(5)));
} }
} }

View File

@@ -88,8 +88,10 @@ import org.dspace.content.MetadataFieldName;
import org.dspace.content.Relationship; import org.dspace.content.Relationship;
import org.dspace.content.RelationshipType; import org.dspace.content.RelationshipType;
import org.dspace.content.WorkspaceItem; import org.dspace.content.WorkspaceItem;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CollectionService; import org.dspace.content.service.CollectionService;
import org.dspace.content.service.ItemService; import org.dspace.content.service.ItemService;
import org.dspace.content.service.RelationshipService;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group; import org.dspace.eperson.Group;
@@ -9808,4 +9810,205 @@ ResourcePolicyBuilder.createResourcePolicy(context, null, adminGroup)
WorkspaceItemBuilder.deleteWorkspaceItem(idRef.get()); WorkspaceItemBuilder.deleteWorkspaceItem(idRef.get());
} }
} }
@Test
public void enforceRequiredRelationTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build();
EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build();
RelationshipType isAuthorOfPublication = RelationshipTypeBuilder
.createRelationshipTypeBuilder(context, publication, person, "isAuthorOfPublication",
"isPublicationOfAuthor", 1, null, 0,
null).withCopyToLeft(false).withCopyToRight(true).build();
isAuthorOfPublication.setTilted(RelationshipType.Tilted.NONE);
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1")
.withEntityType("Person").build();
Collection col2 = CollectionBuilder.createCollection(context, parentCommunity, "123456789/enforced-relation")
.withName("Collection 2")
.withEntityType("Publication").build();
Item author = ItemBuilder.createItem(context, col1)
.withTitle("Author1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.build();
// two workspace items. Only one of them has the required relationship.
WorkspaceItem workspaceItem = WorkspaceItemBuilder.createWorkspaceItem(context, col2)
.withEntityType("Publication")
.build();
WorkspaceItem workspaceItem2 = WorkspaceItemBuilder.createWorkspaceItem(context, col2)
.withEntityType("Publication")
.build();
RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
Relationship relationship1 = relationshipService.create(
context,
workspaceItem.getItem(),
author,
isAuthorOfPublication,
0, 0,
"isAuthorOfPublication",
"isPublicationOfAuthor"
);
context.restoreAuthSystemState();
String adminToken = getAuthToken(admin.getEmail(), password);
// try to deposit the items. One should fail
getClient(adminToken).perform(post("/api/workflow/workflowitems")
.content("/api/submission/workspaceitems/" + workspaceItem.getID())
.contentType(textUriContentType))
.andExpect(status().isCreated());
getClient(adminToken).perform(post("/api/workflow/workflowitems")
.content("/api/submission/workspaceitems/" + workspaceItem2.getID())
.contentType(textUriContentType))
.andExpect(status().isUnprocessableEntity());
}
@Test
public void enforceRequiredRelationTiltedRightTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build();
EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build();
RelationshipType isAuthorOfPublication = RelationshipTypeBuilder
.createRelationshipTypeBuilder(context, publication, person, "isAuthorOfPublication",
"isPublicationOfAuthor", 1, null, 0,
null).withCopyToLeft(false).withCopyToRight(true).build();
isAuthorOfPublication.setTilted(RelationshipType.Tilted.RIGHT);
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1")
.withEntityType("Person").build();
Collection col2 = CollectionBuilder.createCollection(context, parentCommunity, "123456789/enforced-relation")
.withName("Collection 2")
.withEntityType("Publication").build();
Item author = ItemBuilder.createItem(context, col1)
.withTitle("Author1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.build();
// two workspace items. Only one of them has the required relationship.
WorkspaceItem workspaceItem = WorkspaceItemBuilder.createWorkspaceItem(context, col2)
.withEntityType("Publication")
.build();
WorkspaceItem workspaceItem2 = WorkspaceItemBuilder.createWorkspaceItem(context, col2)
.withEntityType("Publication")
.build();
RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
Relationship relationship1 = relationshipService.create(
context,
workspaceItem.getItem(),
author,
isAuthorOfPublication,
0, 0,
"isAuthorOfPublication",
"isPublicationOfAuthor"
);
context.restoreAuthSystemState();
String adminToken = getAuthToken(admin.getEmail(), password);
// try to deposit the items. One should fail
getClient(adminToken).perform(post("/api/workflow/workflowitems")
.content("/api/submission/workspaceitems/" + workspaceItem.getID())
.contentType(textUriContentType))
.andExpect(status().isCreated());
getClient(adminToken).perform(post("/api/workflow/workflowitems")
.content("/api/submission/workspaceitems/" + workspaceItem2.getID())
.contentType(textUriContentType))
.andExpect(status().isUnprocessableEntity());
}
@Test
public void enforceRequiredRelationTiltedLeftTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build();
EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build();
RelationshipType isAuthorOfPublication = RelationshipTypeBuilder
.createRelationshipTypeBuilder(context, publication, person, "isAuthorOfPublication",
"isPublicationOfAuthor", 1, null, 0,
null).withCopyToLeft(false).withCopyToRight(true).build();
isAuthorOfPublication.setTilted(RelationshipType.Tilted.LEFT);
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1")
.withEntityType("Person").build();
Collection col2 = CollectionBuilder.createCollection(context, parentCommunity, "123456789/enforced-relation")
.withName("Collection 2")
.withEntityType("Publication").build();
Item author = ItemBuilder.createItem(context, col1)
.withTitle("Author1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.build();
// two workspace items. Only one of them has the required relationship.
WorkspaceItem workspaceItem = WorkspaceItemBuilder.createWorkspaceItem(context, col2)
.withEntityType("Publication")
.build();
WorkspaceItem workspaceItem2 = WorkspaceItemBuilder.createWorkspaceItem(context, col2)
.withEntityType("Publication")
.build();
RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
Relationship relationship1 = relationshipService.create(
context,
workspaceItem.getItem(),
author,
isAuthorOfPublication,
0, 0,
"isAuthorOfPublication",
"isPublicationOfAuthor"
);
context.restoreAuthSystemState();
String adminToken = getAuthToken(admin.getEmail(), password);
// try to deposit the items. One should fail
getClient(adminToken).perform(post("/api/workflow/workflowitems")
.content("/api/submission/workspaceitems/" + workspaceItem.getID())
.contentType(textUriContentType))
.andExpect(status().isCreated());
getClient(adminToken).perform(post("/api/workflow/workflowitems")
.content("/api/submission/workspaceitems/" + workspaceItem2.getID())
.contentType(textUriContentType))
.andExpect(status().isUnprocessableEntity());
}
} }