From db6dec979fe886ff28a06e8a3edc1629ebee2570 Mon Sep 17 00:00:00 2001 From: Jamal Kaabi-Mofrad Date: Thu, 2 Jun 2016 21:41:59 +0000 Subject: [PATCH] Merged API-STRIKES-BACK (5.2.0) to HEAD (5.2) 126329 jvonka: Node Associations - initial api tests (+ve & -ve) for secondary child assocs - RA-745, RA-920, RA-921, RA-930 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@127577 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../api/tests/NodeAssociationsApiTest.java | 305 +++++++++++++++++- .../api/tests/client/data/Association.java | 59 ++++ .../rest/api/tests/client/data/Node.java | 9 +- 3 files changed, 361 insertions(+), 12 deletions(-) create mode 100644 source/test-java/org/alfresco/rest/api/tests/client/data/Association.java diff --git a/source/test-java/org/alfresco/rest/api/tests/NodeAssociationsApiTest.java b/source/test-java/org/alfresco/rest/api/tests/NodeAssociationsApiTest.java index 6c6144fa1c..0efc1e8ad5 100644 --- a/source/test-java/org/alfresco/rest/api/tests/NodeAssociationsApiTest.java +++ b/source/test-java/org/alfresco/rest/api/tests/NodeAssociationsApiTest.java @@ -22,11 +22,13 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.Queries; +import org.alfresco.rest.api.model.AssocChild; import org.alfresco.rest.api.model.AssocTarget; import org.alfresco.rest.api.tests.client.HttpResponse; import org.alfresco.rest.api.tests.client.PublicApiClient; import org.alfresco.rest.api.tests.client.PublicApiClient.Paging; import org.alfresco.rest.api.tests.client.RequestContext; +import org.alfresco.rest.api.tests.client.data.Association; import org.alfresco.rest.api.tests.client.data.ContentInfo; import org.alfresco.rest.api.tests.client.data.Document; import org.alfresco.rest.api.tests.client.data.Folder; @@ -61,7 +63,7 @@ import static org.junit.Assert.*; *
  • {@literal :/alfresco/api//public/alfresco/versions/1/nodes/{targetId}/sources
  • * * - * TODO - Child Associations (parent -> child) - primary vs secondary + * Child Associations (parent -> child) - secondary (*) * * * - * Note: please also refer to NodeApiTests for specific tests for "managing" primary parent/child association. - + * (*) for primary child assocs, please refer to NodeApiTest - eg. create/delete node (primary child), list children, move, copy etc + * * @author janv */ public class NodeAssociationsApiTest extends AbstractBaseApiTest { + private static final String PARAM_ASSOC_TYPE = "assocType"; + + // peer assocs + private static final String URL_TARGETS = "targets"; private static final String URL_SOURCES = "sources"; @@ -84,7 +90,19 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest private static final String ASPECT_CM_PARTABLE = "cm:partable"; private static final String ASSOC_TYPE_CM_PARTS = "cm:parts"; - private static final String PARAM_ASSOC_TYPE = "assocType"; + // child assocs + + private static final String URL_SECONDARY_CHILDREN = "secondary-children"; + private static final String URL_PARENTS = "parents"; + + private static final String ASSOC_TYPE_CM_CONTAINS = "cm:contains"; + + private static final String ASPECT_CM_PREFERENCES = "cm:preferences"; + private static final String ASSOC_TYPE_CM_PREFERENCE_IMAGE = "cm:preferenceImage"; + + private static final String PARAM_CHILD_NAME = "childQName"; + + private String user1; private String user2; @@ -145,14 +163,31 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest return URL_NODES + "/" + nodeId + "/" + URL_SOURCES; } + protected String getNodeSecondaryChildrenUrl(String nodeId) + { + return URL_NODES + "/" + nodeId + "/" + URL_SECONDARY_CHILDREN; + } + + protected String getNodeParentsUrl(String nodeId) + { + return URL_NODES + "/" + nodeId + "/" + URL_PARENTS; + } + /** - * Tests basic api to manage (add, list, remove) peer node associations + * Tests basic api to manage (add, list, remove) node peer associations (ie. source node -> target node) + * + *

    POST:

    + * {@literal :/alfresco/api//public/alfresco/versions/1/nodes//targets} + * + *

    DELETE:

    + * {@literal :/alfresco/api//public/alfresco/versions/1/nodes//targets/} * *

    GET:

    - * {@literal :/alfresco/api//public/alfresco/versions/1/queries/live-search-nodes} + * {@literal :/alfresco/api//public/alfresco/versions/1/nodes//targets} + * {@literal :/alfresco/api//public/alfresco/versions/1/nodes//sources} */ @Test - public void testPeerNodeAssocs() throws Exception + public void testNodePeerAssocs() throws Exception { String myFolderNodeId = getMyNodeId(user1); @@ -366,6 +401,262 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest tgt = new AssocTarget(o1Id, ASSOC_TYPE_CM_REFERENCES); post(getNodeTargetsUrl(o2Id), user1, toJsonAsStringNonNull(tgt), 201); post(getNodeTargetsUrl(o2Id), user1, toJsonAsStringNonNull(tgt), 409); + + // TODO some more negative tests + // 400s - eg. invalid qname + // 404s - eg. unknown src, tgt, assoc of given type + } + finally + { + // some cleanup + Map params = Collections.singletonMap("permanent", "true"); + delete(URL_NODES, user1, f1Id, params, 204); + delete(URL_NODES, user1, f2Id, params, 204); + } + } + + /** + * Tests basic api to manage (add, list, remove) node secondary child associations (ie. parent node -> child node) + * + * Note: refer to NodeApiTest for tests for primary child association + * + *

    POST:

    + * {@literal :/alfresco/api//public/alfresco/versions/1/nodes//secondary-children} + * + *

    DELETE:

    + * {@literal :/alfresco/api//public/alfresco/versions/1/nodes//secondary-children/} + * + *

    GET:

    + * {@literal :/alfresco/api//public/alfresco/versions/1/nodes//secondary-children} + * {@literal :/alfresco/api//public/alfresco/versions/1/nodes//parents} + */ + @Test + public void testNodeSecondaryChildAssocs() throws Exception + { + String myFolderNodeId = getMyNodeId(user1); + + // create folder + Node n = new Node(); + n.setName("f1"); + n.setNodeType(TYPE_CM_FOLDER); + n.setAspectNames(Arrays.asList(ASPECT_CM_PREFERENCES)); + HttpResponse response = post(getNodeChildrenUrl(myFolderNodeId), user1, toJsonAsStringNonNull(n), 201); + String f1Id = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class).getId(); + + // create content node + String o1Name = "o1"; + n = new Node(); + n.setName(o1Name); + n.setNodeType(TYPE_CM_CONTENT); + response = post(getNodeChildrenUrl(f1Id), user1, toJsonAsStringNonNull(n), 201); + String o1Id = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class).getId(); + + // create ano' folder + String f2Id = createFolder(user1, myFolderNodeId, "f2").getId(); + + // create ano' content node + String o2Name = "o2"; + n = new Node(); + n.setName(o2Name); + n.setNodeType(TYPE_CM_CONTENT); + response = post(getNodeChildrenUrl(f2Id), user1, toJsonAsStringNonNull(n), 201); + String o2Id = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class).getId(); + + + try + { + // As user 1 ... + + Paging paging = getPaging(0, 100); + + // -ve test - unauthenticated - belts-and-braces ;-) + getAll(getNodeSecondaryChildrenUrl(f1Id), null, paging, null, 401); + getAll(getNodeParentsUrl(o2Id), null, paging, null, 401); + + // lists - before + + response = getAll(getNodeSecondaryChildrenUrl(f1Id), user1, paging, null, 200); + List nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(0, nodes.size()); + + // primary parent only + response = getAll(getNodeParentsUrl(o2Id), user1, paging, null, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(1, nodes.size()); + assertEquals(f2Id, nodes.get(0).getId()); + assertEquals(ASSOC_TYPE_CM_CONTAINS, nodes.get(0).getAssociation().getAssocType()); + assertEquals("cm:"+o2Name, nodes.get(0).getAssociation().getChildQName()); + assertTrue(nodes.get(0).getAssociation().getIsPrimaryParent()); + + String o2SecChildName = "cm:o2SecChildName"; + + // -ve test - unauthenticated - belts-and-braces ;-) + AssocChild secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS, o2SecChildName); + post(getNodeSecondaryChildrenUrl(f1Id), null, toJsonAsStringNonNull(secChild), 401); + + + // create secondary child assoc + secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS, o2SecChildName); + post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 201); + + // create ano' secondary child assoc (different type) between the same two nodes + secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_PREFERENCE_IMAGE, o2SecChildName); + post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 201); + + + response = getAll(getNodeSecondaryChildrenUrl(f1Id), user1, paging, null, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(2, nodes.size()); + int i = 0; + for (Node node : nodes) + { + Association nodeAssoc = node.getAssociation(); + if (nodeAssoc.getAssocType().equals(ASSOC_TYPE_CM_CONTAINS)) + { + i++; + } + else if ( nodeAssoc.getAssocType().equals(ASSOC_TYPE_CM_PREFERENCE_IMAGE)) + { + i++; + } + assertEquals(o2Id, node.getId()); + assertEquals(o2SecChildName, nodeAssoc.getChildQName()); + assertFalse(nodeAssoc.getIsPrimaryParent()); + } + assertEquals(2, i); + + response = getAll(getNodeParentsUrl(o2Id), user1, paging, null, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(3, nodes.size()); + i = 0; + for (Node node : nodes) + { + String nodeId = node.getId(); + Association nodeAssoc = node.getAssociation(); + if (nodeId.equals(f2Id)) + { + assertEquals(ASSOC_TYPE_CM_CONTAINS, nodeAssoc.getAssocType()); + assertEquals("cm:"+o2Name, nodeAssoc.getChildQName()); + assertTrue(nodeAssoc.getIsPrimaryParent()); + i++; + } + else if (nodeId.equals(f1Id)) + { + if (nodeAssoc.getAssocType().equals(ASSOC_TYPE_CM_CONTAINS)) + { + i++; + } + else if ( nodeAssoc.getAssocType().equals(ASSOC_TYPE_CM_PREFERENCE_IMAGE)) + { + i++; + } + assertEquals(o2SecChildName, nodeAssoc.getChildQName()); + assertFalse(nodeAssoc.getIsPrimaryParent()); + } + } + assertEquals(3, i); + + // test basic list filter + Map params = new HashMap<>(); + params.put("where", "(assocType='"+ASSOC_TYPE_CM_CONTAINS+"')"); + + response = getAll(getNodeSecondaryChildrenUrl(f1Id), user1, paging, params, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(1, nodes.size()); + assertEquals(o2Id, nodes.get(0).getId()); + assertEquals(ASSOC_TYPE_CM_CONTAINS, nodes.get(0).getAssociation().getAssocType()); + + response = getAll(getNodeParentsUrl(o2Id), user1, paging, params, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(2, nodes.size()); + i = 0; + for (Node node : nodes) + { + String nodeId = node.getId(); + Association nodeAssoc = node.getAssociation(); + if (nodeId.equals(f2Id)) + { + assertEquals(ASSOC_TYPE_CM_CONTAINS, nodeAssoc.getAssocType()); + assertEquals("cm:"+o2Name, nodeAssoc.getChildQName()); + assertTrue(nodeAssoc.getIsPrimaryParent()); + i++; + } + else if (nodeId.equals(f1Id)) + { + assertEquals(ASSOC_TYPE_CM_CONTAINS, nodeAssoc.getAssocType()); + assertEquals(o2SecChildName, nodeAssoc.getChildQName()); + assertFalse(nodeAssoc.getIsPrimaryParent()); + i++; + } + } + assertEquals(2, i); + + params = new HashMap<>(); + params.put("where", "(assocType='"+ASSOC_TYPE_CM_PREFERENCE_IMAGE+"')"); + + response = getAll(getNodeSecondaryChildrenUrl(f1Id), user1, paging, params, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(1, nodes.size()); + assertEquals(o2Id, nodes.get(0).getId()); + assertEquals(ASSOC_TYPE_CM_PREFERENCE_IMAGE, nodes.get(0).getAssociation().getAssocType()); + assertFalse(nodes.get(0).getAssociation().getIsPrimaryParent()); + + response = getAll(getNodeParentsUrl(o2Id), user1, paging, params, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(1, nodes.size()); + assertEquals(f1Id, nodes.get(0).getId()); + assertEquals(ASSOC_TYPE_CM_PREFERENCE_IMAGE, nodes.get(0).getAssociation().getAssocType()); + assertFalse(nodes.get(0).getAssociation().getIsPrimaryParent()); + + + params = new HashMap<>(2); + params.put(PARAM_ASSOC_TYPE, ASSOC_TYPE_CM_CONTAINS); + params.put(PARAM_CHILD_NAME, o2SecChildName); + + // -ve test - unauthenticated - belts-and-braces ;-) + delete(getNodeSecondaryChildrenUrl(f1Id), null, o2Id, params, 401); + + // remove one secondary child assoc + delete(getNodeSecondaryChildrenUrl(f1Id), user1, o2Id, params, 204); + + response = getAll(getNodeSecondaryChildrenUrl(f1Id), user1, paging, null, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(1, nodes.size()); + + response = getAll(getNodeParentsUrl(o2Id), user1, paging, null, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(2, nodes.size()); + + params = new HashMap<>(2); + params.put(PARAM_ASSOC_TYPE, ASSOC_TYPE_CM_PREFERENCE_IMAGE); + params.put(PARAM_CHILD_NAME, o2SecChildName); + + // remove other secondary child assoc + delete(getNodeSecondaryChildrenUrl(f1Id), user1, o2Id, params, 204); + + response = getAll(getNodeSecondaryChildrenUrl(f1Id), user1, paging, null, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(0, nodes.size()); + + response = getAll(getNodeParentsUrl(o2Id), user1, paging, null, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + assertEquals(1, nodes.size()); + + // TODO test delete of multiple secondary child assocs (if assoc type is not specified) + + + // -ve test - model integrity + secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS, o2SecChildName); + post(getNodeSecondaryChildrenUrl(o1Id), user1, toJsonAsStringNonNull(secChild), 422); + + // -ve test - duplicate assoc + secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS, o2SecChildName); + post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 201); + post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 409); + + // TODO some more negative tests + // 400s - eg. invalid qname + // 404s - eg. unknown src, tgt, assoc of given type } finally { diff --git a/source/test-java/org/alfresco/rest/api/tests/client/data/Association.java b/source/test-java/org/alfresco/rest/api/tests/client/data/Association.java new file mode 100644 index 0000000000..8dc917fe10 --- /dev/null +++ b/source/test-java/org/alfresco/rest/api/tests/client/data/Association.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2005-2016 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.rest.api.tests.client.data; + +public class Association +{ + // assoc type (child or peer) + private String assocType; + + public String getAssocType() + { + return assocType; + } + + public void setAssocType(String assocType) + { + this.assocType = assocType; + } + + // child assoc + private String prefixAssocChildQName; + private Boolean isPrimaryParent; + + public String getChildQName() + { + return prefixAssocChildQName; + } + + public void setChildQName(String prefixAssocChildQName) + { + this.prefixAssocChildQName = prefixAssocChildQName; + } + + public Boolean getIsPrimaryParent() + { + return isPrimaryParent; + } + + public void setIsPrimaryParent(Boolean isPrimaryParent) + { + this.isPrimaryParent = isPrimaryParent; + } +} diff --git a/source/test-java/org/alfresco/rest/api/tests/client/data/Node.java b/source/test-java/org/alfresco/rest/api/tests/client/data/Node.java index 9d89f47b31..e3da272718 100644 --- a/source/test-java/org/alfresco/rest/api/tests/client/data/Node.java +++ b/source/test-java/org/alfresco/rest/api/tests/client/data/Node.java @@ -18,8 +18,6 @@ */ package org.alfresco.rest.api.tests.client.data; -import org.alfresco.rest.api.model.Assoc; - import java.util.Date; import java.util.List; import java.util.Map; @@ -251,14 +249,15 @@ public class Node this.relativePath = relativePath; } - protected Assoc association; + // note: can be child or peer (latter has assocType only) + protected Association association; - public Assoc getAssociation() + public Association getAssociation() { return association; } - public void setAssociation(Assoc association) + public void setAssociation(Association association) { this.association = association; }