This is an automated email from the ASF dual-hosted git repository.

enorman pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-jcr-mock.git


The following commit(s) were added to refs/heads/master by this push:
     new f2dd563  SLING-11803 Implement session#move support for JCR Mock (#13)
f2dd563 is described below

commit f2dd5632a321a298072df65c662d84f62f4e8322
Author: Eric Norman <[email protected]>
AuthorDate: Wed Mar 15 12:54:49 2023 -0700

    SLING-11803 Implement session#move support for JCR Mock (#13)
---
 .../apache/sling/testing/mock/jcr/ItemData.java    | 22 ++++++
 .../apache/sling/testing/mock/jcr/MockSession.java | 50 +++++++++++++-
 .../sling/testing/mock/jcr/MockSessionTest.java    | 80 ++++++++++++++++++++++
 3 files changed, 151 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/ItemData.java 
b/src/main/java/org/apache/sling/testing/mock/jcr/ItemData.java
index e528ceb..c52e7c1 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/ItemData.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/ItemData.java
@@ -50,6 +50,24 @@ class ItemData {
         this.isChanged = false;
     }
 
+    /**
+     * Copy constructor
+     *
+     * @param destPath the destination path of the copied item data
+     * @param itemData the source item data to copy
+     */
+    private ItemData(String destPath, ItemData itemData) {
+        this.path = destPath;
+        this.name = ResourceUtil.getName(path);
+        this.isNode = itemData.isNode;
+        this.uuid = itemData.uuid;
+        this.nodeType = itemData.nodeType;
+        this.values = itemData.values;
+        this.isMultiple = itemData.isMultiple;
+        this.isNew = itemData.isNew;
+        this.isChanged = itemData.isChanged;
+    }
+
     public String getPath() {
         return path;
     }
@@ -153,6 +171,10 @@ class ItemData {
         return false;
     }
 
+    public static ItemData cloneItemAtNewPath(String destPath, ItemData 
itemData) {
+        return new ItemData(destPath, itemData);
+    }
+
     public static ItemData newNode(String path, NodeType nodeType) {
         return new ItemData(path, true, UUID.randomUUID().toString(), 
nodeType);
     }
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockSession.java 
b/src/main/java/org/apache/sling/testing/mock/jcr/MockSession.java
index 4953e7f..e06345c 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/MockSession.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockSession.java
@@ -18,16 +18,21 @@
  */
 package org.apache.sling.testing.mock.jcr;
 
+import static java.util.Objects.requireNonNull;
+
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.regex.Pattern;
 
 import javax.jcr.Credentials;
 import javax.jcr.Item;
+import javax.jcr.ItemExistsException;
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.Node;
 import javax.jcr.PathNotFoundException;
@@ -421,7 +426,50 @@ class MockSession implements Session {
 
     @Override
     public void move(final String srcAbsPath, final String destAbsPath) throws 
RepositoryException {
-        throw new UnsupportedOperationException();
+        checkLive();
+
+        requireNonNull(srcAbsPath, "parameter 'srcAbsPath' must not be null");
+        requireNonNull(destAbsPath, "parameter 'destAbsPath' must not be 
null");
+
+        if (ResourceUtil.getName(destAbsPath).matches(".*\\[\\d+\\]")) {
+            throw new RepositoryException("The destination path must not have 
an index on its final element");
+        }
+
+        if (nodeExists(destAbsPath) &&
+                
!"true".equals(getRepository().getDescriptor(Repository.NODE_TYPE_MANAGEMENT_SAME_NAME_SIBLINGS_SUPPORTED)))
 {
+            throw new ItemExistsException("The destination path already 
exists");
+        }
+        String destParentPath = ResourceUtil.getParent(destAbsPath);
+        if (!nodeExists(destParentPath)) {
+            throw new PathNotFoundException("The destination parent path does 
not exist");
+        }
+        if (!itemExists(srcAbsPath)) {
+            throw new PathNotFoundException("The source path does not exist");
+        }
+
+        // move node and any descendants
+        final ItemData parent = getItemData(srcAbsPath);
+        if (!parent.isNode()) {
+            throw new RepositoryException("The source path must be a node");
+        }
+        final String descendantPrefix = parent.getPath() + "/";
+
+        final Map<String, String> pathsToMove = new LinkedHashMap<>();
+        pathsToMove.put(parent.getPath(), destAbsPath);
+        for (String itemPath : this.items.keySet()) {
+            if (itemPath.startsWith(descendantPrefix)) {
+                String newPath = String.format("%s/%s", destAbsPath, 
itemPath.substring(descendantPrefix.length()));
+                pathsToMove.put(itemPath, newPath);
+            }
+        }
+        for (Entry<String, String> pathToMove : pathsToMove.entrySet()) {
+            // remove the data from the old path
+            ItemData itemData = this.items.remove(pathToMove.getKey());
+            // add the data back at the new path
+            addItem(ItemData.cloneItemAtNewPath(pathToMove.getValue(), 
itemData));
+        }
+
+        hasKnownChanges = true;
     }
 
     @Override
diff --git 
a/src/test/java/org/apache/sling/testing/mock/jcr/MockSessionTest.java 
b/src/test/java/org/apache/sling/testing/mock/jcr/MockSessionTest.java
index 1e1410e..13a76f9 100644
--- a/src/test/java/org/apache/sling/testing/mock/jcr/MockSessionTest.java
+++ b/src/test/java/org/apache/sling/testing/mock/jcr/MockSessionTest.java
@@ -22,8 +22,10 @@ import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 
+import javax.jcr.ItemExistsException;
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.NamespaceRegistry;
 import javax.jcr.Node;
@@ -329,4 +331,82 @@ public class MockSessionTest {
         assertFalse(session.isLive());
     }
 
+    @Test
+    public void testMoveWhenSrcAbsPathIsNull() throws Exception {
+        Session session = MockJcr.newSession();
+
+        assertThrows(NullPointerException.class, () -> session.move(null, 
"/node1/child2"));
+    }
+
+    @Test
+    public void testMoveWhenDestAbsPathIsNull() throws Exception {
+        Session session = MockJcr.newSession();
+
+        assertThrows(NullPointerException.class, () -> 
session.move("/node1/child1", null));
+    }
+
+    @Test
+    public void testMoveWhenSrcAbsPathDoesNotExist() throws Exception {
+        Session session = MockJcr.newSession();
+        session.getRootNode().addNode("node1");
+
+        assertThrows(PathNotFoundException.class, () -> 
session.move("/node1/child1", "/node1/child2"));
+    }
+
+    @Test
+    public void testMoveWhenDestAbsPathAlreadyExists() throws Exception {
+        Session session = MockJcr.newSession();
+        Node node1 = session.getRootNode().addNode("node1");
+        node1.addNode("child1");
+        node1.addNode("child2");
+
+        assertThrows(ItemExistsException.class, () -> 
session.move("/node1/child1", "/node1/child2"));
+    }
+
+    @Test
+    public void testMoveWhenDestAbsPathHasIndexInName() throws Exception {
+        Session session = MockJcr.newSession();
+        Node node1 = session.getRootNode().addNode("node1");
+        node1.addNode("child1");
+
+        assertThrows(RepositoryException.class, () -> 
session.move("/node1/child1", "/node1/child2[1]"));
+    }
+
+    @Test
+    public void testMoveWhenDestParentDoesNotExist() throws Exception {
+        Session session = MockJcr.newSession();
+        Node node1 = session.getRootNode().addNode("node1");
+        node1.addNode("child1");
+
+        assertThrows(PathNotFoundException.class, () -> 
session.move("/node1/child1", "/node2/child2"));
+    }
+
+    @Test
+    public void testMoveWhenSrcAbsPathIsNotNode() throws Exception {
+        Session session = MockJcr.newSession();
+        Node node1 = session.getRootNode().addNode("node1");
+        node1.setProperty("child1", "value1");
+
+        assertThrows(RepositoryException.class, () -> 
session.move("/node1/child1", "/node1/child2"));
+    }
+
+    @Test
+    public void testMove() throws Exception {
+        Session session = MockJcr.newSession();
+        Node node1 = session.getRootNode().addNode("node1");
+        Node child1 = node1.addNode("child1");
+        child1.setProperty("prop1", "value1");
+        Node grandchild1 = child1.addNode("grandchild1");
+        grandchild1.setProperty("prop1", "value1");
+
+        session.move("/node1/child1", "/node1/child2");
+
+        // verify the data was moved
+        assertFalse(session.nodeExists("/node1/child1"));
+        assertTrue(session.nodeExists("/node1/child2"));
+        assertTrue(session.propertyExists("/node1/child2/prop1"));
+        assertTrue(session.nodeExists("/node1/child2/grandchild1"));
+        assertTrue(session.propertyExists("/node1/child2/grandchild1/prop1"));
+    }
+
 }

Reply via email to