Skip to content

Commit

Permalink
Added: updateFeaturedItems working endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
GPortas committed Jan 10, 2025
1 parent b8853b7 commit 3df4723
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 65 deletions.
59 changes: 35 additions & 24 deletions src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java
Original file line number Diff line number Diff line change
Expand Up @@ -1788,50 +1788,61 @@ public Response updateFeaturedItems(
@FormDataParam("content") List<String> contents,
@FormDataParam("displayOrder") List<Integer> displayOrders,
@FormDataParam("keepFile") List<Boolean> keepFiles,
@FormDataParam("fileName") List<String> fileNames,
@FormDataParam("file") List<FormDataBodyPart> files) {
try {
if (ids == null || contents == null || displayOrders == null || keepFiles == null || files == null) {
throw new WrappedResponse(error(Response.Status.BAD_REQUEST, BundleUtil.getStringFromBundle("dataverse.update.featuredItems.error.missingInputParams")));
if (ids == null || contents == null || displayOrders == null || keepFiles == null || fileNames == null) {
throw new WrappedResponse(error(Response.Status.BAD_REQUEST,
BundleUtil.getStringFromBundle("dataverse.update.featuredItems.error.missingInputParams")));
}

int size = ids.size();
if (contents.size() != size || displayOrders.size() != size || keepFiles.size() != size || files.size() != size) {
throw new WrappedResponse(error(Response.Status.BAD_REQUEST, BundleUtil.getStringFromBundle("dataverse.update.featuredItems.error.inputListsSizeMismatch")));
if (contents.size() != size || displayOrders.size() != size || keepFiles.size() != size || fileNames.size() != size) {
throw new WrappedResponse(error(Response.Status.BAD_REQUEST,
BundleUtil.getStringFromBundle("dataverse.update.featuredItems.error.inputListsSizeMismatch")));
}

Dataverse dataverse = findDataverseOrDie(dvIdtf);
List<NewDataverseFeaturedItemDTO> newDataverseFeaturedItemDTOs = new ArrayList<>();
Map<DataverseFeaturedItem, UpdatedDataverseFeaturedItemDTO> dataverseFeaturedItemsToUpdate = new HashMap<>();
List<NewDataverseFeaturedItemDTO> newItems = new ArrayList<>();
Map<DataverseFeaturedItem, UpdatedDataverseFeaturedItemDTO> itemsToUpdate = new HashMap<>();

for (int i = 0; i < contents.size(); i++) {
Long id = ids.get(i);
String content = contents.get(i);
Integer displayOrder = displayOrders.get(i);
boolean keepFile = keepFiles.get(i);
FormDataBodyPart fileBodyPart = files.get(i);

InputStream fileInputStream = fileBodyPart.getValueAs(InputStream.class);
FormDataContentDisposition contentDispositionHeader = fileBodyPart.getFormDataContentDisposition();

if (id == 0) {
NewDataverseFeaturedItemDTO newDTO = NewDataverseFeaturedItemDTO.fromFormData(content, displayOrder, fileInputStream, contentDispositionHeader);
newDataverseFeaturedItemDTOs.add(newDTO);
String fileName = fileNames.get(i);
InputStream fileInputStream = null;
FormDataContentDisposition contentDisposition = null;

if (files != null) {
Optional<FormDataBodyPart> matchingFile = files.stream()
.filter(file -> file.getFormDataContentDisposition().getFileName().equals(fileName))
.findFirst();

if (matchingFile.isPresent()) {
fileInputStream = matchingFile.get().getValueAs(InputStream.class);
contentDisposition = matchingFile.get().getFormDataContentDisposition();
}
}

if (ids.get(i) == 0) {
newItems.add(NewDataverseFeaturedItemDTO.fromFormData(
contents.get(i), displayOrders.get(i), fileInputStream, contentDisposition));
} else {
DataverseFeaturedItem existingItem = dataverseFeaturedItemServiceBean.findById(id);
DataverseFeaturedItem existingItem = dataverseFeaturedItemServiceBean.findById(ids.get(i));
if (existingItem == null) {
throw new WrappedResponse(error(Response.Status.NOT_FOUND, MessageFormat.format(BundleUtil.getStringFromBundle("dataverseFeaturedItems.errors.notFound"), id)));
throw new WrappedResponse(error(Response.Status.NOT_FOUND,
MessageFormat.format(BundleUtil.getStringFromBundle("dataverseFeaturedItems.errors.notFound"), ids.get(i))));
}
UpdatedDataverseFeaturedItemDTO updatedDTO = UpdatedDataverseFeaturedItemDTO.fromFormData(content, displayOrder, keepFile, fileInputStream, contentDispositionHeader);
dataverseFeaturedItemsToUpdate.put(existingItem, updatedDTO);
itemsToUpdate.put(existingItem, UpdatedDataverseFeaturedItemDTO.fromFormData(
contents.get(i), displayOrders.get(i), keepFiles.get(i), fileInputStream, contentDisposition));
}
}

List<DataverseFeaturedItem> featuredItems = execCommand(new UpdateDataverseFeaturedItemsCommand(
createDataverseRequest(getRequestUser(crc)),
dataverse,
newDataverseFeaturedItemDTOs,
dataverseFeaturedItemsToUpdate
newItems,
itemsToUpdate
));

return ok(jsonDataverseFeaturedItems(featuredItems));
} catch (WrappedResponse wr) {
return wr.getResponse();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import edu.harvard.iq.dataverse.engine.command.*;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

Expand All @@ -34,34 +36,43 @@ public UpdateDataverseFeaturedItemsCommand(DataverseRequest request, Dataverse d

@Override
public List<DataverseFeaturedItem> execute(CommandContext ctxt) throws CommandException {
updateOrDeleteExistingFeaturedItems(ctxt);
createNewFeaturedItems(ctxt);

return ctxt.engine().submit(new ListDataverseFeaturedItemsCommand(getRequest(), dataverse));
List<DataverseFeaturedItem> dataverseFeaturedItems = updateOrDeleteExistingFeaturedItems(ctxt);
dataverseFeaturedItems.addAll(createNewFeaturedItems(ctxt));
dataverseFeaturedItems.sort(Comparator.comparingLong(DataverseFeaturedItem::getId));
return dataverseFeaturedItems;
}

private void updateOrDeleteExistingFeaturedItems(CommandContext ctxt) throws CommandException {
private List<DataverseFeaturedItem> updateOrDeleteExistingFeaturedItems(CommandContext ctxt) throws CommandException {
List<DataverseFeaturedItem> updatedFeaturedItems = new ArrayList<>();
List<DataverseFeaturedItem> featuredItemsToDelete = dataverse.getDataverseFeaturedItems();

for (Map.Entry<DataverseFeaturedItem, UpdatedDataverseFeaturedItemDTO> entry : dataverseFeaturedItemsToUpdate.entrySet()) {
DataverseFeaturedItem featuredItem = entry.getKey();
UpdatedDataverseFeaturedItemDTO updatedDTO = entry.getValue();

if (featuredItemsToDelete.contains(featuredItem)) {
featuredItemsToDelete.remove(featuredItem);
}
featuredItemsToDelete.stream()
.filter(item -> item.getId().equals(featuredItem.getId()))
.findFirst().ifPresent(featuredItemsToDelete::remove);

ctxt.engine().submit(new UpdateDataverseFeaturedItemCommand(getRequest(), featuredItem, updatedDTO));
DataverseFeaturedItem updatedFeatureItem = ctxt.engine().submit(new UpdateDataverseFeaturedItemCommand(getRequest(), featuredItem, updatedDTO));
updatedFeaturedItems.add(updatedFeatureItem);
}

for (DataverseFeaturedItem featuredItem : featuredItemsToDelete) {
ctxt.engine().submit(new DeleteDataverseFeaturedItemCommand(getRequest(), featuredItem));
}

return updatedFeaturedItems;
}

private void createNewFeaturedItems(CommandContext ctxt) throws CommandException {
private List<DataverseFeaturedItem> createNewFeaturedItems(CommandContext ctxt) throws CommandException {
List<DataverseFeaturedItem> createdFeaturedItems = new ArrayList<>();

for (NewDataverseFeaturedItemDTO dto : newDataverseFeaturedItemDTOs) {
ctxt.engine().submit(new CreateDataverseFeaturedItemCommand(getRequest(), dataverse, dto));
DataverseFeaturedItem createdFeatureItem = ctxt.engine().submit(new CreateDataverseFeaturedItemCommand(getRequest(), dataverse, dto));
createdFeaturedItems.add(createdFeatureItem);
}

return createdFeaturedItems;
}
}
4 changes: 2 additions & 2 deletions src/main/java/propertyFiles/Bundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -982,8 +982,8 @@ dataverse.create.error.jsonparsetodataverse=Error parsing the POSTed json into a
dataverse.create.featuredItem.error.imageFileProcessing=Error processing featured item file: {0}
dataverse.create.featuredItem.error.fileSizeExceedsLimit=File exceeds the maximum size of {0}
dataverse.create.featuredItem.error.invalidFileType=Invalid image file type
dataverse.update.featuredItems.error.missingInputParams=All input parameters (id, content, displayOrder, keepFile, file) are required.
dataverse.update.featuredItems.error.inputListsSizeMismatch=All input lists (id, content, displayOrder, keepFile, file) must have the same size.
dataverse.update.featuredItems.error.missingInputParams=All input parameters (id, content, displayOrder, keepFile, fileNames) are required.
dataverse.update.featuredItems.error.inputListsSizeMismatch=All input lists (id, content, displayOrder, keepFile, fileNames) must have the same size.
# rolesAndPermissionsFragment.xhtml

# advanced.xhtml
Expand Down
114 changes: 107 additions & 7 deletions src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -1622,25 +1622,125 @@ public void testCreateFeaturedItem() {
.statusCode(NOT_FOUND.getStatusCode());
}

// TODO: Complete
@Test
public void testUpdateFeaturedItems() {
Response createUserResponse = UtilIT.createRandomUser();
String apiToken = UtilIT.getApiTokenFromResponse(createUserResponse);
Response createDataverseResponse = UtilIT.createRandomDataverse(apiToken);
createDataverseResponse.then().assertThat().statusCode(CREATED.getStatusCode());
String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse);
String baseUri = UtilIT.getRestAssuredBaseUri();

// Create new items
List<Long> ids = Arrays.asList(0L, 0L);
List<String> contents = Arrays.asList("Content 1", "Content 2");
List<Integer> orders = Arrays.asList(1, 2);
List<Boolean> keepFiles = Arrays.asList(false, false);
List<String> pathsToFiles = Arrays.asList("src/test/resources/images/coffeeshop.png", "src/test/resources/images/coffeeshop.png");

List<Long> ids = Arrays.asList(0L, 0L, 0L);
List<String> contents = Arrays.asList("Content 1", "Content 2", "Content 3");
List<Integer> orders = Arrays.asList(0, 1, 2);
List<Boolean> keepFiles = Arrays.asList(false, false, false);
List<String> pathsToFiles = Arrays.asList("src/test/resources/images/coffeeshop.png", null, null);

Response updateDataverseFeaturedItemsResponse = UtilIT.updateDataverseFeaturedItems(dataverseAlias, ids, contents, orders, keepFiles, pathsToFiles, apiToken);
updateDataverseFeaturedItemsResponse.prettyPrint();
updateDataverseFeaturedItemsResponse.then().assertThat()
.body("data.size()", equalTo(3))
.body("data[0].content", equalTo("Content 1"))
.body("data[0].imageFileName", equalTo("coffeeshop.png"))
.body("data[0].imageFileUrl", containsString(baseUri + "/api/access/dataverseFeatureItemImage/"))
.body("data[0].displayOrder", equalTo(0))
.body("data[1].content", equalTo("Content 2"))
.body("data[1].imageFileName", equalTo(null))
.body("data[1].imageFileUrl", equalTo(null))
.body("data[1].displayOrder", equalTo(1))
.body("data[2].content", equalTo("Content 3"))
.body("data[2].imageFileName", equalTo(null))
.body("data[2].imageFileUrl", equalTo(null))
.body("data[2].displayOrder", equalTo(2))
.statusCode(OK.getStatusCode());

Long firstItemId = JsonPath.from(updateDataverseFeaturedItemsResponse.body().asString()).getLong("data[0].id");
Long secondItemId = JsonPath.from(updateDataverseFeaturedItemsResponse.body().asString()).getLong("data[1].id");
Long thirdItemId = JsonPath.from(updateDataverseFeaturedItemsResponse.body().asString()).getLong("data[2].id");

// Update first item (content, order, and keeping image), delete the rest and create new items

ids = Arrays.asList(firstItemId, 0L, 0L);
contents = Arrays.asList("Content 1 updated", "Content 2", "Content 3");
orders = Arrays.asList(1, 0, 2);
keepFiles = Arrays.asList(true, false, false);
pathsToFiles = Arrays.asList(null, null, null);

updateDataverseFeaturedItemsResponse = UtilIT.updateDataverseFeaturedItems(dataverseAlias, ids, contents, orders, keepFiles, pathsToFiles, apiToken);
updateDataverseFeaturedItemsResponse.then().assertThat()
.body("data.size()", equalTo(3))
.body("data[0].content", equalTo("Content 1 updated"))
.body("data[0].imageFileName", equalTo("coffeeshop.png"))
.body("data[0].imageFileUrl", containsString(baseUri + "/api/access/dataverseFeatureItemImage/"))
.body("data[0].displayOrder", equalTo(1))
.body("data[1].content", equalTo("Content 2"))
.body("data[1].imageFileName", equalTo(null))
.body("data[1].imageFileUrl", equalTo(null))
.body("data[1].displayOrder", equalTo(0))
.body("data[2].content", equalTo("Content 3"))
.body("data[2].imageFileName", equalTo(null))
.body("data[2].imageFileUrl", equalTo(null))
.body("data[2].displayOrder", equalTo(2))
.statusCode(OK.getStatusCode());

Long firstItemIdAfterUpdate = JsonPath.from(updateDataverseFeaturedItemsResponse.body().asString()).getLong("data[0].id");
Long secondItemIdAfterUpdate = JsonPath.from(updateDataverseFeaturedItemsResponse.body().asString()).getLong("data[1].id");
Long thirdItemIdAfterUpdate = JsonPath.from(updateDataverseFeaturedItemsResponse.body().asString()).getLong("data[2].id");

assertEquals(firstItemId, firstItemIdAfterUpdate);
assertNotEquals(secondItemId, secondItemIdAfterUpdate);
assertNotEquals(thirdItemId, thirdItemIdAfterUpdate);

// Update first item (removing image), update second item (adding image), delete the third item and create a new item

ids = Arrays.asList(firstItemId, secondItemIdAfterUpdate, 0L);
contents = Arrays.asList("Content 1 updated", "Content 2", "Content 3");
orders = Arrays.asList(1, 0, 2);
keepFiles = Arrays.asList(false, false, false);
pathsToFiles = Arrays.asList(null, "src/test/resources/images/coffeeshop.png", null);

updateDataverseFeaturedItemsResponse = UtilIT.updateDataverseFeaturedItems(dataverseAlias, ids, contents, orders, keepFiles, pathsToFiles, apiToken);
updateDataverseFeaturedItemsResponse.then().assertThat()
.body("data.size()", equalTo(3))
.body("data[0].content", equalTo("Content 1 updated"))
.body("data[0].imageFileName", equalTo(null))
.body("data[0].imageFileUrl", equalTo(null))
.body("data[0].displayOrder", equalTo(1))
.body("data[1].content", equalTo("Content 2"))
.body("data[1].imageFileName", equalTo("coffeeshop.png"))
.body("data[1].imageFileUrl", containsString(baseUri + "/api/access/dataverseFeatureItemImage/"))
.body("data[1].displayOrder", equalTo(0))
.body("data[2].content", equalTo("Content 3"))
.body("data[2].imageFileName", equalTo(null))
.body("data[2].imageFileUrl", equalTo(null))
.body("data[2].displayOrder", equalTo(2))
.statusCode(OK.getStatusCode());

Long firstItemIdAftersSecondUpdate = JsonPath.from(updateDataverseFeaturedItemsResponse.body().asString()).getLong("data[0].id");
Long secondItemIdAfterSecondUpdate = JsonPath.from(updateDataverseFeaturedItemsResponse.body().asString()).getLong("data[1].id");
Long thirdItemIdAfterSecondUpdate = JsonPath.from(updateDataverseFeaturedItemsResponse.body().asString()).getLong("data[2].id");

assertEquals(firstItemId, firstItemIdAftersSecondUpdate);
assertEquals(secondItemIdAfterUpdate, secondItemIdAfterSecondUpdate);
assertNotEquals(thirdItemIdAfterUpdate, thirdItemIdAfterSecondUpdate);

// Only keep first featured item

ids = List.of(firstItemId);
contents = List.of("Content 1 updated");
orders = List.of(0);
keepFiles = List.of(false);
pathsToFiles = null;

updateDataverseFeaturedItemsResponse = UtilIT.updateDataverseFeaturedItems(dataverseAlias, ids, contents, orders, keepFiles, pathsToFiles, apiToken);
updateDataverseFeaturedItemsResponse.then().assertThat()
.body("data.size()", equalTo(1))
.body("data[0].content", equalTo("Content 1 updated"))
.body("data[0].imageFileName", equalTo(null))
.body("data[0].imageFileUrl", equalTo(null))
.body("data[0].displayOrder", equalTo(0))
.statusCode(OK.getStatusCode());
}
}
Loading

0 comments on commit 3df4723

Please sign in to comment.