diff --git a/src/main/java/org/alfresco/rest/api/model/ActionDefinition.java b/src/main/java/org/alfresco/rest/api/model/ActionDefinition.java index 2966e9af9a..7dc98c3864 100644 --- a/src/main/java/org/alfresco/rest/api/model/ActionDefinition.java +++ b/src/main/java/org/alfresco/rest/api/model/ActionDefinition.java @@ -29,13 +29,20 @@ import java.util.List; public class ActionDefinition { - private final String name; - private final String title; - private final String description; - private final List applicableTypes; - private final boolean adhocPropertiesAllowed; - private final boolean trackStatus; - private final List parameterDefinitions; + private String name; + private String title; + private String description; + private List applicableTypes; + private boolean adhocPropertiesAllowed; + private boolean trackStatus; + private List parameterDefinitions; + + /** + * For Jackson deserialisation. + */ + public ActionDefinition() + { + } public ActionDefinition(String name, String title, @@ -54,6 +61,14 @@ public class ActionDefinition this.parameterDefinitions = parameterDefinitions; } + /** + * Synonym for name. + */ + public String getId() + { + return getName(); + } + public String getName() { return name; @@ -91,13 +106,19 @@ public class ActionDefinition public static class ParameterDefinition { + private String name; + private String type; + private boolean multiValued; + private boolean mandatory; + private String displayLabel; + private String parameterConstraintName; - private final String name; - private final String type; - private final boolean multiValued; - private final boolean mandatory; - private final String displayLabel; - private final String parameterConstraintName; + /** + * For Jackson deserialisation. + */ + public ParameterDefinition() + { + } public ParameterDefinition(String name, String type, diff --git a/src/test/java/org/alfresco/rest/api/tests/TestActions.java b/src/test/java/org/alfresco/rest/api/tests/TestActions.java index 657f2f25f7..36268da546 100644 --- a/src/test/java/org/alfresco/rest/api/tests/TestActions.java +++ b/src/test/java/org/alfresco/rest/api/tests/TestActions.java @@ -26,14 +26,18 @@ package org.alfresco.rest.api.tests; import org.alfresco.model.ContentModel; +import org.alfresco.repo.action.executer.AddFeaturesActionExecuter; +import org.alfresco.repo.action.executer.CheckInActionExecuter; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.rest.api.model.ActionDefinition; import org.alfresco.rest.api.tests.client.Pair; import org.alfresco.rest.api.tests.client.PublicApiClient; import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse; import org.alfresco.rest.api.tests.client.RequestContext; +import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.action.ParameterizedItemDefinition; +import org.alfresco.service.cmr.coci.CheckOutCheckInService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; @@ -113,12 +117,87 @@ public class TestActions extends AbstractBaseApiTest // Get the actions available on the -my- node-ref alias { ListResponse actionDefs = actions.getActionDefinitionsForNode("-my-", emptyParams, 200); - + assertNotNull("Action definition list should not be null", actionDefs); assertFalse("Action definition list should not be empty", actionDefs.getList().isEmpty()); + + // Check defaults, given that no paging params were sent in the request + assertEquals(Paging.DEFAULT_MAX_ITEMS, actionDefs.getPaging().getMaxItems().intValue()); + assertEquals(Paging.DEFAULT_SKIP_COUNT, actionDefs.getPaging().getSkipCount().intValue()); + + // Check ActionDefinition fields + List actionDefinitions = actionDefs.getList().stream(). + filter(ad -> ad.getName().equals("add-features")).collect(Collectors.toList()); + assertEquals(1, actionDefinitions.size()); + + ActionDefinition action = actionDefinitions.get(0); + assertEquals("add-features", action.getId()); + assertEquals("add-features", action.getName()); + assertEquals("Add aspect", action.getTitle()); + assertEquals("This will add an aspect to the matched item.", action.getDescription()); + // Applicable types + assertEquals(0, action.getApplicableTypes().size()); + assertEquals(false, action.isTrackStatus()); + // Parameter definitions + assertEquals(1, action.getParameterDefinitions().size()); + ActionDefinition.ParameterDefinition paramDefs = action.getParameterDefinitions().get(0); + assertEquals(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, paramDefs.getName()); + assertEquals("d:qname", paramDefs.getType()); + assertEquals(true, paramDefs.isMandatory()); + assertEquals("Aspect", paramDefs.getDisplayLabel()); + assertEquals(false, paramDefs.isMultiValued()); + assertEquals("ac-aspects", paramDefs.getParameterConstraintName()); } AuthenticationUtil.setFullyAuthenticatedUser(person1); + + // Get the actions for a "checked out" node - there should be a "check-in" action present. + // Inspect the fields, to make sure that they're all there. Especially applicableTypes, as + // this isn't available on any of the actions that appear for the "-my-" alias in the test above. + { + NodeRef nodeForCheckout = nodeService.createNode( + new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, getMyNodeId()), + ContentModel.ASSOC_CONTAINS, + QName.createQName("test", "test-node-checkedout"), + ContentModel.TYPE_CONTENT).getChildRef(); + CheckOutCheckInService coci = applicationContext.getBean("CheckOutCheckInService", CheckOutCheckInService.class); + coci.checkout(nodeForCheckout); + + ListResponse actionDefs = + actions.getActionDefinitionsForNode(nodeForCheckout.getId(), emptyParams, 200); + + List actionDefinitions = actionDefs.getList().stream(). + filter(ad -> ad.getName().equals("check-in")).collect(Collectors.toList()); + assertEquals(1, actionDefinitions.size()); + + ActionDefinition action = actionDefinitions.get(0); + assertEquals("check-in", action.getId()); + assertEquals("check-in", action.getName()); + assertEquals("Check in", action.getTitle()); + assertEquals("This will check in the matched content.", action.getDescription()); + // Applicable types + assertEquals(1, action.getApplicableTypes().size()); + assertEquals("cm:content", action.getApplicableTypes().get(0)); + assertEquals(false, action.isTrackStatus()); + // Parameter definitions + assertEquals(2, action.getParameterDefinitions().size()); + // "description" + ActionDefinition.ParameterDefinition paramDefs = action.getParameterDefinitions().get(0); + assertEquals(CheckInActionExecuter.PARAM_DESCRIPTION, paramDefs.getName()); + assertEquals("d:text", paramDefs.getType()); + assertEquals(false, paramDefs.isMandatory()); + assertEquals("Description", paramDefs.getDisplayLabel()); + assertEquals(false, paramDefs.isMultiValued()); + assertEquals(null, paramDefs.getParameterConstraintName()); + // "minorChange" + paramDefs = action.getParameterDefinitions().get(1); + assertEquals(CheckInActionExecuter.PARAM_MINOR_CHANGE, paramDefs.getName()); + assertEquals("d:boolean", paramDefs.getType()); + assertEquals(false, paramDefs.isMandatory()); + assertEquals("Minor change", paramDefs.getDisplayLabel()); + assertEquals(false, paramDefs.isMultiValued()); + assertEquals(null, paramDefs.getParameterConstraintName()); + } String myNode = getMyNodeId(); NodeRef validNode = nodeService.createNode( @@ -320,7 +399,6 @@ public class TestActions extends AbstractBaseApiTest assertEquals(expectedActions, retrievedActions); } - // Non-existent node ID { NodeRef nodeRef = new NodeRef( diff --git a/src/test/java/org/alfresco/rest/api/tests/client/PublicApiClient.java b/src/test/java/org/alfresco/rest/api/tests/client/PublicApiClient.java index 20c0f2ccf0..053f625de9 100644 --- a/src/test/java/org/alfresco/rest/api/tests/client/PublicApiClient.java +++ b/src/test/java/org/alfresco/rest/api/tests/client/PublicApiClient.java @@ -42,6 +42,7 @@ import java.util.Map; import javax.servlet.http.HttpServletResponse; +import com.fasterxml.jackson.databind.ObjectMapper; import org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl; import org.alfresco.opencmis.CMISDispatcherRegistry.Binding; import org.alfresco.rest.api.model.ActionDefinition; @@ -130,6 +131,7 @@ public class PublicApiClient private ThreadLocal rc = new ThreadLocal(); + private ObjectMapper objectMapper = new ObjectMapper(); public PublicApiClient(PublicApiHttpClient client, UserDataService userDataService) { @@ -2685,17 +2687,17 @@ public class PublicApiClient private ActionDefinition parseActionDefinition(JSONObject entry) { - ActionDefinition def = new ActionDefinition( - (String) entry.get("name"), - (String) entry.get("title"), - (String) entry.get("description"), - null, - (Boolean) entry.get("adhocPropertiesAllowed"), - (Boolean) entry.get("trackStatus"), - null - ); + ActionDefinition def = null; + try + { + def = objectMapper.readValue(entry.toString(), ActionDefinition.class); + } + catch (IOException e) + { + throw new RuntimeException("Unable to parse ActionDefinition JSON", e); + } + return def; } - } }