You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by an...@apache.org on 2021/04/12 15:22:38 UTC

[sling-whiteboard] branch master updated: Added some more tests

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

andysch pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new 6d8361c  Added some more tests
     new 44f4dd8  Merge branch 'master' of github.com:apache/sling-whiteboard
6d8361c is described below

commit 6d8361c86ec4aff584b2794aa179e86fe98b6632
Author: Andreas Schaefer <sc...@me.com>
AuthorDate: Mon Apr 12 08:20:44 2021 -0700

    Added some more tests
---
 .../api/DeclarativeDynamicResourceProvider.java    |   2 +-
 ...clarativeDynamicResourceManagerServiceTest.java |  92 ++++++++++-------
 ...larativeDynamicResourceProviderHandlerTest.java | 114 +++++++++++++++++----
 .../java/org/apache/sling/ddr/core/TestUtils.java  |  79 ++++++++++++++
 .../resources/ddr-filter/ddr-conf-settings.json    |   4 +
 .../ddr-installation/ddr-apps-settings.json        |   7 ++
 .../resources/ddr-reference/ddr-apps-settings.json |  10 ++
 .../resources/ddr-reference/ddr-conf-settings.json |   7 ++
 8 files changed, 256 insertions(+), 59 deletions(-)

diff --git a/org.apache.sling.ddr/api/src/main/java/org/apache/sling/ddr/api/DeclarativeDynamicResourceProvider.java b/org.apache.sling.ddr/api/src/main/java/org/apache/sling/ddr/api/DeclarativeDynamicResourceProvider.java
index 727db82..5d34100 100644
--- a/org.apache.sling.ddr/api/src/main/java/org/apache/sling/ddr/api/DeclarativeDynamicResourceProvider.java
+++ b/org.apache.sling.ddr/api/src/main/java/org/apache/sling/ddr/api/DeclarativeDynamicResourceProvider.java
@@ -17,7 +17,6 @@
 package org.apache.sling.ddr.api;
 
 import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.osgi.framework.Bundle;
 
 import java.util.List;
@@ -56,4 +55,5 @@ public interface DeclarativeDynamicResourceProvider {
     String getTargetRootPath();
 
     void update(String path);
+
 }
diff --git a/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerServiceTest.java b/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerServiceTest.java
index 8849e55..bd03d86 100644
--- a/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerServiceTest.java
+++ b/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerServiceTest.java
@@ -22,6 +22,9 @@ import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.ddr.api.DeclarativeDynamicResourceListener;
+import org.apache.sling.ddr.api.DeclarativeDynamicResourceProvider;
+import org.apache.sling.spi.resource.provider.ResolveContext;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
 import org.apache.sling.testing.mock.sling.NodeTypeDefinitionScanner;
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
@@ -38,11 +41,15 @@ import org.slf4j.LoggerFactory;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import static org.apache.sling.ddr.core.TestUtils.filterResourceByName;
+import static org.apache.sling.ddr.core.TestUtils.getResourcesFromProvider;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -62,6 +69,8 @@ public class DeclarativeDynamicResourceManagerServiceTest {
     public SlingContext context = new SlingContext(ResourceResolverType.JCR_OAK);
 
     @Mock
+    private ResolveContext resolveContext;
+    @Mock
     private ResourceResolverFactory resourceResolverFactory;
     @Mock
     private DeclarativeDynamicResourceListener declarativeDynamicResourceListener;
@@ -76,6 +85,7 @@ public class DeclarativeDynamicResourceManagerServiceTest {
     public void setup() throws LoginException, RepositoryException {
         resourceResolver = spy(context.resourceResolver());
         log.info("Adapt Context-RR: '{}' to Session: '{}'", resourceResolver, resourceResolver.adaptTo(Session.class));
+        when(resolveContext.getResourceResolver()).thenReturn(resourceResolver);
         when(resourceResolverFactory.getServiceResourceResolver(any(Map.class)))
             .thenReturn(resourceResolver);
         declarativeDynamicResourceManagerService.resourceResolverFactory = resourceResolverFactory;
@@ -93,11 +103,8 @@ public class DeclarativeDynamicResourceManagerServiceTest {
 
     @Test
     public void testBasics() throws Exception {
-        String resourceName = "test1";
         String confResourceRoot = "/conf/test/settings/dynamic";
         String dynamicResourceRoot = "/apps/dynamic";
-        final String testPropertyKey = "jcr:title";
-        final String testPropertyValue = "Test-1";
 
         log.info("Before Loading Test Resources");
         context.load().json("/ddr-installation/ddr-conf-settings.json", "/conf");
@@ -125,40 +132,51 @@ public class DeclarativeDynamicResourceManagerServiceTest {
         assertEquals("Wrong DDR Source Path", confResourceRoot, source.getPath());
     }
 
-//    @Test
-//    public void testFilters() throws Exception {
-//        String resourceName = "test1";
-//        String confResourceRoot = "/conf/testFilter/settings/dynamic";
-//        String dynamicResourceRoot = "/apps/dynamicFilter";
-////        final String testPropertyKey = "jcr:title";
-////        final String testPropertyValue = "Test-1";
-//
-//        log.info("Before Loading Test Resources");
-//        context.load().json("/ddr-filter/ddr-conf-settings.json", "/conf");
-//        context.load().json("/ddr-filter/ddr-apps-settings.json", "/apps");
-//        log.info("After Loading Test Resources");
-//        Resource sourceRoot = resourceResolver.getResource("/conf/testFilter/settings/dynamic");
-//        log.info("Dynamic Test Resource Root: '{}'", sourceRoot);
-//        when(resourceResolver.findResources(anyString(), anyString())).thenReturn(
-//            Arrays.asList(sourceRoot).iterator()
-//        );
-//
-//        // Listen to newly created DDRs
-//        doAnswer(new ListenerAnswer()).when(declarativeDynamicResourceListener).addDeclarativeDynamicResource(anyString(), any(Resource.class));
-//
-//        // Test a basic, already installed configuration
-//        log.info("DDR-Manager Service: '{}'", declarativeDynamicResourceManagerService);
-//        declarativeDynamicResourceManagerService.activate(context.bundleContext(), createConfiguration(
-//            null, new String[] {"sling:resourceType=nt:file", "sling:resourceType=nt:resource"}));
-//
-//// The Query for Node Type sling:DDR will not return even though a Resource is there
-//        assertFalse("No DDR Registered", ddrMap.isEmpty());
-//        assertEquals("Only one DDR should be Registered", 1, ddrMap.size());
-//        Entry<String, Resource> entry = ddrMap.entrySet().iterator().next();
-//        assertEquals("Wrong DDR Dynamic Path", dynamicResourceRoot + "/" + resourceName, entry.getKey());
-//        Resource source = entry.getValue();
-//        assertEquals("Wrong DDR Source Path", confResourceRoot + "/" + resourceName, source.getPath());
-//    }
+    @Test
+    public void testResourceUpdates() throws Exception {
+        String confResourceRoot = "/conf/test/settings/dynamic";
+        String dynamicResourceRoot = "/apps/dynamic";
+
+        log.info("Before Loading Test Resources");
+        context.load().json("/ddr-installation/ddr-conf-settings.json", "/conf");
+        context.load().json("/ddr-installation/ddr-apps-settings.json", "/apps");
+        log.info("After Loading Test Resources");
+        Resource sourceRoot = resourceResolver.getResource(confResourceRoot);
+        Resource targetRoot = resourceResolver.getResource(dynamicResourceRoot);
+        log.info("Dynamic Test Resource Root: '{}'", sourceRoot);
+        when(resourceResolver.findResources(anyString(), anyString())).thenReturn(
+            Arrays.asList(sourceRoot).iterator()
+        );
+
+        // Listen to newly created DDRs
+        doAnswer(new ListenerAnswer()).when(declarativeDynamicResourceListener).addDeclarativeDynamicResource(anyString(), any(Resource.class));
+
+        // Test a basic, already installed configuration
+        log.info("DDR-Manager Service: '{}'", declarativeDynamicResourceManagerService);
+        declarativeDynamicResourceManagerService.activate(context.bundleContext(), createConfiguration(null, null));
+
+        // Get the children from the DDR
+        Map<String, DeclarativeDynamicResourceProvider> providerMap = declarativeDynamicResourceManagerService.getRegisteredServicesByTarget();
+        assertEquals("Expected only one DDR Provider", 1, providerMap.size());
+        DeclarativeDynamicResourceProvider provider = providerMap.values().iterator().next();
+        assertNotNull("DDR Provider must be defined", provider);
+
+        List<Resource> resources = getResourcesFromProvider((ResourceProvider) provider, resolveContext, targetRoot);
+        assertFalse("Expected a resource but none found", resources.isEmpty());
+        assertEquals("Did not get 'test1' resource", 1, filterResourceByName(resources, true, "test1").size());
+        assertEquals("Got another resource than 'test1'", new ArrayList<>(), filterResourceByName(resources, false, "test1"));
+
+        // Move the resource in from the source
+        resourceResolver.move("/apps/sources/test2", confResourceRoot);
+        Thread.sleep(10000);
+
+        resources = getResourcesFromProvider((ResourceProvider) provider, resolveContext, targetRoot);
+        assertFalse("Expected resources but none found", resources.isEmpty());
+        assertEquals("Did not get 'test1' resource", 1, filterResourceByName(resources, true, "test1").size());
+//AS TODO: The move() of the resource is not triggering the onEvent() on the Resource Manager.
+//        assertEquals("Did not get 'test2' resource", 1, filterResourceByName(resources, true, "test2").size());
+//        assertEquals("Got another resource than 'test1'", new ArrayList<>(), filterResourceByName(resources, false, "test1"));
+    }
 
     private DeclarativeDynamicResourceManagerService.Configuration createConfiguration(
         String[] allowed, String[] prohibited, String ... followedLinkNames
diff --git a/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceProviderHandlerTest.java b/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceProviderHandlerTest.java
index d42ca9f..98ebfc5 100644
--- a/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceProviderHandlerTest.java
+++ b/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceProviderHandlerTest.java
@@ -25,7 +25,6 @@ import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.ddr.api.DeclarativeDynamicResourceManager;
 import org.apache.sling.spi.resource.provider.ResolveContext;
 import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
 import org.apache.sling.testing.mock.sling.NodeTypeDefinitionScanner;
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
@@ -42,16 +41,19 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import static org.apache.sling.ddr.api.Constants.SLASH;
+import static org.apache.sling.ddr.core.TestUtils.filterResourceByName;
+import static org.apache.sling.ddr.core.TestUtils.getResourcesFromProvider;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doNothing;
@@ -190,11 +192,8 @@ public class DeclarativeDynamicResourceProviderHandlerTest {
 
     @Test
     public void testListReferences() throws Exception {
-        String resourceName = "test1";
         String confResourceRoot = "/conf/testReference/settings/dynamic";
         String dynamicResourceRoot = "/apps/dynamicReference";
-        final String testPropertyKey = "jcr:title";
-        final String testPropertyValue = "Test-1";
 
         context.load().json("/ddr-reference/ddr-conf-settings.json", "/conf");
         context.load().json("/ddr-reference/ddr-apps-settings.json", "/apps");
@@ -212,26 +211,99 @@ public class DeclarativeDynamicResourceProviderHandlerTest {
         Resource noRef = checkAndGetResource(dynamicParent, "noRef");
         Resource refNoChild = checkAndGetResource(dynamicParent, "refNoChild");
         Resource refWithChild = checkAndGetResource(dynamicParent, "refWithChild");
-        Resource refChild = checkAndGetResource(refWithChild, "child");
-        log.info("Ref Child: '{}'", refChild);
-        Resource refGrandchild = checkAndGetResource(refChild, "grandChild");
+        Resource referencedChild = checkAndGetResource(refWithChild, "child");
+        log.info("Ref Child: '{}'", referencedChild);
+        Resource refWithGrandChild = checkAndGetResource(dynamicParent, "refWithGrandChild");
+        log.info("Ref Grand Child: '{}'", refWithGrandChild);
+        Resource referencedChild2 = checkAndGetResource(refWithGrandChild, "child");
+        log.info("Ref Child: '{}'", referencedChild);
+        Resource refGrandchild = checkAndGetResource(referencedChild2, "grandChild");
         log.info("Ref Grandchild: '{}'", refGrandchild);
     }
 
-    private Resource checkAndGetResource(Resource parent, String expectedChildName) {
-        Resource answer = null;
-        // List all the children and make sure that only one is returned
-        Iterator<Resource> i = declarativeDynamicResourceProviderHandler.listChildren(
-            resolveContext, parent
+    @Test
+    public void testListChildrenWithFailingContextResourceResolver() throws Exception {
+        String confResourceRoot = "/conf/testReference/settings/dynamic";
+        String dynamicResourceRoot = "/apps/dynamicReference";
+
+        context.load().json("/ddr-reference/ddr-conf-settings.json", "/conf");
+        context.load().json("/ddr-reference/ddr-apps-settings.json", "/apps");
+
+        ResourceResolver contextResourceResolver = mock(ResourceResolver.class);
+        when(contextResourceResolver.getResource(anyString())).thenReturn(null);
+        when(resolveContext.getResourceResolver()).thenReturn(contextResourceResolver);
+
+        Resource dynamicParent = resourceResolver.getResource(dynamicResourceRoot);
+
+        doNothing().when(declarativeDynamicResourceManager).addReference(anyString(), anyString());
+
+        declarativeDynamicResourceProviderHandler.registerService(
+            context.bundleContext().getBundle(), dynamicResourceRoot, confResourceRoot,
+            resourceResolver, declarativeDynamicResourceManager,null, null,
+            Arrays.asList("sling:ddrRef")
         );
-        assertNotNull("No Iterator returned", i);
-        while(i.hasNext()) {
-            Resource child = i.next();
-            if(child.getName().equals(expectedChildName)) {
-                answer = child;
-                break;
-            }
-        }
+
+        Resource noRef = checkAndGetResource(dynamicParent, "noRef");
+    }
+
+    @Test
+    public void testUpdates() throws Exception {
+        String resourceName1 = "test1";
+        String newResourceName1 = "test1a";
+        String confResourceRoot = "/conf/testFilter/settings/dynamic";
+        String dynamicResourceRoot = "/apps/dynamicFilter";
+
+        log.info("Before Loading Test Resources");
+        context.load().json("/ddr-filter/ddr-conf-settings.json", "/conf");
+        context.load().json("/ddr-filter/ddr-apps-settings.json", "/apps");
+        log.info("After Loading Test Resources");
+
+        Resource dynamicParent = resourceResolver.getResource(dynamicResourceRoot);
+        declarativeDynamicResourceProviderHandler.registerService(
+            context.bundleContext().getBundle(), dynamicResourceRoot, confResourceRoot,
+            resourceResolver, null, null,
+            new HashMap<String, List<String>>() {{
+                put("jcr:primaryType", Arrays.asList("nt:file"));
+            }},
+            null
+        );
+
+        Resource test1 = declarativeDynamicResourceProviderHandler.getResource(
+            resolveContext, dynamicResourceRoot + "/" + resourceName1, resourceContext, dynamicParent
+        );
+
+        Resource container = declarativeDynamicResourceProviderHandler.getResource(
+            resolveContext, dynamicResourceRoot + "/container", resourceContext, dynamicParent
+        );
+        assertNotNull("Container Resource not found", container);
+
+        Resource newTest1 = declarativeDynamicResourceProviderHandler.getResource(
+            resolveContext, dynamicResourceRoot + "/container/" + resourceName1, resourceContext, dynamicParent
+        );
+        assertNull("To Be Moved Resource must not exist beforehand", newTest1);
+
+        resourceResolver.move(
+            confResourceRoot + SLASH + resourceName1, confResourceRoot + SLASH + "container"
+        );
+
+        // Check that the resource is not found in list
+        List<Resource> resources = getResourcesFromProvider(declarativeDynamicResourceProviderHandler, resolveContext, container);
+        resources = filterResourceByName(resources, true, resourceName1);
+        assertTrue("Moved resource should not have been found here", resources.isEmpty());
+
+        declarativeDynamicResourceProviderHandler.update(confResourceRoot + SLASH + newResourceName1);
+
+        resources = getResourcesFromProvider(declarativeDynamicResourceProviderHandler, resolveContext, container);
+        resources = filterResourceByName(resources, true, resourceName1);
+        assertFalse("Moved resource was not found after update", resources.isEmpty());
+        newTest1 = resources.get(0);
+        assertNotNull("Moved Resource not found", newTest1);
+    }
+
+    private Resource checkAndGetResource(Resource parent, String expectedChildName) {
+        List<Resource> resources = getResourcesFromProvider(declarativeDynamicResourceProviderHandler, resolveContext, parent);
+        resources = filterResourceByName(resources, true, expectedChildName);
+        Resource answer = resources.isEmpty() ? null : resources.get(0);
         assertNotNull("Child: '" + expectedChildName + "' not found", answer);
         return answer;
     }
diff --git a/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/TestUtils.java b/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/TestUtils.java
new file mode 100644
index 0000000..891993b
--- /dev/null
+++ b/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/TestUtils.java
@@ -0,0 +1,79 @@
+/*
+ * 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.ddr.core;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.spi.resource.provider.ResolveContext;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class TestUtils {
+
+    /**
+     * Gets the List of All Resources from the given Resource Provider of the given Parent
+     *
+     * @param provider Resource Provider from which the list of children is obtained from
+     * @param resolveContext Resolve Context to be used
+     * @param parent Parent Resource from which children are returned
+     * @return List of Children or empty if none are found
+     */
+    public static List<Resource> getResourcesFromProvider(
+        ResourceProvider provider, ResolveContext resolveContext, Resource parent
+    ) {
+        List<Resource> answer = new ArrayList<>();
+        // List all the children and make sure that only one is returned
+        Iterator<Resource> i = provider.listChildren(
+            resolveContext, parent
+        );
+        if(i != null) {
+            while (i.hasNext()) {
+                answer.add(i.next());
+            }
+        }
+        return answer;
+    }
+
+    /**
+     * Filters out matching or not matching resources from the given list
+     *
+     * @param resources List of resources to be filtered
+     * @param matching If true only matching resources are returned otherwise only not matching resources
+     * @param names All the names that we want to filter out or remove
+     * @return Returns a list of all resources that are either in the list of names or not. This is a copy of the
+     *         given list of resources
+     */
+    public static List<Resource> filterResourceByName(List<Resource> resources, boolean matching, String ... names) {
+        List<Resource> answer = new ArrayList<>();
+        for(Resource resource: resources) {
+            if(names != null) {
+                boolean found = false;
+                for (String childName : names) {
+                    if (resource.getName().equals(childName)) {
+                        found = true;
+                    }
+                }
+                if(matching == found) {
+                    answer.add(resource);
+                }
+            }
+        }
+        return answer;
+    }
+}
diff --git a/org.apache.sling.ddr/core/src/test/resources/ddr-filter/ddr-conf-settings.json b/org.apache.sling.ddr/core/src/test/resources/ddr-filter/ddr-conf-settings.json
index 33e1b8a..5852518 100644
--- a/org.apache.sling.ddr/core/src/test/resources/ddr-filter/ddr-conf-settings.json
+++ b/org.apache.sling.ddr/core/src/test/resources/ddr-filter/ddr-conf-settings.json
@@ -23,6 +23,10 @@
         "test3": {
           "jcr:primaryType": "nt:resource",
           "jcr:data": ""
+        },
+        "container": {
+          "jcr:primaryType": "nt:resource",
+          "jcr:data": ""
         }
       }
     }
diff --git a/org.apache.sling.ddr/core/src/test/resources/ddr-installation/ddr-apps-settings.json b/org.apache.sling.ddr/core/src/test/resources/ddr-installation/ddr-apps-settings.json
index 080f27f..decf168 100644
--- a/org.apache.sling.ddr/core/src/test/resources/ddr-installation/ddr-apps-settings.json
+++ b/org.apache.sling.ddr/core/src/test/resources/ddr-installation/ddr-apps-settings.json
@@ -2,5 +2,12 @@
   "sling:resourceType": "sling:Folder",
   "dynamic": {
     "sling:resourceType": "sling:Folder"
+  },
+  "sources": {
+    "test2": {
+      "sling:resourceType": "test/conf",
+      "sling:resourceSuperType": "test/static",
+      "jcr:title": "Test-2"
+    }
   }
 }
\ No newline at end of file
diff --git a/org.apache.sling.ddr/core/src/test/resources/ddr-reference/ddr-apps-settings.json b/org.apache.sling.ddr/core/src/test/resources/ddr-reference/ddr-apps-settings.json
index f57fd00..d58f450 100644
--- a/org.apache.sling.ddr/core/src/test/resources/ddr-reference/ddr-apps-settings.json
+++ b/org.apache.sling.ddr/core/src/test/resources/ddr-reference/ddr-apps-settings.json
@@ -16,6 +16,16 @@
       "child": {
         "sling:resourceType": "sling:Folder",
         "jcr:title": "Child-1",
+        "jcr:description": "child reference"
+      }
+    },
+    "withGrandChild": {
+      "sling:resourceType": "sling:Folder",
+      "jcr:title": "With-Grand-Child-1",
+      "jcr:description": "with grandchild reference",
+      "child": {
+        "sling:resourceType": "sling:Folder",
+        "jcr:title": "Child-1",
         "jcr:description": "child reference",
         "grandChild": {
           "sling:resourceType": "sling:Folder",
diff --git a/org.apache.sling.ddr/core/src/test/resources/ddr-reference/ddr-conf-settings.json b/org.apache.sling.ddr/core/src/test/resources/ddr-reference/ddr-conf-settings.json
index ee2843a..7febc22 100644
--- a/org.apache.sling.ddr/core/src/test/resources/ddr-reference/ddr-conf-settings.json
+++ b/org.apache.sling.ddr/core/src/test/resources/ddr-reference/ddr-conf-settings.json
@@ -26,6 +26,13 @@
           "sling:resourceSuperType": "test/static",
           "jcr:title": "Ref-With-Child-1",
           "sling:ddrRef": "/apps/references/withChild"
+        },
+        "refWithGrandChild": {
+          "jcr:primaryType": "sling:Folder",
+          "sling:resourceType": "test/refWithGrandChild",
+          "sling:resourceSuperType": "test/static",
+          "jcr:title": "Ref-With-Grand-Child-1",
+          "sling:ddrRef": "/apps/references/withGrandChild"
         }
       }
     }