Skip to content

Commit

Permalink
Stash: endpoint for create/update/delete all dv featured items at onc…
Browse files Browse the repository at this point in the history
…e WIP
  • Loading branch information
GPortas committed Jan 7, 2025
1 parent 034cea4 commit 812ff0f
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 6 deletions.
68 changes: 68 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.StreamingOutput;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;

Expand Down Expand Up @@ -112,6 +113,9 @@ public class Dataverses extends AbstractApiBean {

@EJB
PermissionServiceBean permissionService;

@EJB
DataverseFeaturedItemServiceBean dataverseFeaturedItemServiceBean;

@POST
@AuthRequired
Expand Down Expand Up @@ -1772,4 +1776,68 @@ public Response listFeaturedItems(@Context ContainerRequestContext crc, @PathPar
return e.getResponse();
}
}

// TODO: Refine
@PUT
@AuthRequired
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("{dataverseId}/featuredItems")
public Response updateFeaturedItems(
@Context ContainerRequestContext crc,
@PathParam("dataverseId") String dvIdtf,
@FormDataParam("id") List<Long> ids,
@FormDataParam("content") List<String> contents,
@FormDataParam("displayOrder") List<Integer> displayOrders,
@FormDataParam("keepFile") List<Boolean> keepFiles,
@FormDataParam("file") List<FormDataBodyPart> files) {

try {
if (contents.size() != displayOrders.size() || displayOrders.size() != files.size()) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("Mismatch between contents, displayOrders, and files.")
.build();
}

Dataverse dataverse = findDataverseOrDie(dvIdtf);
List<NewDataverseFeaturedItemDTO> newDataverseFeaturedItemDTOs = new ArrayList<>();
Map<DataverseFeaturedItem, UpdatedDataverseFeaturedItemDTO> dataverseFeaturedItemsToUpdate = 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);
} else {
DataverseFeaturedItem existingItem = dataverseFeaturedItemServiceBean.findById(id);
if (existingItem == null) {
return Response.status(Response.Status.NOT_FOUND)
// TODO
.entity("Featured item not found with ID: " + id)
.build();
}
UpdatedDataverseFeaturedItemDTO updatedDTO = UpdatedDataverseFeaturedItemDTO.fromFormData(content, displayOrder, keepFile, fileInputStream, contentDispositionHeader);
dataverseFeaturedItemsToUpdate.put(existingItem, updatedDTO);
}
}

execCommand(new UpdateDataverseFeaturedItemsCommand(
createDataverseRequest(getRequestUser(crc)),
dataverse,
newDataverseFeaturedItemDTOs,
dataverseFeaturedItemsToUpdate
));

return Response.ok().entity("Featured items updated successfully").build();
} catch (WrappedResponse wr) {
return wr.getResponse();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package edu.harvard.iq.dataverse.engine.command.impl;

import edu.harvard.iq.dataverse.Dataverse;
import edu.harvard.iq.dataverse.DataverseFeaturedItem;
import edu.harvard.iq.dataverse.api.dto.NewDataverseFeaturedItemDTO;
import edu.harvard.iq.dataverse.api.dto.UpdatedDataverseFeaturedItemDTO;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.engine.command.AbstractVoidCommand;
import edu.harvard.iq.dataverse.engine.command.CommandContext;
import edu.harvard.iq.dataverse.engine.command.DataverseRequest;
import edu.harvard.iq.dataverse.engine.command.RequiredPermissions;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;

import java.util.List;
import java.util.Map;

@RequiredPermissions({Permission.EditDataverse})
public class UpdateDataverseFeaturedItemsCommand extends AbstractVoidCommand {

private final Dataverse dataverse;
private final List<NewDataverseFeaturedItemDTO> newDataverseFeaturedItemDTOs;
private final Map<DataverseFeaturedItem, UpdatedDataverseFeaturedItemDTO> dataverseFeaturedItemsToUpdate;

public UpdateDataverseFeaturedItemsCommand(DataverseRequest request,
Dataverse dataverse,
List<NewDataverseFeaturedItemDTO> newDataverseFeaturedItemDTOs,
Map<DataverseFeaturedItem, UpdatedDataverseFeaturedItemDTO> dataverseFeaturedItemsToUpdate) {
super(request, dataverse);
this.dataverse = dataverse;
this.newDataverseFeaturedItemDTOs = newDataverseFeaturedItemDTOs;
this.dataverseFeaturedItemsToUpdate = dataverseFeaturedItemsToUpdate;
}

@Override
protected void executeImpl(CommandContext ctxt) throws CommandException {
updateOrDeleteExistingFeaturedItems(ctxt);
createNewFeaturedItems(ctxt);
}

private void updateOrDeleteExistingFeaturedItems(CommandContext ctxt) throws CommandException {
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);
}

ctxt.engine().submit(new UpdateDataverseFeaturedItemCommand(getRequest(), featuredItem, updatedDTO));
}

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

private void createNewFeaturedItems(CommandContext ctxt) throws CommandException {
for (NewDataverseFeaturedItemDTO dto : newDataverseFeaturedItemDTOs) {
ctxt.engine().submit(new CreateDataverseFeaturedItemCommand(getRequest(), dataverse, dto));
}
}
}
23 changes: 23 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -1621,4 +1621,27 @@ public void testCreateFeaturedItem() {
.body("message", equalTo("Can't find dataverse with identifier='thisDataverseDoesNotExist'"))
.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);

List<String> contents = Arrays.asList("Content 1", "Content 2");
List<Integer> orders = Arrays.asList(1, 2);
List<String> pathsToFiles = Arrays.asList("src/test/resources/images/coffeeshop.png", "src/test/resources/images/coffeeshop.png");

Response updateDataverseFeaturedItemsResponse = UtilIT.updateDataverseFeaturedItems(dataverseAlias, contents, orders, pathsToFiles, apiToken);
updateDataverseFeaturedItemsResponse.prettyPrint();
updateDataverseFeaturedItemsResponse.then().assertThat()
.statusCode(OK.getStatusCode());

Response listFeaturedItemsResponse = UtilIT.listDataverseFeaturedItems(dataverseAlias, apiToken);
listFeaturedItemsResponse.prettyPrint();

}
}
50 changes: 44 additions & 6 deletions src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package edu.harvard.iq.dataverse.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import edu.harvard.iq.dataverse.api.dto.NewDataverseFeaturedItemDTO;
import edu.harvard.iq.dataverse.util.json.NullSafeJsonBuilder;
import io.restassured.http.ContentType;
import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;

import java.io.*;
import java.util.UUID;
import java.util.*;
import java.util.logging.Logger;
import jakarta.json.Json;
import jakarta.json.JsonObjectBuilder;
Expand All @@ -29,15 +31,13 @@
import org.junit.jupiter.api.Test;
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
import io.restassured.specification.RequestSpecification;
import java.util.List;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.mashape.unirest.request.GetRequest;
import edu.harvard.iq.dataverse.util.FileUtil;
import java.util.Base64;
import org.apache.commons.io.IOUtils;
import java.nio.file.Path;
import java.util.ArrayList;

import org.apache.commons.lang3.math.NumberUtils;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
Expand All @@ -52,8 +52,7 @@
import edu.harvard.iq.dataverse.settings.FeatureFlags;
import edu.harvard.iq.dataverse.util.StringUtil;

import java.util.Collections;

import static org.apache.http.entity.ContentType.APPLICATION_JSON;
import static org.junit.jupiter.api.Assertions.*;

public class UtilIT {
Expand Down Expand Up @@ -4414,4 +4413,43 @@ static Response listDataverseFeaturedItems(String dataverseAlias, String apiToke
.contentType("application/json")
.get("/api/dataverses/" + dataverseAlias + "/featuredItems");
}


// TODO: Refine
static Response updateDataverseFeaturedItems(
String dataverseAlias,
List<String> contents,
List<Integer> orders,
List<String> pathsToFiles,
String apiToken) {

RequestSpecification requestSpecification = given()
.header(API_TOKEN_HTTP_HEADER, apiToken)
.contentType(ContentType.MULTIPART);

int size = contents.size();
if (orders.size() != size || pathsToFiles.size() != size) {
throw new IllegalArgumentException("Contents, orders, and pathsToFiles must have the same size.");
}

for (int i = 0; i < size; i++) {
String content = contents.get(i);
Integer order = orders.get(i);

requestSpecification.multiPart("content", content);
requestSpecification.multiPart("displayOrder", order);
requestSpecification.multiPart("keepFile", false);
requestSpecification.multiPart("id", 0);

String pathToFile = pathsToFiles.get(i);
if (pathToFile != null && !pathToFile.isEmpty()) {
requestSpecification.multiPart("file", new File(pathToFile));
}
}

return requestSpecification
.when()
.put("/api/dataverses/" + dataverseAlias + "/featuredItems");
}

}

0 comments on commit 812ff0f

Please sign in to comment.