From cdb58a0d36eae763a1e2f582c9c6920b4eff36cd Mon Sep 17 00:00:00 2001 From: Dave Ward Date: Sat, 20 Mar 2010 15:52:04 +0000 Subject: [PATCH] Unit tests for Alfresco aspect setting CMIS extensions - Pioneered hybrid Surf/Chemistry approach to unit testing REST calls in the build - Corrections to javascript library and Abdera extension - Checking in source for Spring Surf Webscript test classes, generated with "mvn source:test-jar" git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19433 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/cmis/lib/modify.lib.js | 2 +- .../repo/cmis/rest/SetAspectsExtension.java | 18 +- .../AspectTest.addAspects.cmisatomentry.xml | 30 +++ .../AspectTest.createObject.atomentry.xml | 17 ++ .../repo/cmis/rest/test/AspectTest.java | 228 ++++++++++++++++++ ...Test.removeAndAddAspects.cmisatomentry.xml | 26 ++ 6 files changed, 312 insertions(+), 9 deletions(-) create mode 100644 source/java/org/alfresco/repo/cmis/rest/test/AspectTest.addAspects.cmisatomentry.xml create mode 100644 source/java/org/alfresco/repo/cmis/rest/test/AspectTest.createObject.atomentry.xml create mode 100644 source/java/org/alfresco/repo/cmis/rest/test/AspectTest.java create mode 100644 source/java/org/alfresco/repo/cmis/rest/test/AspectTest.removeAndAddAspects.cmisatomentry.xml diff --git a/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/modify.lib.js b/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/modify.lib.js index a873bb8c39..1e5f886d36 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/modify.lib.js +++ b/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/modify.lib.js @@ -113,7 +113,7 @@ function updateNode(node, entry, exclude, validator) if (extension != null) { // Add and remove aspects - cmis.setAspects(node, extension.aspectsToAdd, extension.aspectsToRemove); + cmis.setAspects(node, extension.aspectsToRemove, extension.aspectsToAdd); // Apply the provided properties of the aspects unpackProperties(node, null, extension.properties, exclude, validator, vals); diff --git a/source/java/org/alfresco/repo/cmis/rest/SetAspectsExtension.java b/source/java/org/alfresco/repo/cmis/rest/SetAspectsExtension.java index 4a52cd1668..a183a02f0e 100644 --- a/source/java/org/alfresco/repo/cmis/rest/SetAspectsExtension.java +++ b/source/java/org/alfresco/repo/cmis/rest/SetAspectsExtension.java @@ -82,11 +82,12 @@ public class SetAspectsExtension extends ExtensibleElementWrapper public Set getAspectsToAdd() { Set aspects = new TreeSet(); - for (Element aspect = getFirstChild(ASPECTS_TO_ADD); aspect != null; aspect = aspect - .getNextSibling(ASPECTS_TO_ADD)) + for (Element aspect : this) { - aspects.add(aspect.getText()); - + if (aspect.getQName().equals(ASPECTS_TO_ADD)) + { + aspects.add(aspect.getText()); + } } return aspects; } @@ -99,11 +100,12 @@ public class SetAspectsExtension extends ExtensibleElementWrapper public Set getAspectsToRemove() { Set aspects = new TreeSet(); - for (Element aspect = getFirstChild(ASPECTS_TO_REMOVE); aspect != null; aspect = aspect - .getNextSibling(ASPECTS_TO_REMOVE)) + for (Element aspect : this) { - aspects.add(aspect.getText()); - + if (aspect.getQName().equals(ASPECTS_TO_REMOVE)) + { + aspects.add(aspect.getText()); + } } return aspects; } diff --git a/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.addAspects.cmisatomentry.xml b/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.addAspects.cmisatomentry.xml new file mode 100644 index 0000000000..1408a41930 --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.addAspects.cmisatomentry.xml @@ -0,0 +1,30 @@ + + + urn:uuid:00000000-0000-0000-0000-000000000000 + Aspect Test + 2010-01-01T00:00:00Z + admin + Aspect Test (summary) + Content + + + + cmis:document + + + P:cm:syndication + P:cm:summarizable + + + Aspect Test (summary) + + + + David Ward + + + + + + diff --git a/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.createObject.atomentry.xml b/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.createObject.atomentry.xml new file mode 100644 index 0000000000..04b49f51d6 --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.createObject.atomentry.xml @@ -0,0 +1,17 @@ + + + urn:uuid:00000000-0000-0000-0000-000000000000 + ${NAME} + 2010-01-01T00:00:00Z + admin + + ${NAME} (summary) + + + + ${TYPE} + + + + diff --git a/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.java b/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.java new file mode 100644 index 0000000000..7be9effc94 --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2005-2010 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.repo.cmis.rest.test; + +import java.io.Reader; +import java.io.StringReader; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.xml.namespace.QName; + +import org.alfresco.repo.cmis.rest.AlfrescoCMISExtensionFactory; +import org.alfresco.repo.web.scripts.BaseWebScriptTest; +import org.apache.abdera.Abdera; +import org.apache.abdera.factory.Factory; +import org.apache.abdera.i18n.iri.IRI; +import org.apache.abdera.model.Document; +import org.apache.abdera.model.Element; +import org.apache.abdera.model.Entry; +import org.apache.abdera.model.Link; +import org.apache.abdera.model.Service; +import org.apache.abdera.parser.Parser; +import org.apache.chemistry.abdera.ext.CMISConstants; +import org.apache.chemistry.abdera.ext.CMISObject; +import org.apache.chemistry.abdera.ext.CMISProperty; +import org.apache.chemistry.tck.atompub.client.CMISClient; +import org.apache.chemistry.tck.atompub.utils.ResourceLoader; +import org.junit.Assert; +import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest; +import org.springframework.extensions.webscripts.TestWebScriptServer.PostRequest; +import org.springframework.extensions.webscripts.TestWebScriptServer.PutRequest; +import org.springframework.extensions.webscripts.TestWebScriptServer.Request; +import org.springframework.extensions.webscripts.TestWebScriptServer.Response; + +/** + * Tests Alfresco CMIS REST API extensions for Aspects. + */ +public class AspectTest extends BaseWebScriptTest +{ + private static final QName ELEMENT_PROPERTIES = new QName("http://www.alfresco.org", "properties"); + private static final QName ELEMENT_APPLIED_ASPECTS = new QName("http://www.alfresco.org", "appliedAspects"); + + private static final String URL_CMIS = "/cmis"; + + private Abdera abdera; + private Parser parser; + private Factory factory; + + public AspectTest() { + // construct Abdera Service + abdera = new Abdera(); + factory = abdera.getFactory(); + factory.registerExtension(new AlfrescoCMISExtensionFactory()); + parser = factory.newParser(); + + // construct test templates + localTemplates = new ResourceLoader('/' + AspectTest.class.getPackage().getName().replace('.', '/') + '/'); + + // Create a dummy client. We won't / can't use it to make requests. + cmisClient = new CMISClient(null, null, null, null); + } + private CMISClient cmisClient; + private ResourceLoader localTemplates; + private Service cmisService; + private Entry testCaseFolder; + + @Override + public void setUp() throws Exception + { + super.setUp(); + + setDefaultRunAs("admin"); + + Request req = new GetRequest(URL_CMIS); + Response res = sendRequest(req, 200); + String xml = res.getContentAsString(); + Assert.assertNotNull(xml); + Assert.assertTrue(xml.length() > 0); + cmisService = parse(new StringReader(xml)); + Assert.assertNotNull(cmisService); + IRI rootFolderHREF = cmisClient.getRootCollection(cmisClient.getWorkspace(cmisService)); + Assert.assertNotNull(rootFolderHREF); + String folderName = getClass().getSimpleName() + System.currentTimeMillis() + " - " + getName(); + testCaseFolder = createObject(rootFolderHREF, folderName, "cmis:folder"); + } + + private T parse(Reader doc) { + Document entryDoc = parser.parse(doc); + return entryDoc.getRoot(); + } + + private Entry createObject(IRI parent, String name, String type) throws Exception { + String createFolder = localTemplates.load("AspectTest.createObject.atomentry.xml"); + createFolder = createFolder.replace("${NAME}", name); + createFolder = createFolder.replace("${TYPE}", type); + Request req = new PostRequest(parent.toString(), createFolder, CMISConstants.MIMETYPE_ENTRY); + Response res = sendRequest(req, 201); + Assert.assertNotNull(res); + String xml = res.getContentAsString(); + Entry entry = parse(new StringReader(xml)); + Assert.assertNotNull(entry); + return entry; + } + + public void testAspectSet() throws Exception + { + // create document for checkout + Link children = cmisClient.getChildrenLink(testCaseFolder); + Entry document = createObject(children.getHref(), getName(), "cmis:document"); + Request documentReq = new GetRequest(document.getSelfLink().getHref().toString()); + Response documentRes = sendRequest(documentReq, 200); + Assert.assertNotNull(documentRes); + String xml = documentRes.getContentAsString(); + Assert.assertNotNull(xml); + + // checkout + IRI checkedoutHREF = cmisClient.getCheckedOutCollection(cmisClient.getWorkspace(cmisService)); + Request checkoutReq = new PostRequest(checkedoutHREF.toString(), xml, CMISConstants.MIMETYPE_ENTRY); + Response pwcRes = sendRequest(checkoutReq, 201); + Assert.assertNotNull(pwcRes); + Entry pwc = parse(new StringReader(pwcRes.getContentAsString())); + Assert.assertNotNull(pwc); + + // Apply some aspects to the working copy + String updateFile = localTemplates.load("AspectTest.addAspects.cmisatomentry.xml"); + + Request updateReq = new PutRequest(pwc.getEditLink().getHref().toString(), updateFile, + CMISConstants.MIMETYPE_ENTRY); + Response pwcUpdatedres = sendRequest(updateReq, 200); + Assert.assertNotNull(pwcUpdatedres); + Entry updated = parse(new StringReader(pwcUpdatedres.getContentAsString())); + + { + Set appliedAspects = new HashSet(5); + Map aspectProperties = new HashMap(11); + extractAspectsAndProperties(updated, appliedAspects, aspectProperties); + assertContains(appliedAspects, "P:cm:syndication", "P:cm:summarizable", "P:cm:author"); + assertEquals("Aspect Test (summary)", aspectProperties.get("cm:summary")); + assertEquals("David Ward", aspectProperties.get("cm:author")); + } + + // check in with updated aspects + String checkinFile = localTemplates.load("AspectTest.removeAndAddAspects.cmisatomentry.xml"); + String checkinUrl = pwc.getSelfLink().getHref().toString(); + Request checkinReq = new PutRequest(checkinUrl, checkinFile, CMISConstants.MIMETYPE_ENTRY).setArgs(Collections + .singletonMap("checkin", "true")); + Response checkinRes = sendRequest(checkinReq, 200); + Assert.assertNotNull(checkinRes); + Entry checkedIn = parse(new StringReader(checkinRes.getContentAsString())); + { + Set appliedAspects = new HashSet(5); + Map aspectProperties = new HashMap(11); + extractAspectsAndProperties(checkedIn, appliedAspects, aspectProperties); + assertContains(appliedAspects, "P:cm:syndication", "P:cm:summarizable", "P:cm:countable"); + assertDoesNotContain(appliedAspects, "P:cm:author"); + assertEquals("Aspect Test (new summary)", aspectProperties.get("cm:summary")); + assertNull(aspectProperties.get("cm:author")); + } + } + + /** + * @param document + * @param appliedAspects + * @param aspectProperties + */ + private void extractAspectsAndProperties(Entry document, Set appliedAspects, + Map aspectProperties) + { + CMISObject documentObject = document.getExtension(CMISConstants.OBJECT); + Assert.assertNotNull(documentObject); + Element aspectEl = documentObject.getProperties().getExtension(new QName("http://www.alfresco.org", "aspects")); + Assert.assertNotNull(aspectEl); + for (Element child : aspectEl) + { + if (child.getQName().equals(ELEMENT_APPLIED_ASPECTS)) + { + appliedAspects.add(child.getText()); + } + else if (child.getQName().equals(ELEMENT_PROPERTIES)) + { + for (Element propertyEl : child) + { + if (propertyEl instanceof CMISProperty) + { + CMISProperty prop = (CMISProperty) propertyEl; + aspectProperties.put(prop.getId(), prop.getStringValue()); + } + } + } + else + { + fail("Unexpected element: " + child.getQName()); + } + } + } + + private void assertContains(Set actual, String... expected) + { + Assert.assertTrue(actual.containsAll(Arrays.asList(expected))); + } + + private void assertDoesNotContain(Set actual, String... unexpected) + { + Set copy = new HashSet(actual); + copy.retainAll(Arrays.asList(unexpected)); + Assert.assertTrue(copy.isEmpty()); + } +} diff --git a/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.removeAndAddAspects.cmisatomentry.xml b/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.removeAndAddAspects.cmisatomentry.xml new file mode 100644 index 0000000000..10026e5ed3 --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/rest/test/AspectTest.removeAndAddAspects.cmisatomentry.xml @@ -0,0 +1,26 @@ + + + urn:uuid:00000000-0000-0000-0000-000000000000 + Aspect Test + 2010-01-01T00:00:00Z + admin + Aspect Test (summary) + Content + + + + cmis:document + + + P:cm:countable + P:cm:author + + + Aspect Test (new summary) + + + + + +