Merge pull request #9195 from 4Science/CST-12042-addSupportForThePrimaryBitstreamFlag

Add support for the primary bitstream flag
This commit is contained in:
Tim Donohue
2024-02-20 17:09:36 -06:00
committed by GitHub
9 changed files with 812 additions and 41 deletions

View File

@@ -9,6 +9,7 @@ package org.dspace.app.rest.model.step;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
@@ -19,6 +20,11 @@ import com.fasterxml.jackson.annotation.JsonUnwrapped;
*/
public class DataUpload implements SectionData {
/*
* primary bitstream uuid
*/
private UUID primary;
@JsonUnwrapped
private List<UploadBitstreamRest> files;
@@ -32,4 +38,13 @@ public class DataUpload implements SectionData {
public void setFiles(List<UploadBitstreamRest> files) {
this.files = files;
}
public UUID getPrimary() {
return primary;
}
public void setPrimary(UUID primary) {
this.primary = primary;
}
}

View File

@@ -39,6 +39,7 @@ public interface DataProcessingStep extends RestProcessingStep {
public static final String ACCESS_CONDITION_STEP_OPERATION_ENTRY = "discoverable";
public static final String ACCESS_CONDITION_POLICY_STEP_OPERATION_ENTRY = "accessConditions";
public static final String SHOW_IDENTIFIERS_ENTRY = "identifiers";
public static final String PRIMARY_FLAG_ENTRY = "primary";
public static final String UPLOAD_STEP_METADATA_PATH = "metadata";

View File

@@ -53,7 +53,7 @@ public class BitstreamMetadataValueAddPatchOperation extends MetadataValueAddPat
bitstreamMetadataValuePathUtils.validate(absolutePath);
Item item = source.getItem();
List<Bundle> bundle = itemService.getBundles(item, Constants.CONTENT_BUNDLE_NAME);
;
for (Bundle bb : bundle) {
int idx = 0;
for (Bitstream b : bb.getBitstreams()) {

View File

@@ -0,0 +1,87 @@
/**
* 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.submit.factory.impl;
import static org.dspace.core.Constants.CONTENT_BUNDLE_NAME;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.InProgressSubmission;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Submission "add" operation to set primary bitstream.
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
*/
public class PrimaryBitstreamAddPatchOperation extends AddPatchOperation<String> {
@Autowired
private ItemService itemService;
@Override
void add(Context context, HttpServletRequest currentRequest, InProgressSubmission source, String path, Object value)
throws Exception {
Item item = source.getItem();
UUID primaryUUID = parseValue(value);
List<Bundle> bundles = itemService.getBundles(item, CONTENT_BUNDLE_NAME);
Optional<Bundle> currentPrimaryBundle = bundles.stream()
.filter(bundle -> Objects.nonNull(bundle.getPrimaryBitstream()))
.findFirst();
Optional<Bitstream> primaryBitstreamToAdd = null;
for (Bundle bundle : bundles) {
primaryBitstreamToAdd = bundle.getBitstreams().stream()
.filter(b -> b.getID().equals(primaryUUID))
.findFirst();
if (primaryBitstreamToAdd.isPresent()) {
if (currentPrimaryBundle.isPresent()) {
currentPrimaryBundle.get().setPrimaryBitstreamID(null);
}
bundle.setPrimaryBitstreamID(primaryBitstreamToAdd.get());
break;
}
}
if (primaryBitstreamToAdd.isEmpty()) {
throw new UnprocessableEntityException("The provided uuid: " + primaryUUID +
" of bitstream to set as primary doesn't match any bitstream!");
}
}
private UUID parseValue(Object value) {
UUID primaryBitstreamUUID;
try {
primaryBitstreamUUID = UUID.fromString((String) value);
} catch (Exception e) {
throw new UnprocessableEntityException("The provided value is invalid!", e);
}
return primaryBitstreamUUID;
}
@Override
protected Class<String[]> getArrayClassForEvaluation() {
return null;
}
@Override
protected Class<String> getClassForEvaluation() {
return null;
}
}

View File

@@ -0,0 +1,50 @@
/**
* 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.submit.factory.impl;
import static org.dspace.core.Constants.CONTENT_BUNDLE_NAME;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.dspace.content.Bundle;
import org.dspace.content.InProgressSubmission;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Submission "remove" operation to remove primary bitstream.
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
*/
public class PrimaryBitstreamRemovePatchOperation extends RemovePatchOperation<String> {
@Autowired
private ItemService itemService;
@Override
void remove(Context context, HttpServletRequest request, InProgressSubmission source, String path, Object value)
throws Exception {
Item item = source.getItem();
List<Bundle> bundles = itemService.getBundles(item, CONTENT_BUNDLE_NAME);
bundles.forEach(b -> b.setPrimaryBitstreamID(null));
}
@Override
protected Class<String[]> getArrayClassForEvaluation() {
return null;
}
@Override
protected Class<String> getClassForEvaluation() {
return null;
}
}

View File

@@ -0,0 +1,88 @@
/**
* 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.submit.factory.impl;
import static org.dspace.core.Constants.CONTENT_BUNDLE_NAME;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.InProgressSubmission;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Submission "replace" operation to replace primary bitstream.
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
*/
public class PrimaryBitstreamReplacePatchOperation extends ReplacePatchOperation<String> {
private final String EX_MESSAGE = "It is impossible to replace primary bitstrem if it wasn't set!";
@Autowired
private ItemService itemService;
@Override
void replace(Context context, HttpServletRequest request, InProgressSubmission source, String path, Object value)
throws Exception {
Item item = source.getItem();
UUID primaryUUID = parseValue(value);
List<Bundle> bundles = itemService.getBundles(item, CONTENT_BUNDLE_NAME);
Bundle currentPrimaryBundle = bundles.stream()
.filter(bundle -> Objects.nonNull(bundle.getPrimaryBitstream()))
.findFirst()
.orElseThrow(() -> new UnprocessableEntityException(EX_MESSAGE));
Optional<Bitstream> primaryBitstream = null;
for (Bundle bundle : bundles) {
primaryBitstream = bundle.getBitstreams().stream()
.filter(b -> b.getID().equals(primaryUUID))
.findFirst();
if (primaryBitstream.isPresent()) {
currentPrimaryBundle.setPrimaryBitstreamID(null);
bundle.setPrimaryBitstreamID(primaryBitstream.get());
break;
}
}
if (primaryBitstream.isEmpty()) {
throw new UnprocessableEntityException("The provided uuid: " + primaryUUID +
" of bitstream to set as primary doesn't match any bitstream!");
}
}
private UUID parseValue(Object value) {
UUID primaryBitstreamUUID;
try {
primaryBitstreamUUID = UUID.fromString((String) value);
} catch (Exception e) {
throw new UnprocessableEntityException("The provided value is invalid!", e);
}
return primaryBitstreamUUID;
}
@Override
protected Class<String[]> getArrayClassForEvaluation() {
return null;
}
@Override
protected Class<String> getClassForEvaluation() {
return null;
}
}

View File

@@ -10,8 +10,10 @@ package org.dspace.app.rest.submit.step;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.List;
import java.util.Objects;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.ErrorRest;
@@ -56,8 +58,12 @@ public class UploadStep extends AbstractProcessingStep
List<Bundle> bundles = itemService.getBundles(obj.getItem(), Constants.CONTENT_BUNDLE_NAME);
for (Bundle bundle : bundles) {
for (Bitstream source : bundle.getBitstreams()) {
Bitstream primaryBitstream = bundle.getPrimaryBitstream();
UploadBitstreamRest b = submissionService.buildUploadBitstream(configurationService, source);
result.getFiles().add(b);
if (Objects.nonNull(primaryBitstream)) {
result.setPrimary(primaryBitstream.getID());
}
}
}
return result;
@@ -73,6 +79,8 @@ public class UploadStep extends AbstractProcessingStep
instance = UPLOAD_STEP_METADATA_OPERATION_ENTRY;
} else if (op.getPath().contains(UPLOAD_STEP_ACCESSCONDITIONS_OPERATION_ENTRY)) {
instance = stepConf.getType() + "." + UPLOAD_STEP_ACCESSCONDITIONS_OPERATION_ENTRY;
} else if (op.getPath().contains(PRIMARY_FLAG_ENTRY)) {
instance = PRIMARY_FLAG_ENTRY;
} else {
instance = UPLOAD_STEP_REMOVE_OPERATION_ENTRY;
}
@@ -87,9 +95,11 @@ public class UploadStep extends AbstractProcessingStep
instance = stepConf.getType() + "." + UPLOAD_STEP_ACCESSCONDITIONS_OPERATION_ENTRY;
} else if (op.getPath().contains(UPLOAD_STEP_METADATA_PATH)) {
instance = UPLOAD_STEP_METADATA_OPERATION_ENTRY;
} else if (op.getPath().contains(PRIMARY_FLAG_ENTRY)) {
instance = PRIMARY_FLAG_ENTRY;
}
}
if (instance == null) {
if (StringUtils.isBlank(instance)) {
throw new UnprocessableEntityException("The path " + op.getPath() + " is not supported by the operation "
+ op.getOp());
}

View File

@@ -20,18 +20,15 @@
<map>
<!-- WARNING do not change "key" it match with Java code (TODO dynamic discover from PATCH operation); -->
<entry key="itemmetadata">
<bean
class="org.dspace.app.rest.submit.factory.impl.ItemMetadataValueMovePatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.ItemMetadataValueMovePatchOperation"/>
</entry>
<entry key="bitstreammetadata">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamMetadataValueMovePatchOperation">
<bean class="org.dspace.app.rest.submit.factory.impl.BitstreamMetadataValueMovePatchOperation">
<property name="bitstreamMetadataValuePathUtils" ref="org.dspace.app.rest.utils.BitstreamMetadataValuePathUtils" />
</bean>
</entry>
<entry key="bitstreammove">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamMovePatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.BitstreamMovePatchOperation"/>
</entry>
</map>
</entry>
@@ -39,90 +36,80 @@
<map>
<!-- WARNING do not change "key" it match with Java code (TODO dynamic discover from PATCH operation); -->
<entry key="itemmetadata">
<bean
class="org.dspace.app.rest.submit.factory.impl.ItemMetadataValueAddPatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.ItemMetadataValueAddPatchOperation"/>
</entry>
<entry key="bitstreammetadata">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamMetadataValueAddPatchOperation">
<bean class="org.dspace.app.rest.submit.factory.impl.BitstreamMetadataValueAddPatchOperation">
<property name="bitstreamMetadataValuePathUtils" ref="org.dspace.app.rest.utils.BitstreamMetadataValuePathUtils" />
</bean>
</entry>
<entry key="granted">
<bean
class="org.dspace.app.rest.submit.factory.impl.LicenseAddPatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.LicenseAddPatchOperation"/>
</entry>
<entry key="upload.accessConditions">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamResourcePolicyAddPatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.BitstreamResourcePolicyAddPatchOperation"/>
</entry>
<entry key="cclicense/uri">
<bean
class="org.dspace.app.rest.submit.factory.impl.CCLicenseAddPatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.CCLicenseAddPatchOperation"/>
</entry>
<entry key="accessConditions">
<bean class="org.dspace.app.rest.submit.factory.impl.AccessConditionAddPatchOperation"/>
</entry>
<entry key="primary">
<bean class="org.dspace.app.rest.submit.factory.impl.PrimaryBitstreamAddPatchOperation"/>
</entry>
</map>
</entry>
<entry key="remove">
<map>
<!-- WARNING do not change "key" it match with Java code (TODO dynamic discover from PATCH operation); -->
<entry key="itemmetadata">
<bean
class="org.dspace.app.rest.submit.factory.impl.ItemMetadataValueRemovePatchOperation" />
<bean class="org.dspace.app.rest.submit.factory.impl.ItemMetadataValueRemovePatchOperation" />
</entry>
<entry key="bitstreammetadata">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamMetadataValueRemovePatchOperation">
<bean class="org.dspace.app.rest.submit.factory.impl.BitstreamMetadataValueRemovePatchOperation">
<property name="bitstreamMetadataValuePathUtils" ref="org.dspace.app.rest.utils.BitstreamMetadataValuePathUtils" />
</bean>
</entry>
<entry key="granted">
<bean
class="org.dspace.app.rest.submit.factory.impl.LicenseRemovePatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.LicenseRemovePatchOperation"/>
</entry>
<entry key="bitstreamremove">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamRemovePatchOperation" />
<bean class="org.dspace.app.rest.submit.factory.impl.BitstreamRemovePatchOperation" />
</entry>
<entry key="upload.accessConditions">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamResourcePolicyRemovePatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.BitstreamResourcePolicyRemovePatchOperation"/>
</entry>
<entry key="cclicense/uri">
<bean
class="org.dspace.app.rest.submit.factory.impl.CCLicenseRemovePatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.CCLicenseRemovePatchOperation"/>
</entry>
<entry key="accessConditions">
<bean class="org.dspace.app.rest.submit.factory.impl.AccessConditionRemovePatchOperation"/>
</entry>
<entry key="primary">
<bean class="org.dspace.app.rest.submit.factory.impl.PrimaryBitstreamRemovePatchOperation"/>
</entry>
</map>
</entry>
<entry key="replace">
<map>
<!-- WARNING do not change "key" it match with Java code (TODO dynamic discover from PATCH operation); -->
<entry key="itemmetadata">
<bean
class="org.dspace.app.rest.submit.factory.impl.ItemMetadataValueReplacePatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.ItemMetadataValueReplacePatchOperation"/>
</entry>
<entry key="bitstreammetadata">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamMetadataValueReplacePatchOperation">
<bean class="org.dspace.app.rest.submit.factory.impl.BitstreamMetadataValueReplacePatchOperation">
<property name="bitstreamMetadataValuePathUtils" ref="org.dspace.app.rest.utils.BitstreamMetadataValuePathUtils" />
</bean>
</entry>
<entry key="granted">
<bean
class="org.dspace.app.rest.submit.factory.impl.LicenseReplacePatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.LicenseReplacePatchOperation"/>
</entry>
<entry key="upload.accessConditions">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamResourcePolicyReplacePatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.BitstreamResourcePolicyReplacePatchOperation"/>
</entry>
<entry key="collection">
<bean
class="org.dspace.app.rest.submit.factory.impl.CollectionReplacePatchOperation"/>
<bean class="org.dspace.app.rest.submit.factory.impl.CollectionReplacePatchOperation"/>
</entry>
<entry key="discoverable">
<bean class="org.dspace.app.rest.submit.factory.impl.AccessConditionDiscoverableReplacePatchOperation"/>
@@ -130,6 +117,9 @@
<entry key="accessConditions">
<bean class="org.dspace.app.rest.submit.factory.impl.AccessConditionReplacePatchOperation"/>
</entry>
<entry key="primary">
<bean class="org.dspace.app.rest.submit.factory.impl.PrimaryBitstreamReplacePatchOperation"/>
</entry>
</map>
</entry>
</map>

View File

@@ -8601,6 +8601,536 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
.content("/api/submission/workspaceitems/" + workspaceItem.getID())
.contentType(textUriContentType))
.andExpect(status().isCreated());
}
@Test
public void patchAddPrimaryTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("TITLE test")
.withIssueDate("2023-10-18")
.withFulltext("simple-article.pdf",
"/local/path/simple-article.pdf", pdf)
.withSubject("testEntry")
.build();
context.restoreAuthSystemState();
AtomicReference<String> idRef = new AtomicReference<String>();
String tokenAdmin = getAuthToken(admin.getEmail(), password);
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()))
.andDo(result -> idRef.set(read(result.getResponse().getContentAsString(),
"$.sections.upload.files[0].uuid")));
List<Operation> addPrimaryOps = new ArrayList<Operation>();
addPrimaryOps.add(new AddOperation("/sections/upload/primary", idRef.get()));
String patchBody = getPatchContent(addPrimaryOps);
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(patchBody)
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", is(idRef.get())));
}
@Test
public void patchAddPrimaryBitstreamWithOwnerTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
context.setCurrentUser(eperson);
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("TITLE test")
.withIssueDate("2023-10-18")
.withFulltext("simple-article.pdf",
"/local/path/simple-article.pdf", pdf)
.withSubject("testEntry")
.build();
context.restoreAuthSystemState();
AtomicReference<String> idRef = new AtomicReference<String>();
String tokenSubmitter = getAuthToken(eperson.getEmail(), password);
getClient(tokenSubmitter).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()))
.andDo(result -> idRef.set(read(result.getResponse().getContentAsString(),
"$.sections.upload.files[0].uuid")));
List<Operation> addPrimaryOps = new ArrayList<Operation>();
addPrimaryOps.add(new AddOperation("/sections/upload/primary", idRef.get()));
String patchBody = getPatchContent(addPrimaryOps);
getClient(tokenSubmitter).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(patchBody)
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk());
getClient(tokenSubmitter).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", is(idRef.get())));
}
@Test
public void patchAddPrimaryBitstreamWithNotOwnerTest() throws Exception {
context.turnOffAuthorisationSystem();
EPerson submitter = EPersonBuilder.createEPerson(context)
.withEmail("test-email@mail.com")
.withPassword(password)
.build();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
context.setCurrentUser(submitter);
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("TITLE test")
.withIssueDate("2023-10-18")
.withFulltext("simple-article.pdf",
"/local/path/simple-article.pdf", pdf)
.withSubject("testEntry")
.build();
context.restoreAuthSystemState();
AtomicReference<String> idRef = new AtomicReference<String>();
String tokenSubmitter = getAuthToken(submitter.getEmail(), password);
getClient(tokenSubmitter).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()))
.andDo(result -> idRef.set(read(result.getResponse().getContentAsString(),
"$.sections.upload.files[0].uuid")));
List<Operation> addPrimaryOps = new ArrayList<Operation>();
addPrimaryOps.add(new AddOperation("/sections/upload/primary", idRef.get()));
String tokenNotSubmitter = getAuthToken(eperson.getEmail(), password);
// non submitter cannot add primary bitstream
getClient(tokenNotSubmitter).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(getPatchContent(addPrimaryOps))
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isForbidden());
// even anonymous users cannot add primary bitstream
getClient().perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(getPatchContent(addPrimaryOps))
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isUnauthorized());
getClient(tokenSubmitter).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()));
}
@Test
public void patchAddPrimaryBitstreamUpdateAlredySettedOneTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
InputStream pdf2 = getClass().getResourceAsStream("bibtex-test.bib");
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("TITLE test")
.withIssueDate("2023-10-18")
.withFulltext("simple-article.pdf",
"/local/path/simple-article.pdf", pdf)
.withFulltext("bibtex-test.bib",
"/local/path/bibtex-test.bib", pdf2)
.withSubject("testEntry")
.build();
context.restoreAuthSystemState();
AtomicReference<String> idFirstPdf = new AtomicReference<String>();
AtomicReference<String> idSecondPdf = new AtomicReference<String>();
String tokenAdmin = getAuthToken(admin.getEmail(), password);
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()))
.andDo(result -> idFirstPdf.set(read(result.getResponse().getContentAsString(),
"$.sections.upload.files[0].uuid")))
.andDo(result -> idSecondPdf.set(read(result.getResponse().getContentAsString(),
"$.sections.upload.files[1].uuid")));
List<Operation> addPrimaryOps = new ArrayList<Operation>();
addPrimaryOps.add(new AddOperation("/sections/upload/primary", idFirstPdf.get()));
String patchBody = getPatchContent(addPrimaryOps);
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(patchBody)
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", is(idFirstPdf.get())));
List<Operation> addPrimaryOps2 = new ArrayList<Operation>();
addPrimaryOps2.add(new AddOperation("/sections/upload/primary", idSecondPdf.get()));
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(getPatchContent(addPrimaryOps2))
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", is(idSecondPdf.get())));
}
@Test
public void patchAddPrimaryUUIDofNotExistingBitstreamTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("TITLE test")
.withIssueDate("2023-10-18")
.withFulltext("simple-article.pdf",
"/local/path/simple-article.pdf", pdf)
.withSubject("testEntry")
.build();
context.restoreAuthSystemState();
String tokenAdmin = getAuthToken(admin.getEmail(), password);
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()));
List<Operation> addOperations = new ArrayList<Operation>();
addOperations.add(new AddOperation("/sections/upload/primary", UUID.randomUUID()));
String patchBody = getPatchContent(addOperations);
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(patchBody)
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isUnprocessableEntity());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()));
}
@Test
public void patchAddPrimaryWrongUUIDTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("TITLE test")
.withIssueDate("2023-10-18")
.withFulltext("simple-article.pdf",
"/local/path/simple-article.pdf", pdf)
.withSubject("testEntry")
.build();
context.restoreAuthSystemState();
String tokenAdmin = getAuthToken(admin.getEmail(), password);
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()));
List<Operation> addOperations = new ArrayList<Operation>();
addOperations.add(new AddOperation("/sections/upload/primary", "wrong-uuid"));
String patchBody = getPatchContent(addOperations);
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(patchBody)
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isUnprocessableEntity());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()));
}
@Test
public void patchRemovePrimaryTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("TITLE test")
.withIssueDate("2023-10-18")
.withFulltext("simple-article.pdf",
"/local/path/simple-article.pdf", pdf)
.withSubject("testEntry")
.build();
context.restoreAuthSystemState();
AtomicReference<String> idRef = new AtomicReference<String>();
String tokenAdmin = getAuthToken(admin.getEmail(), password);
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()))
.andDo(result -> idRef.set(read(result.getResponse().getContentAsString(),
"$.sections.upload.files[0].uuid")));
List<Operation> addOperations = new ArrayList<Operation>();
addOperations.add(new AddOperation("/sections/upload/primary", idRef.get()));
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(getPatchContent(addOperations))
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", is(idRef.get())));
List<Operation> removeOps = new ArrayList<Operation>();
removeOps.add(new RemoveOperation("/sections/upload/primary"));
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(getPatchContent(removeOps))
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()));
}
@Test
public void patchReplacePrimaryTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
InputStream pdf2 = getClass().getResourceAsStream("bibtex-test.bib");
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("TITLE test")
.withIssueDate("2023-10-18")
.withFulltext("simple-article.pdf",
"/local/path/simple-article.pdf", pdf)
.withFulltext("bibtex-test.bib",
"/local/path/bibtex-test.bib", pdf2)
.withSubject("testEntry")
.build();
context.restoreAuthSystemState();
AtomicReference<String> idFirstPdf = new AtomicReference<String>();
AtomicReference<String> idSecondPdf = new AtomicReference<String>();
String tokenAdmin = getAuthToken(admin.getEmail(), password);
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()))
.andDo(result -> idFirstPdf.set(read(result.getResponse().getContentAsString(),
"$.sections.upload.files[0].uuid")))
.andDo(result -> idSecondPdf.set(read(result.getResponse().getContentAsString(),
"$.sections.upload.files[1].uuid")));
List<Operation> addOperations = new ArrayList<Operation>();
addOperations.add(new AddOperation("/sections/upload/primary", idFirstPdf.get()));
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(getPatchContent(addOperations))
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", is(idFirstPdf.get())));
List<Operation> replaceOperations = new ArrayList<Operation>();
replaceOperations.add(new ReplaceOperation("/sections/upload/primary", idSecondPdf.get()));
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(getPatchContent(replaceOperations))
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", is(idSecondPdf.get())));
}
@Test
public void patchReplacePrimaryWhenPrimariIsUnsetTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
InputStream pdf2 = getClass().getResourceAsStream("bibtex-test.bib");
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("TITLE test")
.withIssueDate("2023-10-18")
.withFulltext("simple-article.pdf",
"/local/path/simple-article.pdf", pdf)
.withSubject("testEntry")
.build();
context.restoreAuthSystemState();
AtomicReference<String> idPdf = new AtomicReference<String>();
String tokenAdmin = getAuthToken(admin.getEmail(), password);
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()))
.andDo(result -> idPdf.set(read(result.getResponse().getContentAsString(),
"$.sections.upload.files[0].uuid")));
List<Operation> replaceOperations = new ArrayList<Operation>();
replaceOperations.add(new ReplaceOperation("/sections/upload/primary", idPdf.get()));
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(getPatchContent(replaceOperations))
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isUnprocessableEntity());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()));
}
@Test
public void patchReplaceProvidingWrongPrimaryTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("TITLE test")
.withIssueDate("2023-10-18")
.withFulltext("simple-article.pdf",
"/local/path/simple-article.pdf", pdf)
.build();
context.restoreAuthSystemState();
AtomicReference<String> idFirstPdf = new AtomicReference<String>();
String tokenAdmin = getAuthToken(admin.getEmail(), password);
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", nullValue()))
.andDo(result -> idFirstPdf.set(read(result.getResponse().getContentAsString(),
"$.sections.upload.files[0].uuid")));
List<Operation> addOperations = new ArrayList<Operation>();
addOperations.add(new AddOperation("/sections/upload/primary", idFirstPdf.get()));
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(getPatchContent(addOperations))
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", is(idFirstPdf.get())));
List<Operation> replaceOperations = new ArrayList<Operation>();
replaceOperations.add(new ReplaceOperation("/sections/upload/primary", UUID.randomUUID()));
getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(getPatchContent(replaceOperations))
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isUnprocessableEntity());
getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.upload.primary", is(idFirstPdf.get())));
}
}