/*
 * 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 SF 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.resourceresolver.impl;

import static org.apache.sling.resourceresolver.util.MockTestUtil.getResourceName;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.apache.sling.resourceresolver.impl.mapping.MapEntries;
import org.apache.sling.resourceresolver.impl.observation.ResourceChangeListenerWhiteboard;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderInfo;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
import org.apache.sling.serviceusermapping.ServiceUserMapper;
import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
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.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceReference;

/**
 * This tests the ResourceResolver using mocks. The Unit test is in addition to
 * ResourceResolverImplTest which covers API conformance more than it covers all
 * code paths.
 */
// TODO: Configure mapping to react correctly.
// TODO: test external redirect.
// TODO: Map to URI
// TODO: Statresource
public class MockedResourceResolverImplTest {

    private static final List<Resource> EMPTY_RESOURCE_LIST = new ArrayList<Resource>();
    private static final String FAKE_QUERY_LANGUAGE = "fake";
    private static final String PATH = "path";

    private ResourceResolverFactoryActivator activator;

    private List<ResourceProviderHandler> handlers = new ArrayList<ResourceProviderHandler>();

    @Mock
    private BundleContext bundleContext;

    @Mock
    private Bundle usingBundle;

    @Mock
    private BundleContext usingBundleContext;

    @Mock
    private ResourceProviderTracker resourceProviderTracker;

    @Mock
    private ResourceChangeListenerWhiteboard resourceChangeListenerWhiteboard;

    @SuppressWarnings("rawtypes")
    @Mock
    private QueryLanguageProvider queryProvider;

    private Map<String, Object> services = new HashMap<String, Object>();

    private Map<String, Object> serviceProperties = new HashMap<String, Object>();

    private ResourceResolverFactoryImpl resourceResolverFactory;

    @Mock
    private ResourceProvider<?> resourceProvider;

    /**
     * deals with /etc resolution.
     */
    @Mock
    private ResourceProvider<?> mappingResourceProvider;

    /**
     * deals with /apps and /libs resolution.
     */
    @Mock
    private ResourceProvider<?> appsResourceProvider;

    /**
     * QueriableResourceProviders
     */
    @Mock
    private ResourceProvider<?> queriableResourceProviderA;


    public MockedResourceResolverImplTest() {
        MockitoAnnotations.initMocks(this);
    }

    @SuppressWarnings("unchecked")
    @Before
    public void before() throws LoginException {
        activator = new ResourceResolverFactoryActivator();

        // system bundle access
        final Bundle systemBundle = Mockito.mock(Bundle.class);
        Mockito.when(systemBundle.getState()).thenReturn(Bundle.ACTIVE);
        Mockito.when(bundleContext.getBundle(Constants.SYSTEM_BUNDLE_LOCATION)).thenReturn(systemBundle);
        activator.resourceAccessSecurityTracker = new ResourceAccessSecurityTracker();
        activator.resourceProviderTracker = resourceProviderTracker;
        activator.changeListenerWhiteboard = resourceChangeListenerWhiteboard;
        activator.serviceUserMapper = Mockito.mock(ServiceUserMapper.class);
        handlers.add(createRPHandler(resourceProvider, "org.apache.sling.resourceresolver.impl.DummyTestProvider", 10L, "/"));

        // setup mapping resources at /etc/map to exercise vanity etc.
        // hmm, can't provide the resolver since its not up and ready.
        // mapping almost certainly work properly until this can be setup correctly.
        buildMappingResource("/etc/map", mappingResourceProvider, null);

        handlers.add(createRPHandler(mappingResourceProvider, "org.apache.sling.resourceresolver.impl.MapProvider", 11L, "/etc"));
        handlers.add(createRPHandler(appsResourceProvider, "org.apache.sling.resourceresolver.impl.AppsProvider", 12L, "/libs"));
        handlers.add(createRPHandler(appsResourceProvider, "org.apache.sling.resourceresolver.impl.AppsProvider", 13L, "/apps"));
        handlers.add(createRPHandler(queriableResourceProviderA, "org.apache.sling.resourceresolver.impl.QueriableResourceProviderA", 14L, "/searchA"));
        Mockito.when(queriableResourceProviderA.getQueryLanguageProvider()).thenReturn(queryProvider);

        ResourceProviderStorage storage = new ResourceProviderStorage(handlers);

        Mockito.when(resourceProviderTracker.getResourceProviderStorage()).thenReturn(storage);

        // activate the components.
        activator.activate(bundleContext, new ResourceResolverFactoryConfig() {
            @Override
            public Class<? extends Annotation> annotationType() {
                return null;
            }

            @Override
            public String[] resource_resolver_virtual() {
                return new String[] {"/:/"};
            }

            @Override
            public String[] resource_resolver_vanitypath_whitelist() {
                return null;
            }

            @Override
            public boolean resource_resolver_vanitypath_maxEntries_startup() {
                return true;
            }

            @Override
            public int resource_resolver_vanitypath_maxEntries() {
                return -1;
            }

            @Override
            public int resource_resolver_vanitypath_bloomfilter_maxBytes() {
                return 1024000;
            }

            @Override
            public String[] resource_resolver_vanitypath_blacklist() {
                return null;
            }

            @Override
            public boolean resource_resolver_vanity_precedence() {
                return false;
            }

            @Override
            public String[] resource_resolver_searchpath() {
                return new String[] {"/apps", "/libs"};
            }

            @Override
            public String[] resource_resolver_required_providers() {
                return  new String[] { "org.apache.sling.resourceresolver.impl.DummyTestProvider" };
            }

            @Override
            public String[] resource_resolver_required_providernames() {
                return null;
            }

            @Override
            public boolean resource_resolver_providerhandling_paranoid() {
                return false;
            }

            @Override
            public boolean resource_resolver_optimize_alias_resolution() {
                return true;
            }

            @Override
            public String[] resource_resolver_mapping() {
                return new String[] { "/:/",
                        "/content/:/", "/system/docroot/:/", "/content.html-/$" };
            }

            @Override
            public String[] resource_resolver_map_observation() {
                return new String[] {"/"};
            }

            @Override
            public String resource_resolver_map_location() {
                return MapEntries.DEFAULT_MAP_ROOT;
            }

            @Override
            public boolean resource_resolver_manglenamespaces() {
                return true;
            }

            @Override
            public boolean resource_resolver_log_closing() {
                return false;
            }

            @Override
            public boolean resource_resolver_enable_vanitypath() {
                return true;
            }

            @Override
            public int resource_resolver_default_vanity_redirect_status() {
                return 302;
            }

            @Override
            public boolean resource_resolver_allowDirect() {
                return true;
            }

            @Override
            public boolean resource_resolver_log_unclosed() {
                return true;
            }
        });

        // configure using Bundle
        Mockito.when(usingBundle.getBundleContext()).thenReturn(usingBundleContext);
        Mockito.when(usingBundleContext.getBundle()).thenReturn(usingBundle);

        // extract any services that were registered into a map.
        ArgumentCaptor<Class> classesCaptor = ArgumentCaptor.forClass(Class.class);
        ArgumentCaptor<ServiceFactory> serviceCaptor = ArgumentCaptor.forClass(ServiceFactory.class);
        @SuppressWarnings("rawtypes")
        ArgumentCaptor<Dictionary> propertiesCaptor = ArgumentCaptor.forClass(Dictionary.class);
        Mockito.verify(bundleContext, Mockito.atLeastOnce()).registerService(
            (Class<ResourceResolverFactory>)classesCaptor.capture(), (ServiceFactory<ResourceResolverFactory>)serviceCaptor.capture(),
            propertiesCaptor.capture());

        int si = 0;
        List<ServiceFactory> serviceList = serviceCaptor.getAllValues();
        @SuppressWarnings({ "unused", "rawtypes" })
        List<Dictionary> servicePropertiesList = propertiesCaptor.getAllValues();
        for (Class serviceClass : classesCaptor.getAllValues()) {
            services.put(serviceClass.getName(), serviceList.get(si));
            serviceProperties.put(serviceClass.getName(), serviceProperties.get(si));
            si++;
        }
        // verify that a ResourceResolverFactoryImpl was created and registered.
        Assert.assertNotNull("" + services, services.get(ResourceResolverFactory.class.getName()));
        Object rrf = services.get(ResourceResolverFactory.class.getName());
        if (rrf instanceof ServiceFactory) {
            rrf = ((ServiceFactory) rrf).getService(usingBundle, null);
        }
        Assert.assertTrue(rrf instanceof ResourceResolverFactoryImpl);
        resourceResolverFactory = (ResourceResolverFactoryImpl) rrf;
    }

    public static ResourceProviderHandler createRPHandler(ResourceProvider<?> rp, String pid, long ranking,
            String path) {
        ServiceReference ref = Mockito.mock(ServiceReference.class);
        BundleContext bc = Mockito.mock(BundleContext.class);
        Mockito.when(bc.getService(Mockito.eq(ref))).thenReturn(rp);
        Mockito.when(ref.getProperty(Mockito.eq(Constants.SERVICE_ID))).thenReturn(new Random().nextLong());
        Mockito.when(ref.getProperty(Mockito.eq(Constants.SERVICE_PID))).thenReturn(pid);
        Mockito.when(ref.getProperty(Mockito.eq(Constants.SERVICE_RANKING))).thenReturn(ranking);
        Mockito.when(ref.getProperty(Mockito.eq(ResourceProvider.PROPERTY_ROOT))).thenReturn(path);
        Mockito.when(ref.getProperty(Mockito.eq(ResourceProvider.PROPERTY_MODIFIABLE))).thenReturn(true);
        Mockito.when(ref.getProperty(Mockito.eq(ResourceProvider.PROPERTY_ATTRIBUTABLE))).thenReturn(true);
        Mockito.when(ref.getProperty(Mockito.eq(ResourceProvider.PROPERTY_ADAPTABLE))).thenReturn(true);

        ResourceProviderInfo info = new ResourceProviderInfo(ref);
        final ResourceProviderHandler handler = new ResourceProviderHandler(bc, info);
        handler.activate();
        return handler;
    }

    @SuppressWarnings("unchecked")
    private Resource buildMappingResource(String path,
            ResourceProvider<?> provider, ResourceResolver resourceResolver) {
        List<Resource> localHostAnyList = new ArrayList<Resource>();
        localHostAnyList.add(buildResource(path+"/http/example.com.80/cgi-bin", EMPTY_RESOURCE_LIST, resourceResolver, provider, "sling:internalRedirect", "/scripts" ));
        localHostAnyList.add(buildResource(path+"/http/example.com.80/gateway", EMPTY_RESOURCE_LIST, resourceResolver, provider,"sling:internalRedirect", "http://gbiv.com"));
        localHostAnyList.add(buildResource(path+"/http/example.com.80/stories", EMPTY_RESOURCE_LIST, resourceResolver, provider,"sling:internalRedirect", "/anecdotes/$1"));

        List<Resource> mappingChildren = new ArrayList<Resource>();
        mappingChildren.add(buildResource(path+"/http/example.com.80", EMPTY_RESOURCE_LIST, resourceResolver, provider,"sling:redirect", "http://www.example.com/"));
        mappingChildren.add(buildResource(path+"/http/www.example.com.80", EMPTY_RESOURCE_LIST, resourceResolver, provider,"sling:internalRedirect", "/example"));
        mappingChildren.add(buildResource(path+"/http/any_example.com.80", EMPTY_RESOURCE_LIST, resourceResolver, provider,"sling:match", ".+\\.example\\.com\\.80", "sling:redirect", "http://www.example.com/"));
        mappingChildren.add(buildResource(path+"/http/localhost_any", localHostAnyList, resourceResolver, provider,"sling:match", "localhost\\.\\d*", "sling:internalRedirect", "/content"));

        Resource etcMapResource = buildResource(path+"/http", mappingChildren);
        Mockito.when(provider.getResource(Mockito.any(ResolveContext.class), Mockito.eq(path), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(etcMapResource);
        return etcMapResource;
    }

    @After
    public void after() {
        handlers.clear();
    }

    /**
     * build child resources as an iterable of resources.
     * @param parent
     * @return
     */
    private Iterable<Resource> buildChildResources(String parent) {
        List<Resource> mappingResources = new ArrayList<Resource>();
        for ( int i = 0; i < 5; i++ ) {
            mappingResources.add(buildResource(parent+"/m"+i, EMPTY_RESOURCE_LIST));
        }
        return mappingResources;
    }
    /**
     * Build a resource based on path and children.
     * @param fullpath
     * @param children
     * @return
     */
    private Resource buildResource(String fullpath, Iterable<Resource> children) {
        return buildResource(fullpath, children, null, null, new String[0]);
    }

    /** Build a List of ValueMap */
    private List<ValueMap> buildValueMapCollection(int howMany, String pathPrefix) {
        final List<ValueMap> result = new ArrayList<ValueMap>();
        for(int i=0;  i < howMany; i++) {
            final Map<String, Object> m = new HashMap<String, Object>();
            m.put(PATH, pathPrefix + i);
            result.add(new ValueMapDecorator(m));
        }
        return result;
    }

    /**
     * Build a resource with path, children and resource resolver.
     * @param fullpath
     * @param children
     * @param resourceResolver
     * @return
     */
    @SuppressWarnings("unchecked")
    private Resource buildResource(String fullpath, Iterable<Resource> children, ResourceResolver resourceResolver, ResourceProvider<?> provider, String ... properties) {
        Resource resource = Mockito.mock(Resource.class);
        Mockito.when(resource.getName()).thenReturn(getResourceName(fullpath));
        Mockito.when(resource.getPath()).thenReturn(fullpath);
        ResourceMetadata resourceMetadata = new ResourceMetadata();
        Mockito.when(resource.getResourceMetadata()).thenReturn(resourceMetadata);
        Mockito.when(resource.listChildren()).thenReturn(children.iterator());
        Mockito.when(resource.getResourceResolver()).thenReturn(resourceResolver);

        // register the resource with the provider
        if ( provider != null ) {
            Mockito.when(provider.listChildren(Mockito.any(ResolveContext.class), Mockito.eq(resource))).thenReturn(children.iterator());
            Mockito.when(provider.getResource(Mockito.any(ResolveContext.class), Mockito.eq(fullpath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(resource);
        }
        if ( properties != null ) {
            ValueMap vm = new SimpleValueMapImpl();
            for ( int i=0; i < properties.length; i+=2) {
                resourceMetadata.put(properties[i], properties[i+1]);
                vm.put(properties[i], properties[i+1]);
            }
            Mockito.when(resource.getValueMap()).thenReturn(vm);
            Mockito.when(resource.adaptTo(Mockito.eq(ValueMap.class))).thenReturn(vm);
        } else {
            Mockito.when(resource.getValueMap()).thenReturn(ValueMapDecorator.EMPTY);
            Mockito.when(resource.adaptTo(Mockito.eq(ValueMap.class))).thenReturn(ValueMapDecorator.EMPTY);
        }

        return resource;
    }

    /**
     * Test getting a resolver.
     * @throws LoginException
     */
    @Test
    public void testGetResolver() throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
        Assert.assertNotNull(resourceResolver);
        Map<String, Object> authenticationInfo = new HashMap<String, Object>();
        resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(authenticationInfo);
        Assert.assertNotNull(resourceResolver);
    }

    /**
     * Misceleneous coverage.
     * @throws LoginException
     */
    @Test
    public void testResolverMisc() throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
        try {
            resourceResolver.getAttribute(null);
            Assert.fail("Should have thrown a NPE");
        } catch ( NullPointerException e) {
            // this is expected.
        }
        Assert.assertArrayEquals(new String[]{"/apps/","/libs/"}, resourceResolver.getSearchPath());
    }

    /**
     * Test various administrative resource resolvers.
     * @throws LoginException
     */
    @Test
    public void testGetAuthenticatedResolve() throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
        Assert.assertNotNull(resourceResolver);
        Map<String, Object> authenticationInfo = new HashMap<String, Object>();

        resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(authenticationInfo);
        Assert.assertNotNull(resourceResolver);
    }

    /**
     * Test getResource for a resource provided by a resource provider.
     * @throws LoginException
     */
    @Test
    public void testGetResource() throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
        Assert.assertNotNull(resourceResolver);
        Resource singleResource = buildResource("/single/test", EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
        Resource resource = resourceResolver.getResource("/single/test");
        Assert.assertEquals(singleResource, resource);
    }

    /**
     * Test getResource where path contains intermediate . verifying fix for SLING-864
     * @throws LoginException
     */
    @Test
    public void testGetResourceSLING864() throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
        Assert.assertNotNull(resourceResolver);
        Resource singleResource = buildResource("/single/test.with/extra.dots/inthepath", EMPTY_RESOURCE_LIST,resourceResolver, resourceProvider);
        Resource resource = resourceResolver.getResource("/single/test.with/extra.dots/inthepath");
        Assert.assertEquals(singleResource, resource);
    }


    /**
     * Test search paths
     * @throws LoginException
     */
    @Test
    public void testRelativeResource() throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
        Assert.assertNotNull(resourceResolver);
        Resource appResource = buildResource("/apps/store/inventory", EMPTY_RESOURCE_LIST, resourceResolver, appsResourceProvider);
        Resource libResource = buildResource("/libs/store/catalog", EMPTY_RESOURCE_LIST, resourceResolver, appsResourceProvider);
        Resource testResource = resourceResolver.getResource("store/inventory");
        Assert.assertEquals(appResource, testResource);
        testResource = resourceResolver.getResource("store/catalog");
        Assert.assertEquals(libResource, testResource);
    }

    /**
     * Basic test of mapping functionality, at the moment needs more
     * configuration in the virtual /etc/map.
     *
     * @throws LoginException
     */
    @Test
    public void testMapping() throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
        buildResource("/single/test", EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
        HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
        Mockito.when(request.getScheme()).thenReturn("http");
        Mockito.when(request.getServerPort()).thenReturn(80);
        Mockito.when(request.getServerName()).thenReturn("localhost");
        String path = resourceResolver.map(request,"/single/test?q=123123");
        Assert.assertEquals("/single/test?q=123123", path);
        buildResource("/single/test", EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
        path = resourceResolver.map(request,"/single/test");
        Assert.assertEquals("/single/test", path);

        buildResource("/single/test", EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
        // test path mapping without a request.
        path = resourceResolver.map("/single/test");
        Assert.assertEquals("/single/test", path);

        buildResource("/content", EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
        path = resourceResolver.map("/content.html");
        Assert.assertEquals("/content.html", path);

        path = resourceResolver.map(request,"some/relative/path/test");
        Assert.assertEquals("some/relative/path/test", path);
      
        buildResource("/", EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
        buildResource("/single", EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
        buildResource("/single/test", EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
        path = resourceResolver.map("/single//test.html");
        Assert.assertEquals("/single/test.html", path);
    }


    /**
     * Tests list children via the resource (NB, this doesn't really test the
     * resource resolver at all, but validates this unit test.)
     *
     * @throws LoginException
     */
    @Test
    public void testListChildren() throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
        buildResource("/single/test/withchildren", buildChildResources("/single/test/withchildren"), resourceResolver, resourceProvider );


        Resource resource = resourceResolver.getResource("/single/test/withchildren");
        Assert.assertNotNull(resource);

        // test via the resource list children itself, this really just tests this test case.
        Iterator<Resource> resourceIterator = resource.listChildren();
        Assert.assertNotNull(resourceResolver);
        int i = 0;
        while(resourceIterator.hasNext()) {
            Assert.assertEquals("m"+i, resourceIterator.next().getName());
            i++;
        }
        Assert.assertEquals(5, i);
    }

    /**
     * Test listing children via the resource resolver listChildren call.
     * @throws LoginException
     */
    @Test
    public void testResourceResolverListChildren() throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
        buildResource("/single/test/withchildren", buildChildResources("/single/test/withchildren"), resourceResolver, resourceProvider);


        Resource resource = resourceResolver.getResource("/single/test/withchildren");
        Assert.assertNotNull(resource);

        // test via the resource list children itself, this really just tests this test case.
        Iterator<Resource> resourceIterator = resourceResolver.listChildren(resource);
        Assert.assertNotNull(resourceResolver);
        int i = 0;
        while(resourceIterator.hasNext()) {
            Assert.assertEquals("m"+i, resourceIterator.next().getName());
            i++;
        }
        Assert.assertEquals(5,i);
    }

    /**
     * Tests listing children via the resource resolver getChildren call.
     * @throws LoginException
     */
    @Test
    public void testResourceResolverGetChildren() throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
        buildResource("/single/test/withchildren", buildChildResources("/single/test/withchildren"), resourceResolver, resourceProvider);


        Resource resource = resourceResolver.getResource("/single/test/withchildren");
        Assert.assertNotNull(resource);

        // test via the resource list children itself, this really just tests this test case.
        Iterable<Resource> resourceIterator = resourceResolver.getChildren(resource);
        Assert.assertNotNull(resourceResolver);
        int i = 0;
        for(Resource r : resourceIterator) {
            Assert.assertEquals("m"+i, r.getName());
            i++;
        }
        Assert.assertEquals(5,i);
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testQueryResources() throws LoginException {
        final int n = 3;
        String[] languages = new String[] {FAKE_QUERY_LANGUAGE};
        Mockito.when(queryProvider.getSupportedLanguages(Mockito.any(ResolveContext.class))).thenReturn(languages);
        Mockito.when(queryProvider.queryResources(Mockito.any(ResolveContext.class), Mockito.any(String.class), Mockito.any(String.class)))
        .thenReturn(buildValueMapCollection(n, "A_").iterator());

        final ResourceResolver rr = resourceResolverFactory.getResourceResolver(null);
        buildResource("/search/test/withchildren", buildChildResources("/search/test/withchildren"), rr, resourceProvider);
        final Iterator<Map<String, Object>> it = rr.queryResources("/search", FAKE_QUERY_LANGUAGE);
        final Set<String> toFind = new HashSet<String>();
        for(int i=0; i < n; i++) {
            toFind.add("A_" + i);
        }

        assertTrue("Expecting non-empty result (" + n + ")", it.hasNext());
        while(it.hasNext()) {
            final Map<String, Object> m = it.next();
            toFind.remove(m.get(PATH));
        }
        assertTrue("Expecting no leftovers (" + n + ") in" + toFind, toFind.isEmpty());
    }

    @Test public void test_versions() throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);

        Resource resource = resourceResolver.resolve("/content/test.html;v=1.0");
        Map<String, String> parameters = resource.getResourceMetadata().getParameterMap();
        assertEquals("/content/test.html", resource.getPath());
        assertEquals("test.html", resource.getName());
        assertEquals(Collections.singletonMap("v", "1.0"), parameters);

        resource = resourceResolver.resolve("/content/test;v='1.0'.html");
        parameters = resource.getResourceMetadata().getParameterMap();
        assertEquals("/content/test.html", resource.getPath());
        assertEquals("test.html", resource.getName());
        assertEquals(Collections.singletonMap("v", "1.0"), parameters);

        buildResource("/single/test/withchildren", buildChildResources("/single/test/withchildren"), resourceResolver, resourceProvider);
        resource = resourceResolver.getResource("/single/test/withchildren;v='1.0'");
        assertNotNull(resource);
        assertEquals("/single/test/withchildren", resource.getPath());
        assertEquals("withchildren", resource.getName());
    }
}
