mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-17 15:03:18 +00:00
Merge branch 'master' into DS-4317_bundles-in-REST
# Conflicts: # dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamRestRepository.java
This commit is contained in:
@@ -27,8 +27,6 @@
|
|||||||
<resource.delimiter>@</resource.delimiter>
|
<resource.delimiter>@</resource.delimiter>
|
||||||
<!-- Define our starting class for our Spring Boot Application -->
|
<!-- Define our starting class for our Spring Boot Application -->
|
||||||
<start-class>org.dspace.app.rest.Application</start-class>
|
<start-class>org.dspace.app.rest.Application</start-class>
|
||||||
<!-- Library for reading JSON documents: https://github.com/json-path/JsonPath -->
|
|
||||||
<json-path.version>2.4.0</json-path.version>
|
|
||||||
<!-- Library for managing JSON Web Tokens (JWT): https://bitbucket.org/connect2id/nimbus-jose-jwt/wiki/Home -->
|
<!-- Library for managing JSON Web Tokens (JWT): https://bitbucket.org/connect2id/nimbus-jose-jwt/wiki/Home -->
|
||||||
<nimbus-jose-jwt.version>6.2</nimbus-jose-jwt.version>
|
<nimbus-jose-jwt.version>6.2</nimbus-jose-jwt.version>
|
||||||
</properties>
|
</properties>
|
||||||
@@ -150,6 +148,37 @@
|
|||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<attachClasses>true</attachClasses>
|
||||||
|
<!-- Filter the web.xml (needed for IDE compatibility/debugging) -->
|
||||||
|
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<!-- Builds a *-tests.jar of all test classes -->
|
||||||
|
<goal>test-jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -299,7 +328,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<version>${spring-boot.version}</version>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<!-- Temporary exclusion to avoid dependency conflict with version of org.json:json used by dspace-api.
|
<!-- Temporary exclusion to avoid dependency conflict with version of org.json:json used by dspace-api.
|
||||||
@@ -325,7 +353,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.jayway.jsonpath</groupId>
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
<artifactId>json-path-assert</artifactId>
|
<artifactId>json-path-assert</artifactId>
|
||||||
<version>${json-path.version}</version>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency> <!-- Keep jmockit before junit -->
|
<dependency> <!-- Keep jmockit before junit -->
|
||||||
@@ -418,7 +445,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.solr</groupId>
|
<groupId>org.apache.solr</groupId>
|
||||||
<artifactId>solr-cell</artifactId>
|
<artifactId>solr-cell</artifactId>
|
||||||
<version>${solr.client.version}</version>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
@@ -480,7 +506,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.lucene</groupId>
|
<groupId>org.apache.lucene</groupId>
|
||||||
<artifactId>lucene-analyzers-icu</artifactId>
|
<artifactId>lucene-analyzers-icu</artifactId>
|
||||||
<version>${solr.client.version}</version>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@@ -0,0 +1,112 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||||
|
import org.dspace.app.rest.model.BitstreamRest;
|
||||||
|
import org.dspace.app.rest.model.CollectionRest;
|
||||||
|
import org.dspace.app.rest.model.hateoas.BitstreamResource;
|
||||||
|
import org.dspace.app.rest.repository.CollectionRestRepository;
|
||||||
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.service.CollectionService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.rest.webmvc.ControllerUtils;
|
||||||
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
|
import org.springframework.hateoas.ResourceSupport;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This RestController takes care of the creation and deletion of Collection's nested objects
|
||||||
|
* This class will typically receive the UUID of a Collection and it'll perform logic on its nested objects
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/" + CollectionRest.CATEGORY + "/" + CollectionRest.PLURAL_NAME
|
||||||
|
+ CollectionLogoController.REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID + "/logo")
|
||||||
|
public class CollectionLogoController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regular expression in the request mapping to accept UUID as identifier
|
||||||
|
*/
|
||||||
|
protected static final String REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID =
|
||||||
|
"/{uuid:[0-9a-fxA-FX]{8}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{12}}";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected Utils utils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CollectionRestRepository collectionRestRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CollectionService collectionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will add a logo to the collection.
|
||||||
|
*
|
||||||
|
* curl -X POST http://<dspace.restUrl>/api/core/collections/1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb/logo' \
|
||||||
|
* -XPOST -H 'Content-Type: multipart/form-data' \
|
||||||
|
* -H 'Authorization: Bearer eyJhbGciOiJI...' \
|
||||||
|
* -F "file=@Downloads/test.png"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* <pre>
|
||||||
|
* {@code
|
||||||
|
* curl -X POST http://<dspace.restUrl>/api/core/collections/1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb/logo' \
|
||||||
|
* -XPOST -H 'Content-Type: multipart/form-data' \
|
||||||
|
* -H 'Authorization: Bearer eyJhbGciOiJI...' \
|
||||||
|
* -F "file=@Downloads/test.png"
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
* @param request The StandardMultipartHttpServletRequest that will contain the logo in its body
|
||||||
|
* @param uuid The UUID of the collection
|
||||||
|
* @return The created bitstream
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
* @throws IOException If something goes wrong
|
||||||
|
* @throws AuthorizeException If the user doesn't have the correct rights
|
||||||
|
*/
|
||||||
|
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')")
|
||||||
|
@RequestMapping(method = RequestMethod.POST,
|
||||||
|
headers = "content-type=multipart/form-data")
|
||||||
|
public ResponseEntity<ResourceSupport> createLogo(HttpServletRequest request, @PathVariable UUID uuid,
|
||||||
|
@RequestParam(value = "file", required = false) MultipartFile uploadfile)
|
||||||
|
throws SQLException, IOException, AuthorizeException {
|
||||||
|
|
||||||
|
if (uploadfile == null) {
|
||||||
|
throw new UnprocessableEntityException("No file was given");
|
||||||
|
}
|
||||||
|
Context context = ContextUtil.obtainContext(request);
|
||||||
|
|
||||||
|
Collection collection = collectionService.find(context, uuid);
|
||||||
|
if (collection == null) {
|
||||||
|
throw new ResourceNotFoundException(
|
||||||
|
"The given uuid did not resolve to a collection on the server: " + uuid);
|
||||||
|
}
|
||||||
|
BitstreamRest bitstream = collectionRestRepository.setLogo(context, collection, uploadfile);
|
||||||
|
|
||||||
|
BitstreamResource bitstreamResource = new BitstreamResource(bitstream, utils);
|
||||||
|
context.complete();
|
||||||
|
return ControllerUtils.toResponseEntity(HttpStatus.CREATED, null, bitstreamResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,114 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||||
|
import org.dspace.app.rest.model.BitstreamRest;
|
||||||
|
import org.dspace.app.rest.model.CommunityRest;
|
||||||
|
import org.dspace.app.rest.model.hateoas.BitstreamResource;
|
||||||
|
import org.dspace.app.rest.repository.CommunityRestRepository;
|
||||||
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.service.CommunityService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.rest.webmvc.ControllerUtils;
|
||||||
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
|
import org.springframework.hateoas.ResourceSupport;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This RestController takes care of the creation and deletion of Communities' nested objects
|
||||||
|
* This class will typically receive the UUID of a Community and it'll perform logic on its nested objects
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/" + CommunityRest.CATEGORY + "/" + CommunityRest.PLURAL_NAME
|
||||||
|
+ CommunityLogoController.REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID + "/logo")
|
||||||
|
public class CommunityLogoController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regular expression in the request mapping to accept UUID as identifier
|
||||||
|
*/
|
||||||
|
protected static final String REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID =
|
||||||
|
"/{uuid:[0-9a-fxA-FX]{8}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{12}}";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected Utils utils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CommunityRestRepository communityRestRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CommunityService communityService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will add a logo to the community.
|
||||||
|
*
|
||||||
|
* curl -X POST http://<dspace.restUrl>/api/core/communities/1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb/logo' \
|
||||||
|
* -XPOST -H 'Content-Type: multipart/form-data' \
|
||||||
|
* -H 'Authorization: Bearer eyJhbGciOiJI...' \
|
||||||
|
* -F "file=@Downloads/test.png"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* <pre>
|
||||||
|
* {@code
|
||||||
|
* curl -X POST http://<dspace.restUrl>/api/core/communities/1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb/logo' \
|
||||||
|
* -XPOST -H 'Content-Type: multipart/form-data' \
|
||||||
|
* -H 'Authorization: Bearer eyJhbGciOiJI...' \
|
||||||
|
* -F "file=@Downloads/test.png"
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
* @param request The StandardMultipartHttpServletRequest that will contain the logo in its body
|
||||||
|
* @param uuid The UUID of the community
|
||||||
|
* @return The created bitstream
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
* @throws IOException If something goes wrong
|
||||||
|
* @throws AuthorizeException If the user doesn't have the correct rights
|
||||||
|
*/
|
||||||
|
@PreAuthorize("hasPermission(#uuid, 'COMMUNITY', 'WRITE')")
|
||||||
|
@RequestMapping(method = RequestMethod.POST,
|
||||||
|
headers = "content-type=multipart/form-data")
|
||||||
|
public ResponseEntity<ResourceSupport> createLogo(HttpServletRequest request, @PathVariable UUID uuid,
|
||||||
|
@RequestParam(value = "file", required = false) MultipartFile uploadfile)
|
||||||
|
throws SQLException, IOException, AuthorizeException {
|
||||||
|
|
||||||
|
if (uploadfile == null) {
|
||||||
|
throw new UnprocessableEntityException("No file was given");
|
||||||
|
}
|
||||||
|
|
||||||
|
Context context = ContextUtil.obtainContext(request);
|
||||||
|
|
||||||
|
Community community = communityService.find(context, uuid);
|
||||||
|
if (community == null) {
|
||||||
|
throw new ResourceNotFoundException(
|
||||||
|
"The given uuid did not resolve to a community on the server: " + uuid);
|
||||||
|
}
|
||||||
|
BitstreamRest bitstream = communityRestRepository.setLogo(context, community, uploadfile);
|
||||||
|
|
||||||
|
BitstreamResource bitstreamResource = new BitstreamResource(bitstream, utils);
|
||||||
|
context.complete();
|
||||||
|
return ControllerUtils.toResponseEntity(HttpStatus.CREATED, null, bitstreamResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
})
|
})
|
||||||
public class CollectionRest extends DSpaceObjectRest {
|
public class CollectionRest extends DSpaceObjectRest {
|
||||||
public static final String NAME = "collection";
|
public static final String NAME = "collection";
|
||||||
|
public static final String PLURAL_NAME = "collections";
|
||||||
public static final String CATEGORY = RestAddressableModel.CORE;
|
public static final String CATEGORY = RestAddressableModel.CORE;
|
||||||
public static final String LICENSE = "license";
|
public static final String LICENSE = "license";
|
||||||
public static final String HARVEST = "harvester";
|
public static final String HARVEST = "harvester";
|
||||||
|
@@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
*/
|
*/
|
||||||
public class CommunityRest extends DSpaceObjectRest {
|
public class CommunityRest extends DSpaceObjectRest {
|
||||||
public static final String NAME = "community";
|
public static final String NAME = "community";
|
||||||
|
public static final String PLURAL_NAME = "communities";
|
||||||
public static final String CATEGORY = RestAddressableModel.CORE;
|
public static final String CATEGORY = RestAddressableModel.CORE;
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
|
@@ -18,7 +18,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
|
|
||||||
import org.dspace.app.rest.converter.BitstreamConverter;
|
import org.dspace.app.rest.converter.BitstreamConverter;
|
||||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
|
||||||
import org.dspace.app.rest.model.BitstreamRest;
|
import org.dspace.app.rest.model.BitstreamRest;
|
||||||
import org.dspace.app.rest.model.hateoas.BitstreamResource;
|
import org.dspace.app.rest.model.hateoas.BitstreamResource;
|
||||||
import org.dspace.app.rest.model.patch.Patch;
|
import org.dspace.app.rest.model.patch.Patch;
|
||||||
@@ -27,8 +26,12 @@ import org.dspace.authorize.AuthorizeException;
|
|||||||
import org.dspace.authorize.service.AuthorizeService;
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
import org.dspace.content.Bitstream;
|
import org.dspace.content.Bitstream;
|
||||||
import org.dspace.content.Bundle;
|
import org.dspace.content.Bundle;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Community;
|
||||||
import org.dspace.content.service.BitstreamService;
|
import org.dspace.content.service.BitstreamService;
|
||||||
import org.dspace.content.service.BundleService;
|
import org.dspace.content.service.BundleService;
|
||||||
|
import org.dspace.content.service.CollectionService;
|
||||||
|
import org.dspace.content.service.CommunityService;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -56,6 +59,12 @@ public class BitstreamRestRepository extends DSpaceObjectRestRepository<Bitstrea
|
|||||||
@Autowired
|
@Autowired
|
||||||
AuthorizeService authorizeService;
|
AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CollectionService collectionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CommunityService communityService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public BitstreamRestRepository(BitstreamService dsoService,
|
public BitstreamRestRepository(BitstreamService dsoService,
|
||||||
BitstreamConverter dsoConverter) {
|
BitstreamConverter dsoConverter) {
|
||||||
@@ -126,10 +135,21 @@ public class BitstreamRestRepository extends DSpaceObjectRestRepository<Bitstrea
|
|||||||
Bitstream bit = null;
|
Bitstream bit = null;
|
||||||
try {
|
try {
|
||||||
bit = bs.find(context, id);
|
bit = bs.find(context, id);
|
||||||
if (bit.getCommunity() != null | bit.getCollection() != null) {
|
if (bit == null) {
|
||||||
throw new UnprocessableEntityException("The bitstream cannot be deleted it is a logo");
|
throw new ResourceNotFoundException("The bitstream with uuid " + id + " could not be found");
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
if (bit.isDeleted()) {
|
||||||
|
throw new ResourceNotFoundException("The bitstream with uuid " + id + " was already deleted");
|
||||||
|
}
|
||||||
|
Community community = bit.getCommunity();
|
||||||
|
if (community != null) {
|
||||||
|
communityService.setLogo(context, community, null);
|
||||||
|
}
|
||||||
|
Collection collection = bit.getCollection();
|
||||||
|
if (collection != null) {
|
||||||
|
collectionService.setLogo(context, collection, null);
|
||||||
|
}
|
||||||
|
} catch (SQLException | IOException e) {
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@@ -17,13 +17,16 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.app.rest.Parameter;
|
import org.dspace.app.rest.Parameter;
|
||||||
import org.dspace.app.rest.SearchRestMethod;
|
import org.dspace.app.rest.SearchRestMethod;
|
||||||
|
import org.dspace.app.rest.converter.BitstreamConverter;
|
||||||
import org.dspace.app.rest.converter.CollectionConverter;
|
import org.dspace.app.rest.converter.CollectionConverter;
|
||||||
import org.dspace.app.rest.converter.MetadataConverter;
|
import org.dspace.app.rest.converter.MetadataConverter;
|
||||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||||
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
|
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
|
||||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||||
|
import org.dspace.app.rest.model.BitstreamRest;
|
||||||
import org.dspace.app.rest.model.CollectionRest;
|
import org.dspace.app.rest.model.CollectionRest;
|
||||||
import org.dspace.app.rest.model.CommunityRest;
|
import org.dspace.app.rest.model.CommunityRest;
|
||||||
import org.dspace.app.rest.model.hateoas.CollectionResource;
|
import org.dspace.app.rest.model.hateoas.CollectionResource;
|
||||||
@@ -31,8 +34,10 @@ import org.dspace.app.rest.model.patch.Patch;
|
|||||||
import org.dspace.app.rest.repository.patch.DSpaceObjectPatch;
|
import org.dspace.app.rest.repository.patch.DSpaceObjectPatch;
|
||||||
import org.dspace.app.rest.utils.CollectionRestEqualityUtils;
|
import org.dspace.app.rest.utils.CollectionRestEqualityUtils;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.service.BitstreamService;
|
||||||
import org.dspace.content.service.CollectionService;
|
import org.dspace.content.service.CollectionService;
|
||||||
import org.dspace.content.service.CommunityService;
|
import org.dspace.content.service.CommunityService;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
@@ -44,6 +49,7 @@ import org.springframework.data.domain.Pageable;
|
|||||||
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the repository responsible to manage Item Rest object
|
* This is the repository responsible to manage Item Rest object
|
||||||
@@ -54,7 +60,8 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component(CollectionRest.CATEGORY + "." + CollectionRest.NAME)
|
@Component(CollectionRest.CATEGORY + "." + CollectionRest.NAME)
|
||||||
public class CollectionRestRepository extends DSpaceObjectRestRepository<Collection, CollectionRest> {
|
public class CollectionRestRepository extends DSpaceObjectRestRepository<Collection, CollectionRest> {
|
||||||
|
|
||||||
private final CollectionService cs;
|
private static final Logger log = org.apache.logging.log4j.LogManager
|
||||||
|
.getLogger(CollectionRestRepository.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
CommunityService communityService;
|
CommunityService communityService;
|
||||||
@@ -62,17 +69,24 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
|
|||||||
@Autowired
|
@Autowired
|
||||||
CollectionConverter converter;
|
CollectionConverter converter;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
BitstreamConverter bitstreamConverter;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
MetadataConverter metadataConverter;
|
MetadataConverter metadataConverter;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
CollectionRestEqualityUtils collectionRestEqualityUtils;
|
CollectionRestEqualityUtils collectionRestEqualityUtils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CollectionService cs;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BitstreamService bitstreamService;
|
||||||
|
|
||||||
public CollectionRestRepository(CollectionService dsoService,
|
public CollectionRestRepository(CollectionService dsoService,
|
||||||
CollectionConverter dsoConverter) {
|
CollectionConverter dsoConverter) {
|
||||||
super(dsoService, dsoConverter, new DSpaceObjectPatch<CollectionRest>() {});
|
super(dsoService, dsoConverter, new DSpaceObjectPatch<CollectionRest>() {});
|
||||||
this.cs = dsoService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -253,4 +267,28 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
|
|||||||
throw new RuntimeException("Unable to delete collection because the logo couldn't be deleted", e);
|
throw new RuntimeException("Unable to delete collection because the logo couldn't be deleted", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to install a logo on a Collection which doesn't have a logo
|
||||||
|
* Called by request mappings in CollectionLogoController
|
||||||
|
* @param context
|
||||||
|
* @param collection The collection on which to install the logo
|
||||||
|
* @param uploadfile The new logo
|
||||||
|
* @return The created bitstream containing the new logo
|
||||||
|
* @throws IOException
|
||||||
|
* @throws AuthorizeException
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public BitstreamRest setLogo(Context context, Collection collection, MultipartFile uploadfile)
|
||||||
|
throws IOException, AuthorizeException, SQLException {
|
||||||
|
|
||||||
|
if (collection.getLogo() != null) {
|
||||||
|
throw new UnprocessableEntityException(
|
||||||
|
"The collection with the given uuid already has a logo: " + collection.getID());
|
||||||
|
}
|
||||||
|
Bitstream bitstream = cs.setLogo(context, collection, uploadfile.getInputStream());
|
||||||
|
cs.update(context, collection);
|
||||||
|
bitstreamService.update(context, bitstream);
|
||||||
|
return bitstreamConverter.fromModel(context.reloadEntity(bitstream));
|
||||||
|
}
|
||||||
}
|
}
|
@@ -17,20 +17,25 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.app.rest.Parameter;
|
import org.dspace.app.rest.Parameter;
|
||||||
import org.dspace.app.rest.SearchRestMethod;
|
import org.dspace.app.rest.SearchRestMethod;
|
||||||
|
import org.dspace.app.rest.converter.BitstreamConverter;
|
||||||
import org.dspace.app.rest.converter.CommunityConverter;
|
import org.dspace.app.rest.converter.CommunityConverter;
|
||||||
import org.dspace.app.rest.converter.MetadataConverter;
|
import org.dspace.app.rest.converter.MetadataConverter;
|
||||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||||
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
|
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
|
||||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||||
|
import org.dspace.app.rest.model.BitstreamRest;
|
||||||
import org.dspace.app.rest.model.CommunityRest;
|
import org.dspace.app.rest.model.CommunityRest;
|
||||||
import org.dspace.app.rest.model.hateoas.CommunityResource;
|
import org.dspace.app.rest.model.hateoas.CommunityResource;
|
||||||
import org.dspace.app.rest.model.patch.Patch;
|
import org.dspace.app.rest.model.patch.Patch;
|
||||||
import org.dspace.app.rest.repository.patch.DSpaceObjectPatch;
|
import org.dspace.app.rest.repository.patch.DSpaceObjectPatch;
|
||||||
import org.dspace.app.rest.utils.CommunityRestEqualityUtils;
|
import org.dspace.app.rest.utils.CommunityRestEqualityUtils;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.service.BitstreamService;
|
||||||
import org.dspace.content.service.CommunityService;
|
import org.dspace.content.service.CommunityService;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -40,6 +45,7 @@ import org.springframework.data.domain.Pageable;
|
|||||||
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the repository responsible to manage Community Rest object
|
* This is the repository responsible to manage Community Rest object
|
||||||
@@ -50,21 +56,30 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component(CommunityRest.CATEGORY + "." + CommunityRest.NAME)
|
@Component(CommunityRest.CATEGORY + "." + CommunityRest.NAME)
|
||||||
public class CommunityRestRepository extends DSpaceObjectRestRepository<Community, CommunityRest> {
|
public class CommunityRestRepository extends DSpaceObjectRestRepository<Community, CommunityRest> {
|
||||||
|
|
||||||
private final CommunityService cs;
|
private static final Logger log = org.apache.logging.log4j.LogManager
|
||||||
|
.getLogger(CommunityRestRepository.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
CommunityConverter converter;
|
CommunityConverter converter;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
BitstreamConverter bitstreamConverter;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
MetadataConverter metadataConverter;
|
MetadataConverter metadataConverter;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
CommunityRestEqualityUtils communityRestEqualityUtils;
|
CommunityRestEqualityUtils communityRestEqualityUtils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CommunityService cs;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BitstreamService bitstreamService;
|
||||||
|
|
||||||
public CommunityRestRepository(CommunityService dsoService,
|
public CommunityRestRepository(CommunityService dsoService,
|
||||||
CommunityConverter dsoConverter) {
|
CommunityConverter dsoConverter) {
|
||||||
super(dsoService, dsoConverter, new DSpaceObjectPatch<CommunityRest>() {});
|
super(dsoService, dsoConverter, new DSpaceObjectPatch<CommunityRest>() {});
|
||||||
this.cs = dsoService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -260,4 +275,28 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
|
|||||||
throw new RuntimeException("Unable to delete community because the logo couldn't be deleted", e);
|
throw new RuntimeException("Unable to delete community because the logo couldn't be deleted", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to install a logo on a Community which doesn't have a logo
|
||||||
|
* Called by request mappings in CommunityLogoController
|
||||||
|
* @param context
|
||||||
|
* @param community The community on which to install the logo
|
||||||
|
* @param uploadfile The new logo
|
||||||
|
* @return The created bitstream containing the new logo
|
||||||
|
* @throws IOException
|
||||||
|
* @throws AuthorizeException
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public BitstreamRest setLogo(Context context, Community community, MultipartFile uploadfile)
|
||||||
|
throws IOException, AuthorizeException, SQLException {
|
||||||
|
|
||||||
|
if (community.getLogo() != null) {
|
||||||
|
throw new UnprocessableEntityException(
|
||||||
|
"The community with the given uuid already has a logo: " + community.getID());
|
||||||
|
}
|
||||||
|
Bitstream bitstream = cs.setLogo(context, community, uploadfile.getInputStream());
|
||||||
|
cs.update(context, community);
|
||||||
|
bitstreamService.update(context, bitstream);
|
||||||
|
return bitstreamConverter.fromModel(context.reloadEntity(bitstream));
|
||||||
|
}
|
||||||
}
|
}
|
@@ -474,7 +474,7 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteUnauthorized() throws Exception {
|
public void deleteForbidden() throws Exception {
|
||||||
|
|
||||||
//We turn off the authorization system in order to create the structure as defined below
|
//We turn off the authorization system in order to create the structure as defined below
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -521,7 +521,7 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteForbidden() throws Exception {
|
public void deleteUnauthorized() throws Exception {
|
||||||
|
|
||||||
//We turn off the authorization system in order to create the structure as defined below
|
//We turn off the authorization system in order to create the structure as defined below
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -581,13 +581,72 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
|
|
||||||
String token = getAuthToken(admin.getEmail(), password);
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
// 422 error when trying to DELETE parentCommunity logo
|
// trying to DELETE parentCommunity logo should work
|
||||||
getClient(token).perform(delete("/api/core/bitstreams/" + parentCommunity.getLogo().getID()))
|
getClient(token).perform(delete("/api/core/bitstreams/" + parentCommunity.getLogo().getID()))
|
||||||
.andExpect(status().is(422));
|
.andExpect(status().is(204));
|
||||||
|
|
||||||
// 422 error when trying to DELETE collection logo
|
// trying to DELETE collection logo should work
|
||||||
getClient(token).perform(delete("/api/core/bitstreams/" + col.getLogo().getID()))
|
getClient(token).perform(delete("/api/core/bitstreams/" + col.getLogo().getID()))
|
||||||
.andExpect(status().is(422));
|
.andExpect(status().is(204));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteMissing() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
getClient(token).perform(delete("/api/core/bitstreams/1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb"))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
|
||||||
|
// Verify 404 after failed delete
|
||||||
|
getClient(token).perform(delete("/api/core/bitstreams/1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb"))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteDeleted() throws Exception {
|
||||||
|
//We turn off the authorization system in order to create the structure as defined below
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
//1. A community-collection structure with one parent community with sub-community and one collection.
|
||||||
|
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();
|
||||||
|
|
||||||
|
//2. One public items that is readable by Anonymous
|
||||||
|
Item publicItem1 = ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("Test")
|
||||||
|
.withIssueDate("2010-10-17")
|
||||||
|
.withAuthor("Smith, Donald")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String bitstreamContent = "ThisIsSomeDummyText";
|
||||||
|
//Add a bitstream to an item
|
||||||
|
Bitstream bitstream = null;
|
||||||
|
try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) {
|
||||||
|
bitstream = BitstreamBuilder.
|
||||||
|
createBitstream(context, publicItem1, is)
|
||||||
|
.withName("Bitstream")
|
||||||
|
.withDescription("Description")
|
||||||
|
.withMimeType("text/plain")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
getClient(token).perform(delete("/api/core/bitstreams/" + bitstream.getID()))
|
||||||
|
.andExpect(status().is(204));
|
||||||
|
|
||||||
|
// Verify 404 when trying to delete a non-existing bitstream
|
||||||
|
getClient(token).perform(delete("/api/core/bitstreams/" + bitstream.getID()))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -0,0 +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;
|
||||||
|
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.dspace.app.rest.builder.CollectionBuilder;
|
||||||
|
import org.dspace.app.rest.builder.CommunityBuilder;
|
||||||
|
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
|
public class CollectionLogoControllerIT extends AbstractControllerIntegrationTest {
|
||||||
|
|
||||||
|
private ObjectMapper mapper;
|
||||||
|
private String adminAuthToken;
|
||||||
|
private String bitstreamContent;
|
||||||
|
private MockMultipartFile bitstreamFile;
|
||||||
|
private Collection childCollection;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createStructure() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
childCollection = CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1").build();
|
||||||
|
adminAuthToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
bitstreamContent = "Hello, World!";
|
||||||
|
bitstreamFile = new MockMultipartFile("file",
|
||||||
|
"hello.txt", MediaType.TEXT_PLAIN_VALUE,
|
||||||
|
bitstreamContent.getBytes());
|
||||||
|
mapper = new ObjectMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createLogoInternal() throws Exception {
|
||||||
|
MvcResult mvcPostResult = getClient(adminAuthToken).perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate(childCollection.getID().toString()))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isCreated())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
String postContent = mvcPostResult.getResponse().getContentAsString();
|
||||||
|
Map<String, Object> mapPostResult = mapper.readValue(postContent, Map.class);
|
||||||
|
return String.valueOf(mapPostResult.get("uuid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createLogoNotLoggedIn() throws Exception {
|
||||||
|
getClient().perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate(childCollection.getID().toString()))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createLogo() throws Exception {
|
||||||
|
String postUuid = createLogoInternal();
|
||||||
|
assert (postUuid != null);
|
||||||
|
|
||||||
|
MvcResult mvcGetResult = getClient().perform(get(getLogoUrlTemplate(childCollection.getID().toString())))
|
||||||
|
.andExpect(status().is2xxSuccessful())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
String getContent = mvcGetResult.getResponse().getContentAsString();
|
||||||
|
Map<String, Object> mapGetResult = mapper.readValue(getContent, Map.class);
|
||||||
|
String getUuid = String.valueOf(mapGetResult.get("uuid"));
|
||||||
|
assert (postUuid.equals(getUuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createLogoNoRights() throws Exception {
|
||||||
|
String userToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(userToken).perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate(childCollection.getID().toString()))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createDuplicateLogo() throws Exception {
|
||||||
|
getClient(adminAuthToken).perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate(childCollection.getID().toString()))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isCreated());
|
||||||
|
|
||||||
|
getClient(adminAuthToken).perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate(childCollection.getID().toString()))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isUnprocessableEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createLogoForNonexisting() throws Exception {
|
||||||
|
getClient(adminAuthToken).perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate("16a4b65b-3b3f-4ef5-8058-ef6f5a653ef9"))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteLogoNotLoggedIn() throws Exception {
|
||||||
|
String postUuid = createLogoInternal();
|
||||||
|
|
||||||
|
getClient().perform(delete(getBitstreamUrlTemplate(postUuid)))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteLogo() throws Exception {
|
||||||
|
String postUuid = createLogoInternal();
|
||||||
|
|
||||||
|
getClient(adminAuthToken).perform(delete(getBitstreamUrlTemplate(postUuid)))
|
||||||
|
.andExpect(status().isNoContent());
|
||||||
|
|
||||||
|
getClient(adminAuthToken).perform(get(getLogoUrlTemplate(childCollection.getID().toString())))
|
||||||
|
.andExpect(status().isNoContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteLogoNoRights() throws Exception {
|
||||||
|
String postUuid = createLogoInternal();
|
||||||
|
|
||||||
|
String userToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(userToken).perform(delete(getBitstreamUrlTemplate(postUuid)))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLogoUrlTemplate(String uuid) {
|
||||||
|
return "/api/core/collections/" + uuid + "/logo";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getBitstreamUrlTemplate(String uuid) {
|
||||||
|
return "/api/core/bitstreams/" + uuid;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,147 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.dspace.app.rest.builder.CommunityBuilder;
|
||||||
|
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
|
public class CommunityLogoControllerIT extends AbstractControllerIntegrationTest {
|
||||||
|
|
||||||
|
private ObjectMapper mapper;
|
||||||
|
private String adminAuthToken;
|
||||||
|
private String bitstreamContent;
|
||||||
|
private MockMultipartFile bitstreamFile;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createStructure() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
adminAuthToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
bitstreamContent = "Hello, World!";
|
||||||
|
bitstreamFile = new MockMultipartFile("file",
|
||||||
|
"hello.txt", MediaType.TEXT_PLAIN_VALUE,
|
||||||
|
bitstreamContent.getBytes());
|
||||||
|
mapper = new ObjectMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createLogoInternal() throws Exception {
|
||||||
|
MvcResult mvcPostResult = getClient(adminAuthToken).perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate(parentCommunity.getID().toString()))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isCreated())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
String postContent = mvcPostResult.getResponse().getContentAsString();
|
||||||
|
Map<String, Object> mapPostResult = mapper.readValue(postContent, Map.class);
|
||||||
|
return String.valueOf(mapPostResult.get("uuid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createLogoNotLoggedIn() throws Exception {
|
||||||
|
getClient().perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate(parentCommunity.getID().toString()))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createLogo() throws Exception {
|
||||||
|
String postUuid = createLogoInternal();
|
||||||
|
assert (postUuid != null);
|
||||||
|
|
||||||
|
MvcResult mvcGetResult = getClient().perform(get(getLogoUrlTemplate(parentCommunity.getID().toString())))
|
||||||
|
.andExpect(status().is2xxSuccessful())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
String getContent = mvcGetResult.getResponse().getContentAsString();
|
||||||
|
Map<String, Object> mapGetResult = mapper.readValue(getContent, Map.class);
|
||||||
|
String getUuid = String.valueOf(mapGetResult.get("uuid"));
|
||||||
|
assert (postUuid.equals(getUuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createLogoNoRights() throws Exception {
|
||||||
|
String userToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(userToken).perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate(parentCommunity.getID().toString()))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createDuplicateLogo() throws Exception {
|
||||||
|
getClient(adminAuthToken).perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate(parentCommunity.getID().toString()))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isCreated());
|
||||||
|
|
||||||
|
getClient(adminAuthToken).perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate(parentCommunity.getID().toString()))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isUnprocessableEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createLogoForNonexisting() throws Exception {
|
||||||
|
getClient(adminAuthToken).perform(
|
||||||
|
MockMvcRequestBuilders.fileUpload(getLogoUrlTemplate("16a4b65b-3b3f-4ef5-8058-ef6f5a653ef9"))
|
||||||
|
.file(bitstreamFile))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteLogoNotLoggedIn() throws Exception {
|
||||||
|
String postUuid = createLogoInternal();
|
||||||
|
|
||||||
|
getClient().perform(delete(getBitstreamUrlTemplate(postUuid)))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteLogo() throws Exception {
|
||||||
|
String postUuid = createLogoInternal();
|
||||||
|
|
||||||
|
getClient(adminAuthToken).perform(delete(getBitstreamUrlTemplate(postUuid)))
|
||||||
|
.andExpect(status().isNoContent());
|
||||||
|
|
||||||
|
getClient(adminAuthToken).perform(get(getLogoUrlTemplate(parentCommunity.getID().toString())))
|
||||||
|
.andExpect(status().isNoContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteLogoNoRights() throws Exception {
|
||||||
|
String postUuid = createLogoInternal();
|
||||||
|
|
||||||
|
String userToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(userToken).perform(delete(getBitstreamUrlTemplate(postUuid)))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLogoUrlTemplate(String uuid) {
|
||||||
|
return "/api/core/communities/" + uuid + "/logo";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getBitstreamUrlTemplate(String uuid) {
|
||||||
|
return "/api/core/bitstreams/" + uuid;
|
||||||
|
}
|
||||||
|
}
|
@@ -42,6 +42,130 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</profile>
|
</profile>
|
||||||
|
<!-- If Unit Testing is enabled, then setup the Unit Test Environment.
|
||||||
|
See also the 'skiptests' profile in Parent POM. -->
|
||||||
|
<profile>
|
||||||
|
<id>test-environment</id>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>false</activeByDefault>
|
||||||
|
<property>
|
||||||
|
<name>maven.test.skip</name>
|
||||||
|
<value>false</value>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- Unit/Integration Testing setup: This plugin unzips the
|
||||||
|
'testEnvironment.zip' file (created by dspace-parent POM), into
|
||||||
|
the 'target/testing/' folder, to essentially create a test
|
||||||
|
install of DSpace, against which Tests can be run. -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<version>2.8</version>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/testing</outputDirectory>
|
||||||
|
<artifactItems>
|
||||||
|
<artifactItem>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-parent</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>zip</type>
|
||||||
|
<classifier>testEnvironment</classifier>
|
||||||
|
</artifactItem>
|
||||||
|
</artifactItems>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>setupTestEnvironment</id>
|
||||||
|
<phase>generate-test-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>unpack</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>setupIntegrationTestEnvironment</id>
|
||||||
|
<phase>pre-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>unpack</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- This plugin allows us to run a Groovy script in our Maven POM
|
||||||
|
(see: http://gmaven.codehaus.org/Executing+Groovy+Code )
|
||||||
|
We are generating a OS-agnostic version (agnostic.build.dir) of
|
||||||
|
the ${project.build.directory} property (full path of target dir).
|
||||||
|
This is needed by the FileWeaver & Surefire plugins (see below)
|
||||||
|
to initialize the Unit Test environment's dspace.cfg file.
|
||||||
|
Otherwise, the Unit Test Framework will not work on Windows OS.
|
||||||
|
This Groovy code was mostly borrowed from:
|
||||||
|
http://stackoverflow.com/questions/3872355/how-to-convert-file-separator-in-maven
|
||||||
|
-->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.gmaven</groupId>
|
||||||
|
<artifactId>groovy-maven-plugin</artifactId>
|
||||||
|
<version>2.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>setproperty</id>
|
||||||
|
<phase>generate-test-resources
|
||||||
|
</phase> <!-- XXX I think this should be 'initialize' - MHW -->
|
||||||
|
<goals>
|
||||||
|
<goal>execute</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<source>
|
||||||
|
project.properties['agnostic.build.dir'] = project.build.directory.replace(File.separator, '/');
|
||||||
|
println("Initializing Maven property 'agnostic.build.dir' to: " + project.properties['agnostic.build.dir']);
|
||||||
|
</source>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- Run Unit Testing! This plugin just kicks off the tests (when enabled). -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<!-- Specify the dspace.dir to use for test environment -->
|
||||||
|
<!-- This system property is loaded by AbstractDSpaceTest to initialize the test environment -->
|
||||||
|
<dspace.dir>${agnostic.build.dir}/testing/dspace/</dspace.dir>
|
||||||
|
<!-- Turn off any DSpace logging -->
|
||||||
|
<dspace.log.init.disable>true</dspace.log.init.disable>
|
||||||
|
<solr.install.dir>${agnostic.build.dir}/testing/dspace/solr/</solr.install.dir>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- Run Integration Testing! This plugin just kicks off the tests (when enabled). -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<!-- Specify the dspace.dir to use for test environment -->
|
||||||
|
<dspace.dir>${agnostic.build.dir}/testing/dspace/</dspace.dir>
|
||||||
|
<!-- Turn off any DSpace logging -->
|
||||||
|
<dspace.log.init.disable>true</dspace.log.init.disable>
|
||||||
|
<solr.install.dir>${agnostic.build.dir}/testing/dspace/solr/</solr.install.dir>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<!-- When running tests, also include test classes from dspace-api
|
||||||
|
(this test-jar is only built when tests are enabled). -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-api</artifactId>
|
||||||
|
<version>7.0-SNAPSHOT</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -73,6 +197,33 @@
|
|||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Keep jmockit before junit -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jmockit</groupId>
|
||||||
|
<artifactId>jmockit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@@ -8,9 +8,7 @@
|
|||||||
package org.dspace.example;
|
package org.dspace.example;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Add Description
|
* This interface serves as an example of how & where to add local customizations to the DSpace REST API.
|
||||||
*
|
|
||||||
* @author mdiggory @ atmire.com
|
|
||||||
*/
|
*/
|
||||||
public interface Example {
|
public interface Example {
|
||||||
}
|
}
|
||||||
|
@@ -10,9 +10,7 @@ package org.dspace.example.impl;
|
|||||||
import org.dspace.example.Example;
|
import org.dspace.example.Example;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Add Description
|
* This class serves as an example of how & where to add local customizations to the DSpace REST API.
|
||||||
*
|
|
||||||
* @author mdiggory @ atmire.com
|
|
||||||
*/
|
*/
|
||||||
public class ExampleImpl implements Example {
|
public class ExampleImpl implements Example {
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* 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.example;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.dspace.AbstractIntegrationTest;
|
||||||
|
import org.dspace.example.impl.ExampleImpl;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This IT serves as an an example of how & where to add integration tests for local customizations to the DSpace API.
|
||||||
|
* See {@link Example} and {@link ExampleImpl} for the class of which the functionality is tested.
|
||||||
|
*/
|
||||||
|
public class ExampleIT extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExampleImpl() {
|
||||||
|
assertTrue(new DSpace().getSingletonService(Example.class) instanceof ExampleImpl);
|
||||||
|
}
|
||||||
|
}
|
@@ -77,6 +77,128 @@ just adding new jar in the classloader</description>
|
|||||||
</build>
|
</build>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
|
<!-- If Unit Testing is enabled, then setup the Unit Test Environment.
|
||||||
|
See also the 'skiptests' profile in Parent POM. -->
|
||||||
|
<profile>
|
||||||
|
<id>test-environment</id>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>false</activeByDefault>
|
||||||
|
<property>
|
||||||
|
<name>maven.test.skip</name>
|
||||||
|
<value>false</value>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- Unit/Integration Testing setup: This plugin unzips the
|
||||||
|
'testEnvironment.zip' file (created by dspace-parent POM), into
|
||||||
|
the 'target/testing/' folder, to essentially create a test
|
||||||
|
install of DSpace, against which Tests can be run. -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/testing</outputDirectory>
|
||||||
|
<artifactItems>
|
||||||
|
<artifactItem>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-parent</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>zip</type>
|
||||||
|
<classifier>testEnvironment</classifier>
|
||||||
|
</artifactItem>
|
||||||
|
</artifactItems>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>setupTestEnvironment</id>
|
||||||
|
<phase>generate-test-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>unpack</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>setupIntegrationTestEnvironment</id>
|
||||||
|
<phase>pre-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>unpack</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- This plugin allows us to run a Groovy script in our Maven POM
|
||||||
|
(see: http://gmaven.codehaus.org/Executing+Groovy+Code )
|
||||||
|
We are generating a OS-agnostic version (agnostic.build.dir) of
|
||||||
|
the ${project.build.directory} property (full path of target dir).
|
||||||
|
This is needed by the FileWeaver & Surefire plugins (see below)
|
||||||
|
to initialize the Unit Test environment's dspace.cfg file.
|
||||||
|
Otherwise, the Unit Test Framework will not work on Windows OS.
|
||||||
|
This Groovy code was mostly borrowed from:
|
||||||
|
http://stackoverflow.com/questions/3872355/how-to-convert-file-separator-in-maven
|
||||||
|
-->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.gmaven</groupId>
|
||||||
|
<artifactId>groovy-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>setproperty</id>
|
||||||
|
<phase>generate-test-resources
|
||||||
|
</phase> <!-- XXX I think this should be 'initialize' - MHW -->
|
||||||
|
<goals>
|
||||||
|
<goal>execute</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<source>
|
||||||
|
project.properties['agnostic.build.dir'] = project.build.directory.replace(File.separator, '/');
|
||||||
|
println("Initializing Maven property 'agnostic.build.dir' to: " + project.properties['agnostic.build.dir']);
|
||||||
|
</source>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- Run Unit Testing! This plugin just kicks off the tests (when enabled). -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<!-- Specify the dspace.dir to use for test environment -->
|
||||||
|
<!-- This system property is loaded by AbstractDSpaceTest to initialize the test environment -->
|
||||||
|
<dspace.dir>${agnostic.build.dir}/testing/dspace/</dspace.dir>
|
||||||
|
<!-- Turn off any DSpace logging -->
|
||||||
|
<dspace.log.init.disable>true</dspace.log.init.disable>
|
||||||
|
<solr.install.dir>${agnostic.build.dir}/testing/dspace/solr/</solr.install.dir>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- Run Integration Testing! This plugin just kicks off the tests (when enabled). -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<!-- Specify the dspace.dir to use for test environment -->
|
||||||
|
<dspace.dir>${agnostic.build.dir}/testing/dspace/</dspace.dir>
|
||||||
|
<!-- Turn off any DSpace logging -->
|
||||||
|
<dspace.log.init.disable>true</dspace.log.init.disable>
|
||||||
|
<solr.install.dir>${agnostic.build.dir}/testing/dspace/solr/</solr.install.dir>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<!-- When running tests, also include test classes from dspace-server-webapp
|
||||||
|
(this test-jar is only built when tests are enabled). -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-server-webapp</artifactId>
|
||||||
|
<version>7.0-SNAPSHOT</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>oracle-support</id>
|
<id>oracle-support</id>
|
||||||
<activation>
|
<activation>
|
||||||
@@ -95,15 +217,85 @@ just adding new jar in the classloader</description>
|
|||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace.modules</groupId>
|
<groupId>org.dspace.modules</groupId>
|
||||||
<artifactId>additions</artifactId>
|
<artifactId>additions</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-server-webapp</artifactId>
|
||||||
|
<classifier>classes</classifier>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-server-webapp</artifactId>
|
<artifactId>dspace-server-webapp</artifactId>
|
||||||
<type>war</type>
|
<type>war</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<!-- Temporary exclusion to avoid dependency conflict with version of org.json:json used by dspace-api.
|
||||||
|
NOTE: THIS CAN BE REMOVED ONCE WE UPGRADE TO SPRING-BOOT v1.5 (or above), see DS-3802
|
||||||
|
As of Spring-Boot 1.5, org.json:json is no longer used by spring-boot-starter-test -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.json</groupId>
|
||||||
|
<artifactId>json</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<!-- More recent version used for testing below -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
|
<artifactId>json-path</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
|
<artifactId>json-path-assert</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jmockit</groupId>
|
||||||
|
<artifactId>jmockit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.solr</groupId>
|
||||||
|
<artifactId>solr-cell</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- Reminder: Keep icu4j (in Parent POM) synced with version used by lucene-analyzers-icu below,
|
||||||
|
otherwise ICUFoldingFilterFactory may throw errors in tests. -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-analyzers-icu</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* 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.example;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This Controller serves as an example of how & where to add local customizations to the DSpace REST API.
|
||||||
|
* See {@link ExampleControllerIT} for the integration tests for this controller.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("example")
|
||||||
|
public class ExampleController {
|
||||||
|
|
||||||
|
@RequestMapping("")
|
||||||
|
public String test() {
|
||||||
|
return "Hello world";
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* 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.example;
|
||||||
|
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This IT serves as an example of how & where to add integration tests for local customizations to the DSpace REST API.
|
||||||
|
* See {@link ExampleController} for the Controller of which the functionality is tested.
|
||||||
|
*/
|
||||||
|
public class ExampleControllerIT extends AbstractControllerIntegrationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTest() throws Exception {
|
||||||
|
|
||||||
|
getClient()
|
||||||
|
.perform(get("/example"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().string("Hello world"));
|
||||||
|
}
|
||||||
|
}
|
79
pom.xml
79
pom.xml
@@ -42,6 +42,9 @@
|
|||||||
<solr.client.version>7.3.1</solr.client.version>
|
<solr.client.version>7.3.1</solr.client.version>
|
||||||
<spring.version>4.3.24.RELEASE</spring.version>
|
<spring.version>4.3.24.RELEASE</spring.version>
|
||||||
<spring-boot.version>1.4.4.RELEASE</spring-boot.version>
|
<spring-boot.version>1.4.4.RELEASE</spring-boot.version>
|
||||||
|
<!-- Library for reading JSON documents: https://github.com/json-path/JsonPath -->
|
||||||
|
<json-path.version>2.4.0</json-path.version>
|
||||||
|
|
||||||
<!-- 'root.basedir' is the path to the root [dspace-src] dir. It must be redefined by each child POM,
|
<!-- 'root.basedir' is the path to the root [dspace-src] dir. It must be redefined by each child POM,
|
||||||
as it is used to reference the LICENSE_HEADER and *.properties file(s) in that directory. -->
|
as it is used to reference the LICENSE_HEADER and *.properties file(s) in that directory. -->
|
||||||
<root.basedir>${basedir}</root.basedir>
|
<root.basedir>${basedir}</root.basedir>
|
||||||
@@ -978,24 +981,25 @@
|
|||||||
<version>7.0-SNAPSHOT</version>
|
<version>7.0-SNAPSHOT</version>
|
||||||
<type>war</type>
|
<type>war</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-server-webapp</artifactId>
|
||||||
|
<version>7.0-SNAPSHOT</version>
|
||||||
|
<type>jar</type>
|
||||||
|
<classifier>classes</classifier>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-server-webapp</artifactId>
|
<artifactId>dspace-server-webapp</artifactId>
|
||||||
<version>7.0-SNAPSHOT</version>
|
<version>7.0-SNAPSHOT</version>
|
||||||
<type>war</type>
|
<type>war</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- DSpace Localization Packages -->
|
<!-- DSpace API Localization Packages -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-api-lang</artifactId>
|
<artifactId>dspace-api-lang</artifactId>
|
||||||
<version>[6.0.0,7.0.0)</version>
|
<version>[6.0.0,7.0.0)</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<artifactId>dspace-xmlui-lang</artifactId>
|
|
||||||
<version>[6.0.0,7.0.0)</version>
|
|
||||||
<type>war</type>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- DSpace third Party Dependencies -->
|
<!-- DSpace third Party Dependencies -->
|
||||||
|
|
||||||
@@ -1105,6 +1109,67 @@
|
|||||||
<version>${spring.version}</version>
|
<version>${spring.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-expression</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<!-- Temporary exclusion to avoid dependency conflict with version of org.json:json used by dspace-api.
|
||||||
|
NOTE: THIS CAN BE REMOVED ONCE WE UPGRADE TO SPRING-BOOT v1.5 (or above), see DS-3802
|
||||||
|
As of Spring-Boot 1.5, org.json:json is no longer used by spring-boot-starter-test -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.json</groupId>
|
||||||
|
<artifactId>json</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<!-- More recent version used for testing below -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
|
<artifactId>json-path</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.solr</groupId>
|
||||||
|
<artifactId>solr-cell</artifactId>
|
||||||
|
<version>${solr.client.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Reminder: Keep icu4j (in Parent POM) synced with version used by lucene-analyzers-icu below,
|
||||||
|
otherwise ICUFoldingFilterFactory may throw errors in tests. -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-analyzers-icu</artifactId>
|
||||||
|
<version>${solr.client.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
|
<artifactId>json-path-assert</artifactId>
|
||||||
|
<version>${json-path.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
|
<artifactId>json-path</artifactId>
|
||||||
|
<version>${json-path.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.ant</groupId>
|
<groupId>org.apache.ant</groupId>
|
||||||
<artifactId>ant</artifactId>
|
<artifactId>ant</artifactId>
|
||||||
|
Reference in New Issue
Block a user