Author: bdelacretaz
Date: Fri Jun 22 12:44:41 2012
New Revision: 1352865
URL: http://svn.apache.org/viewvc?rev=1352865&view=rev
Log:
SLING-2517 - validity checks for CopyFrom paths, with tests
Added:
sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java
Modified:
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletAtCopyTest.java
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java
Modified:
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java?rev=1352865&r1=1352864&r2=1352865&view=diff
==============================================================================
---
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
(original)
+++
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
Fri Jun 22 12:44:41 2012
@@ -97,6 +97,11 @@ public class CopyOperation extends Abstr
static Item copy(Node src, Node dstParent, String name)
throws RepositoryException {
+ if(isAncestorOrSameNode(src, dstParent)) {
+ throw new RepositoryException(
+ "Cannot copy ancestor " + src.getPath() + " to descendant
" + dstParent.getPath());
+ }
+
// ensure destination name
if (name == null) {
name = src.getName();
@@ -127,6 +132,19 @@ public class CopyOperation extends Abstr
}
return dst;
}
+
+ /** @return true if src is an ancestor node of dest, or if
+ * both are the same node */
+ static boolean isAncestorOrSameNode(Node src, Node dest) throws
RepositoryException {
+ if(src.getPath().equals("/")) {
+ return true;
+ } else if(src.getPath().equals(dest.getPath())) {
+ return true;
+ } else if(dest.getPath().startsWith(src.getPath() + "/")) {
+ return true;
+ }
+ return false;
+ }
/**
* Copy the <code>src</code> property into the <code>dstParent</code>
Added:
sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java?rev=1352865&view=auto
==============================================================================
---
sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java
(added)
+++
sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java
Fri Jun 22 12:44:41 2012
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.servlets.post.impl.operations;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import junit.framework.TestCase;
+
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(JMock.class)
+public class CopyOperationTest extends TestCase {
+ private Mockery context = new JUnit4Mockery();
+ private int counter;
+
+ private void assertResult(final String srcPath, final String destPath,
Boolean expectedResult) throws RepositoryException {
+ counter++;
+ final Node src = context.mock(Node.class, "src" + counter);
+ final Node dest = context.mock(Node.class, "dest" + counter);
+
+ context.checking(new Expectations() {
+ {
+ allowing(src).getPath();
+ will(returnValue(srcPath));
+ allowing(dest).getPath();
+ will(returnValue(destPath));
+ }
+ });
+
+ final boolean result = CopyOperation.isAncestorOrSameNode(src, dest);
+ assertEquals(
+ "Expecting isAncestorOrSameNode to be " + expectedResult + "
for " + srcPath + " and " + destPath,
+ expectedResult.booleanValue(), result);
+ }
+
+ @Test
+ public void testIsAncestorOrSameNode() throws RepositoryException {
+ final Object [] testCases = {
+ "/", "/", true,
+ "/a", "/a", true,
+ "/a/bee/ceee", "/a/bee/ceee", true,
+ "/", "/tmp", true,
+ "/a", "/a/b", true,
+ "/a", "/a/b/c/dee/eeee", true,
+ "/a", "/ab", false,
+ "/ab/cd", "/ab/cde", false,
+ "/ab", "/cd", false,
+ };
+
+ for(int i=0; i < testCases.length; i+=3) {
+ assertResult((String)testCases[i], (String)testCases[i+1],
(Boolean)(testCases[i+2]));
+ }
+
+ }
+}
\ No newline at end of file
Modified:
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletAtCopyTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletAtCopyTest.java?rev=1352865&r1=1352864&r2=1352865&view=diff
==============================================================================
---
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletAtCopyTest.java
(original)
+++
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletAtCopyTest.java
Fri Jun 22 12:44:41 2012
@@ -17,9 +17,14 @@
package org.apache.sling.launchpad.webapp.integrationtest.servlets.post;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.httpclient.NameValuePair;
import org.apache.sling.commons.testing.integration.HttpTestBase;
/** Test item copy support by @CopyFrom suffix (SLING-455) */
@@ -195,5 +200,35 @@ public class PostServletAtCopyTest exten
String content = getContent(HTTP_BASE_URL + testPath +
"/some/not/existing/structure.json", CONTENT_TYPE_JSON);
assertJavascript("Hello", content, "out.println(data.text)");
}
-
+
+ /** Copying siblings should work */
+ public void testCopySibling() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/AT_sibling/" +
System.currentTimeMillis();
+ final Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello ATcsp");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/a/1", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/a/12", props);
+
+ final List<NameValuePair> opt = new ArrayList<NameValuePair>();
+ opt.add(new NameValuePair(testPath + "/a/12/13@CopyFrom", testPath +
"/a/1"));
+
+ final int expectedStatus = HttpServletResponse.SC_OK;
+ assertPostStatus(HTTP_BASE_URL + testPath, expectedStatus, opt,
"Expecting status " + expectedStatus);
+
+ // assert content at old and new locations
+ for(String path : new String[] { "/a/1", "/a/12", "/a/12/13" }) {
+ final String content = getContent(HTTP_BASE_URL + testPath + path
+ ".json", CONTENT_TYPE_JSON);
+ assertJavascript("Hello ATcsp", content, "out.println(data.text)",
"at path " + path);
+ }
+ }
+
+ public void testCopyAncestor() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/AT_tcanc/" +
System.currentTimeMillis();
+
+ final List<NameValuePair> opt = new ArrayList<NameValuePair>();
+ opt.add(new NameValuePair(testPath + "./@CopyFrom", "../"));
+
+ final int expectedStatus =
HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+ assertPostStatus(HTTP_BASE_URL + testPath, expectedStatus, opt,
"Expecting status " + expectedStatus);
+ }
}
\ No newline at end of file
Modified:
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java?rev=1352865&r1=1352864&r2=1352865&view=diff
==============================================================================
---
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java
(original)
+++
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java
Fri Jun 22 12:44:41 2012
@@ -578,4 +578,43 @@ public class PostServletCopyTest extends
testClient.delete(testRoot);
}
+
+ /** Copying siblings should work */
+ public void testCopySibling() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/csp/" +
System.currentTimeMillis();
+ final Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello csp");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/a/1", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/a/12", props);
+
+ props.clear();
+ props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_COPY);
+ props.put(SlingPostConstants.RP_DEST, testPath + "/a/12/13");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/a/1", props);
+
+ // assert content at old and new locations
+ for(String path : new String[] { "/a/1", "/a/12", "/a/12/13" }) {
+ final String content = getContent(HTTP_BASE_URL + testPath + path
+ ".json", CONTENT_TYPE_JSON);
+ assertJavascript("Hello csp", content, "out.println(data.text)",
"at path " + path);
+ }
+ }
+
+ /** Copying an ancestor to a descendant should fail */
+ public void testCopyAncestor() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/tcanc/" +
System.currentTimeMillis();
+ final String testRoot = testClient.createNode(HTTP_BASE_URL +
testPath, null);
+ final String parentPath = testPath + "/a/b";
+ final String childPath = parentPath + "/child";
+
+ final String parentUrl = testClient.createNode(HTTP_BASE_URL +
parentPath, null);
+ assertFalse("child node must not exist before copy",
+ getContent(parentUrl + ".2.json",
CONTENT_TYPE_JSON).contains("child"));
+
+ final List<NameValuePair> opt = new ArrayList<NameValuePair>();
+ opt.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_COPY));
+ opt.add(new NameValuePair(SlingPostConstants.RP_DEST, childPath));
+
+ final int expectedStatus =
HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+ assertPostStatus(testRoot, expectedStatus, opt, "Expecting status " +
expectedStatus);
+ }
}
\ No newline at end of file