mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 18:14:26 +00:00
DS-3484: Refactoring builders and extended Browse by title test
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -25,7 +25,6 @@ dist/
|
||||
nbdist/
|
||||
nbactions.xml
|
||||
nb-configuration.xml
|
||||
META-INF/
|
||||
|
||||
## Ignore all *.properties file in root folder, EXCEPT build.properties (the default)
|
||||
## KEPT FOR BACKWARDS COMPATIBILITY WITH 5.x (build.properties is now replaced with local.cfg)
|
||||
|
@@ -506,31 +506,6 @@
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-solr</artifactId>
|
||||
<classifier>classes</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
<artifactId>lucene-analyzers-icu</artifactId>
|
||||
<version>${solr.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
<artifactId>lucene-analyzers-smartcn</artifactId>
|
||||
<version>${solr.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
<artifactId>lucene-analyzers-stempel</artifactId>
|
||||
<version>${solr.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.rometools</groupId>
|
||||
@@ -698,7 +673,6 @@
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.9.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
|
@@ -81,7 +81,7 @@ public class AbstractDSpaceTest
|
||||
if (!kernelImpl.isRunning())
|
||||
{
|
||||
// NOTE: the "dspace.dir" system property MUST be specified via Maven
|
||||
kernelImpl.start(System.getProperty("dspace.dir")); // init the kernel
|
||||
kernelImpl.start(getDspaceDir()); // init the kernel
|
||||
}
|
||||
|
||||
// Initialize mock Util class (allows Util.getSourceVersion() to work in Unit tests)
|
||||
@@ -111,4 +111,8 @@ public class AbstractDSpaceTest
|
||||
}
|
||||
kernelImpl = null;
|
||||
}
|
||||
public static String getDspaceDir(){
|
||||
return System.getProperty("dspace.dir");
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -92,9 +92,9 @@ public class GoogleBitstreamComparatorTest extends AbstractUnitTest{
|
||||
when(bitstreamFormat1.getMIMEType()).thenReturn("application/pdf");
|
||||
when(bitstreamFormat2.getMIMEType()).thenReturn("application/pdf");
|
||||
when(bitstreamFormat3.getMIMEType()).thenReturn("application/pdf");
|
||||
when(bitstream1.getSize()).thenReturn(new Long(100));
|
||||
when(bitstream2.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream3.getSize()).thenReturn(new Long(300));
|
||||
when(bitstream1.getSize()).thenReturn(Long.valueOf(100));
|
||||
when(bitstream2.getSize()).thenReturn(Long.valueOf(200));
|
||||
when(bitstream3.getSize()).thenReturn(Long.valueOf(300));
|
||||
|
||||
List<Bitstream> toSort = bundle.getBitstreams();
|
||||
Collections.sort(toSort, new GoogleBitstreamComparator(context, settings));
|
||||
@@ -130,9 +130,9 @@ public class GoogleBitstreamComparatorTest extends AbstractUnitTest{
|
||||
when(bitstreamFormat1.getMIMEType()).thenReturn("text/richtext");
|
||||
when(bitstreamFormat2.getMIMEType()).thenReturn("text/richtext");
|
||||
when(bitstreamFormat3.getMIMEType()).thenReturn("application/postscript");
|
||||
when(bitstream1.getSize()).thenReturn(new Long(100));
|
||||
when(bitstream2.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream3.getSize()).thenReturn(new Long(300));
|
||||
when(bitstream1.getSize()).thenReturn(Long.valueOf(100));
|
||||
when(bitstream2.getSize()).thenReturn(Long.valueOf(200));
|
||||
when(bitstream3.getSize()).thenReturn(Long.valueOf(300));
|
||||
|
||||
List<Bitstream> toSort = bundle.getBitstreams();
|
||||
Collections.sort(toSort, new GoogleBitstreamComparator(context, settings));
|
||||
@@ -150,9 +150,9 @@ public class GoogleBitstreamComparatorTest extends AbstractUnitTest{
|
||||
when(bitstreamFormat1.getMIMEType()).thenReturn("application/pdf");
|
||||
when(bitstreamFormat2.getMIMEType()).thenReturn("application/pdf");
|
||||
when(bitstreamFormat3.getMIMEType()).thenReturn("application/pdf");
|
||||
when(bitstream1.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream2.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream3.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream1.getSize()).thenReturn(Long.valueOf(200));
|
||||
when(bitstream2.getSize()).thenReturn(Long.valueOf(200));
|
||||
when(bitstream3.getSize()).thenReturn(Long.valueOf(200));
|
||||
|
||||
List<Bitstream> toSort = bundle.getBitstreams();
|
||||
Collections.sort(toSort, new GoogleBitstreamComparator(context, settings));
|
||||
@@ -170,9 +170,9 @@ public class GoogleBitstreamComparatorTest extends AbstractUnitTest{
|
||||
when(bitstreamFormat1.getMIMEType()).thenReturn("unknown");
|
||||
when(bitstreamFormat2.getMIMEType()).thenReturn("text/richtext");
|
||||
when(bitstreamFormat3.getMIMEType()).thenReturn("text/richtext");
|
||||
when(bitstream1.getSize()).thenReturn(new Long(400));
|
||||
when(bitstream2.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream3.getSize()).thenReturn(new Long(300));
|
||||
when(bitstream1.getSize()).thenReturn(Long.valueOf(400));
|
||||
when(bitstream2.getSize()).thenReturn(Long.valueOf(200));
|
||||
when(bitstream3.getSize()).thenReturn(Long.valueOf(300));
|
||||
|
||||
List<Bitstream> toSort = bundle.getBitstreams();
|
||||
Collections.sort(toSort, new GoogleBitstreamComparator(context, settings));
|
||||
@@ -190,9 +190,9 @@ public class GoogleBitstreamComparatorTest extends AbstractUnitTest{
|
||||
when(bitstreamFormat1.getMIMEType()).thenReturn("unknown");
|
||||
when(bitstreamFormat2.getMIMEType()).thenReturn("unknown");
|
||||
when(bitstreamFormat3.getMIMEType()).thenReturn("unknown");
|
||||
when(bitstream1.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream2.getSize()).thenReturn(new Long(300));
|
||||
when(bitstream3.getSize()).thenReturn(new Long(100));
|
||||
when(bitstream1.getSize()).thenReturn(Long.valueOf(200));
|
||||
when(bitstream2.getSize()).thenReturn(Long.valueOf(300));
|
||||
when(bitstream3.getSize()).thenReturn(Long.valueOf(100));
|
||||
|
||||
List<Bitstream> toSort = bundle.getBitstreams();
|
||||
Collections.sort(toSort, new GoogleBitstreamComparator(context, settings));
|
||||
@@ -223,9 +223,9 @@ public class GoogleBitstreamComparatorTest extends AbstractUnitTest{
|
||||
*/
|
||||
@Test
|
||||
public void testNoMimeType() throws Exception{
|
||||
when(bitstream1.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream2.getSize()).thenReturn(new Long(300));
|
||||
when(bitstream3.getSize()).thenReturn(new Long(100));
|
||||
when(bitstream1.getSize()).thenReturn(Long.valueOf(200));
|
||||
when(bitstream2.getSize()).thenReturn(Long.valueOf(300));
|
||||
when(bitstream3.getSize()).thenReturn(Long.valueOf(100));
|
||||
|
||||
List<Bitstream> toSort = bundle.getBitstreams();
|
||||
Collections.sort(toSort, new GoogleBitstreamComparator(context, settings));
|
||||
@@ -272,9 +272,9 @@ public class GoogleBitstreamComparatorTest extends AbstractUnitTest{
|
||||
when(bitstreamFormat1.getMIMEType()).thenReturn("text/richtext");
|
||||
when(bitstreamFormat2.getMIMEType()).thenReturn("application/msword");
|
||||
when(bitstreamFormat3.getMIMEType()).thenReturn("application/postscript");
|
||||
when(bitstream1.getSize()).thenReturn(new Long(100));
|
||||
when(bitstream2.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream3.getSize()).thenReturn(new Long(300));
|
||||
when(bitstream1.getSize()).thenReturn(Long.valueOf(100));
|
||||
when(bitstream2.getSize()).thenReturn(Long.valueOf(200));
|
||||
when(bitstream3.getSize()).thenReturn(Long.valueOf(300));
|
||||
|
||||
List<Bitstream> toSort = bundle.getBitstreams();
|
||||
Collections.sort(toSort, new GoogleBitstreamComparator(context, settings));
|
||||
@@ -295,9 +295,9 @@ public class GoogleBitstreamComparatorTest extends AbstractUnitTest{
|
||||
when(bitstreamFormat1.getMIMEType()).thenReturn("text/richtext");
|
||||
when(bitstreamFormat2.getMIMEType()).thenReturn("application/msword");
|
||||
when(bitstreamFormat3.getMIMEType()).thenReturn("application/postscript");
|
||||
when(bitstream1.getSize()).thenReturn(new Long(100));
|
||||
when(bitstream2.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream3.getSize()).thenReturn(new Long(300));
|
||||
when(bitstream1.getSize()).thenReturn(Long.valueOf(100));
|
||||
when(bitstream2.getSize()).thenReturn(Long.valueOf(200));
|
||||
when(bitstream3.getSize()).thenReturn(Long.valueOf(300));
|
||||
|
||||
List<Bitstream> toSort = bundle.getBitstreams();
|
||||
Collections.sort(toSort, new GoogleBitstreamComparator(context, settings));
|
||||
@@ -315,9 +315,9 @@ public class GoogleBitstreamComparatorTest extends AbstractUnitTest{
|
||||
when(bitstreamFormat1.getMIMEType()).thenReturn("text/richtext");
|
||||
when(bitstreamFormat2.getMIMEType()).thenReturn("application/msword");
|
||||
when(bitstreamFormat3.getMIMEType()).thenReturn("application/postscript");
|
||||
when(bitstream1.getSize()).thenReturn(new Long(100));
|
||||
when(bitstream2.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream3.getSize()).thenReturn(new Long(300));
|
||||
when(bitstream1.getSize()).thenReturn(Long.valueOf(100));
|
||||
when(bitstream2.getSize()).thenReturn(Long.valueOf(200));
|
||||
when(bitstream3.getSize()).thenReturn(Long.valueOf(300));
|
||||
|
||||
List<Bitstream> toSort = bundle.getBitstreams();
|
||||
Collections.sort(toSort, new GoogleBitstreamComparator(context, settings));
|
||||
@@ -335,9 +335,9 @@ public class GoogleBitstreamComparatorTest extends AbstractUnitTest{
|
||||
when(bitstreamFormat1.getMIMEType()).thenReturn("text/richtext");
|
||||
when(bitstreamFormat2.getMIMEType()).thenReturn("application/msword");
|
||||
when(bitstreamFormat3.getMIMEType()).thenReturn("audio/x-wav");
|
||||
when(bitstream1.getSize()).thenReturn(new Long(300));
|
||||
when(bitstream2.getSize()).thenReturn(new Long(200));
|
||||
when(bitstream3.getSize()).thenReturn(new Long(100));
|
||||
when(bitstream1.getSize()).thenReturn(Long.valueOf(300));
|
||||
when(bitstream2.getSize()).thenReturn(Long.valueOf(200));
|
||||
when(bitstream3.getSize()).thenReturn(Long.valueOf(100));
|
||||
|
||||
List<Bitstream> toSort = bundle.getBitstreams();
|
||||
Collections.sort(toSort, new GoogleBitstreamComparator(context, settings));
|
||||
|
@@ -7,8 +7,6 @@
|
||||
*/
|
||||
package org.dspace.discovery;
|
||||
|
||||
import org.dspace.solr.MockSolrServer;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -16,16 +14,12 @@ import org.springframework.stereotype.Service;
|
||||
* Mock SOLR service for the Search Core
|
||||
*/
|
||||
@Service
|
||||
public class MockSolrServiceImpl extends SolrServiceImpl implements InitializingBean, DisposableBean {
|
||||
|
||||
private MockSolrServer mockSolrServer;
|
||||
public class MockSolrServiceImpl extends SolrServiceImpl implements InitializingBean {
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
mockSolrServer = new MockSolrServer("search");
|
||||
solr = mockSolrServer.getSolrServer();
|
||||
//We don't use SOLR in the tests of this module
|
||||
solr = null;
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
mockSolrServer.destroy();
|
||||
}
|
||||
}
|
||||
|
@@ -7,12 +7,18 @@
|
||||
*/
|
||||
package org.dspace.eperson;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.dspace.AbstractDSpaceTest;
|
||||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
import org.dspace.core.Constants;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -77,14 +83,13 @@ public class PasswordHashTest extends AbstractDSpaceTest
|
||||
*/
|
||||
@Test
|
||||
public void testMatches()
|
||||
throws NoSuchAlgorithmException
|
||||
{
|
||||
throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
||||
System.out.println("matches");
|
||||
final String secret = "Clark Kent is Superman";
|
||||
|
||||
// Test old 1-trip MD5 hash
|
||||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
||||
PasswordHash hash = new PasswordHash(null, null, digest.digest(secret.getBytes()));
|
||||
PasswordHash hash = new PasswordHash(null, null, digest.digest(secret.getBytes(Constants.DEFAULT_ENCODING)));
|
||||
boolean result = hash.matches(secret);
|
||||
assertTrue("Old unsalted 1-trip MD5 hash", result);
|
||||
|
||||
|
@@ -13,6 +13,8 @@ import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.AbstractUnitTest;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
@@ -411,7 +413,7 @@ public class DOIIdentifierProviderTest
|
||||
DSpaceObject dso = provider.getObjectByDOI(context, doi);
|
||||
|
||||
assertNotNull("Failed to load DSpaceObject by DOI.", dso);
|
||||
if (item.getType() != dso.getType() || item.getID() != dso.getID())
|
||||
if (item.getType() != dso.getType() || ObjectUtils.notEqual(item.getID(), dso.getID()))
|
||||
{
|
||||
fail("Object loaded by DOI was another object then expected!");
|
||||
}
|
||||
@@ -428,7 +430,7 @@ public class DOIIdentifierProviderTest
|
||||
DSpaceObject dso = provider.resolve(context, doi);
|
||||
|
||||
assertNotNull("Failed to resolve DOI.", dso);
|
||||
if (item.getType() != dso.getType() || item.getID() != dso.getID())
|
||||
if (item.getType() != dso.getType() || ObjectUtils.notEqual(item.getID(), dso.getID()))
|
||||
{
|
||||
fail("Object return by DOI lookup was another object then expected!");
|
||||
}
|
||||
|
@@ -1,57 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.solr;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
|
||||
import org.apache.solr.core.CoreContainer;
|
||||
|
||||
/**
|
||||
* Abstract class to mock a service that uses SOLR
|
||||
*/
|
||||
public class MockSolrServer {
|
||||
|
||||
private String coreName;
|
||||
|
||||
private SolrServer solrServer = null;
|
||||
|
||||
public MockSolrServer(final String coreName) throws Exception {
|
||||
this.coreName = coreName;
|
||||
initSolrServer();
|
||||
}
|
||||
|
||||
public SolrServer getSolrServer() {
|
||||
return solrServer;
|
||||
}
|
||||
|
||||
protected void initSolrServer() throws Exception {
|
||||
CoreContainer container = new CoreContainer(System.getProperty("dspace.dir") + File.separator + "solr");
|
||||
container.load();
|
||||
|
||||
solrServer = new EmbeddedSolrServer(container, coreName);
|
||||
|
||||
//Start with an empty index
|
||||
try {
|
||||
solrServer.deleteByQuery("*:*");
|
||||
solrServer.commit();
|
||||
} catch (SolrServerException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
if(solrServer != null) {
|
||||
solrServer.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -12,6 +12,7 @@ import java.io.IOException;
|
||||
|
||||
import com.maxmind.geoip.Location;
|
||||
import com.maxmind.geoip.LookupService;
|
||||
import org.dspace.AbstractDSpaceTest;
|
||||
|
||||
/**
|
||||
* Mock service to mock the location Lookup Service used by the SOLR statistics logger
|
||||
@@ -20,7 +21,7 @@ public class MockLookupService extends LookupService {
|
||||
|
||||
public MockLookupService() throws IOException {
|
||||
//Just give our super class a file so that he's happy. We'll mock all responses anyway.
|
||||
super(System.getProperty("dspace.dir") + File.separator + "config" + File.separator + "dspace.cfg");
|
||||
super(AbstractDSpaceTest.getDspaceDir() + File.separator + "config" + File.separator + "dspace.cfg");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -8,31 +8,23 @@
|
||||
package org.dspace.statistics;
|
||||
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.solr.MockSolrServer;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* Mock service that uses an embedded SOLR server for the statistics core
|
||||
*/
|
||||
public class MockSolrLoggerServiceImpl extends SolrLoggerServiceImpl implements InitializingBean, DisposableBean {
|
||||
|
||||
private MockSolrServer mockSolrServer;
|
||||
public class MockSolrLoggerServiceImpl extends SolrLoggerServiceImpl implements InitializingBean {
|
||||
|
||||
@Autowired(required = true)
|
||||
private ConfigurationService configurationService;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
mockSolrServer = new MockSolrServer("statistics");
|
||||
solr = mockSolrServer.getSolrServer();
|
||||
//We don' use SOLR in the tests of this module
|
||||
solr = null;
|
||||
locationService = new MockLookupService();
|
||||
useProxies = configurationService.getBooleanProperty("useProxies");
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
mockSolrServer.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -252,6 +252,10 @@
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- TEST DEPENDENCIES -->
|
||||
<dependency> <!-- Keep jmockit before junit -->
|
||||
|
@@ -6,25 +6,28 @@
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
import org.dspace.app.rest.builder.CollectionBuilder;
|
||||
import org.dspace.app.rest.builder.CommunityBuilder;
|
||||
import org.dspace.app.rest.builder.GroupBuilder;
|
||||
import org.dspace.app.rest.builder.ItemBuilder;
|
||||
import org.dspace.app.rest.matcher.BrowseIndexMatchers;
|
||||
import org.dspace.app.rest.matcher.BrowseIndexMatcher;
|
||||
import org.dspace.app.rest.matcher.ItemMatcher;
|
||||
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Integration test to test the /api/discover/browses endpoint
|
||||
* (Class has to start or end with IT to be picked up by the failsafe plugin)
|
||||
*/
|
||||
public class BrowsesResourceControllerTest extends AbstractControllerIntegrationTest {
|
||||
public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void findAll() throws Exception {
|
||||
@@ -46,10 +49,10 @@ public class BrowsesResourceControllerTest extends AbstractControllerIntegration
|
||||
|
||||
//Check that all (and only) the default browse indexes are present
|
||||
.andExpect(jsonPath("$._embedded.browses", containsInAnyOrder(
|
||||
BrowseIndexMatchers.dateIssuedBrowseIndex("asc"),
|
||||
BrowseIndexMatchers.contributorBrowseIndex("asc"),
|
||||
BrowseIndexMatchers.titleBrowseIndex("asc"),
|
||||
BrowseIndexMatchers.subjectBrowseIndex("asc")
|
||||
BrowseIndexMatcher.dateIssuedBrowseIndex("asc"),
|
||||
BrowseIndexMatcher.contributorBrowseIndex("asc"),
|
||||
BrowseIndexMatcher.titleBrowseIndex("asc"),
|
||||
BrowseIndexMatcher.subjectBrowseIndex("asc")
|
||||
)))
|
||||
;
|
||||
}
|
||||
@@ -64,7 +67,7 @@ public class BrowsesResourceControllerTest extends AbstractControllerIntegration
|
||||
.andExpect(content().contentType(contentType))
|
||||
|
||||
//Check that the JSON root matches the expected browse index
|
||||
.andExpect(jsonPath("$", BrowseIndexMatchers.titleBrowseIndex("asc")))
|
||||
.andExpect(jsonPath("$", BrowseIndexMatcher.titleBrowseIndex("asc")))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -78,7 +81,7 @@ public class BrowsesResourceControllerTest extends AbstractControllerIntegration
|
||||
.andExpect(content().contentType(contentType))
|
||||
|
||||
//Check that the JSON root matches the expected browse index
|
||||
.andExpect(jsonPath("$", BrowseIndexMatchers.dateIssuedBrowseIndex("asc")))
|
||||
.andExpect(jsonPath("$", BrowseIndexMatcher.dateIssuedBrowseIndex("asc")))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -92,7 +95,7 @@ public class BrowsesResourceControllerTest extends AbstractControllerIntegration
|
||||
.andExpect(content().contentType(contentType))
|
||||
|
||||
//Check that the JSON root matches the expected browse index
|
||||
.andExpect(jsonPath("$", BrowseIndexMatchers.contributorBrowseIndex("asc")))
|
||||
.andExpect(jsonPath("$", BrowseIndexMatcher.contributorBrowseIndex("asc")))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -106,57 +109,111 @@ public class BrowsesResourceControllerTest extends AbstractControllerIntegration
|
||||
.andExpect(content().contentType(contentType))
|
||||
|
||||
//Check that the JSON root matches the expected browse index
|
||||
.andExpect(jsonPath("$", BrowseIndexMatchers.subjectBrowseIndex("asc")))
|
||||
.andExpect(jsonPath("$", BrowseIndexMatcher.subjectBrowseIndex("asc")))
|
||||
;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findBrowseByTitleItems() throws Exception {
|
||||
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
//** GIVEN **
|
||||
//1. A community-collection structure with one parent community with sub-community and two collections.
|
||||
parentCommunity = new CommunityBuilder().createCommunity(context)
|
||||
.withName("Parent Community")
|
||||
.build();
|
||||
|
||||
Community child1 = new CommunityBuilder().createSubCommunity(context, parentCommunity)
|
||||
.withName("Sub Community")
|
||||
.build();
|
||||
|
||||
Collection col1 = new CollectionBuilder().createCollection(context, child1).withName("Collection 1").build();
|
||||
Collection col2 = new CollectionBuilder().createCollection(context, child1).withName("Collection 2").build();
|
||||
|
||||
Item item1 = new ItemBuilder().createItem(context, col1)
|
||||
.withTitle("My first test item")
|
||||
//2. Two public items that are readable by Anonymous
|
||||
Item publicItem1 = new ItemBuilder().createItem(context, col1)
|
||||
.withTitle("Public item 1")
|
||||
.withIssueDate("2017-10-17")
|
||||
.withAuthor("Smith, Donald")
|
||||
.withAuthor("Doe, John")
|
||||
.withSubject("Java")
|
||||
.withSubject("Unit Testing")
|
||||
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
||||
.withSubject("Java").withSubject("Unit Testing")
|
||||
.build();
|
||||
|
||||
Item item2 = new ItemBuilder().createItem(context, col2)
|
||||
.withTitle("My second test item")
|
||||
Item publicItem2 = new ItemBuilder().createItem(context, col2)
|
||||
.withTitle("Public item 2")
|
||||
.withIssueDate("2016-02-13")
|
||||
.withAuthor("Smith, Maria")
|
||||
.withAuthor("Doe, Jane")
|
||||
.withSubject("Angular")
|
||||
.withSubject("Unit Testing")
|
||||
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
|
||||
.withSubject("Angular").withSubject("Unit Testing")
|
||||
.build();
|
||||
|
||||
//3. An item that has been made private
|
||||
Item privateItem = new ItemBuilder().createItem(context, col1)
|
||||
.withTitle("This is a private item")
|
||||
.withIssueDate("2015-03-12")
|
||||
.withAuthor("Duck, Donald")
|
||||
.withSubject("Cartoons").withSubject("Ducks")
|
||||
.makePrivate()
|
||||
.build();
|
||||
|
||||
//4. An item with an item-level embargo
|
||||
Item embargoedItem = new ItemBuilder().createItem(context, col2)
|
||||
.withTitle("An embargoed publication")
|
||||
.withIssueDate("2017-08-10")
|
||||
.withAuthor("Mouse, Mickey")
|
||||
.withSubject("Cartoons").withSubject("Mice")
|
||||
.withEmbargoPeriod("12 months")
|
||||
.build();
|
||||
|
||||
//5. An item that is only readable for an internal groups
|
||||
Group internalGroup = new GroupBuilder().createGroup(context)
|
||||
.withName("Internal Group")
|
||||
.build();
|
||||
|
||||
Item internalItem = new ItemBuilder().createItem(context, col2)
|
||||
.withTitle("Internal publication")
|
||||
.withIssueDate("2016-09-19")
|
||||
.withAuthor("Doe, John")
|
||||
.withSubject("Unknown")
|
||||
.withReaderGroup(internalGroup)
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
//When we browse the items in the Browse by item endpoint
|
||||
mockMvc.perform(get("/api/discover/browses/title/items"))
|
||||
//** WHEN **
|
||||
//An anonymous user browses the items in the Browse by item endpoint
|
||||
//sorted descending by tile
|
||||
mockMvc.perform(get("/api/discover/browses/title/items")
|
||||
.param("sort", "title,desc"))
|
||||
|
||||
//** THEN **
|
||||
//The status has to be 200 OK
|
||||
.andExpect(status().isOk())
|
||||
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||
.andExpect(content().contentType(contentType))
|
||||
|
||||
//We expect our two created items to be present
|
||||
//We expect only the two public items and the embargoed item to be present
|
||||
.andExpect(jsonPath("$.page.size", is(20)))
|
||||
.andExpect(jsonPath("$.page.totalElements", is(2)))
|
||||
.andExpect(jsonPath("$.page.totalElements", is(3)))
|
||||
.andExpect(jsonPath("$.page.totalPages", is(1)))
|
||||
.andExpect(jsonPath("$.page.number", is(0)))
|
||||
|
||||
//Verify that the title of the public and embargoed items are present and sorted descending
|
||||
.andExpect(jsonPath("$._embedded.items",
|
||||
contains(ItemMatcher.matchItemWithTitleAndDateIssued(publicItem2,
|
||||
"Public item 2", "2016-02-13"),
|
||||
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1,
|
||||
"Public item 1", "2017-10-17"),
|
||||
ItemMatcher.matchItemWithTitleAndDateIssued(embargoedItem,
|
||||
"An embargoed publication", "2017-08-10"))))
|
||||
|
||||
//The private item must not be present
|
||||
.andExpect(jsonPath("$._embedded.items[*].metadata[?(@.key=='dc.title')].value",
|
||||
not(hasItem("This is a private item"))))
|
||||
|
||||
//The internal item must not be present
|
||||
.andExpect(jsonPath("$._embedded.items[*].metadata[?(@.key=='dc.title')].value",
|
||||
not(hasItem("Internal publication"))))
|
||||
;
|
||||
|
||||
//** CLEANUP **
|
||||
context.turnOffAuthorisationSystem();
|
||||
new GroupBuilder().delete(context, internalGroup);
|
||||
}
|
||||
}
|
@@ -18,7 +18,7 @@ import org.junit.Test;
|
||||
/**
|
||||
* Integration test for the {@link RootRestResourceController}
|
||||
*/
|
||||
public class RootRestResourceControllerTest extends AbstractControllerIntegrationTest {
|
||||
public class RootRestResourceControllerIT extends AbstractControllerIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void listDefinedEndpoint() throws Exception {
|
@@ -1,46 +1,152 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest.builder;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
import org.dspace.authorize.factory.AuthorizeServiceFactory;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.authorize.service.ResourcePolicyService;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.BitstreamService;
|
||||
import org.dspace.content.service.BundleService;
|
||||
import org.dspace.content.service.CollectionService;
|
||||
import org.dspace.content.service.CommunityService;
|
||||
import org.dspace.content.service.InstallItemService;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.content.service.WorkspaceItemService;
|
||||
import org.dspace.content.service.*;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.IndexingService;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
import org.dspace.eperson.service.EPersonService;
|
||||
import org.dspace.eperson.service.GroupService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.MutablePeriod;
|
||||
import org.joda.time.format.PeriodFormat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* TODO TOM UNIT TEST
|
||||
* Abstract builder to construct DSpace Objects
|
||||
*/
|
||||
public class AbstractBuilder {
|
||||
public abstract class AbstractBuilder<T extends DSpaceObject> {
|
||||
|
||||
protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
|
||||
protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
||||
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
|
||||
protected InstallItemService installItemService = ContentServiceFactory.getInstance().getInstallItemService();
|
||||
protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
|
||||
protected EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
||||
protected GroupService groupService = EPersonServiceFactory.getInstance().getGroupService();
|
||||
protected BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
|
||||
protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
|
||||
|
||||
protected IndexingService indexingService = DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName(IndexingService.class.getName(),IndexingService.class);
|
||||
static CommunityService communityService;
|
||||
static CollectionService collectionService;
|
||||
static ItemService itemService;
|
||||
static InstallItemService installItemService;
|
||||
static WorkspaceItemService workspaceItemService;
|
||||
static EPersonService ePersonService;
|
||||
static GroupService groupService;
|
||||
static BundleService bundleService;
|
||||
static BitstreamService bitstreamService;
|
||||
static AuthorizeService authorizeService;
|
||||
static ResourcePolicyService resourcePolicyService;
|
||||
static IndexingService indexingService;
|
||||
|
||||
protected Context context;
|
||||
|
||||
/** log4j category */
|
||||
private static final Logger log = Logger.getLogger(AbstractBuilder.class);
|
||||
|
||||
protected <T> T handleException(final Exception e) {
|
||||
public static void init() {
|
||||
communityService = ContentServiceFactory.getInstance().getCommunityService();
|
||||
collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
||||
itemService = ContentServiceFactory.getInstance().getItemService();
|
||||
installItemService = ContentServiceFactory.getInstance().getInstallItemService();
|
||||
workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
|
||||
ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
||||
groupService = EPersonServiceFactory.getInstance().getGroupService();
|
||||
bundleService = ContentServiceFactory.getInstance().getBundleService();
|
||||
bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
|
||||
authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
resourcePolicyService = AuthorizeServiceFactory.getInstance().getResourcePolicyService();
|
||||
indexingService = DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName(IndexingService.class.getName(),IndexingService.class);
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
communityService = null;
|
||||
collectionService = null;
|
||||
itemService = null;
|
||||
installItemService = null;
|
||||
workspaceItemService = null;
|
||||
ePersonService = null;
|
||||
groupService = null;
|
||||
bundleService = null;
|
||||
bitstreamService = null;
|
||||
authorizeService = null;
|
||||
resourcePolicyService = null;
|
||||
indexingService = null;
|
||||
}
|
||||
|
||||
protected <B> B handleException(final Exception e) {
|
||||
log.error(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract DSpaceObjectService<T> getDsoService();
|
||||
|
||||
protected <B extends AbstractBuilder<T>> B addMetadataValue(final T dso, final String schema, final String element, final String qualifier, final String value) {
|
||||
try {
|
||||
getDsoService().addMetadata(context, dso, schema, element, qualifier, Item.ANY, value);
|
||||
} catch (SQLException e) {
|
||||
return handleException(e);
|
||||
}
|
||||
return (B) this;
|
||||
}
|
||||
|
||||
protected <B extends AbstractBuilder<T>> B setMetadataSingleValue(final T dso, final String schema, final String element, final String qualifier, final String value) {
|
||||
try {
|
||||
getDsoService().setMetadataSingleValue(context, dso, schema, element, qualifier, Item.ANY, value);
|
||||
} catch (SQLException e) {
|
||||
return handleException(e);
|
||||
}
|
||||
|
||||
return (B) this;
|
||||
}
|
||||
|
||||
protected <B extends AbstractBuilder<T>> B setEmbargo(String embargoPeriod, DSpaceObject dso) {
|
||||
// add policy just for anonymous
|
||||
try {
|
||||
MutablePeriod period = PeriodFormat.getDefault().parseMutablePeriod(embargoPeriod);
|
||||
Date embargoDate = DateTime.now(DateTimeZone.UTC).plus(period).toDate();
|
||||
|
||||
return setOnlyReadPermission(dso, groupService.findByName(context, Group.ANONYMOUS), embargoDate);
|
||||
} catch (Exception e) {
|
||||
return handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected <B extends AbstractBuilder<T>> B setOnlyReadPermission(DSpaceObject dso, Group group, Date startDate) {
|
||||
// add policy just for anonymous
|
||||
try {
|
||||
authorizeService.removeAllPolicies(context, dso);
|
||||
|
||||
ResourcePolicy rp = authorizeService.createOrModifyPolicy(null, context, null, group,
|
||||
null, startDate, Constants.READ, "Integration Test", dso);
|
||||
if (rp != null) {
|
||||
resourcePolicyService.update(context, rp);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return handleException(e);
|
||||
}
|
||||
return (B) this;
|
||||
}
|
||||
|
||||
public abstract T build();
|
||||
|
||||
public void delete(Context context, T dso) throws SQLException, IOException, AuthorizeException {
|
||||
T attachedDso = context.reloadEntity(dso);
|
||||
if(attachedDso != null) {
|
||||
getDsoService().delete(context, attachedDso);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,21 +1,28 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest.builder;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.service.DSpaceObjectService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.SearchServiceException;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* TODO TOM UNIT TEST
|
||||
* Builder to construct Collection objects
|
||||
*/
|
||||
public class CollectionBuilder extends AbstractBuilder {
|
||||
public class CollectionBuilder extends AbstractBuilder<Collection> {
|
||||
|
||||
private Collection collection;
|
||||
private Context context;
|
||||
|
||||
public CollectionBuilder createCollection(final Context context, final Community parent) {
|
||||
this.context = context;
|
||||
@@ -29,22 +36,24 @@ public class CollectionBuilder extends AbstractBuilder {
|
||||
}
|
||||
|
||||
public CollectionBuilder withName(final String name) {
|
||||
try {
|
||||
collectionService.setMetadataSingleValue(context, collection, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY, name);
|
||||
} catch (SQLException e) {
|
||||
return handleException(e);
|
||||
}
|
||||
|
||||
return this;
|
||||
return setMetadataSingleValue(collection, MetadataSchema.DC_SCHEMA, "title", null, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection build() {
|
||||
context.dispatchEvents();
|
||||
try {
|
||||
collectionService.update(context, collection);
|
||||
context.dispatchEvents();
|
||||
|
||||
indexingService.commit();
|
||||
} catch (SearchServiceException e) {
|
||||
} catch (Exception e) {
|
||||
return handleException(e);
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DSpaceObjectService<Collection> getDsoService() {
|
||||
return collectionService;
|
||||
}
|
||||
}
|
||||
|
@@ -1,27 +1,24 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest.builder;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.CommunityService;
|
||||
import org.dspace.content.service.DSpaceObjectService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.IndexingService;
|
||||
import org.dspace.discovery.SearchServiceException;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
|
||||
/**
|
||||
* TODO TOM UNIT TEST
|
||||
* Builder to construct Community objects
|
||||
*/
|
||||
public class CommunityBuilder {
|
||||
|
||||
protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
|
||||
protected IndexingService indexingService = DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName(IndexingService.class.getName(),IndexingService.class);
|
||||
public class CommunityBuilder extends AbstractBuilder<Community> {
|
||||
|
||||
private Community community;
|
||||
private Context context;
|
||||
|
||||
public CommunityBuilder createCommunity(final Context context) {
|
||||
return createSubCommunity(context, null);
|
||||
@@ -40,24 +37,25 @@ public class CommunityBuilder {
|
||||
}
|
||||
|
||||
public CommunityBuilder withName(final String communityName) {
|
||||
try {
|
||||
communityService.setMetadataSingleValue(context, community, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY, communityName);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return this;
|
||||
return setMetadataSingleValue(community, MetadataSchema.DC_SCHEMA, "title", null, communityName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Community build() {
|
||||
context.dispatchEvents();
|
||||
try {
|
||||
communityService.update(context, community);
|
||||
context.dispatchEvents();
|
||||
|
||||
indexingService.commit();
|
||||
} catch (SearchServiceException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return community;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DSpaceObjectService<Community> getDsoService() {
|
||||
return communityService;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest.builder;
|
||||
|
||||
import org.dspace.content.service.DSpaceObjectService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
|
||||
/**
|
||||
* Builder to construct Group objects
|
||||
*/
|
||||
public class GroupBuilder extends AbstractBuilder<Group> {
|
||||
|
||||
private Group group;
|
||||
|
||||
@Override
|
||||
protected DSpaceObjectService<Group> getDsoService() {
|
||||
return groupService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group build() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public GroupBuilder createGroup(final Context context) {
|
||||
this.context = context;
|
||||
try {
|
||||
group = groupService.create(context);
|
||||
} catch (Exception e) {
|
||||
return handleException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public GroupBuilder withName(String groupName) {
|
||||
try {
|
||||
groupService.setName(group, groupName);
|
||||
} catch (Exception e) {
|
||||
return handleException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public GroupBuilder withParent(Group parent) {
|
||||
try {
|
||||
groupService.addMember(context, parent, group);
|
||||
} catch (Exception e) {
|
||||
return handleException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public GroupBuilder addMember(EPerson eperson) {
|
||||
try {
|
||||
groupService.addMember(context, group, eperson);
|
||||
} catch (Exception e) {
|
||||
return handleException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
@@ -1,20 +1,24 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest.builder;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.DCDate;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.WorkspaceItem;
|
||||
import org.dspace.content.*;
|
||||
import org.dspace.content.service.DSpaceObjectService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.Group;
|
||||
|
||||
/**
|
||||
* TODO TOM UNIT TEST
|
||||
* Builder to construct Item objects
|
||||
*/
|
||||
public class ItemBuilder extends AbstractBuilder {
|
||||
public class ItemBuilder extends AbstractBuilder<Item> {
|
||||
|
||||
private WorkspaceItem workspaceItem;
|
||||
private Group readerGroup = null;
|
||||
|
||||
public ItemBuilder createItem(final Context context, final Collection col1) {
|
||||
this.context = context;
|
||||
@@ -29,46 +33,58 @@ public class ItemBuilder extends AbstractBuilder {
|
||||
}
|
||||
|
||||
public ItemBuilder withTitle(final String title) {
|
||||
try {
|
||||
itemService.setMetadataSingleValue(context, workspaceItem.getItem(), MetadataSchema.DC_SCHEMA, "title", null, Item.ANY, title);
|
||||
} catch (SQLException e) {
|
||||
return handleException(e);
|
||||
}
|
||||
|
||||
return this;
|
||||
return setMetadataSingleValue(workspaceItem.getItem(), MetadataSchema.DC_SCHEMA, "title", null, title);
|
||||
}
|
||||
|
||||
public ItemBuilder withIssueDate(final String issueDate) {
|
||||
return addMetadataValueToItem(MetadataSchema.DC_SCHEMA, "date", "issued", new DCDate(issueDate).toString());
|
||||
return addMetadataValue(workspaceItem.getItem(), MetadataSchema.DC_SCHEMA, "date", "issued", new DCDate(issueDate).toString());
|
||||
}
|
||||
|
||||
public ItemBuilder withAuthor(final String authorName) {
|
||||
return addMetadataValueToItem(MetadataSchema.DC_SCHEMA, "date", "issued", authorName);
|
||||
return addMetadataValue(workspaceItem.getItem(), MetadataSchema.DC_SCHEMA, "contributor", "author", authorName);
|
||||
}
|
||||
|
||||
public ItemBuilder withSubject(final String subject) {
|
||||
return addMetadataValueToItem(MetadataSchema.DC_SCHEMA, "subject", null, subject);
|
||||
return addMetadataValue(workspaceItem.getItem(), MetadataSchema.DC_SCHEMA, "subject", null, subject);
|
||||
}
|
||||
|
||||
public ItemBuilder makePrivate() {
|
||||
workspaceItem.getItem().setDiscoverable(false);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder withEmbargoPeriod(String embargoPeriod) {
|
||||
return setEmbargo(embargoPeriod, workspaceItem.getItem());
|
||||
}
|
||||
|
||||
public ItemBuilder withReaderGroup(Group group) {
|
||||
readerGroup = group;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item build() {
|
||||
try {
|
||||
Item item = installItemService.installItem(context, workspaceItem);
|
||||
context.dispatchEvents();
|
||||
indexingService.commit();
|
||||
itemService.update(context, item);
|
||||
|
||||
//Check if we need to make this item private. This has to be done after item install.
|
||||
if(readerGroup != null) {
|
||||
setOnlyReadPermission(workspaceItem.getItem(), readerGroup, null);
|
||||
}
|
||||
|
||||
context.dispatchEvents();
|
||||
|
||||
indexingService.commit();
|
||||
return item;
|
||||
} catch (Exception e) {
|
||||
return handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ItemBuilder addMetadataValueToItem(final String schema, final String element, final String qualifier, final String value) {
|
||||
try {
|
||||
itemService.addMetadata(context, workspaceItem.getItem(), schema, element, qualifier, Item.ANY, value);
|
||||
} catch (SQLException e) {
|
||||
return handleException(e);
|
||||
@Override
|
||||
protected DSpaceObjectService<Item> getDsoService() {
|
||||
return itemService;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest.matcher;
|
||||
|
||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||
@@ -8,8 +15,13 @@ import static org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
public class BrowseIndexMatchers {
|
||||
public BrowseIndexMatchers() {
|
||||
/**
|
||||
* Utility class to construct a Matcher for a browse index
|
||||
*/
|
||||
public class BrowseIndexMatcher {
|
||||
|
||||
public BrowseIndexMatcher() {
|
||||
|
||||
}
|
||||
|
||||
public static Matcher<? super Object> subjectBrowseIndex(final String order) {
|
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest.matcher;
|
||||
|
||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||
import static org.dspace.app.rest.test.AbstractControllerIntegrationTest.REST_SERVER_URL;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
import org.dspace.content.Item;
|
||||
import org.hamcrest.Matcher;
|
||||
|
||||
/**
|
||||
* Utility class to construct a Matcher for an item
|
||||
*/
|
||||
public class ItemMatcher {
|
||||
|
||||
public static Matcher<? super Object> matchItemWithTitleAndDateIssued(Item item, String title, String dateIssued) {
|
||||
return allOf(
|
||||
//Check item properties
|
||||
matchItemProperties(item),
|
||||
|
||||
//Check core metadata (the JSON Path expression evaluates to a collection so we have to use contains)
|
||||
hasJsonPath("$.metadata[?(@.key=='dc.title')].value", contains(title)),
|
||||
hasJsonPath("$.metadata[?(@.key=='dc.date.issued')].value", contains(dateIssued)),
|
||||
|
||||
//Check links
|
||||
matchItemLinks(item)
|
||||
);
|
||||
}
|
||||
|
||||
public static Matcher<? super Object> matchItemLinks(Item item) {
|
||||
return allOf(
|
||||
hasJsonPath("$._links.self.href", startsWith(REST_SERVER_URL)),
|
||||
hasJsonPath("$._links.bitstreams.href", startsWith(REST_SERVER_URL)),
|
||||
hasJsonPath("$._links.owningCollection.href", startsWith(REST_SERVER_URL)),
|
||||
hasJsonPath("$._links.templateItemOf.href", startsWith(REST_SERVER_URL)),
|
||||
hasJsonPath("$._links.self.href", startsWith(REST_SERVER_URL))
|
||||
);
|
||||
}
|
||||
|
||||
public static Matcher<? super Object> matchItemProperties(Item item) {
|
||||
return allOf(
|
||||
hasJsonPath("$.uuid", is(item.getID().toString())),
|
||||
hasJsonPath("$.name", is(item.getName())),
|
||||
hasJsonPath("$.handle", is(item.getHandle())),
|
||||
hasJsonPath("$.inArchive", is(item.isArchived())),
|
||||
hasJsonPath("$.discoverable", is(item.isDiscoverable())),
|
||||
hasJsonPath("$.withdrawn", is(item.isWithdrawn())),
|
||||
hasJsonPath("$.lastModified", is(notNullValue())),
|
||||
hasJsonPath("$.type", is("item"))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@@ -47,7 +47,7 @@ import org.springframework.web.context.WebApplicationContext;
|
||||
TransactionalTestExecutionListener.class})
|
||||
@DirtiesContext
|
||||
@WebAppConfiguration
|
||||
public class AbstractControllerIntegrationTest extends AbstractUnitTestWithDatabase {
|
||||
public class AbstractControllerIntegrationTest extends AbstractIntegrationTestWithDatabase {
|
||||
|
||||
public static final String REST_SERVER_URL = "http://localhost/api/";
|
||||
|
||||
|
@@ -16,6 +16,7 @@ import java.util.Properties;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.app.rest.builder.AbstractBuilder;
|
||||
import org.dspace.servicemanager.DSpaceKernelImpl;
|
||||
import org.dspace.servicemanager.DSpaceKernelInit;
|
||||
import org.junit.AfterClass;
|
||||
@@ -24,10 +25,11 @@ import org.junit.BeforeClass;
|
||||
/**
|
||||
* Abstract Test class copied from DSpace API
|
||||
*/
|
||||
public class AbstractDSpaceTest
|
||||
public class AbstractDSpaceIntegrationTest
|
||||
{
|
||||
|
||||
/** log4j category */
|
||||
private static final Logger log = Logger.getLogger(AbstractDSpaceTest.class);
|
||||
private static final Logger log = Logger.getLogger(AbstractDSpaceIntegrationTest.class);
|
||||
|
||||
/**
|
||||
* Test properties. These configure our general test environment
|
||||
@@ -57,7 +59,7 @@ public class AbstractDSpaceTest
|
||||
|
||||
//load the properties of the tests
|
||||
testProps = new Properties();
|
||||
URL properties = AbstractDSpaceTest.class.getClassLoader()
|
||||
URL properties = AbstractDSpaceIntegrationTest.class.getClassLoader()
|
||||
.getResource("test-config.properties");
|
||||
testProps.load(properties.openStream());
|
||||
|
||||
@@ -66,8 +68,9 @@ public class AbstractDSpaceTest
|
||||
if (!kernelImpl.isRunning())
|
||||
{
|
||||
// NOTE: the "dspace.dir" system property MUST be specified via Maven
|
||||
kernelImpl.start(System.getProperty("dspace.dir")); // init the kernel
|
||||
kernelImpl.start(getDspaceDir()); // init the kernel
|
||||
}
|
||||
AbstractBuilder.init();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
@@ -76,7 +79,6 @@ public class AbstractDSpaceTest
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will be run after all tests finish as per @AfterClass. It
|
||||
* will clean resources initialized by the @BeforeClass methods.
|
||||
@@ -87,11 +89,18 @@ public class AbstractDSpaceTest
|
||||
testProps.clear();
|
||||
testProps = null;
|
||||
|
||||
AbstractBuilder.destroy();
|
||||
|
||||
//Also clear out the kernel & nullify (so JUnit will clean it up)
|
||||
if (kernelImpl != null) {
|
||||
kernelImpl.destroy();
|
||||
}
|
||||
kernelImpl = null;
|
||||
}
|
||||
|
||||
public static String getDspaceDir(){
|
||||
return System.getProperty("dspace.dir");
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -28,9 +28,9 @@ import org.junit.BeforeClass;
|
||||
/**
|
||||
* Abstract Test class that will initialize the in-memory database
|
||||
*/
|
||||
public class AbstractUnitTestWithDatabase extends AbstractDSpaceTest {
|
||||
public class AbstractIntegrationTestWithDatabase extends AbstractDSpaceIntegrationTest {
|
||||
/** log4j category */
|
||||
private static final Logger log = Logger.getLogger(AbstractUnitTestWithDatabase.class);
|
||||
private static final Logger log = Logger.getLogger(AbstractIntegrationTestWithDatabase.class);
|
||||
|
||||
/**
|
||||
* Context mock object to use in the tests.
|
||||
@@ -54,7 +54,7 @@ public class AbstractUnitTestWithDatabase extends AbstractDSpaceTest {
|
||||
* NOTE: Per JUnit, "The @BeforeClass methods of superclasses will be run before those the current class."
|
||||
* http://junit.org/apidocs/org/junit/BeforeClass.html
|
||||
* <p>
|
||||
* This method builds on the initialization in AbstractDSpaceTest, and
|
||||
* This method builds on the initialization in AbstractDSpaceIntegrationTest, and
|
||||
* initializes the in-memory database for tests that need it.
|
||||
*/
|
||||
@BeforeClass
|
@@ -1,3 +1,10 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest.test;
|
||||
|
||||
import java.util.List;
|
||||
|
@@ -9,21 +9,32 @@ package org.dspace.solr;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
|
||||
import org.apache.solr.core.CoreContainer;
|
||||
import org.dspace.app.rest.test.AbstractDSpaceIntegrationTest;
|
||||
|
||||
/**
|
||||
* Abstract class to mock a service that uses SOLR
|
||||
*/
|
||||
public class MockSolrServer {
|
||||
|
||||
private static final Logger log = Logger.getLogger(MockSolrServer.class);
|
||||
private static final ConcurrentMap<String, SolrServer> loadedCores = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentMap<String, AtomicLong> usersPerCore = new ConcurrentHashMap<>();
|
||||
private static CoreContainer container = null;
|
||||
|
||||
private String coreName;
|
||||
|
||||
private SolrServer solrServer = null;
|
||||
|
||||
|
||||
public MockSolrServer(final String coreName) throws Exception {
|
||||
this.coreName = coreName;
|
||||
initSolrServer();
|
||||
@@ -34,24 +45,65 @@ public class MockSolrServer {
|
||||
}
|
||||
|
||||
protected void initSolrServer() throws Exception {
|
||||
CoreContainer container = new CoreContainer(System.getProperty("dspace.dir") + File.separator + "solr");
|
||||
container.load();
|
||||
solrServer = loadedCores.get(coreName);
|
||||
if(solrServer == null) {
|
||||
solrServer = initSolrServerForCore(coreName);
|
||||
}
|
||||
|
||||
solrServer = new EmbeddedSolrServer(container, coreName);
|
||||
usersPerCore.putIfAbsent(coreName, new AtomicLong(0));
|
||||
usersPerCore.get(coreName).incrementAndGet();
|
||||
}
|
||||
|
||||
private static synchronized SolrServer initSolrServerForCore(final String coreName) {
|
||||
SolrServer server = loadedCores.get(coreName);
|
||||
if(server == null) {
|
||||
initSolrContainer();
|
||||
|
||||
server = new EmbeddedSolrServer(container, coreName);
|
||||
|
||||
//Start with an empty index
|
||||
try {
|
||||
solrServer.deleteByQuery("*:*");
|
||||
solrServer.commit();
|
||||
server.deleteByQuery("*:*");
|
||||
server.commit();
|
||||
} catch (SolrServerException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
loadedCores.put(coreName, server);
|
||||
log.info("SOLR Server for core " + coreName + " initialized");
|
||||
}
|
||||
return server;
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
if(solrServer != null) {
|
||||
long remainingUsers = usersPerCore.get(coreName).decrementAndGet();
|
||||
if(remainingUsers <= 0) {
|
||||
solrServer.shutdown();
|
||||
usersPerCore.remove(coreName);
|
||||
loadedCores.remove(coreName);
|
||||
log.info("SOLR Server for core " + coreName + " destroyed");
|
||||
}
|
||||
|
||||
if(usersPerCore.isEmpty()) {
|
||||
destroyContainer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized void initSolrContainer() {
|
||||
if(container == null) {
|
||||
String solrDir = AbstractDSpaceIntegrationTest.getDspaceDir() + File.separator + "solr";
|
||||
log.info("Initializing SOLR CoreContainer with directory " + solrDir);
|
||||
container = new CoreContainer(solrDir);
|
||||
container.load();
|
||||
log.info("SOLR CoreContainer initialized");
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized void destroyContainer() {
|
||||
container = null;
|
||||
log.info("SOLR CoreContainer destroyed");
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ import java.io.IOException;
|
||||
|
||||
import com.maxmind.geoip.Location;
|
||||
import com.maxmind.geoip.LookupService;
|
||||
import org.dspace.app.rest.test.AbstractDSpaceIntegrationTest;
|
||||
|
||||
/**
|
||||
* Mock service to mock the location Lookup Service used by the SOLR statistics logger
|
||||
@@ -20,7 +21,7 @@ public class MockLookupService extends LookupService {
|
||||
|
||||
public MockLookupService() throws IOException {
|
||||
//Just give our super class a file so that he's happy. We'll mock all responses anyway.
|
||||
super(System.getProperty("dspace.dir") + File.separator + "config" + File.separator + "dspace.cfg");
|
||||
super(AbstractDSpaceIntegrationTest.getDspaceDir() + File.separator + "config" + File.separator + "dspace.cfg");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,2 @@
|
||||
org.springframework.test.context.ContextCustomizerFactory= \
|
||||
org.dspace.app.rest.test.DSpaceKernelContextCustomizerFactory
|
@@ -1,7 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml"/>
|
||||
<!-- Set custom log levels for Spring REST integration tests here -->
|
||||
<logger name="org.springframework.web" level="INFO"/>
|
||||
<logger name="org.hibernate" level="INFO"/>
|
||||
<logger name="org.hibernate" level="WARN"/>
|
||||
<logger name="net.sf.ehcache" level="INFO"/>
|
||||
<logger name="org.apache.solr" level="WARN"/>
|
||||
</configuration>
|
5
pom.xml
5
pom.xml
@@ -1147,6 +1147,11 @@
|
||||
<artifactId>commons-validator</artifactId>
|
||||
<version>1.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.9.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
|
Reference in New Issue
Block a user