Merge branch 'main' into tilted_rels

This commit is contained in:
Bruno Roemers
2021-04-01 10:20:07 +02:00
15 changed files with 992 additions and 115 deletions

View File

@@ -305,6 +305,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
// metadataValueService.update(context, metadataValue); // metadataValueService.update(context, metadataValue);
dso.addDetails(metadataField.toString()); dso.addDetails(metadataField.toString());
} }
setMetadataModified(dso);
return newMetadata; return newMetadata;
} }

View File

@@ -112,6 +112,16 @@ public class Item extends DSpaceObject implements DSpaceObjectLegacySupport {
@Transient @Transient
private transient ItemService itemService; private transient ItemService itemService;
/**
* True if anything else was changed since last metadata retrieval()
* (to drive metadata cache)
*/
@Transient
private boolean modifiedMetadataCache = true;
@Transient
private List<MetadataValue> cachedMetadata = new ArrayList<>();
/** /**
* Protected constructor, create object using: * Protected constructor, create object using:
* {@link org.dspace.content.service.ItemService#create(Context, WorkspaceItem)} * {@link org.dspace.content.service.ItemService#create(Context, WorkspaceItem)}
@@ -373,4 +383,23 @@ public class Item extends DSpaceObject implements DSpaceObjectLegacySupport {
} }
return itemService; return itemService;
} }
@Override
protected void setMetadataModified() {
super.setMetadataModified();
modifiedMetadataCache = true;
}
public boolean isModifiedMetadataCache() {
return modifiedMetadataCache;
}
protected List<MetadataValue> getCachedMetadata() {
return cachedMetadata;
}
protected void setCachedMetadata(List<MetadataValue> cachedMetadata) {
this.cachedMetadata = cachedMetadata;
modifiedMetadataCache = false;
}
} }

View File

@@ -1328,42 +1328,33 @@ prevent the generation of resource policy entry values with null dspace_object a
@Override @Override
public List<MetadataValue> getMetadata(Item item, String schema, String element, String qualifier, String lang, public List<MetadataValue> getMetadata(Item item, String schema, String element, String qualifier, String lang,
boolean enableVirtualMetadata) { boolean enableVirtualMetadata) {
//Fields of the relation schema are virtual metadata if (!enableVirtualMetadata) {
//except for relation.type which is the type of item in the model log.debug("Called getMetadata for " + item.getID() + " without enableVirtualMetadata");
if (StringUtils.equals(schema, MetadataSchemaEnum.RELATION.getName()) && !StringUtils.equals(element, "type")) { return super.getMetadata(item, schema, element, qualifier, lang);
}
List<RelationshipMetadataValue> relationMetadata = relationshipMetadataService if (item.isModifiedMetadataCache()) {
.getRelationshipMetadata(item, enableVirtualMetadata); log.debug("Called getMetadata for " + item.getID() + " with invalid cache");
List<MetadataValue> listToReturn = new LinkedList<>(); //rebuild cache
for (MetadataValue metadataValue : relationMetadata) { List<MetadataValue> dbMetadataValues = item.getMetadata();
if (StringUtils.equals(metadataValue.getMetadataField().getElement(), element)) {
listToReturn.add(metadataValue);
}
}
listToReturn = sortMetadataValueList(listToReturn);
return listToReturn;
} else {
List<MetadataValue> dbMetadataValues = super.getMetadata(item, schema, element, qualifier, lang);
List<MetadataValue> fullMetadataValueList = new LinkedList<>(); List<MetadataValue> fullMetadataValueList = new LinkedList<>();
if (enableVirtualMetadata) { fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true));
fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true));
}
fullMetadataValueList.addAll(dbMetadataValues); fullMetadataValueList.addAll(dbMetadataValues);
List<MetadataValue> finalList = new LinkedList<>(); item.setCachedMetadata(sortMetadataValueList(fullMetadataValueList));
for (MetadataValue metadataValue : fullMetadataValueList) {
if (match(schema, element, qualifier, lang, metadataValue)) {
finalList.add(metadataValue);
}
}
finalList = sortMetadataValueList(finalList);
return finalList;
} }
log.debug("Called getMetadata for " + item.getID() + " based on cache");
// Build up list of matching values based on the cache
List<MetadataValue> values = new ArrayList<>();
for (MetadataValue dcv : item.getCachedMetadata()) {
if (match(schema, element, qualifier, lang, dcv)) {
values.add(dcv);
}
}
// Create an array of matching values
return values;
} }
/** /**

View File

@@ -164,6 +164,7 @@ public class Relationship implements ReloadableEntity<Integer> {
*/ */
public void setLeftPlace(int leftPlace) { public void setLeftPlace(int leftPlace) {
this.leftPlace = leftPlace; this.leftPlace = leftPlace;
leftItem.setMetadataModified();
} }
/** /**
@@ -180,6 +181,7 @@ public class Relationship implements ReloadableEntity<Integer> {
*/ */
public void setRightPlace(int rightPlace) { public void setRightPlace(int rightPlace) {
this.rightPlace = rightPlace; this.rightPlace = rightPlace;
rightItem.setMetadataModified();
} }
/** /**

View File

@@ -13,6 +13,7 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import javax.xml.xpath.XPath; import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
@@ -315,6 +316,9 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements Hiera
private String getNodeLabel(String key, boolean useHierarchy) { private String getNodeLabel(String key, boolean useHierarchy) {
try { try {
Node node = getNode(key); Node node = getNode(key);
if (Objects.isNull(node)) {
return null;
}
if (useHierarchy) { if (useHierarchy) {
return this.buildString(node); return this.buildString(node);
} else { } else {

View File

@@ -9,11 +9,13 @@ package org.dspace.content;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.AbstractIntegrationTestWithDatabase;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
@@ -203,13 +205,38 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
public void testDeleteAuthorRelationshipCopyToLeftItem() throws Exception { public void testDeleteAuthorRelationshipCopyToLeftItem() throws Exception {
initPublicationAuthor(); initPublicationAuthor();
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
//verify the dc.contributor.author virtual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
List<MetadataValue> plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(0));
//verify there's no relation.isAuthorOfPublication actual metadata
List<MetadataValue> plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(0));
//delete the relationship, copying the virtual metadata to actual metadata on the leftItem //delete the relationship, copying the virtual metadata to actual metadata on the leftItem
//leftItem is the publication //leftItem is the publication
relationshipService.delete(context, relationship, true, false); relationshipService.delete(context, relationship, true, false);
context.restoreAuthSystemState(); context.restoreAuthSystemState();
//verify the dc.contributor.author actual metadata //verify the dc.contributor.author actual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1)); assertThat(authorList.size(), equalTo(1));
assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName")); assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName"));
assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc")); assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc"));
@@ -217,10 +244,15 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author"));
assertNull(authorList.get(0).getAuthority()); assertNull(authorList.get(0).getAuthority());
//verify there's no relation.isAuthorOfPublication actual metadata //verify there's relation.isAuthorOfPublication actual metadata
plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(1));
//verify there's relation.isAuthorOfPublication actual metadata
List<MetadataValue> relationshipMetadataList = itemService List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0)); assertThat(relationshipMetadataList.size(), equalTo(1));
//request the virtual metadata of the publication only //request the virtual metadata of the publication only
List<RelationshipMetadataValue> list = relationshipMetadataService.getRelationshipMetadata(leftItem, true); List<RelationshipMetadataValue> list = relationshipMetadataService.getRelationshipMetadata(leftItem, true);
@@ -244,18 +276,50 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
List<MetadataValue> relationshipMetadataList = itemService List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0)); assertThat(relationshipMetadataList.size(), equalTo(0));
//verify there's relation.isPublicationOfAuthor actual metadata on the author
assertThat(rightItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor"))
.collect(Collectors.toList()).size(), equalTo(1));
assertThat(itemService
.getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY)
.size(), equalTo(1));
} }
@Test @Test
public void testDeleteAuthorRelationshipCopyToBothItems() throws Exception { public void testDeleteAuthorRelationshipCopyToBothItems() throws Exception {
initPublicationAuthor(); initPublicationAuthor();
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
//verify the dc.contributor.author virtual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
List<MetadataValue> plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(0));
//verify there's no relation.isAuthorOfPublication actual metadata
List<MetadataValue> plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(0));
//delete the relationship, copying the virtual metadata to actual metadata on the both items //delete the relationship, copying the virtual metadata to actual metadata on the both items
relationshipService.delete(context, relationship, true, true); relationshipService.delete(context, relationship, true, true);
context.restoreAuthSystemState(); context.restoreAuthSystemState();
//verify the dc.contributor.author actual metadata //verify the dc.contributor.author actual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1)); assertThat(authorList.size(), equalTo(1));
assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName")); assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName"));
assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc")); assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc"));
@@ -263,10 +327,21 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author"));
assertNull(authorList.get(0).getAuthority()); assertNull(authorList.get(0).getAuthority());
//verify there's no relation.isAuthorOfPublication actual metadata //verify there's relation.isPublicationOfAuthor actual metadata
List<MetadataValue> relationshipMetadataList = itemService assertEquals(1, rightItem.getMetadata().stream()
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor"))
assertThat(relationshipMetadataList.size(), equalTo(0)); .collect(Collectors.toList()).size());
assertEquals(1, itemService
.getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY)
.size());
//verify there's relation.isAuthorOfPublication actual metadata
assertEquals(1, leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList()).size());
assertEquals(1, itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY)
.size());
} }
@Test @Test
@@ -386,13 +461,38 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
public void testDeleteAuthorRelationshipCopyToLeftItemFromDefaultInDb() throws Exception { public void testDeleteAuthorRelationshipCopyToLeftItemFromDefaultInDb() throws Exception {
initPublicationAuthorWithCopyParams(true, false); initPublicationAuthorWithCopyParams(true, false);
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
//verify the dc.contributor.author virtual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
List<MetadataValue> plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(0));
//verify there's no relation.isAuthorOfPublication actual metadata
List<MetadataValue> plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(0));
//delete the relationship, copying the virtual metadata to actual metadata on the leftItem //delete the relationship, copying the virtual metadata to actual metadata on the leftItem
//leftItem is the publication //leftItem is the publication
relationshipService.delete(context, relationship); relationshipService.delete(context, relationship);
context.restoreAuthSystemState(); context.restoreAuthSystemState();
//verify the dc.contributor.author actual metadata //verify the dc.contributor.author actual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1)); assertThat(authorList.size(), equalTo(1));
assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName")); assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName"));
assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc")); assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc"));
@@ -400,10 +500,15 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author"));
assertNull(authorList.get(0).getAuthority()); assertNull(authorList.get(0).getAuthority());
//verify there's no relation.isAuthorOfPublication actual metadata //verify there's relation.isAuthorOfPublication actual metadata
plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(1));
//verify there's relation.isAuthorOfPublication actual metadata
List<MetadataValue> relationshipMetadataList = itemService List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0)); assertThat(relationshipMetadataList.size(), equalTo(1));
//request the virtual metadata of the publication only //request the virtual metadata of the publication only
List<RelationshipMetadataValue> list = relationshipMetadataService.getRelationshipMetadata(leftItem, true); List<RelationshipMetadataValue> list = relationshipMetadataService.getRelationshipMetadata(leftItem, true);
@@ -427,18 +532,50 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
List<MetadataValue> relationshipMetadataList = itemService List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0)); assertThat(relationshipMetadataList.size(), equalTo(0));
//verify there's relation.isPublicationOfAuthor actual metadata on the author
assertThat(rightItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor"))
.collect(Collectors.toList()).size(), equalTo(1));
assertThat(itemService
.getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY)
.size(), equalTo(1));
} }
@Test @Test
public void testDeleteAuthorRelationshipCopyToBothItemsFromDefaultsInDb() throws Exception { public void testDeleteAuthorRelationshipCopyToBothItemsFromDefaultsInDb() throws Exception {
initPublicationAuthorWithCopyParams(true, true); initPublicationAuthorWithCopyParams(true, true);
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
//verify the dc.contributor.author virtual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
List<MetadataValue> plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(0));
//verify there's no relation.isAuthorOfPublication actual metadata
List<MetadataValue> plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(0));
//delete the relationship, copying the virtual metadata to actual metadata on the both items //delete the relationship, copying the virtual metadata to actual metadata on the both items
relationshipService.delete(context, relationship); relationshipService.delete(context, relationship);
context.restoreAuthSystemState(); context.restoreAuthSystemState();
//verify the dc.contributor.author actual metadata //verify the dc.contributor.author actual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1)); assertThat(authorList.size(), equalTo(1));
assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName")); assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName"));
assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc")); assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc"));
@@ -446,10 +583,20 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author"));
assertNull(authorList.get(0).getAuthority()); assertNull(authorList.get(0).getAuthority());
//verify there's no relation.isAuthorOfPublication actual metadata //verify there's relation.isAuthorOfPublication actual metadata on the publication
List<MetadataValue> relationshipMetadataList = itemService assertThat(leftItem.getMetadata().stream()
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
assertThat(relationshipMetadataList.size(), equalTo(0)); .collect(Collectors.toList()).size(), equalTo(1));
assertThat(itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY)
.size(), equalTo(1));
//verify there's relation.isPublicationOfAuthor actual metadata on the author
assertThat(rightItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor"))
.collect(Collectors.toList()).size(), equalTo(1));
assertThat(itemService
.getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY)
.size(), equalTo(1));
} }
@Test @Test

View File

@@ -27,6 +27,9 @@ import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem; import org.dspace.content.WorkspaceItem;
import org.dspace.content.authority.Choices;
import org.dspace.content.authority.factory.ContentAuthorityServiceFactory;
import org.dspace.content.authority.service.MetadataAuthorityService;
import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.ItemService; import org.dspace.content.service.ItemService;
import org.dspace.content.service.WorkspaceItemService; import org.dspace.content.service.WorkspaceItemService;
@@ -36,6 +39,7 @@ import org.dspace.discovery.indexobject.IndexablePoolTask;
import org.dspace.discovery.indexobject.IndexableWorkflowItem; import org.dspace.discovery.indexobject.IndexableWorkflowItem;
import org.dspace.discovery.indexobject.IndexableWorkspaceItem; import org.dspace.discovery.indexobject.IndexableWorkspaceItem;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.services.ConfigurationService;
import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.workflow.WorkflowException; import org.dspace.workflow.WorkflowException;
import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.WorkflowConfigurationException;
@@ -73,6 +77,10 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase {
.getServiceByName(IndexingService.class.getName(), .getServiceByName(IndexingService.class.getName(),
IndexingService.class); IndexingService.class);
ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
MetadataAuthorityService metadataAuthorityService = ContentAuthorityServiceFactory.getInstance()
.getMetadataAuthorityService();
@Test @Test
public void solrRecordsAfterDepositOrDeletionOfWorkspaceItemTest() throws Exception { public void solrRecordsAfterDepositOrDeletionOfWorkspaceItemTest() throws Exception {
@@ -273,6 +281,41 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase {
} }
@Test
public void solrRecordFromMessyItemTest() throws Exception {
configurationService.setProperty("authority.controlled.dc.subject", "true");
metadataAuthorityService.clearCache();
try {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1").build();
context.restoreAuthSystemState();
assertSearchQuery(IndexableItem.TYPE, 0);
context.turnOffAuthorisationSystem();
ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2021-01-21")
.withAuthor("Smith, Donald")
.withSubject("Test Value", "NOT-EXISTING", Choices.CF_ACCEPTED)
.build();
context.restoreAuthSystemState();
assertSearchQuery(IndexableItem.TYPE, 1);
} finally {
configurationService.setProperty("authority.controlled.dc.subject", "false");
metadataAuthorityService.clearCache();
}
}
private void assertSearchQuery(String resourceType, int size) throws SearchServiceException { private void assertSearchQuery(String resourceType, int size) throws SearchServiceException {
DiscoverQuery discoverQuery = new DiscoverQuery(); DiscoverQuery discoverQuery = new DiscoverQuery();
discoverQuery.setQuery("*:*"); discoverQuery.setQuery("*:*");

View File

@@ -41,6 +41,7 @@ public class DiscoverFacetResultsConverter {
Projection projection) { Projection projection) {
FacetResultsRest facetResultsRest = new FacetResultsRest(); FacetResultsRest facetResultsRest = new FacetResultsRest();
facetResultsRest.setProjection(projection); facetResultsRest.setProjection(projection);
facetResultsRest.setConfiguration(configuration.getId());
setRequestInformation(context, facetName, prefix, query, dsoTypes, dsoScope, searchFilters, searchResult, setRequestInformation(context, facetName, prefix, query, dsoTypes, dsoScope, searchFilters, searchResult,
configuration, facetResultsRest, page, projection); configuration, facetResultsRest, page, projection);

View File

@@ -12,6 +12,7 @@ import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.emptyOrNullString;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -720,7 +721,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest
//The scope has to be the same as the one that we've given in the parameters //The scope has to be the same as the one that we've given in the parameters
.andExpect(jsonPath("$.scope", is("testScope"))) .andExpect(jsonPath("$.scope", is("testScope")))
//There always needs to be a self link available //There always needs to be a self link available
.andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author"))) .andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author?scope=testScope")))
//These are all the authors for the items that were created and thus they have to be present in //These are all the authors for the items that were created and thus they have to be present in
// the embedded values section // the embedded values section
.andExpect(jsonPath("$._embedded.values", containsInAnyOrder( .andExpect(jsonPath("$._embedded.values", containsInAnyOrder(
@@ -748,7 +749,9 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest
//The scope has to be same as the param that we've entered //The scope has to be same as the param that we've entered
.andExpect(jsonPath("$.scope", is("testScope"))) .andExpect(jsonPath("$.scope", is("testScope")))
//There always needs to be a self link available //There always needs to be a self link available
.andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author"))) .andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author?scope=testScope")))
.andExpect(jsonPath("$._links.next.href",
containsString("api/discover/facets/author?scope=testScope&page=1&size=2")))
//These are the values that need to be present as it's ordered by count and these authors are the //These are the values that need to be present as it's ordered by count and these authors are the
// most common ones in the items that we've created // most common ones in the items that we've created
.andExpect(jsonPath("$._embedded.values", containsInAnyOrder( .andExpect(jsonPath("$._embedded.values", containsInAnyOrder(
@@ -5227,4 +5230,245 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest
.andExpect(jsonPath("$._embedded.searchResult.page.totalElements", is(3))); .andExpect(jsonPath("$._embedded.searchResult.page.totalElements", is(3)));
} }
@Test
public void discoverSearchFacetValuesTest() throws Exception {
context.turnOffAuthorisationSystem();
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();
Collection col2 = CollectionBuilder.createCollection(context, child1)
.withName("Collection 2").build();
ItemBuilder.createItem(context, col1)
.withTitle("Public Test Item")
.withIssueDate("2010-10-17")
.withAuthor("Smith, Donald")
.withSubject("ExtraEntry").build();
ItemBuilder.createItem(context, col2)
.withTitle("Withdrawn Test Item")
.withIssueDate("1990-02-13")
.withAuthor("Smith, Maria")
.withAuthor("Doe, Jane")
.withSubject("ExtraEntry")
.withdrawn().build();
ItemBuilder.createItem(context, col2)
.withTitle("Private Test Item")
.withIssueDate("2010-02-13")
.withAuthor("Smith, Maria")
.withAuthor("Doe, Jane")
.withSubject("AnotherTest")
.withSubject("ExtraEntry")
.makeUnDiscoverable().build();
context.restoreAuthSystemState();
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/discover/facets/discoverable")
.param("configuration", "administrativeView")
.param("sort", "score,DESC")
.param("page", "0")
.param("size", "10"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._links.self.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC")))
.andExpect(jsonPath("$._embedded.values", Matchers.containsInAnyOrder(
SearchResultMatcher.matchEmbeddedFacetValues("true", 2, "discover",
"/api/discover/search/objects?configuration=administrativeView&f.discoverable=true,equals"),
SearchResultMatcher.matchEmbeddedFacetValues("false", 1, "discover",
"/api/discover/search/objects?configuration=administrativeView&f.discoverable=false,equals")
)));
}
@Test
public void discoverSearchFacetValuesPaginationTest() throws Exception {
context.turnOffAuthorisationSystem();
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();
Collection col2 = CollectionBuilder.createCollection(context, child1)
.withName("Collection 2").build();
ItemBuilder.createItem(context, col1)
.withTitle("Public Test Item")
.withIssueDate("2010-10-17")
.withAuthor("Smith, Donald")
.withSubject("ExtraEntry").build();
ItemBuilder.createItem(context, col2)
.withTitle("Withdrawn Test Item")
.withIssueDate("1990-02-13")
.withAuthor("Smith, Maria")
.withAuthor("Doe, Jane")
.withSubject("ExtraEntry")
.withdrawn().build();
ItemBuilder.createItem(context, col2)
.withTitle("Private Test Item")
.withIssueDate("2010-02-13")
.withAuthor("Smith, Maria")
.withAuthor("Doe, Jane")
.withSubject("AnotherTest")
.withSubject("ExtraEntry")
.makeUnDiscoverable().build();
context.restoreAuthSystemState();
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/discover/facets/discoverable")
.param("configuration", "administrativeView")
.param("sort", "score,DESC")
.param("page", "0")
.param("size", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._links.self.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC")))
.andExpect(jsonPath("$._links.next.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=1&size=1")))
.andExpect(jsonPath("$._embedded.values", Matchers.contains(
SearchResultMatcher.matchEmbeddedFacetValues("true", 2, "discover",
"/api/discover/search/objects?configuration=administrativeView&f.discoverable=true,equals")
)));
getClient(adminToken).perform(get("/api/discover/facets/discoverable")
.param("configuration", "administrativeView")
.param("sort", "score,DESC")
.param("page", "1")
.param("size", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._links.first.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=0&size=1")))
.andExpect(jsonPath("$._links.prev.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=0&size=1")))
.andExpect(jsonPath("$._links.self.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=1&size=1")))
.andExpect(jsonPath("$._embedded.values", Matchers.contains(
SearchResultMatcher.matchEmbeddedFacetValues("false", 1, "discover",
"/api/discover/search/objects?configuration=administrativeView&f.discoverable=false,equals")
)));
}
@Test
public void discoverFacetsTestWithQueryTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 2").build();
Item publicItem1 = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2019-10-17")
.withAuthor("Smith, Donald")
.withSubject("ExtraEntry")
.build();
Item publicItem2 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2020-02-13")
.withAuthor("Doe, Jane")
.withSubject("TestingForMore").withSubject("ExtraEntry")
.build();
Item publicItem3 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2020-02-13")
.withAuthor("Anton, Senek")
.withSubject("AnotherTest").withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
context.restoreAuthSystemState();
getClient().perform(get("/api/discover/facets/author")
.param("query", "Donald"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.type", is("discover")))
.andExpect(jsonPath("$.name", is("author")))
.andExpect(jsonPath("$.facetType", is("text")))
.andExpect(jsonPath("$.scope", is(emptyOrNullString())))
.andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author?query=Donald")))
.andExpect(jsonPath("$._embedded.values[0].label", is("Smith, Donald")))
.andExpect(jsonPath("$._embedded.values[0].count", is(1)))
.andExpect(jsonPath("$._embedded.values[0]._links.search.href",
containsString("api/discover/search/objects?query=Donald&f.author=Smith, Donald,equals")))
.andExpect(jsonPath("$._embedded.values").value(Matchers.hasSize(1)));
}
@Test
public void discoverFacetsTestWithDsoTypeTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 2").build();
Item publicItem1 = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald")
.withSubject("ExtraEntry")
.build();
Item publicItem2 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2020-02-13")
.withAuthor("Doe, Jane")
.withSubject("ExtraEntry")
.build();
Item publicItem3 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2020-02-13")
.withAuthor("Anton, Senek")
.withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
context.restoreAuthSystemState();
getClient().perform(get("/api/discover/facets/dateIssued")
.param("dsoType", "Item"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.type", is("discover")))
.andExpect(jsonPath("$.name", is("dateIssued")))
.andExpect(jsonPath("$.facetType", is("date")))
.andExpect(jsonPath("$.scope", is(emptyOrNullString())))
.andExpect(jsonPath("$._links.self.href",
containsString("api/discover/facets/dateIssued?dsoType=Item")))
.andExpect(jsonPath("$._embedded.values[0].label", is("2017 - 2020")))
.andExpect(jsonPath("$._embedded.values[0].count", is(3)))
.andExpect(jsonPath("$._embedded.values[0]._links.search.href",
containsString("api/discover/search/objects?dsoType=Item&f.dateIssued=[2017 TO 2020],equals")))
.andExpect(jsonPath("$._embedded.values").value(Matchers.hasSize(1)));
}
} }

View File

@@ -29,6 +29,7 @@ import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.builder.MetadataSchemaBuilder; import org.dspace.builder.MetadataSchemaBuilder;
import org.dspace.content.MetadataSchema; import org.dspace.content.MetadataSchema;
import org.dspace.content.factory.ContentServiceFactory;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -271,74 +272,85 @@ public class MetadataSchemaRestRepositoryIT extends AbstractControllerIntegratio
@Test @Test
public void findAllPaginationTest() throws Exception { public void findAllPaginationTest() throws Exception {
// Determine number of schemas from database
int numberOfSchema = ContentServiceFactory.getInstance()
.getMetadataSchemaService().findAll(context).size();
// If we return 6 schema per page, determine number of pages we expect
int pageSize = 6;
int numberOfPages = (int) Math.ceil((double) numberOfSchema / pageSize);
// In these tests we just validate the first 3 pages, as we currently have at least that many schema
getClient().perform(get("/api/core/metadataschemas") getClient().perform(get("/api/core/metadataschemas")
.param("size", "6") .param("size", String.valueOf(pageSize))
.param("page", "0")) .param("page", "0"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry()))) .andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry())))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf( .andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=0"), Matchers.containsString("size=6")))) Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf( .andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=0"), Matchers.containsString("size=6")))) Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.next.href", Matchers.allOf( .andExpect(jsonPath("$._links.next.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=1"), Matchers.containsString("size=6")))) Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf( .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=2"), Matchers.containsString("size=6")))) Matchers.containsString("page=" + (numberOfPages - 1)),
.andExpect(jsonPath("$.page.totalElements", is(16))) Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.totalElements", is(numberOfSchema)))
.andExpect(jsonPath("$.page.size", is(6))); .andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
getClient().perform(get("/api/core/metadataschemas") getClient().perform(get("/api/core/metadataschemas")
.param("size", "6") .param("size", String.valueOf(pageSize))
.param("page", "1")) .param("page", "1"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry()))) .andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry())))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf( .andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=0"), Matchers.containsString("size=6")))) Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf( .andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=0"), Matchers.containsString("size=6")))) Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf( .andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=1"), Matchers.containsString("size=6")))) Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.next.href", Matchers.allOf( .andExpect(jsonPath("$._links.next.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=2"), Matchers.containsString("size=6")))) Matchers.containsString("page=2"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf( .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=2"), Matchers.containsString("size=6")))) Matchers.containsString("page=" + (numberOfPages - 1)),
.andExpect(jsonPath("$.page.totalElements", is(16))) Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.totalElements", is(numberOfSchema)))
.andExpect(jsonPath("$.page.size", is(6))); .andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
getClient().perform(get("/api/core/metadataschemas") getClient().perform(get("/api/core/metadataschemas")
.param("size", "6") .param("size", String.valueOf(pageSize))
.param("page", "2")) .param("page", "2"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry()))) .andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry())))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf( .andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=0"), Matchers.containsString("size=6")))) Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf( .andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=1"), Matchers.containsString("size=6")))) Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf( .andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=2"), Matchers.containsString("size=6")))) Matchers.containsString("page=2"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf( .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"), Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=2"), Matchers.containsString("size=6")))) Matchers.containsString("page=" + (numberOfPages - 1)),
.andExpect(jsonPath("$.page.totalElements", is(16))) Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.totalElements", is(numberOfSchema)))
.andExpect(jsonPath("$.page.size", is(6))); .andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
} }

View File

@@ -32,6 +32,7 @@ import org.dspace.builder.MetadataSchemaBuilder;
import org.dspace.content.MetadataField; import org.dspace.content.MetadataField;
import org.dspace.content.MetadataFieldServiceImpl; import org.dspace.content.MetadataFieldServiceImpl;
import org.dspace.content.MetadataSchema; import org.dspace.content.MetadataSchema;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.MetadataSchemaService; import org.dspace.content.service.MetadataSchemaService;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Before; import org.junit.Before;
@@ -966,11 +967,21 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration
@Test @Test
public void findAllPaginationTest() throws Exception { public void findAllPaginationTest() throws Exception {
// Determine number of metadata fields from database
int numberOfMdFields = ContentServiceFactory.getInstance().getMetadataFieldService().findAll(context).size();
// If we return 3 fields per page, determine number of pages we expect
int pageSize = 3;
int numberOfPages = (int) Math.ceil((double) numberOfMdFields / pageSize);
// Check first page
getClient().perform(get("/api/core/metadatafields") getClient().perform(get("/api/core/metadatafields")
.param("size", "3") .param("size", String.valueOf(pageSize))
.param("page", "0")) .param("page", "0"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
// Metadata fields are returned alphabetically. So, look for the first 3 alphabetically
.andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems( .andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems(
MetadataFieldMatcher.matchMetadataFieldByKeys("creativework","datePublished", null), MetadataFieldMatcher.matchMetadataFieldByKeys("creativework","datePublished", null),
MetadataFieldMatcher.matchMetadataFieldByKeys("creativework", "editor", null), MetadataFieldMatcher.matchMetadataFieldByKeys("creativework", "editor", null),
@@ -978,25 +989,28 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration
))) )))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf( .andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=0"), Matchers.containsString("size=3")))) Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf( .andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=0"), Matchers.containsString("size=3")))) Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.next.href", Matchers.allOf( .andExpect(jsonPath("$._links.next.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=1"), Matchers.containsString("size=3")))) Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf( .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=63"), Matchers.containsString("size=3")))) Matchers.containsString("page=" + (numberOfPages - 1)),
.andExpect(jsonPath("$.page.totalElements", is(192))) Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalPages", is(64))) .andExpect(jsonPath("$.page.totalElements", is(numberOfMdFields)))
.andExpect(jsonPath("$.page.size", is(3))); .andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
// Check second page
getClient().perform(get("/api/core/metadatafields") getClient().perform(get("/api/core/metadatafields")
.param("size", "3") .param("size", String.valueOf(pageSize))
.param("page", "1")) .param("page", "1"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
// Metadata fields are returned alphabetically. So, look for the next 3 alphabetically
.andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems( .andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems(
MetadataFieldMatcher.matchMetadataFieldByKeys("creativework","publisher", null), MetadataFieldMatcher.matchMetadataFieldByKeys("creativework","publisher", null),
MetadataFieldMatcher.matchMetadataFieldByKeys("creativeworkseries", "issn", null), MetadataFieldMatcher.matchMetadataFieldByKeys("creativeworkseries", "issn", null),
@@ -1004,48 +1018,53 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration
))) )))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf( .andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=0"), Matchers.containsString("size=3")))) Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf( .andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=0"), Matchers.containsString("size=3")))) Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf( .andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=1"), Matchers.containsString("size=3")))) Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.next.href", Matchers.allOf( .andExpect(jsonPath("$._links.next.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=2"), Matchers.containsString("size=3")))) Matchers.containsString("page=2"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf( .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=63"), Matchers.containsString("size=3")))) Matchers.containsString("page=" + (numberOfPages - 1)),
.andExpect(jsonPath("$.page.totalElements", is(192))) Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalPages", is(64))) .andExpect(jsonPath("$.page.totalElements", is(numberOfMdFields)))
.andExpect(jsonPath("$.page.size", is(3))); .andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
// Check last page
getClient().perform(get("/api/core/metadatafields") getClient().perform(get("/api/core/metadatafields")
.param("size", "3") .param("size", String.valueOf(pageSize))
.param("page", "63")) .param("page", String.valueOf(numberOfPages - 1)))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
// Metadata fields are returned alphabetically.
// So, on the last page we'll just ensure it *at least* includes the last field alphabetically
.andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems( .andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems(
MetadataFieldMatcher.matchMetadataFieldByKeys("relation","isVolumeOfJournal", null),
MetadataFieldMatcher.matchMetadataFieldByKeys("relationship", "type", null),
MetadataFieldMatcher.matchMetadataFieldByKeys("workflow", "score", null) MetadataFieldMatcher.matchMetadataFieldByKeys("workflow", "score", null)
))) )))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf( .andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=0"), Matchers.containsString("size=3")))) Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf( .andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=62"), Matchers.containsString("size=3")))) Matchers.containsString("page=" + (numberOfPages - 2)),
Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf( .andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=63"), Matchers.containsString("size=3")))) Matchers.containsString("page=" + (numberOfPages - 1)),
Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf( .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"), Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=63"), Matchers.containsString("size=3")))) Matchers.containsString("page=" + (numberOfPages - 1)),
.andExpect(jsonPath("$.page.totalElements", is(192))) Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalPages", is(64))) .andExpect(jsonPath("$.page.totalElements", is(numberOfMdFields)))
.andExpect(jsonPath("$.page.size", is(3))); .andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
} }
} }

View File

@@ -7,8 +7,12 @@
*/ */
package org.dspace.app.rest; package org.dspace.app.rest;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
import static org.dspace.content.Item.ANY;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.startsWith; import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
@@ -221,6 +225,35 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void testDeleteAuthorRelationshipCopyToLeftItem() throws Exception { public void testDeleteAuthorRelationshipCopyToLeftItem() throws Exception {
initPublicationAuthor(); initPublicationAuthor();
// Verify the dc.contributor.author virtual metadata of the left item
assertEquals(
1,
itemService
.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY)
.size()
);
// Verify there's no dc.contributor.author actual metadata on the left item
assertEquals(
0,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the left item
assertEquals(
0,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
getClient(adminAuthToken).perform( getClient(adminAuthToken).perform(
delete("/api/core/relationships/" + relationship.getID() + "?copyVirtualMetadata=left")) delete("/api/core/relationships/" + relationship.getID() + "?copyVirtualMetadata=left"))
.andExpect(status().isNoContent()); .andExpect(status().isNoContent());
@@ -235,12 +268,35 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author"));
assertNull(authorList.get(0).getAuthority()); assertNull(authorList.get(0).getAuthority());
// Check that the relation metadata values are gone because the relationship is gone
List<MetadataValue> relationshipMetadataList = itemService List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY); .getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0)); assertThat(relationshipMetadataList.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the left item
assertEquals(
1,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(toList())
.size()
);
// Verify there's relation.isAuthorOfPublication actual metadata on the left item
assertEquals(
1,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
// Check right item to ensure that no metadata is copied
rightItem = context.reloadEntity(rightItem);
relationshipMetadataList = itemService relationshipMetadataList = itemService
.getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY); .getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0)); assertThat(relationshipMetadataList.size(), equalTo(0));
@@ -250,6 +306,27 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void testAuthorDeleteRelationshipCopyToRightItem() throws Exception { public void testAuthorDeleteRelationshipCopyToRightItem() throws Exception {
initPublicationAuthor(); initPublicationAuthor();
// Verify there's no dc.contributor.author actual metadata on the right item
assertEquals(
0,
rightItem.getMetadata()
.stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's no relation.isPublicationOfAuthor actual metadata on the right item
assertEquals(
0,
rightItem.getMetadata()
.stream()
.filter(metadataValue -> "isPublicationOfAuthor"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
getClient(adminAuthToken).perform( getClient(adminAuthToken).perform(
delete("/api/core/relationships/" + relationship.getID() + "?copyVirtualMetadata=right")) delete("/api/core/relationships/" + relationship.getID() + "?copyVirtualMetadata=right"))
.andExpect(status().isNoContent()); .andExpect(status().isNoContent());
@@ -259,14 +336,27 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(0)); assertThat(authorList.size(), equalTo(0));
// Check that the relation metadata values are gone because the relationship is gone
List<MetadataValue> relationshipMetadataList = itemService List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY); .getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0)); assertThat(relationshipMetadataList.size(), equalTo(0));
// Check right item to ensure that the metadata is copied
rightItem = itemService.find(context, rightItem.getID());
relationshipMetadataList = itemService relationshipMetadataList = itemService
.getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY); .getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0)); assertThat(relationshipMetadataList.size(), equalTo(1));
// Verify there's relation.isPublicationOfAuthor actual metadata on the right item
assertEquals(
1,
rightItem.getMetadata()
.stream()
.filter(metadataValue -> "isPublicationOfAuthor"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
// There is no additional Metadata to check on the rightItem because the configuration of the virtual // There is no additional Metadata to check on the rightItem because the configuration of the virtual
// metadata holds no config to display virtual metadata on the author of the publication // metadata holds no config to display virtual metadata on the author of the publication
@@ -291,11 +381,44 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
List<MetadataValue> relationshipMetadataList = itemService List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY); .getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0)); assertThat(relationshipMetadataList.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the left item
assertEquals(
1,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isAuthorOfPublication actual metadata on the left item
assertEquals(
1,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
rightItem = itemService.find(context, rightItem.getID());
relationshipMetadataList = itemService relationshipMetadataList = itemService
.getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY); .getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0)); assertThat(relationshipMetadataList.size(), equalTo(1));
// Verify there's relation.isPublicationOfAuthor actual metadata on the right item
assertEquals(
1,
rightItem.getMetadata()
.stream()
.filter(metadataValue -> "isPublicationOfAuthor"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
// There is no additional Metadata to check on the rightItem because the configuration of the virtual // There is no additional Metadata to check on the rightItem because the configuration of the virtual
// metadata holds no config to display virtual metadata on the author of the publication // metadata holds no config to display virtual metadata on the author of the publication
@@ -375,6 +498,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void deleteItemCopyVirtualMetadataAll() throws Exception { public void deleteItemCopyVirtualMetadataAll() throws Exception {
initPersonProjectPublication(); initPersonProjectPublication();
for (Item item : asList(publicationItem, projectItem)) {
// Verify the dc.contributor.author virtual metadata
assertEquals(
1,
itemService.getMetadata(item, "dc", "contributor", "author", ANY).size()
);
// Verify there's no dc.contributor.author actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList()).size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList()).size()
);
}
getClient(adminAuthToken).perform( getClient(adminAuthToken).perform(
delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata=all")) delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata=all"))
.andExpect(status().isNoContent()); .andExpect(status().isNoContent());
@@ -387,7 +536,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(publicationAuthorList.get(0).getAuthority()); assertNull(publicationAuthorList.get(0).getAuthority());
List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem, List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem,
"relation", "isAuthorOfPublication", Item.ANY, Item.ANY); "relation", "isAuthorOfPublication", Item.ANY, Item.ANY);
assertThat(publicationRelationships.size(), equalTo(0)); assertThat(publicationRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isAuthorOfPublication actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
projectItem = itemService.find(context, projectItem.getID()); projectItem = itemService.find(context, projectItem.getID());
List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem, List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem,
@@ -397,13 +565,58 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(projectAuthorList.get(0).getAuthority()); assertNull(projectAuthorList.get(0).getAuthority());
List<MetadataValue> projectRelationships = itemService.getMetadata(projectItem, List<MetadataValue> projectRelationships = itemService.getMetadata(projectItem,
"relation", "isPersonOfProject", Item.ANY, Item.ANY); "relation", "isPersonOfProject", Item.ANY, Item.ANY);
assertThat(projectRelationships.size(), equalTo(0)); assertThat(projectRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isPersonOfProject actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "isPersonOfProject"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
} }
@Test @Test
public void deleteItemCopyVirtualMetadataOneType() throws Exception { public void deleteItemCopyVirtualMetadataOneType() throws Exception {
initPersonProjectPublication(); initPersonProjectPublication();
for (Item item : asList(publicationItem, projectItem)) {
// Verify the dc.contributor.author virtual metadata
assertEquals(
1,
itemService.getMetadata(item, "dc", "contributor", "author", ANY).size()
);
// Verify there's no dc.contributor.author actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList()).size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList()).size()
);
}
getClient(adminAuthToken).perform( getClient(adminAuthToken).perform(
delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata=" delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata="
+ publicationPersonRelationshipType.getID())) + publicationPersonRelationshipType.getID()))
@@ -417,7 +630,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(publicationAuthorList.get(0).getAuthority()); assertNull(publicationAuthorList.get(0).getAuthority());
List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem, List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem,
"relation", "isAuthorOfPublication", Item.ANY, Item.ANY); "relation", "isAuthorOfPublication", Item.ANY, Item.ANY);
assertThat(publicationRelationships.size(), equalTo(0)); assertThat(publicationRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isAuthorOfPublication actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
projectItem = itemService.find(context, projectItem.getID()); projectItem = itemService.find(context, projectItem.getID());
List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem, List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem,
@@ -432,6 +664,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void deleteItemCopyVirtualMetadataTwoTypes() throws Exception { public void deleteItemCopyVirtualMetadataTwoTypes() throws Exception {
initPersonProjectPublication(); initPersonProjectPublication();
for (Item item : asList(publicationItem, projectItem)) {
// Verify the dc.contributor.author virtual metadata
assertEquals(
1,
itemService.getMetadata(item, "dc", "contributor", "author", ANY).size()
);
// Verify there's no dc.contributor.author actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList()).size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList()).size()
);
}
getClient(adminAuthToken).perform( getClient(adminAuthToken).perform(
delete("/api/core/items/" + personItem.getID() delete("/api/core/items/" + personItem.getID()
+ "?copyVirtualMetadata=" + publicationPersonRelationshipType.getID() + "?copyVirtualMetadata=" + publicationPersonRelationshipType.getID()
@@ -446,7 +704,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(publicationAuthorList.get(0).getAuthority()); assertNull(publicationAuthorList.get(0).getAuthority());
List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem, List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem,
"relation", "isAuthorOfPublication", Item.ANY, Item.ANY); "relation", "isAuthorOfPublication", Item.ANY, Item.ANY);
assertThat(publicationRelationships.size(), equalTo(0)); assertThat(publicationRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isAuthorOfPublication actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
projectItem = itemService.find(context, projectItem.getID()); projectItem = itemService.find(context, projectItem.getID());
List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem, List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem,
@@ -456,7 +733,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(projectAuthorList.get(0).getAuthority()); assertNull(projectAuthorList.get(0).getAuthority());
List<MetadataValue> projectRelationships = itemService.getMetadata(projectItem, List<MetadataValue> projectRelationships = itemService.getMetadata(projectItem,
"relation", "isPersonOfProject", Item.ANY, Item.ANY); "relation", "isPersonOfProject", Item.ANY, Item.ANY);
assertThat(projectRelationships.size(), equalTo(0)); assertThat(projectRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isPersonOfProject actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "isPersonOfProject"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
} }
@Test @Test
@@ -520,6 +816,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void deleteItemCopyVirtualMetadataAllNoPermissions() throws Exception { public void deleteItemCopyVirtualMetadataAllNoPermissions() throws Exception {
initPersonProjectPublication(); initPersonProjectPublication();
for (Item item : asList(publicationItem, projectItem)) {
// Verify the dc.contributor.author virtual metadata
assertEquals(
1,
itemService.getMetadata(item, "dc", "contributor", "author", ANY).size()
);
// Verify there's no dc.contributor.author actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList()).size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList()).size()
);
}
getClient(getAuthToken(eperson.getEmail(), password)).perform( getClient(getAuthToken(eperson.getEmail(), password)).perform(
delete("/api/core/items/" + personItem.getID())) delete("/api/core/items/" + personItem.getID()))
.andExpect(status().isForbidden()); .andExpect(status().isForbidden());
@@ -608,6 +930,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void deleteItemCopyVirtualMetadataConfigured() throws Exception { public void deleteItemCopyVirtualMetadataConfigured() throws Exception {
initPersonProjectPublication(); initPersonProjectPublication();
for (Item item : asList(publicationItem, projectItem)) {
// Verify the dc.contributor.author virtual metadata
assertEquals(
1,
itemService.getMetadata(item, "dc", "contributor", "author", ANY).size()
);
// Verify there's no dc.contributor.author actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList()).size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList()).size()
);
}
getClient(adminAuthToken).perform( getClient(adminAuthToken).perform(
delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata=configured")) delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata=configured"))
.andExpect(status().isNoContent()); .andExpect(status().isNoContent());
@@ -629,7 +977,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(projectAuthorList.get(0).getAuthority()); assertNull(projectAuthorList.get(0).getAuthority());
List<MetadataValue> projectRelationships = itemService.getMetadata(projectItem, List<MetadataValue> projectRelationships = itemService.getMetadata(projectItem,
"relation", "isPersonOfProject", Item.ANY, Item.ANY); "relation", "isPersonOfProject", Item.ANY, Item.ANY);
assertThat(projectRelationships.size(), equalTo(0)); assertThat(projectRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isPersonOfProject actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "isPersonOfProject"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
} }
@Test @Test
@@ -653,7 +1020,7 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(publicationAuthorList.get(0).getAuthority()); assertNull(publicationAuthorList.get(0).getAuthority());
List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem, List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem,
"relation", "isAuthorOfPublication", Item.ANY, Item.ANY); "relation", "isAuthorOfPublication", Item.ANY, Item.ANY);
assertThat(publicationRelationships.size(), equalTo(0)); assertThat(publicationRelationships.size(), equalTo(1));
projectItem = itemService.find(context, projectItem.getID()); projectItem = itemService.find(context, projectItem.getID());
List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem, List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem,

View File

@@ -776,6 +776,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andDo(result -> idRef2.set(read(result.getResponse().getContentAsString(), "$.id"))); .andDo(result -> idRef2.set(read(result.getResponse().getContentAsString(), "$.id")));
publication1 = itemService.find(context, publication1.getID());
list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY);
// Ensure that we now have three dc.contributor.author mdv ("Smith, Donald", "plain text", "Smith, Maria" // Ensure that we now have three dc.contributor.author mdv ("Smith, Donald", "plain text", "Smith, Maria"
// In that order which will be checked below the rest call // In that order which will be checked below the rest call
@@ -802,6 +803,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
itemService.update(context, publication1); itemService.update(context, publication1);
context.restoreAuthSystemState(); context.restoreAuthSystemState();
publication1 = itemService.find(context, publication1.getID());
list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY);
// Assert that the list of dc.contributor.author mdv is now of size 4 in the following order: // Assert that the list of dc.contributor.author mdv is now of size 4 in the following order:
@@ -839,6 +841,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andDo(result -> idRef3.set(read(result.getResponse().getContentAsString(), "$.id"))); .andDo(result -> idRef3.set(read(result.getResponse().getContentAsString(), "$.id")));
publication1 = itemService.find(context, publication1.getID());
list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY);
// Assert that our dc.contributor.author mdv list is now of size 5 // Assert that our dc.contributor.author mdv list is now of size 5
assertEquals(5, list.size()); assertEquals(5, list.size());
@@ -902,6 +905,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
itemService.update(context, publication1); itemService.update(context, publication1);
context.restoreAuthSystemState(); context.restoreAuthSystemState();
publication1 = itemService.find(context, publication1.getID());
list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY);
assertEquals(10, list.size()); assertEquals(10, list.size());

View File

@@ -83,4 +83,16 @@ public class SearchResultMatcher {
)) ))
); );
} }
public static Matcher<? super Object> matchEmbeddedFacetValues(String label, int count,
String type,
String search_href) {
return allOf(
hasJsonPath("$.label", is(label)),
hasJsonPath("$.count", is(count)),
hasJsonPath("$.type", is(type)),
hasJsonPath("$._links.search.href", containsString(search_href))
);
}
} }

View File

@@ -404,6 +404,7 @@
<!--The configuration settings for discovery of withdrawn and undiscoverable items (admin only) and regular items--> <!--The configuration settings for discovery of withdrawn and undiscoverable items (admin only) and regular items-->
<bean id="administrativeView" class="org.dspace.discovery.configuration.DiscoveryConfiguration" scope="prototype"> <bean id="administrativeView" class="org.dspace.discovery.configuration.DiscoveryConfiguration" scope="prototype">
<!--Which sidebar facets are to be displayed--> <!--Which sidebar facets are to be displayed-->
<property name="id" value="administrativeView" />
<property name="sidebarFacets"> <property name="sidebarFacets">
<list> <list>
<ref bean="searchFilterDiscoverable" /> <ref bean="searchFilterDiscoverable" />