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

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


The following commit(s) were added to refs/heads/master by this push:
     new dd68324  SLING-12410 ResourceResolver: Add impl for copy and move 
methods (#16)
dd68324 is described below

commit dd68324dd96f1772e81249f38089d40627748748
Author: Bart <[email protected]>
AuthorDate: Tue Aug 20 12:41:12 2024 +0200

    SLING-12410 ResourceResolver: Add impl for copy and move methods (#16)
    
    Co-authored-by: Bart Thierens <[email protected]>
    Co-authored-by: Stefan Seifert <[email protected]>
---
 .../resourceresolver/MockResourceResolver.java     |  55 ++++-
 .../CopyMoveResourceResolverTest.java              | 240 +++++++++++++++++++++
 ...pyMoveResourceResolverResourceProviderTest.java |  39 ++++
 3 files changed, 324 insertions(+), 10 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java
 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java
index 09e7857..f0f15fe 100644
--- 
a/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java
+++ 
b/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java
@@ -518,6 +518,51 @@ public class MockResourceResolver extends SlingAdaptable 
implements ResourceReso
                 .orElse(Collections.emptyIterator());
     }
 
+    @Override
+    public Resource copy(String srcAbsPath, String destAbsPath) throws 
PersistenceException {
+        Resource source = getResource(srcAbsPath);
+        if (source == null) {
+            throw new PersistenceException("Copy source does not exist");
+        }
+        Resource destinationParent = getResource(destAbsPath);
+        if (destinationParent == null) {
+            throw new PersistenceException("Copy destination does not exist");
+        }
+        if (destinationParent.getChild(source.getName()) != null) {
+            throw new PersistenceException("A resource with the same name 
already exists at " + destAbsPath);
+        }
+        recursivelyCreate(source, destinationParent);
+        Resource destination = getResource(destAbsPath + "/" + 
source.getName());
+        if (destination == null) {
+            throw new PersistenceException("Something went wrong");
+        }
+        return destination;
+    }
+
+    private void recursivelyCreate(Resource source, Resource destParent) 
throws PersistenceException {
+        ValueMap sourceProperties = source.getValueMap();
+        Resource target = create(destParent, source.getName(), 
sourceProperties);
+        Iterator<Resource> childrenIter = source.listChildren();
+        while (childrenIter.hasNext()) {
+            recursivelyCreate(childrenIter.next(), target);
+        }
+    }
+
+    @Override
+    public Resource move(String srcAbsPath, String destAbsPath) throws 
PersistenceException {
+        Resource source = getResource(srcAbsPath);
+        if (source == null) {
+            throw new PersistenceException("Move source does not exist");
+        }
+        Resource destinationParent = getResource(destAbsPath);
+        if (destinationParent == null) {
+            throw new PersistenceException("Move destination does not exist");
+        }
+        Resource destination = copy(srcAbsPath, destAbsPath);
+        delete(source);
+        return destination;
+    }
+
     /**
      * Adds a handler that can provide a mocked query resources result. You 
can add multiple handlers which are called
      * in the order they were added when calling {@link 
#queryResources(String, String)}.
@@ -556,16 +601,6 @@ public class MockResourceResolver extends SlingAdaptable 
implements ResourceReso
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public Resource copy(String srcAbsPath, String destAbsPath) throws 
PersistenceException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Resource move(String srcAbsPath, String destAbsPath) throws 
PersistenceException {
-        throw new UnsupportedOperationException();
-    }
-
     // Sling API 2.24.0
     public boolean orderBefore(@NotNull Resource parent, @NotNull String name, 
@Nullable String followingSiblingName)
             throws UnsupportedOperationException, PersistenceException, 
IllegalArgumentException {
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/CopyMoveResourceResolverTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/CopyMoveResourceResolverTest.java
new file mode 100644
index 0000000..ace876a
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/CopyMoveResourceResolverTest.java
@@ -0,0 +1,240 @@
+/*
+ * 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.testing.resourceresolver;
+
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Map;
+import java.util.Random;
+import java.util.UUID;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests copy and move operation on resources
+ */
+public class CopyMoveResourceResolverTest {
+
+    private ResourceResolver resourceResolver;
+    private Resource testRoot;
+    private Resource testDestination;
+
+    @Before
+    @SuppressWarnings("null")
+    public final void setUp() throws Exception {
+        resourceResolver = createResourceResolver();
+        Resource root = resourceResolver.getResource("/");
+        testRoot = resourceResolver.create(root, "test", ValueMap.EMPTY);
+        testDestination = resourceResolver.create(root, "test-dest", 
ValueMap.EMPTY);
+    }
+
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        return new MockResourceResolverFactory().getResourceResolver(null);
+    }
+
+    @Test
+    public void testSimpleCopy() throws PersistenceException {
+        Resource testSource = resourceResolver.create(testRoot, 
"simple-copy-resource", Map.of("testprop", "testval"));
+        assertNotNull(testSource);
+
+        Resource destination = resourceResolver.copy(testSource.getPath(), 
testDestination.getPath());
+        testSource = resourceResolver.getResource(testSource.getPath());
+        assertNotNull(testSource);
+        assertNotNull(destination);
+        final ValueMap destinationProperties = destination.getValueMap();
+        assertEquals(testSource.getValueMap().size(), 
destinationProperties.size());
+        testSource.getValueMap().forEach((key, value) -> assertEquals(value, 
destinationProperties.get(key)));
+
+        assertTrue(resourceResolver.hasChanges());
+    }
+
+    @Test
+    public void testComplexCopy() throws PersistenceException {
+        Resource testSource = resourceResolver.create(testRoot, 
"complex-copy-resource", createUniqueProperties());
+        Resource child1 = resourceResolver.create(testSource, "child-1", 
createUniqueProperties());
+        resourceResolver.create(child1, "grand-child-1-1", 
createUniqueProperties());
+        Resource child2 = resourceResolver.create(testSource, "child-2", 
createUniqueProperties());
+        resourceResolver.create(child2, "grand-child-2-1", 
createUniqueProperties());
+        Resource grandChild22 = resourceResolver.create(child2, 
"grand-child-2-2", createUniqueProperties());
+        resourceResolver.create(grandChild22, "great-grand-child-2-2-1", 
createUniqueProperties());
+        resourceResolver.create(grandChild22, "great-grand-child-2-2-2", 
createUniqueProperties());
+        resourceResolver.create(grandChild22, "great-grand-child-2-2-3", 
createUniqueProperties());
+
+        final String[] pathsToCheck = {
+            "/test-dest/complex-copy-resource",
+            "/test-dest/complex-copy-resource/child-1",
+            "/test-dest/complex-copy-resource/child-1/grand-child-1-1",
+            "/test-dest/complex-copy-resource/child-2",
+            "/test-dest/complex-copy-resource/child-2/grand-child-2-1",
+            "/test-dest/complex-copy-resource/child-2/grand-child-2-2",
+            
"/test-dest/complex-copy-resource/child-2/grand-child-2-2/great-grand-child-2-2-1",
+            
"/test-dest/complex-copy-resource/child-2/grand-child-2-2/great-grand-child-2-2-2",
+            
"/test-dest/complex-copy-resource/child-2/grand-child-2-2/great-grand-child-2-2-3"
+        };
+
+        Resource destination = resourceResolver.copy(testSource.getPath(), 
testDestination.getPath());
+        assertNotNull(destination);
+        Arrays.stream(pathsToCheck).forEach(path -> {
+            Resource copiedResource = resourceResolver.getResource(path);
+            assertNotNull(copiedResource);
+            Resource relSource = 
resourceResolver.getResource(path.replace("/test-dest", "/test"));
+            assertNotNull(relSource);
+            final ValueMap copiedProps = copiedResource.getValueMap();
+            assertEquals(relSource.getValueMap().size(), copiedProps.size());
+            relSource.getValueMap().forEach((key, value) -> 
assertEquals(value, copiedProps.get(key)));
+        });
+
+        assertTrue(resourceResolver.hasChanges());
+    }
+
+    @Test(expected = PersistenceException.class)
+    @SuppressWarnings("null")
+    public void testFailedCopy_DestinationExists() throws PersistenceException 
{
+        Resource testSource = resourceResolver.create(testRoot, 
"failed-copy-resource", ValueMap.EMPTY);
+        resourceResolver.copy(testSource.getPath(), 
testSource.getParent().getPath());
+    }
+
+    @Test(expected = PersistenceException.class)
+    public void testFailedCopy_SourceDoesntExist() throws PersistenceException 
{
+        Resource testSource = resourceResolver.create(testRoot, 
"failed-copy-resource", ValueMap.EMPTY);
+        resourceResolver.copy(testSource.getPath(), "/non-existing-parent");
+    }
+
+    @Test(expected = PersistenceException.class)
+    public void testFailedCopy_DestinationParentDoesntExist() throws 
PersistenceException {
+        resourceResolver.copy("/non-existing-path", "/test");
+    }
+
+    @Test
+    public void testSimpleMove() throws PersistenceException {
+        Resource testSource = resourceResolver.create(testRoot, 
"simple-move-resource", Map.of("testprop", "testval"));
+        assertNotNull(testSource);
+
+        Resource destination = resourceResolver.move(testSource.getPath(), 
testDestination.getPath());
+        assertNull(resourceResolver.getResource(testSource.getPath()));
+        assertNotNull(destination);
+        final ValueMap destinationProperties = destination.getValueMap();
+        assertEquals(testSource.getValueMap().size(), 
destinationProperties.size());
+        testSource.getValueMap().forEach((key, value) -> assertEquals(value, 
destinationProperties.get(key)));
+
+        assertTrue(resourceResolver.hasChanges());
+    }
+
+    @Test
+    public void testComplexMove() throws PersistenceException {
+        Resource testSource = resourceResolver.create(testRoot, 
"complex-copy-resource", createUniqueProperties());
+        Resource child1 = resourceResolver.create(testSource, "child-1", 
createUniqueProperties());
+        Resource grandChild11 = resourceResolver.create(child1, 
"grand-child-1-1", createUniqueProperties());
+        Resource child2 = resourceResolver.create(testSource, "child-2", 
createUniqueProperties());
+        Resource grandChild21 = resourceResolver.create(child2, 
"grand-child-2-1", createUniqueProperties());
+        Resource grandChild22 = resourceResolver.create(child2, 
"grand-child-2-2", createUniqueProperties());
+        Resource greatGrandChild221 =
+                resourceResolver.create(grandChild22, 
"great-grand-child-2-2-1", createUniqueProperties());
+        Resource greatGrandChild222 =
+                resourceResolver.create(grandChild22, 
"great-grand-child-2-2-2", createUniqueProperties());
+        Resource greatGrandChild223 =
+                resourceResolver.create(grandChild22, 
"great-grand-child-2-2-3", createUniqueProperties());
+
+        assertResourceMovedCorrectly(
+                testSource, resourceResolver.move(testSource.getPath(), 
testDestination.getPath()));
+        assertResourceMovedCorrectly(child1, 
resourceResolver.getResource("/test-dest/complex-copy-resource/child-1"));
+        assertResourceMovedCorrectly(
+                grandChild11, 
resourceResolver.getResource("/test-dest/complex-copy-resource/child-1/grand-child-1-1"));
+        assertResourceMovedCorrectly(child2, 
resourceResolver.getResource("/test-dest/complex-copy-resource/child-2"));
+        assertResourceMovedCorrectly(
+                grandChild21, 
resourceResolver.getResource("/test-dest/complex-copy-resource/child-2/grand-child-2-1"));
+        assertResourceMovedCorrectly(
+                grandChild22, 
resourceResolver.getResource("/test-dest/complex-copy-resource/child-2/grand-child-2-2"));
+        assertResourceMovedCorrectly(
+                greatGrandChild221,
+                resourceResolver.getResource(
+                        
"/test-dest/complex-copy-resource/child-2/grand-child-2-2/great-grand-child-2-2-1"));
+        assertResourceMovedCorrectly(
+                greatGrandChild222,
+                resourceResolver.getResource(
+                        
"/test-dest/complex-copy-resource/child-2/grand-child-2-2/great-grand-child-2-2-2"));
+        assertResourceMovedCorrectly(
+                greatGrandChild223,
+                resourceResolver.getResource(
+                        
"/test-dest/complex-copy-resource/child-2/grand-child-2-2/great-grand-child-2-2-3"));
+
+        assertTrue(resourceResolver.hasChanges());
+    }
+
+    @Test(expected = PersistenceException.class)
+    @SuppressWarnings("null")
+    public void testFailedMove_DestinationExists() throws PersistenceException 
{
+        Resource testSource = resourceResolver.create(testRoot, 
"failed-move-resource", ValueMap.EMPTY);
+        resourceResolver.move(testSource.getPath(), 
testSource.getParent().getPath());
+    }
+
+    @Test(expected = PersistenceException.class)
+    public void testFailedMove_SourceDoesntExist() throws PersistenceException 
{
+        Resource testSource = resourceResolver.create(testRoot, 
"failed-copy-resource", ValueMap.EMPTY);
+        resourceResolver.move(testSource.getPath(), "/non-existing-parent");
+    }
+
+    @Test(expected = PersistenceException.class)
+    public void testFailedMove_DestinationParentDoesntExist() throws 
PersistenceException {
+        resourceResolver.move("/non-existing-path", "/test");
+    }
+
+    private void assertResourceMovedCorrectly(Resource originalResource, 
Resource movedResource) {
+        assertNotNull(movedResource);
+        assertNull(resourceResolver.getResource(originalResource.getPath()));
+        final ValueMap movedProps = movedResource.getValueMap();
+        assertEquals(originalResource.getValueMap().size(), movedProps.size());
+        originalResource.getValueMap().forEach((key, value) -> 
assertEquals(value, movedProps.get(key)));
+    }
+
+    private Map<String, Object> createUniqueProperties() {
+        return Map.of(
+                JcrConstants.JCR_PRIMARYTYPE,
+                "my:Type",
+                SlingConstants.PROPERTY_RESOURCE_TYPE,
+                "test/my-resource-type",
+                "string-value",
+                UUID.randomUUID(),
+                "int-value",
+                new Random().nextInt(10000),
+                "date-value",
+                Calendar.getInstance(),
+                "long-value",
+                System.nanoTime(),
+                "bool-value",
+                Math.random() < 0.5,
+                "array-value",
+                new String[] {"string 1", "string 2", "string 3"},
+                "jcr:mixinTypes",
+                new String[] {"rep:AccessControllable", "mix:versionable"});
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/testing/resourceresolver/provider/CopyMoveResourceResolverResourceProviderTest.java
 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/CopyMoveResourceResolverResourceProviderTest.java
new file mode 100644
index 0000000..4ba84d6
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/testing/resourceresolver/provider/CopyMoveResourceResolverResourceProviderTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.testing.resourceresolver.provider;
+
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.resourceresolver.CopyMoveResourceResolverTest;
+import org.apache.sling.testing.resourceresolver.MockResourceProvider;
+import org.junit.Rule;
+
+public class CopyMoveResourceResolverResourceProviderTest extends 
CopyMoveResourceResolverTest {
+
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.NONE);
+
+    @Override
+    protected ResourceResolver createResourceResolver() throws LoginException {
+        context.registerInjectActivateService(MockResourceProvider.class);
+        return context.resourceResolver();
+    }
+}

Reply via email to