SLING-6710 : Vanity Path might get removed if a resource is updated

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/resourceresolver@1788498 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
index 3308db2..c0d44b2 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
@@ -57,6 +57,8 @@
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.resource.observation.ResourceChange;
+import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
 import org.apache.sling.api.resource.path.Path;
 import org.apache.sling.api.wrappers.ValueMapDecorator;
 import org.apache.sling.resourceresolver.impl.ResourceResolverImpl;
@@ -297,6 +299,78 @@
 
     }
 
+    @Test
+    public void test_vanity_path_updates() throws Exception {
+        Resource parent = mock(Resource.class, "parent");
+        when(parent.getPath()).thenReturn("/foo/parent");
+        when(parent.getName()).thenReturn("parent");
+        when(parent.getValueMap()).thenReturn(new ValueMapDecorator(Collections.<String, Object>emptyMap()));
+        when(resourceResolver.getResource(parent.getPath())).thenReturn(parent);
+
+        Resource child = mock(Resource.class, "jcrcontent");
+        when(child.getPath()).thenReturn("/foo/parent/jcr:content");
+        when(child.getName()).thenReturn("jcr:content");
+        when(child.getValueMap()).thenReturn(buildValueMap("sling:vanityPath", "/target/found"));
+        when(child.getParent()).thenReturn(parent);
+        when(parent.getChild(child.getName())).thenReturn(child);
+        when(resourceResolver.getResource(child.getPath())).thenReturn(child);
+
+        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
+
+            @Override
+            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
+                return Collections.<Resource> emptySet().iterator();
+            }
+        });
+
+        mapEntries.doInit();
+        mapEntries.initializeVanityPaths();
+
+        // map entries should have no alias atm
+        assertTrue( mapEntries.getResolveMaps().isEmpty());
+
+        // add parent
+        mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.ADDED, parent.getPath(), false)));
+        assertTrue( mapEntries.getResolveMaps().isEmpty());
+
+        // add child
+        mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.ADDED, child.getPath(), false)));
+
+        // two entries for the vanity path
+        List<MapEntry> entries = mapEntries.getResolveMaps();
+        assertEquals(2, entries.size());
+        for (MapEntry entry : entries) {
+            assertTrue(entry.getPattern().contains("/target/found"));
+        }
+
+        // update parent - no change
+        mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.CHANGED, parent.getPath(), false)));
+        entries = mapEntries.getResolveMaps();
+        assertEquals(2, entries.size());
+        for (MapEntry entry : entries) {
+            assertTrue(entry.getPattern().contains("/target/found"));
+        }
+
+        // update child - no change
+        mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.CHANGED, child.getPath(), false)));
+        entries = mapEntries.getResolveMaps();
+        assertEquals(2, entries.size());
+        for (MapEntry entry : entries) {
+            assertTrue(entry.getPattern().contains("/target/found"));
+        }
+
+        // remove child - empty again
+        when(resourceResolver.getResource(child.getPath())).thenReturn(null);
+        when(parent.getChild(child.getName())).thenReturn(null);
+        mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.REMOVED, child.getPath(), false)));
+        assertTrue( mapEntries.getResolveMaps().isEmpty());
+
+        // remove parent - still empty
+        when(resourceResolver.getResource(parent.getPath())).thenReturn(null);
+        mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.REMOVED, parent.getPath(), false)));
+        assertTrue( mapEntries.getResolveMaps().isEmpty());
+    }
+
     private ValueMap buildValueMap(Object... string) {
         final Map<String, Object> data = new HashMap<>();
         for (int i = 0; i < string.length; i = i + 2) {