Package org.geoserver.wfs.v2_0

Source Code of org.geoserver.wfs.v2_0.GetFeaturePagingTest

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wfs.v2_0;

import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.custommonkey.xmlunit.XMLAssert;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogBuilder;
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.ows.util.KvpMap;
import org.geotools.data.DataStore;
import org.geotools.data.FeatureSource;
import org.geotools.data.FeatureStore;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.filter.v2_0.FESConfiguration;
import org.geotools.xml.Parser;
import org.junit.Test;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory;
import org.opengis.filter.Id;
import org.opengis.filter.identity.Identifier;
import org.w3c.dom.Document;

public class GetFeaturePagingTest extends WFS20TestSupport {

    @Override
    protected void setUpInternal(SystemTestData data) throws Exception {
        //run all the tests against a store that can do native paging (h2) and one that
        // can't (property)
        Catalog cat = getCatalog();
        DataStoreInfo ds = cat.getFactory().createDataStore();
        ds.setName("foo");
        ds.setWorkspace(cat.getDefaultWorkspace());
       
        Map params = ds.getConnectionParameters();
        params.put("dbtype", "h2");
        params.put("database", getTestData().getDataDirectoryRoot().getAbsolutePath());
        cat.add(ds);
       
        FeatureSource fs1 = getFeatureSource(SystemTestData.FIFTEEN);
        FeatureSource fs2 = getFeatureSource(SystemTestData.SEVEN);
       
        DataStore store = (DataStore) ds.getDataStore(null);
        SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
       
        tb.init((SimpleFeatureType) fs1.getSchema());
        tb.add("num", Integer.class);
        tb.remove("boundedBy");
        store.createSchema(tb.buildFeatureType());
       
        tb.init((SimpleFeatureType) fs2.getSchema());
        tb.add("num", Integer.class);
        tb.remove("boundedBy");
        store.createSchema(tb.buildFeatureType());
       
        CatalogBuilder cb = new CatalogBuilder(cat);
        cb.setStore(ds);
       
        FeatureStore fs = (FeatureStore) store.getFeatureSource("Fifteen");
        addFeatures(fs, fs1.getFeatures());
       
        FeatureTypeInfo ft = cb.buildFeatureType(fs);
        cat.add(ft);
       
        fs = (FeatureStore) store.getFeatureSource("Seven");
        addFeatures(fs, fs2.getFeatures());
       
        ft = cb.buildFeatureType(fs);
        cat.add(ft);
    }

    void addFeatures(FeatureStore fs, FeatureCollection features) throws Exception {
        SimpleFeatureBuilder b = new SimpleFeatureBuilder((SimpleFeatureType) fs.getSchema());
       
        DefaultFeatureCollection toAdd = new DefaultFeatureCollection(null, null);
        FeatureIterator it = features.features();
        try {
            SimpleFeature f = null;
            int i = 0;
            while(it.hasNext()) {
                f = (SimpleFeature) it.next();
                b.init(f);
                b.add(f.getAttribute("pointProperty"));
                b.add(i++);
                toAdd.add(b.buildFeature(null));
            }
        }
        finally {
            it.close();
        }
        fs.addFeatures(toAdd);
    }
   
    @Test
    public void testSingleType() throws Exception {
        doTestSingleType("gs:Fifteen");
        doTestSingleType("cdf:Fifteen");
    }
   
    void doTestSingleType(String typeName) throws Exception {
       
        Document doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
            "typename=" + typeName + "&startIndex=10");
        XMLAssert.assertXpathEvaluatesTo("5", "count(//" + typeName + ")", doc);
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&startIndex=16");
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + typeName + ")", doc);
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&startIndex=0");
        XMLAssert.assertXpathEvaluatesTo("15", "count(//" + typeName + ")", doc);
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&startIndex=1&count=1");
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + typeName + ")", doc);
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&startIndex=16&count=1");
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + typeName + ")", doc);
    }
   
    @Test
    public void testStartIndexSimplePOST() throws Exception {
        doTestStartIndexSimplePOST("gs:Fifteen");
        doTestStartIndexSimplePOST("cdf:Fifteen");
    }
   
    void doTestStartIndexSimplePOST(String typeName) throws Exception {
       
        Document doc = postAsDOM("wfs", startIndexSimpleXML(typeName, 10,-1));
        XMLAssert.assertXpathEvaluatesTo("5", "count(//" + typeName + ")", doc);
   
        doc = postAsDOM("wfs", startIndexSimpleXML(typeName, 16,-1));
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + typeName + ")", doc);
       
        doc = postAsDOM("wfs", startIndexSimpleXML(typeName, 0,-1));
        XMLAssert.assertXpathEvaluatesTo("15", "count(//" + typeName + ")", doc);
       
        doc = postAsDOM("wfs", startIndexSimpleXML(typeName, 1,1));
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + typeName + ")", doc);
       
        doc = postAsDOM("wfs", startIndexSimpleXML(typeName, 16, 1));
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + typeName + ")", doc);
    }

    String startIndexSimpleXML(String typeName, int startIndex, int count) {
        String xml =
        "<GetFeature version='2.0.0'";
       
        if (startIndex > -1) {
            xml += " startIndex='"+startIndex+"'";
        }
       
        if (count > -1) {
            xml += " count='" + count + "'";
        }
        xml += ">" +
        " <Query typeNames='" + typeName + "'>" +
        " </Query>" +
        "</GetFeature>";
        return xml;
    }
   
    @Test
    public void testStartIndexMultipleTypes() throws Exception {
        doTestStartIndexMultipleTypes("gs:Fifteen", "gs:Seven");
        doTestStartIndexMultipleTypes("cdf:Fifteen", "cdf:Seven");
        //doTestStartIndexMultipleTypes("gs:Fifteen", "cdf:Seven");
        //doTestStartIndexMultipleTypes("cdf:Fifteen", "gs:Seven");
    }
   
    public void doTestStartIndexMultipleTypes(String fifteen, String seven) throws Exception {
        String typeNames = fifteen+","+seven;
        Document doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
            "typename=" + typeNames + "&startIndex=10");
        XMLAssert.assertXpathEvaluatesTo("5", "count(//" + fifteen + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("7", "count(//" + seven + ")", doc);

        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeNames + "&startIndex=16");
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + fifteen + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("6", "count(//" + seven + ")", doc);
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeNames + "&startIndex=10&count=5");
        XMLAssert.assertXpathEvaluatesTo("5", "count(//" + fifteen + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + seven + ")", doc);
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeNames + "&startIndex=10&count=6");
        XMLAssert.assertXpathEvaluatesTo("5", "count(//" + fifteen + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + seven + ")", doc);
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeNames + "&startIndex=25");
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + fifteen + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + seven + ")", doc);
    }
   
    @Test
    public void testStartIndexMultipleTypesPOST() throws Exception {
        doTestStartIndexMultipleTypesPOST("gs:Fifteen", "gs:Seven");
        doTestStartIndexMultipleTypesPOST("cdf:Fifteen", "cdf:Seven");
        //doTestStartIndexMultipleTypesPOST("gs:Fifteen", "cdf:Seven");
        //doTestStartIndexMultipleTypesPOST("cdf:Fifteen", "gs:Seven");
    }
   
    public void doTestStartIndexMultipleTypesPOST(String fifteen, String seven) throws Exception {
        Document doc = postAsDOM("wfs", startIndexMultiXML(fifteen, seven, 10, -1));
        XMLAssert.assertXpathEvaluatesTo("5", "count(//" + fifteen + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("7", "count(//" + seven + ")", doc);

        doc = postAsDOM("wfs", startIndexMultiXML(fifteen, seven, 16, -1));
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + fifteen + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("6", "count(//" + seven + ")", doc);
       
        doc = postAsDOM("wfs", startIndexMultiXML(fifteen, seven, 10, 5));
        XMLAssert.assertXpathEvaluatesTo("5", "count(//" + fifteen + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + seven + ")", doc);
       
        doc = postAsDOM("wfs", startIndexMultiXML(fifteen, seven, 10, 6));
        XMLAssert.assertXpathEvaluatesTo("5", "count(//" + fifteen + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + seven + ")", doc);
       
        doc = postAsDOM("wfs", startIndexMultiXML(fifteen, seven, 25, -1));
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + fifteen + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + seven + ")", doc);
    }
   
    String startIndexMultiXML(String fifteen, String seven, int startIndex, int count) {
        String xml =
        "<GetFeature version=\"2.0.0\" startIndex='"+startIndex+"'";
        if (count > -1) {
            xml += " count='" + count + "'";
        }
        xml += ">" +
        " <Query typeNames='" + fifteen + "'>" +
        " </Query>" +
        " <Query typeNames='" + seven + "'>" +
        " </Query>" +
        "</GetFeature>";
        return xml;
    }
   
    @Test
    public void testWithFilter() throws Exception {
        doTestWithFilter("gs:Fifteen");
        doTestWithFilter("cdf:Fifteen");
    }
   
    public void doTestWithFilter(String typeName) throws Exception {
        Document doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
            "typename=" + typeName + "&startIndex=10");
        XMLAssert.assertXpathEvaluatesTo("5", "count(//" + typeName + ")", doc);
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
            "typename=" + typeName + "&startIndex=10&count=4");
        XMLAssert.assertXpathEvaluatesTo("4", "count(//" + typeName + ")", doc);
       
        String xml = String.format("<GetFeature version='2.0.0' " +
            "startIndex='%d' count='%d'>" +
            "<Query typeNames = '%s'/>" +
            "</GetFeature>", 10, 100, typeName);
       
        doc = postAsDOM("wfs", xml);
        XMLAssert.assertXpathEvaluatesTo("5", "count(//" + typeName + ")", doc);
       
        xml = String.format("<GetFeature version='2.0.0' xmlns:gml='http://www.opengis.net/gml/2.0' " +
            "xmlns:fes='http://www.opengis.net/fes/2.0' startIndex='%d' count='%d'>" +
            "<Query typeNames = '%s'>" +
            "  <fes:Filter>" +
            "   <fes:ResourceId rid='%s'></fes:ResourceId>" +
            "   <fes:ResourceId rid='%s'></fes:ResourceId>" +
            "   <fes:ResourceId rid='%s'></fes:ResourceId>" +
            "  </fes:Filter>" +
            "</Query>"+
            "</GetFeature>", 1, 100, typeName, "Fifteen.3", "Fifteen.4", "Fifteen.5");
           
        doc = postAsDOM("wfs", xml);

        XMLAssert.assertXpathEvaluatesTo("2", "count(//" + typeName + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("0", "count(//" + typeName + "[@gml:id='Fifteen.3'])", doc);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + typeName + "[@gml:id='Fifteen.4'])", doc);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + typeName + "[@gml:id='Fifteen.5'])", doc);
    }

    @Test
    public void testNextPreviousGET() throws Exception {
        doTestNextPreviousGET("gs:Fifteen");
        doTestNextPreviousGET("cdf:Fifteen");
    }

    public void doTestNextPreviousGET(String typeName) throws Exception {
        Document doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&count=5");
        assertFalse(doc.getDocumentElement().hasAttribute("previous"));
        // Without startindex, results are not sorted and next would be inconsistent,
        // so next is not encoded. See GEOS-5085.
        assertFalse(doc.getDocumentElement().hasAttribute("next"));
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&startIndex=0&count=5");
        assertFalse(doc.getDocumentElement().hasAttribute("previous"));
        assertStartIndexCount(doc, "next", 5, 5);
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
            "typename=" + typeName + "&startIndex=5&count=7");
        assertStartIndexCount(doc, "previous", 0, 5);
        assertStartIndexCount(doc, "next", 12, 7);

        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&startIndex=12&count=7");
        assertStartIndexCount(doc, "previous", 5, 7);
        assertFalse(doc.getDocumentElement().hasAttribute("next"));

        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&startIndex=15");
        assertStartIndexCount(doc, "previous", 0, 15);
        assertFalse(doc.getDocumentElement().hasAttribute("next"));
    }
   
    public void doTestNextPreviousMultipleTypesGET(String fifteen, String seven) throws Exception {
        Document doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + fifteen + "&count=5");
        assertFalse(doc.getDocumentElement().hasAttribute("previous"));
        // Without startindex, results are not sorted and next would be inconsistent,
        // so next is not encoded. See GEOS-5085.
        assertFalse(doc.getDocumentElement().hasAttribute("next"));
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + fifteen + "&startIndex=0&count=5");
        assertFalse(doc.getDocumentElement().hasAttribute("previous"));
        assertStartIndexCount(doc, "next", 5, 5);

        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
            "typename=" + fifteen + "&startIndex=5&count=7");
        assertStartIndexCount(doc, "previous", 0, 5);
        assertStartIndexCount(doc, "next", 12, 3);

        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + seven + "&startIndex=15");
        assertStartIndexCount(doc, "previous", 0, 15);
        assertFalse(doc.getDocumentElement().hasAttribute("next"));
    }

    @Test
    public void testNextPreviousPOST() throws Exception {
        doTestNextPreviousPOST("gs:Fifteen");
        doTestNextPreviousPOST("cdf:Fifteen");
    }
   
    public void doTestNextPreviousPOST(String typeName) throws Exception {
       
        Document doc = postAsDOM("wfs", startIndexSimpleXML(typeName, -1, 5));
        assertFalse(doc.getDocumentElement().hasAttribute("previous"));
        // Without startindex, results are not sorted and next would be inconsistent,
        // so next is not encoded. See GEOS-5085.
        assertFalse(doc.getDocumentElement().hasAttribute("next"));
       
        doc = postAsDOM("wfs", startIndexSimpleXML(typeName, 0, 5));
        assertFalse(doc.getDocumentElement().hasAttribute("previous"));
        assertStartIndexCount(doc, "next", 5, 5);
       
        doc = postAsDOM("wfs", startIndexSimpleXML(typeName, 5, 7));
        assertStartIndexCount(doc, "previous", 0, 5);
        assertStartIndexCount(doc, "next", 12, 7);

        doc = postAsDOM("wfs", startIndexSimpleXML(typeName, 15, -1));
        assertStartIndexCount(doc, "previous", 0, 15);
        assertFalse(doc.getDocumentElement().hasAttribute("next"));
    }

    void assertStartIndexCount(Document doc, String att, int startIndex, int count) {
        String s = doc.getDocumentElement().getAttribute(att);
        String[] kvp = s.split("\\?")[1].split("&");
        int actualStartIndex = -1;
        int actualCount = -1;
       
        for (int i = 0; i < kvp.length; i++) {
            String k = kvp[i].split("=")[0];
            String v = kvp[i].split("=")[1];
            if ("startIndex".equalsIgnoreCase(k)) {
                actualStartIndex = Integer.parseInt(v);
            }
            if ("count".equalsIgnoreCase(k)) {
                actualCount = Integer.parseInt(v);
            }
        }
       
        assertEquals(startIndex, actualStartIndex);
        assertEquals(count, actualCount);
    }
   
    @Test
    public void testNextPreviousLinksPOST() throws Exception {
        doTestNextPreviousLinksPOST("gs:Fifteen");
    }
   
    public void doTestNextPreviousLinksPOST(String typeName) throws Exception {
        FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
        Filter filter = ff.id(new LinkedHashSet<Identifier>(Arrays.asList(ff.featureId("Fifteen.5"),
            ff.featureId("Fifteen.6"), ff.featureId("Fifteen.7"),ff.featureId("Fifteen.8"),ff.featureId("Fifteen.9"))));
       
        String xml = String.format("<GetFeature version='2.0.0' xmlns:gml='http://www.opengis.net/gml/2.0' " +
            "xmlns:fes='http://www.opengis.net/fes/2.0' startIndex='%d' count='%d'>" +
            "<Query typeNames = '%s'>" +
            "  <fes:Filter>" +
            "   <fes:ResourceId rid='%s'></fes:ResourceId>" +
            "   <fes:ResourceId rid='%s'></fes:ResourceId>" +
            "   <fes:ResourceId rid='%s'></fes:ResourceId>" +
            "   <fes:ResourceId rid='%s'></fes:ResourceId>" +
            "   <fes:ResourceId rid='%s'></fes:ResourceId>" +
            "  </fes:Filter>" +
            "</Query>"+
            "</GetFeature>", 0, 2, typeName, "Fifteen.5", "Fifteen.6", "Fifteen.7", "Fifteen.8", "Fifteen.9");
        Document doc = postAsDOM("wfs", xml);
        XMLAssert.assertXpathEvaluatesTo("2", "count(//" + typeName + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + typeName + "[@gml:id='Fifteen.5'])", doc);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + typeName + "[@gml:id='Fifteen.6'])", doc);
       
        assertFalse(doc.getDocumentElement().hasAttribute("previous"));
        assertTrue(doc.getDocumentElement().hasAttribute("next"));

        String next = doc.getDocumentElement().getAttribute("next");
        assertKvp(2, 2, typeName, filter, toKvpMap(next));

        doc = getAsDOM(next.substring(next.indexOf("wfs")));
        XMLAssert.assertXpathEvaluatesTo("2", "count(//" + typeName + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + typeName + "[@gml:id='Fifteen.7'])", doc);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + typeName + "[@gml:id='Fifteen.8'])", doc);

        assertTrue(doc.getDocumentElement().hasAttribute("previous"));
        assertTrue(doc.getDocumentElement().hasAttribute("next"));
       
        String prev = doc.getDocumentElement().getAttribute("previous");
        assertKvp(0, 2, typeName, filter, toKvpMap(prev));
       
        next = doc.getDocumentElement().getAttribute("next");
        assertKvp(4, 2, typeName, filter, toKvpMap(next));

        doc = getAsDOM(next.substring(next.indexOf("wfs")));
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + typeName + ")", doc);
        XMLAssert.assertXpathEvaluatesTo("1", "count(//" + typeName + "[@gml:id='Fifteen.9'])", doc);
       
        assertTrue(doc.getDocumentElement().hasAttribute("previous"));
        assertFalse(doc.getDocumentElement().hasAttribute("next"));
       
        prev = doc.getDocumentElement().getAttribute("previous");
        assertKvp(2, 2, typeName, filter, toKvpMap(prev));
    }

    void assertKvp(int startIndex, int count, String typeName, Filter filter, Map kvp) throws Exception {
        assertEquals(String.valueOf(startIndex), kvp.get("STARTINDEX"));
        assertEquals(String.valueOf(count), kvp.get("COUNT"));
        assertEquals("("+typeName+")", URLDecoder.decode((String)kvp.get("TYPENAMES")));
        assertNotNull(kvp.get("FILTER"));
       
        assertFilter(filter, URLDecoder.decode((String) kvp.get("FILTER")));
    }
   
    void assertFilter(Filter expected, String filter) throws Exception {
        filter = filter.substring(1, filter.length()-1);
        Filter f = (Filter)
                new Parser(new FESConfiguration()).parse(new ByteArrayInputStream(filter.getBytes()));
        if (expected instanceof Id) {
            Set s1 = new HashSet();
            for (Identifier id: ((Id) expected).getIdentifiers()) {
                s1.add(id.toString());
            }
            Set s2 = new HashSet();
            for (Identifier id: ((Id) f).getIdentifiers()) {
                s2.add(id.toString());
            }
            assertEquals(s1, s2);
        }
        else {
            assertEquals(expected, f);   
        }
       
    }
   
    KvpMap toKvpMap(String url) {
        url = url.substring(url.indexOf('?')+1);
        String[] kvps = url.split("\\&");
        KvpMap map = new KvpMap();
        for (String kvp : kvps) {
            map.put(kvp.split("=")[0], kvp.split("=")[1]);
        }
        return map;
    }
   
    @Test
    public void testSortingGET() throws Exception {
        Document dom = getAsDOM("wfs?service=WFS&version=2.0.0&request=GetFeature&typeName=gs:Fifteen&sortBy=num ASC&count=1");
        XMLAssert.assertXpathExists("//gs:Fifteen/gs:num[text() = '0']", dom);
       
        dom = getAsDOM("wfs?service=WFS&version=2.0.0&request=GetFeature&typeName=gs:Fifteen&sortBy=num DESC&count=1");
        XMLAssert.assertXpathExists("//gs:Fifteen/gs:num[text() = '14']", dom);
    }

    @Test
    public void testNextPreviousHitsGET() throws Exception {
        doTestNextPreviousHitsGET("gs:Fifteen");
        doTestNextPreviousHitsGET("cdf:Fifteen");
    }
   
    public void doTestNextPreviousHitsGET(String typeName) throws Exception {
        Document doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&count=5&resulttype=hits");
        assertFalse(doc.getDocumentElement().hasAttribute("previous"));
        // Without startindex, results are not sorted and next would be inconsistent,
        // so next is not encoded. See GEOS-5085.
        assertFalse(doc.getDocumentElement().hasAttribute("next"));
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&startIndex=0&count=5&resulttype=hits");
        assertFalse(doc.getDocumentElement().hasAttribute("previous"));
        assertStartIndexCount(doc, "next", 5, 5);
       
        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
            "typename=" + typeName + "&startIndex=5&count=7&resulttype=hits");
        assertStartIndexCount(doc, "previous", 0, 5);
        assertStartIndexCount(doc, "next", 12, 7);

        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&startIndex=12&count=7&resulttype=hits");
        assertStartIndexCount(doc, "previous", 5, 7);
        assertFalse(doc.getDocumentElement().hasAttribute("next"));

        doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=" + typeName + "&startIndex=15&resulttype=hits");
        assertStartIndexCount(doc, "previous", 0, 15);
        assertFalse(doc.getDocumentElement().hasAttribute("next"));
    }
   
    @Test
    public void testCountZero() throws Exception {
        Document doc = getAsDOM("/wfs?request=GetFeature&version=2.0.0&service=wfs&" +
                "typename=gs:Fifteen&count=0");
        XMLAssert.assertXpathExists("/wfs:FeatureCollection", doc);
        XMLAssert.assertXpathEvaluatesTo("0", "/wfs:FeatureCollection/@numberMatched", doc);
        XMLAssert.assertXpathEvaluatesTo("0", "/wfs:FeatureCollection/@numberReturned", doc);
    }

}
TOP

Related Classes of org.geoserver.wfs.v2_0.GetFeaturePagingTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.