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"));
+ }
+
}