/* (c) 2014 - 2015 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.wms.capabilities; import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo; import static org.junit.Assert.assertEquals; import java.io.IOException; import java.io.StringWriter; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.custommonkey.xmlunit.SimpleNamespaceContext; import org.custommonkey.xmlunit.XMLUnit; import org.custommonkey.xmlunit.XpathEngine; import org.custommonkey.xmlunit.exceptions.XpathException; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.Keyword; import org.geoserver.catalog.PublishedInfo; import org.geoserver.catalog.impl.CatalogImpl; import org.geoserver.config.ContactInfo; import org.geoserver.config.GeoServer; import org.geoserver.config.GeoServerInfo; import org.geoserver.config.impl.ContactInfoImpl; import org.geoserver.config.impl.GeoServerImpl; import org.geoserver.config.impl.GeoServerInfoImpl; import org.geoserver.wms.ExtendedCapabilitiesProvider; import org.geoserver.wms.GetCapabilitiesRequest; import org.geoserver.wms.WMS; import org.geoserver.wms.WMSInfo; import org.geoserver.wms.WMSInfoImpl; import org.geoserver.wms.WMSTestSupport; import org.geotools.referencing.CRS; import org.geotools.util.NumberRange; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.helpers.NamespaceSupport; /** * * @author Gabriel Roldan * @version $Id$ */ public class GetCapabilitiesTransformerTest { private static final class EmptyExtendedCapabilitiesProvider implements ExtendedCapabilitiesProvider { public String[] getSchemaLocations(String schemaBaseURL) { throw new UnsupportedOperationException(); } public void registerNamespaces(NamespaceSupport namespaces) { throw new UnsupportedOperationException(); } public List<String> getVendorSpecificCapabilitiesRoots(GetCapabilitiesRequest request) { return null; } /** * * @see org.geoserver.wms.ExtendedCapabilitiesProvider#getVendorSpecificCapabilitiesChildDecls() */ public List<String> getVendorSpecificCapabilitiesChildDecls( GetCapabilitiesRequest request) { return null; } public void encode(Translator tx, WMSInfo wms, GetCapabilitiesRequest request) throws IOException { } @Override public void customizeRootCrsList(Set<String> srs) { } @Override public NumberRange<Double> overrideScaleDenominators(PublishedInfo layer, NumberRange<Double> scaleDenominators) { return null; } } private static final class TestExtendedCapabilitiesProvider implements ExtendedCapabilitiesProvider { public String[] getSchemaLocations(String schemaBaseURL) { throw new UnsupportedOperationException(); } public void registerNamespaces(NamespaceSupport namespaces) { throw new UnsupportedOperationException(); } public List<String> getVendorSpecificCapabilitiesRoots(GetCapabilitiesRequest request) { return Collections.singletonList("TestElement?"); } /** * * @see org.geoserver.wms.ExtendedCapabilitiesProvider#getVendorSpecificCapabilitiesChildDecls() */ public List<String> getVendorSpecificCapabilitiesChildDecls( GetCapabilitiesRequest request) { return Collections.singletonList("<!ELEMENT TestSubElement (#PCDATA) >"); } public void encode(Translator tx, WMSInfo wms, GetCapabilitiesRequest request) throws IOException { tx.start("TestElement"); tx.start("TestSubElement"); tx.end("TestSubElement"); tx.end("TestElement"); } @Override public void customizeRootCrsList(Set<String> srs) { srs.clear(); srs.add("EPSG:4326"); } @Override public NumberRange<Double> overrideScaleDenominators(PublishedInfo layer, NumberRange<Double> scaleDenominators) { return new NumberRange<Double>(Double.class, 0d, 1000d); } } private XpathEngine XPATH; /** default base url to feed a GetCapabilitiesTransformer with for it to append the DTD location */ private static final String baseUrl = "http://localhost/geoserver"; /** test map formats to feed a GetCapabilitiesTransformer with */ private static final Set<String> mapFormats = Collections.singleton("image/png"); /** test legend formats to feed a GetCapabilitiesTransformer with */ private static final Set<String> legendFormats = Collections.singleton("image/png"); /** * a mocked up {@link GeoServer} config, almost empty after setUp(), except for the * {@link WMSInfo}, {@link GeoServerInfo} and empty {@link Catalog}, Specific tests should add * content as needed */ private GeoServerImpl geosConfig; /** * a mocked up {@link GeoServerInfo} for {@link #geosConfig}. Specific tests should set its * properties as needed */ private GeoServerInfoImpl geosInfo; /** * a mocked up {@link WMSInfo} for {@link #geosConfig}, empty except for the WMSInfo after * setUp(), Specific tests should set its properties as needed */ private WMSInfoImpl wmsInfo; /** * a mocked up {@link Catalog} for {@link #geosConfig}, empty after setUp(), Specific tests * should add content as needed */ private CatalogImpl catalog; private GetCapabilitiesRequest req; private WMS wmsConfig; /** * Sets up the configuration objects with default values. Since they're live, specific tests can * modify their state before running the assertions */ @Before public void setUp() throws Exception { geosConfig = new GeoServerImpl(); geosInfo = new GeoServerInfoImpl(geosConfig); geosInfo.setContact(new ContactInfoImpl()); geosConfig.setGlobal(geosInfo); wmsInfo = new WMSInfoImpl(); geosConfig.add(wmsInfo); catalog = new CatalogImpl(); geosConfig.setCatalog(catalog); wmsConfig = new WMS(geosConfig); req = new GetCapabilitiesRequest(); req.setBaseUrl(baseUrl); Map<String, String> namespaces = new HashMap<String, String>(); namespaces.put("xlink", "http://www.w3.org/1999/xlink"); XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces)); XPATH = XMLUnit.newXpathEngine(); } @Test public void testHeader() throws Exception { GetCapabilitiesTransformer tr; tr = new GetCapabilitiesTransformer(wmsConfig, baseUrl, mapFormats, legendFormats, null); StringWriter writer = new StringWriter(); tr.transform(req, writer); String content = writer.getBuffer().toString(); Assert.assertTrue(content.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")); String dtdDef = "<!DOCTYPE WMT_MS_Capabilities SYSTEM \"" + baseUrl + "/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd\">"; Assert.assertTrue(content.contains(dtdDef)); } @Test public void testRootElement() throws Exception { GetCapabilitiesTransformer tr; tr = new GetCapabilitiesTransformer(wmsConfig, baseUrl, mapFormats, legendFormats, null); Document dom = WMSTestSupport.transform(req, tr); Element root = dom.getDocumentElement(); assertEquals("WMT_MS_Capabilities", root.getNodeName()); assertEquals("1.1.1", root.getAttribute("version")); assertEquals("0", root.getAttribute("updateSequence")); geosInfo.setUpdateSequence(10); tr = new GetCapabilitiesTransformer(wmsConfig, baseUrl, mapFormats, legendFormats, null); dom = WMSTestSupport.transform(req, tr); root = dom.getDocumentElement(); assertEquals("10", root.getAttribute("updateSequence")); } @SuppressWarnings("unchecked") @Test public void testServiceSection() throws Exception { wmsInfo.setTitle("title"); wmsInfo.setAbstract("abstract"); wmsInfo.getKeywords().add(new Keyword("k1")); wmsInfo.getKeywords().add(new Keyword("k2")); // @REVISIT: this is not being respected, but the onlineresource is being set based on the // proxyBaseUrl... not sure if that's correct wmsInfo.setOnlineResource("http://onlineresource/fake"); ContactInfo contactInfo = new ContactInfoImpl(); geosInfo.setContact(contactInfo); contactInfo.setContactPerson("contactPerson"); contactInfo.setContactOrganization("contactOrganization"); contactInfo.setContactPosition("contactPosition"); contactInfo.setAddress("address"); contactInfo.setAddressType("addressType"); contactInfo.setAddressCity("city"); contactInfo.setAddressState("state"); contactInfo.setAddressPostalCode("postCode"); contactInfo.setAddressCountry("country"); contactInfo.setContactVoice("voice"); contactInfo.setContactEmail("email"); contactInfo.setContactFacsimile("fax"); wmsInfo.setFees("fees"); wmsInfo.setAccessConstraints("accessConstraints"); GetCapabilitiesTransformer tr; tr = new GetCapabilitiesTransformer(wmsConfig, baseUrl, mapFormats, legendFormats, null); tr.setIndentation(2); Document dom = WMSTestSupport.transform(req, tr); String service = "/WMT_MS_Capabilities/Service"; assertXpathEvaluatesTo("OGC:WMS", service + "/Name", dom); assertXpathEvaluatesTo("title", service + "/Title", dom); assertXpathEvaluatesTo("abstract", service + "/Abstract", dom); assertXpathEvaluatesTo("k1", service + "/KeywordList/Keyword[1]", dom); assertXpathEvaluatesTo("k2", service + "/KeywordList/Keyword[2]", dom); assertXpathEvaluatesTo(wmsInfo.getOnlineResource(), service + "/OnlineResource/@xlink:href", dom); assertXpathEvaluatesTo("contactPerson", service + "/ContactInformation/ContactPersonPrimary/ContactPerson", dom); assertXpathEvaluatesTo("contactOrganization", service + "/ContactInformation/ContactPersonPrimary/ContactOrganization", dom); assertXpathEvaluatesTo("contactPosition", service + "/ContactInformation/ContactPosition", dom); assertXpathEvaluatesTo("address", service + "/ContactInformation/ContactAddress/Address", dom); assertXpathEvaluatesTo("addressType", service + "/ContactInformation/ContactAddress/AddressType", dom); assertXpathEvaluatesTo("city", service + "/ContactInformation/ContactAddress/City", dom); assertXpathEvaluatesTo("state", service + "/ContactInformation/ContactAddress/StateOrProvince", dom); assertXpathEvaluatesTo("postCode", service + "/ContactInformation/ContactAddress/PostCode", dom); assertXpathEvaluatesTo("country", service + "/ContactInformation/ContactAddress/Country", dom); assertXpathEvaluatesTo("voice", service + "/ContactInformation/ContactVoiceTelephone", dom); assertXpathEvaluatesTo("fax", service + "/ContactInformation/ContactFacsimileTelephone", dom); assertXpathEvaluatesTo("email", service + "/ContactInformation/ContactElectronicMailAddress", dom); assertXpathEvaluatesTo("fees", service + "/Fees", dom); assertXpathEvaluatesTo("accessConstraints", service + "/AccessConstraints", dom); } @Test public void testCRSList() throws Exception { GetCapabilitiesTransformer tr; tr = new GetCapabilitiesTransformer(wmsConfig, baseUrl, mapFormats, legendFormats, null); tr.setIndentation(2); Document dom = WMSTestSupport.transform(req, tr); final Set<String> supportedCodes = CRS.getSupportedCodes("EPSG"); supportedCodes.addAll(CRS.getSupportedCodes("AUTO")); NodeList allCrsCodes = XPATH.getMatchingNodes("/WMT_MS_Capabilities/Capability/Layer/SRS", dom); assertEquals(supportedCodes.size() - 1 /* WGS84(DD) */, allCrsCodes.getLength()); } @Test public void testLimitedCRSList() throws Exception { wmsInfo.getSRS().add("EPSG:3246"); wmsInfo.getSRS().add("EPSG:23030"); GetCapabilitiesTransformer tr; tr = new GetCapabilitiesTransformer(wmsConfig, baseUrl, mapFormats, legendFormats, null); tr.setIndentation(2); Document dom = WMSTestSupport.transform(req, tr); NodeList limitedCrsCodes = XPATH.getMatchingNodes( "/WMT_MS_Capabilities/Capability/Layer/SRS", dom); assertEquals(2, limitedCrsCodes.getLength()); } @Test public void testVendorSpecificCapabilities() throws Exception { ExtendedCapabilitiesProvider vendorCapsProvider = new TestExtendedCapabilitiesProvider(); GetCapabilitiesTransformer tr; tr = new GetCapabilitiesTransformer(wmsConfig, baseUrl, mapFormats, legendFormats, Collections.singletonList(vendorCapsProvider)); tr.setIndentation(2); checkVendorSpecificCapsProviders(tr); } @Test public void testVendorSpecificCapabilitiesWithEmptyProvider() throws Exception { ExtendedCapabilitiesProvider emptyCapsProvider = new EmptyExtendedCapabilitiesProvider(); ExtendedCapabilitiesProvider vendorCapsProvider = new TestExtendedCapabilitiesProvider(); GetCapabilitiesTransformer tr; tr = new GetCapabilitiesTransformer(wmsConfig, baseUrl, mapFormats, legendFormats, Arrays.asList(emptyCapsProvider, vendorCapsProvider)); tr.setIndentation(2); checkVendorSpecificCapsProviders(tr); } private void checkVendorSpecificCapsProviders(GetCapabilitiesTransformer tr) throws Exception, XpathException { Document dom = WMSTestSupport.transform(req, tr); assertXpathEvaluatesTo("1", "count(/WMT_MS_Capabilities/Capability/Layer/SRS)", dom); assertXpathEvaluatesTo("1", "count(/WMT_MS_Capabilities/Capability/Layer[SRS='EPSG:4326'])", dom); NodeList list = XPATH.getMatchingNodes( "/WMT_MS_Capabilities/Capability/VendorSpecificCapabilities/TestElement", dom); assertEquals(1, list.getLength()); list = XPATH .getMatchingNodes( "/WMT_MS_Capabilities/Capability/VendorSpecificCapabilities/TestElement/TestSubElement", dom); assertEquals(1, list.getLength()); } }