/* * 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; 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.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.Paging; import org.alfresco.rest.api.tests.client.data.Association; import org.alfresco.rest.api.tests.client.data.Node; import org.alfresco.rest.api.tests.util.RestApiUtil; import org.alfresco.service.cmr.security.MutableAuthenticationService; import org.alfresco.service.cmr.security.PersonService; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull; import static org.junit.Assert.*; /** * API tests for Node Associations * * Peer Associations (source -> target) * * * Child Associations (parent -> child) - secondary (*) * * * * (*) 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"; private static final String ASPECT_CM_REFERENCING = "cm:referencing"; private static final String ASSOC_TYPE_CM_REFERENCES = "cm:references"; private static final String ASPECT_CM_PARTABLE = "cm:partable"; private static final String ASSOC_TYPE_CM_PARTS = "cm:parts"; // 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 String user1; private String user2; private List users = new ArrayList<>(); protected MutableAuthenticationService authenticationService; protected PersonService personService; private final String RUNID = System.currentTimeMillis()+""; @Before public void setup() throws Exception { authenticationService = applicationContext.getBean("authenticationService", MutableAuthenticationService.class); personService = applicationContext.getBean("personService", PersonService.class); // note: createUser currently relies on repoService user1 = createUser("user1-" + RUNID); user2 = createUser("user2-" + RUNID); // We just need to clean the on-premise-users, // so the tests for the specific network would work. users.add(user1); users.add(user2); } @After public void tearDown() throws Exception { AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser(); for (final String user : users) { transactionHelper.doInTransaction(new RetryingTransactionCallback() { @Override public Void execute() throws Throwable { if (personService.personExists(user)) { authenticationService.deleteAuthentication(user); personService.deletePerson(user); } return null; } }); } users.clear(); AuthenticationUtil.clearCurrentSecurityContext(); } protected String getNodeTargetsUrl(String nodeId) { return URL_NODES + "/" + nodeId + "/" + URL_TARGETS; } protected String getNodeSourcesUrl(String nodeId) { 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) 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/nodes//targets} * {@literal :/alfresco/api//public/alfresco/versions/1/nodes//sources} */ @Test public void testNodePeerAssocs() throws Exception { String myFolderNodeId = getMyNodeId(user1); // create folder String f1Id = createFolder(user1, myFolderNodeId, "f1").getId(); // create content node Node n = new Node(); n.setName("o1"); n.setNodeType(TYPE_CM_CONTENT); n.setAspectNames(Arrays.asList(ASPECT_CM_REFERENCING, ASPECT_CM_PARTABLE)); HttpResponse 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 n = new Node(); n.setName("o2"); n.setNodeType(TYPE_CM_CONTENT); n.setAspectNames(Arrays.asList(ASPECT_CM_REFERENCING, ASPECT_CM_PARTABLE)); 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); // empty lists - before response = getAll(getNodeTargetsUrl(o1Id), user1, paging, null, 200); List nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); response = getAll(getNodeSourcesUrl(o1Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); response = getAll(getNodeTargetsUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); response = getAll(getNodeSourcesUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); // create two assocs in one direction (from src to tgt) AssocTarget tgt = new AssocTarget(o2Id, ASSOC_TYPE_CM_REFERENCES); post(getNodeTargetsUrl(o1Id), user1, toJsonAsStringNonNull(tgt), 201); tgt = new AssocTarget(o2Id, ASSOC_TYPE_CM_PARTS); post(getNodeTargetsUrl(o1Id), user1, toJsonAsStringNonNull(tgt), 201); response = getAll(getNodeTargetsUrl(o1Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(2, nodes.size()); response = getAll(getNodeSourcesUrl(o1Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); response = getAll(getNodeTargetsUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); response = getAll(getNodeSourcesUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(2, nodes.size()); // create two assocs in the other direction (from tgt to src) tgt = new AssocTarget(o1Id, ASSOC_TYPE_CM_REFERENCES); post(getNodeTargetsUrl(o2Id), user1, toJsonAsStringNonNull(tgt), 201); tgt = new AssocTarget(o1Id, ASSOC_TYPE_CM_PARTS); post(getNodeTargetsUrl(o2Id), user1, toJsonAsStringNonNull(tgt), 201); response = getAll(getNodeTargetsUrl(o1Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(2, nodes.size()); response = getAll(getNodeSourcesUrl(o1Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(2, nodes.size()); response = getAll(getNodeTargetsUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(2, nodes.size()); response = getAll(getNodeSourcesUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(2, nodes.size()); // test basic list filter Map params = new HashMap<>(); params.put("where", "(assocType='"+ASSOC_TYPE_CM_REFERENCES+"')"); response = getAll(getNodeTargetsUrl(o1Id), 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_REFERENCES, nodes.get(0).getAssociation().getAssocType()); response = getAll(getNodeSourcesUrl(o1Id), 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_REFERENCES, nodes.get(0).getAssociation().getAssocType()); params = new HashMap<>(1); params.put("where", "(assocType='"+ASSOC_TYPE_CM_PARTS+"')"); response = getAll(getNodeTargetsUrl(o2Id), user1, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(1, nodes.size()); assertEquals(o1Id, nodes.get(0).getId()); assertEquals(ASSOC_TYPE_CM_PARTS, nodes.get(0).getAssociation().getAssocType()); response = getAll(getNodeSourcesUrl(o2Id), user1, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(1, nodes.size()); assertEquals(o1Id, nodes.get(0).getId()); assertEquals(ASSOC_TYPE_CM_PARTS, nodes.get(0).getAssociation().getAssocType()); // remove assocs - specific type - in one direction params = new HashMap<>(2); params.put(PARAM_ASSOC_TYPE, ASSOC_TYPE_CM_REFERENCES); delete(getNodeTargetsUrl(o1Id), user1, o2Id, params, 204); response = getAll(getNodeTargetsUrl(o1Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(1, nodes.size()); response = getAll(getNodeSourcesUrl(o1Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(2, nodes.size()); response = getAll(getNodeTargetsUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(2, nodes.size()); response = getAll(getNodeSourcesUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(1, nodes.size()); params = new HashMap<>(2); params.put(PARAM_ASSOC_TYPE, ASSOC_TYPE_CM_PARTS); delete(getNodeTargetsUrl(o1Id), user1, o2Id, params, 204); response = getAll(getNodeTargetsUrl(o1Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); response = getAll(getNodeSourcesUrl(o1Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(2, nodes.size()); response = getAll(getNodeTargetsUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(2, nodes.size()); response = getAll(getNodeSourcesUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); // remove assocs - both types at once (ie. no assocType param) - in the other direction delete(getNodeTargetsUrl(o2Id), user1, o1Id, 204); // empty lists - after response = getAll(getNodeTargetsUrl(o1Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); response = getAll(getNodeSourcesUrl(o1Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); response = getAll(getNodeTargetsUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); response = getAll(getNodeSourcesUrl(o2Id), user1, paging, null, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(0, nodes.size()); // // -ve tests - add assoc // { // -ve test - unauthenticated - belts-and-braces ;-) tgt = new AssocTarget(o2Id, ASSOC_TYPE_CM_REFERENCES); post(getNodeTargetsUrl(o1Id), null, toJsonAsStringNonNull(tgt), 401); // -ve test - model integrity tgt = new AssocTarget(f2Id, ASSOC_TYPE_CM_REFERENCES); post(getNodeTargetsUrl(o1Id), user1, toJsonAsStringNonNull(tgt), 422); // -ve test - duplicate assoc tgt = new AssocTarget(o1Id, ASSOC_TYPE_CM_REFERENCES); post(getNodeTargetsUrl(o2Id), user1, toJsonAsStringNonNull(tgt), 201); post(getNodeTargetsUrl(o2Id), user1, toJsonAsStringNonNull(tgt), 409); tgt = new AssocTarget(o1Id, "cm:unknowntype"); post(getNodeTargetsUrl(o2Id), user1, toJsonAsStringNonNull(tgt), 400); } // // -ve test - list assocs // { // -ve test - unauthenticated - belts-and-braces ;-) getAll(getNodeTargetsUrl(f1Id), null, paging, null, 401); getAll(getNodeSourcesUrl(f1Id), null, paging, null, 401); getAll(getNodeTargetsUrl(UUID.randomUUID().toString()), user1, paging, null, 404); getAll(getNodeSourcesUrl(UUID.randomUUID().toString()), user1, paging, null, 404); params = new HashMap<>(1); params.put("where", "(assocType='cm:unknownassoctype')"); getAll(getNodeTargetsUrl(o1Id), user1, paging, params, 400); getAll(getNodeSourcesUrl(o1Id), user1, paging, params, 400); // TODO paging - in-built sort order ? } // // -ve test - remove assoc(s) // { // -ve test - unauthenticated - belts-and-braces ;-) delete(getNodeTargetsUrl(o1Id), null, o2Id, 401); delete(getNodeTargetsUrl(UUID.randomUUID().toString()), user1, o2Id, null, 404); delete(getNodeTargetsUrl(o1Id), user1, UUID.randomUUID().toString(), null, 404); // -ve test -nothing to delete - for any assoc type delete(getNodeTargetsUrl(o1Id), user1, o2Id, null, 404); // -ve test - nothing to delete - for given assoc type params = new HashMap<>(2); params.put(PARAM_ASSOC_TYPE, ASSOC_TYPE_CM_REFERENCES); delete(getNodeTargetsUrl(o1Id), user1, o2Id, params, 404); // -ve test - unknown assoc type params = new HashMap<>(2); params.put(PARAM_ASSOC_TYPE, "cm:unknowntype"); delete(getNodeTargetsUrl(o1Id), user1, o2Id, params, 400); } } 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); // 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()); assertTrue(nodes.get(0).getAssociation().getIsPrimaryParent()); // create secondary child assoc AssocChild secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS); 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); 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()); 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()); 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++; } 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()); assertTrue(nodeAssoc.getIsPrimaryParent()); i++; } else if (nodeId.equals(f1Id)) { assertEquals(ASSOC_TYPE_CM_CONTAINS, nodeAssoc.getAssocType()); 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); // 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); // 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 +ve test delete of multiple secondary child assocs (if assoc type is not specified) // // -ve tests - add assoc // { // -ve test - unauthenticated - belts-and-braces ;-) secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS); post(getNodeSecondaryChildrenUrl(f1Id), null, toJsonAsStringNonNull(secChild), 401); // -ve test - model integrity secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS); post(getNodeSecondaryChildrenUrl(o1Id), user1, toJsonAsStringNonNull(secChild), 422); // -ve test - duplicate assoc secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS); post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 201); post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 409); delete(getNodeSecondaryChildrenUrl(f1Id), user1, o2Id, null, 204); // cleanup secChild = new AssocChild(o2Id, "cm:unknowntype"); post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 400); } // // -ve test - list assocs // { // -ve test - unauthenticated - belts-and-braces ;-) getAll(getNodeSecondaryChildrenUrl(f1Id), null, paging, null, 401); getAll(getNodeParentsUrl(o2Id), null, paging, null, 401); getAll(getNodeSecondaryChildrenUrl(UUID.randomUUID().toString()), user1, paging, null, 404); getAll(getNodeParentsUrl(UUID.randomUUID().toString()), user1, paging, null, 404); params = new HashMap<>(1); params.put("where", "(assocType='cm:unknownassoctype')"); getAll(getNodeSecondaryChildrenUrl(o1Id), user1, paging, params, 400); getAll(getNodeParentsUrl(o1Id), user1, paging, params, 400); // TODO paging - in-built sort order ? } // // -ve test - remove assoc(s) // { // unauthenticated - belts-and-braces ;-) delete(getNodeSecondaryChildrenUrl(f1Id), null, o2Id, null, 401); delete(getNodeSecondaryChildrenUrl(UUID.randomUUID().toString()), user1, o2Id, null, 404); delete(getNodeSecondaryChildrenUrl(f1Id), user1, UUID.randomUUID().toString(), null, 404); // nothing to delete - for any assoc type delete(getNodeSecondaryChildrenUrl(f1Id), user1, o2Id, null, 404); // nothing to delete - for given assoc type params = new HashMap<>(2); params.put(PARAM_ASSOC_TYPE, ASSOC_TYPE_CM_PREFERENCE_IMAGE); delete(getNodeSecondaryChildrenUrl(f1Id), user1, o2Id, params, 404); // unknown assoc type params = new HashMap<>(2); params.put(PARAM_ASSOC_TYPE, "cm:unknowntype"); delete(getNodeSecondaryChildrenUrl(o1Id), user1, o2Id, params, 400); // TODO 400 - try to delete primary assoc using /secondary-children } } finally { // some cleanup Map params = Collections.singletonMap(Nodes.PARAM_PERMANENT, "true"); delete(URL_NODES, user1, f1Id, params, 204); delete(URL_NODES, user1, f2Id, params, 204); } } @Override public String getScope() { return "public"; } }