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


Reply via email to