diff --git a/geowebcache/core/src/main/java/org/geowebcache/service/OWSException.java b/geowebcache/core/src/main/java/org/geowebcache/service/OWSException.java index 6cc912a96..4fcda3eb8 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/service/OWSException.java +++ b/geowebcache/core/src/main/java/org/geowebcache/service/OWSException.java @@ -55,11 +55,26 @@ public String toString() { str.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"); str.append( " xsi:schemaLocation=\"http://www.opengis.net/ows/1.1 http://geowebcache.org/schema/ows/1.1.0/owsExceptionReport.xsd\">\n"); - str.append(" \n"); + if (locator != null) { + str.append(" \n"); + } else { + str.append(" \n"); + } + str.append(" " + exceptionText + "\n"); str.append(" \n"); str.append("\n"); return str.toString(); } + + /** Returns the OWS exception code attribute */ + public String getExceptionCode() { + return exceptionCode; + } + + /** Returns the OWS exception locator attribute */ + public String getLocator() { + return locator; + } } diff --git a/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSGetCapabilities.java b/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSGetCapabilities.java index 05f582ce3..e391d15f1 100644 --- a/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSGetCapabilities.java +++ b/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSGetCapabilities.java @@ -297,7 +297,10 @@ private void serviceIdentification(XMLBuilder xml, ServiceInformation servInfo) appendTag(xml, "ows:Title", servInfo.getTitle(), "Web Map Tile Service - GeoWebCache"); appendTag(xml, "ows:Abstract", servInfo.getDescription(), null); - if (servInfo != null && servInfo.getKeywords() != null) { + // a keywords element cannot be empty + if (servInfo != null + && servInfo.getKeywords() != null + && !servInfo.getKeywords().isEmpty()) { xml.indentElement("ows:Keywords"); Iterator keywordIter = servInfo.getKeywords().iterator(); while (keywordIter.hasNext()) { @@ -453,17 +456,17 @@ private void layer(XMLBuilder xml, TileLayer layer, String baseurl, Set appendTag(xml, "ows:Identifier", layer.getName(), null); + // WMTS 1.0 Layer is a ows:DatasetDescriptionSummary, which in turn can hold a ows:Metadata, + // which finally + // has the xlink:simpleAttrs attribute group, see https://www.w3.org/1999/xlink.xsd. + // Unfortunately those links do not have a format attribute, so we can't use them for + // metadata links. if (layer.getMetadataURLs() != null) { for (MetadataURL metadataURL : layer.getMetadataURLs()) { - xml.indentElement("MetadataURL"); - xml.attribute("type", metadataURL.getType()); - xml.simpleElement("Format", metadataURL.getFormat(), true); - xml.indentElement("OnlineResource") - .attribute("xmlns:xlink", "http://www.w3.org/1999/xlink") + xml.indentElement("ows:Metadata") .attribute("xlink:type", "simple") .attribute("xlink:href", metadataURL.getUrl().toString()) .endElement(); - xml.endElement(); } } diff --git a/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSGetFeatureInfo.java b/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSGetFeatureInfo.java index 1854c5a56..2c1533efa 100644 --- a/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSGetFeatureInfo.java +++ b/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSGetFeatureInfo.java @@ -67,12 +67,12 @@ protected void writeResponse(RuntimeStats stats) throws OWSException { TileLayer layer = convTile.getLayer(); GridSet gridSet = convTile.getGridSubset().getGridSet(); - if (gridSet.getTileHeight() < j || j < 0) { + if (gridSet.getTileHeight() <= j || j < 0) { throw new OWSException( 400, "PointIJOutOfRange", "J", "J was " + j + ", must be between 0 and " + gridSet.getTileHeight()); } - if (gridSet.getTileWidth() < i || i < 0) { + if (gridSet.getTileWidth() <= i || i < 0) { throw new OWSException( 400, "PointIJOutOfRange", "I", "I was " + i + ", must be between 0 and " + gridSet.getTileWidth()); } diff --git a/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSService.java b/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSService.java index 225fdf347..8d4c2f6fe 100644 --- a/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSService.java +++ b/geowebcache/wmts/src/main/java/org/geowebcache/service/wmts/WMTSService.java @@ -50,6 +50,7 @@ import org.geowebcache.util.NullURLMangler; import org.geowebcache.util.ServletUtils; import org.geowebcache.util.URLMangler; +import org.springframework.http.MediaType; public class WMTSService extends Service { @@ -248,6 +249,21 @@ public Conveyor getConveyor(HttpServletRequest request, HttpServletResponse resp public Conveyor getRestConveyor(HttpServletRequest request, HttpServletResponse response) throws GeoWebCacheException, OWSException { + // CITE compliance, if the representation is not available a 406 should be returned + // This is also the behavior mandated by the HTTP standard + String accept = request.getHeader("Accept"); + if (accept != null) { + List mediaTypes = MediaType.parseMediaTypes(accept); + boolean representationAvailable = false; + for (MediaType mediaType : mediaTypes) { + if (mediaType.includes(MediaType.APPLICATION_XML)) { + representationAvailable = true; + break; + } + } + if (!representationAvailable) throw new HttpErrorCodeException(406, "Representation not available"); + } + final String path = request.getPathInfo(); // special simpler case for GetCapabilities @@ -302,14 +318,13 @@ public Conveyor getKvpConveyor(HttpServletRequest request, HttpServletResponse r // if provided handle accepted versions parameter if (acceptedVersions != null) { // we only support version 1.0.0, so make sure that's one of the accepted versions - String[] versions = acceptedVersions.split("\\s*,\\s*"); - int foundIndex = Arrays.binarySearch(versions, "1.0.0"); - if (foundIndex < 0) { + List versions = Arrays.asList(acceptedVersions.split("\\s*,\\s*")); + if (!versions.contains("1.0.0")) { // no supported version is accepted throw new OWSException( 400, "VersionNegotiationFailed", - null, + "null", "List of versions in AcceptVersions parameter value, in GetCapabilities " + "operation request, did not include any version supported by this server."); } @@ -409,6 +424,8 @@ private ConveyorTile getTile( } MimeType mimeType = null; + // the format should be present and valid also for GetFeatureInfo, while in CITE compliance + // mode if (reqType == RequestType.TILE) { String format = values.get("format"); if (format == null) { @@ -437,6 +454,14 @@ private ConveyorTile getTile( "INFOFORMAT", "Unable to determine requested INFOFORMAT, " + infoFormat); } + + if (isCiteCompliant() && !isRestRequest(request)) { + String format = values.get("format"); + if (format == null) { + throw new OWSException( + 400, "MissingParameterValue", "FORMAT", "Unable to determine requested FORMAT, " + format); + } + } } final String tilematrixset = values.get("tilematrixset"); @@ -485,7 +510,7 @@ private ConveyorTile getTile( throw new OWSException( 400, "TileOutOfRange", - "TILECOLUMN", + "TILECOL", "Column " + x + " is out of range, min: " + gridCov[0] + " max:" + gridCov[2]); } @@ -621,7 +646,7 @@ ServerConfiguration getMainConfiguration() { * * @return TRUE if GWC main configuration or at least one of the WMTS extensions forces CITE compliance */ - private boolean isCiteCompliant() { + protected boolean isCiteCompliant() { // let's see if main GWC configuration forces WMTS implementation to be CITE compliant if (mainConfiguration != null && mainConfiguration.isWmtsCiteCompliant()) { return true; diff --git a/geowebcache/wmts/src/test/java/org/geowebcache/service/wmts/WMTSRestTest.java b/geowebcache/wmts/src/test/java/org/geowebcache/service/wmts/WMTSRestTest.java index 23647d3e1..ede5d66c1 100644 --- a/geowebcache/wmts/src/test/java/org/geowebcache/service/wmts/WMTSRestTest.java +++ b/geowebcache/wmts/src/test/java/org/geowebcache/service/wmts/WMTSRestTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -64,6 +65,7 @@ import org.geowebcache.layer.meta.VectorLayerMetadata; import org.geowebcache.mime.ApplicationMime; import org.geowebcache.mime.MimeType; +import org.geowebcache.service.HttpErrorCodeException; import org.geowebcache.service.OWSException; import org.geowebcache.stats.RuntimeStats; import org.geowebcache.storage.StorageBroker; @@ -142,6 +144,15 @@ public void testGetCap() throws Exception { doc); } + @Test + public void testGetCapInvalidFormat() throws Exception { + MockHttpServletRequest req = new MockHttpServletRequest(); + req.setPathInfo("geowebcache/service/wmts/rest/WMTSCapabilities.xml"); + req.addHeader("Accept", "invalid/format"); + HttpErrorCodeException exception = assertThrows(HttpErrorCodeException.class, () -> dispatch(req)); + assertEquals(406, exception.getErrorCode()); + } + @Test public void testGetTileWithStyle() throws Exception { MockHttpServletRequest req = new MockHttpServletRequest(); diff --git a/geowebcache/wmts/src/test/java/org/geowebcache/service/wmts/WMTSServiceTest.java b/geowebcache/wmts/src/test/java/org/geowebcache/service/wmts/WMTSServiceTest.java index e1e1f2828..0a2100fcf 100644 --- a/geowebcache/wmts/src/test/java/org/geowebcache/service/wmts/WMTSServiceTest.java +++ b/geowebcache/wmts/src/test/java/org/geowebcache/service/wmts/WMTSServiceTest.java @@ -15,6 +15,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; @@ -374,13 +375,11 @@ public void testGetCap() throws Exception { // validator.assertIsValid(); Document doc = XMLUnit.buildTestDocument(result); - Map namespaces = new HashMap<>(); - namespaces.put("xlink", "http://www.w3.org/1999/xlink"); - namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); - namespaces.put("ows", "http://www.opengis.net/ows/1.1"); - namespaces.put("wmts", "http://www.opengis.net/wmts/1.0"); - XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces)); - XpathEngine xp = XMLUnit.newXpathEngine(); + XpathEngine xp = buildWMTSXPath(); + + // check that with no keywords, there is no container ows:Keywords element (can be missing, + // cannot be empty) + assertEquals("0", xp.evaluate("count(//ows:Keywords)", doc)); assertEquals("1", xp.evaluate("count(//wmts:Contents/wmts:Layer)", doc)); assertEquals("1", xp.evaluate("count(//wmts:Contents/wmts:Layer[ows:Identifier='mockLayer'])", doc)); @@ -405,13 +404,7 @@ public void testGetCap() throws Exception { assertEquals( "1", xp.evaluate( - "count(//wmts:Contents/wmts:Layer/wmts:MetadataURL[@type='some-type'][wmts:Format='some-format'])", - doc)); - assertEquals( - "1", - xp.evaluate( - "count(//wmts:Contents/wmts:Layer/wmts:MetadataURL[@type='some-type']" - + "/wmts:OnlineResource[@xlink:href='http://localhost:8080/some-url'])", + "count(//wmts:Contents/wmts:Layer/ows:Metadata[@xlink:href='http://localhost:8080/some-url'])", doc)); // checking that the layer has an associated tile resource URL, for each // supported image @@ -594,13 +587,7 @@ public ServiceInformation getServiceInformation() { assertTrue(result.contains("name-space schema-location")); // instantiate the xpath engine Document doc = XMLUnit.buildTestDocument(result); - Map namespaces = new HashMap<>(); - namespaces.put("xlink", "http://www.w3.org/1999/xlink"); - namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); - namespaces.put("ows", "http://www.opengis.net/ows/1.1"); - namespaces.put("wmts", "http://www.opengis.net/wmts/1.0"); - XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces)); - XpathEngine xpath = XMLUnit.newXpathEngine(); + XpathEngine xpath = buildWMTSXPath(); // checking that we have the service extra information assertEquals("1", xpath.evaluate("count(//wmts:custom-metadata)", doc)); assertEquals("1", xpath.evaluate("count(//ows:ServiceIdentification[ows:Title='custom-service'])", doc)); @@ -691,13 +678,7 @@ public void testGetCapServiceInfo() throws Exception { // validator.assertIsValid(); Document doc = XMLUnit.buildTestDocument(result); - Map namespaces = new HashMap<>(); - namespaces.put("xlink", "http://www.w3.org/1999/xlink"); - namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); - namespaces.put("ows", "http://www.opengis.net/ows/1.1"); - namespaces.put("wmts", "http://www.opengis.net/wmts/1.0"); - XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces)); - XpathEngine xpath = XMLUnit.newXpathEngine(); + XpathEngine xpath = buildWMTSXPath(); assertEquals("John Smith", xpath.evaluate("//ows:IndividualName", doc)); } @@ -764,13 +745,7 @@ public void testGetCapOneWGS84BBox() throws Exception { // validator.assertIsValid(); Document doc = XMLUnit.buildTestDocument(result); - Map namespaces = new HashMap<>(); - namespaces.put("xlink", "http://www.w3.org/1999/xlink"); - namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); - namespaces.put("ows", "http://www.opengis.net/ows/1.1"); - namespaces.put("wmts", "http://www.opengis.net/wmts/1.0"); - XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces)); - XpathEngine xpath = XMLUnit.newXpathEngine(); + XpathEngine xpath = buildWMTSXPath(); assertEquals("1", xpath.evaluate("count(//ows:WGS84BoundingBox)", doc)); } @@ -829,13 +804,7 @@ public void testGetCapUnboundedStyleFilter() throws Exception { // validator.assertIsValid(); Document doc = XMLUnit.buildTestDocument(result); - Map namespaces = new HashMap<>(); - namespaces.put("xlink", "http://www.w3.org/1999/xlink"); - namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); - namespaces.put("ows", "http://www.opengis.net/ows/1.1"); - namespaces.put("wmts", "http://www.opengis.net/wmts/1.0"); - XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces)); - XpathEngine xpath = XMLUnit.newXpathEngine(); + XpathEngine xpath = buildWMTSXPath(); assertEquals("1", xpath.evaluate("count(//wmts:Contents/wmts:Layer)", doc)); assertEquals("1", xpath.evaluate("count(//wmts:Contents/wmts:Layer[ows:Identifier='mockLayer'])", doc)); @@ -897,13 +866,7 @@ public void testGetCapEmptyStyleFilter() throws Exception { validator.assertIsValid(); Document doc = XMLUnit.buildTestDocument(result); - Map namespaces = new HashMap<>(); - namespaces.put("xlink", "http://www.w3.org/1999/xlink"); - namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); - namespaces.put("ows", "http://www.opengis.net/ows/1.1"); - namespaces.put("wmts", "http://www.opengis.net/wmts/1.0"); - XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces)); - XpathEngine xpath = XMLUnit.newXpathEngine(); + XpathEngine xpath = buildWMTSXPath(); assertEquals("1", xpath.evaluate("count(//wmts:Contents/wmts:Layer)", doc)); assertEquals("1", xpath.evaluate("count(//wmts:Contents/wmts:Layer[ows:Identifier='mockLayer'])", doc)); @@ -965,13 +928,7 @@ public void testGetCapMultipleStyles() throws Exception { // validator.assertIsValid(); Document doc = XMLUnit.buildTestDocument(result); - Map namespaces = new HashMap<>(); - namespaces.put("xlink", "http://www.w3.org/1999/xlink"); - namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); - namespaces.put("ows", "http://www.opengis.net/ows/1.1"); - namespaces.put("wmts", "http://www.opengis.net/wmts/1.0"); - XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces)); - XpathEngine xpath = XMLUnit.newXpathEngine(); + XpathEngine xpath = buildWMTSXPath(); assertEquals("1", xpath.evaluate("count(//wmts:Contents/wmts:Layer)", doc)); assertEquals("1", xpath.evaluate("count(//wmts:Contents/wmts:Layer[ows:Identifier='mockLayer'])", doc)); @@ -1006,6 +963,17 @@ public void testGetCapMultipleStyles() throws Exception { doc)); } + private static XpathEngine buildWMTSXPath() { + Map namespaces = new HashMap<>(); + namespaces.put("xlink", "http://www.w3.org/1999/xlink"); + namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); + namespaces.put("ows", "http://www.opengis.net/ows/1.1"); + namespaces.put("wmts", "http://www.opengis.net/wmts/1.0"); + XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces)); + XpathEngine xpath = XMLUnit.newXpathEngine(); + return xpath; + } + /** * Generates a layer with "elevation" and "time" dimensions and mime types "image/png" , "image/jpeg" , "text/plain" * , "text/html" , "application/vnd.ogc.gml" then checks if in the capabilities documents each @@ -1070,13 +1038,7 @@ public void testGetCapWithMultipleDimensions() throws Exception { String result = resp.getContentAsString(); Document doc = XMLUnit.buildTestDocument(result); - Map namespaces = new HashMap<>(); - namespaces.put("xlink", "http://www.w3.org/1999/xlink"); - namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); - namespaces.put("ows", "http://www.opengis.net/ows/1.1"); - namespaces.put("wmts", "http://www.opengis.net/wmts/1.0"); - XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces)); - XpathEngine xpath = XMLUnit.newXpathEngine(); + XpathEngine xpath = buildWMTSXPath(); assertEquals("1", xpath.evaluate("count(//wmts:Contents/wmts:Layer)", doc)); assertEquals("1", xpath.evaluate("count(//wmts:Contents/wmts:Layer[ows:Identifier='mockLayer'])", doc)); @@ -1208,7 +1170,51 @@ public boolean handleRequest(Conveyor conveyor) throws OWSException { } @Test - public void testGetFeature() throws Exception { + public void testGetFeatureInfo() throws Exception { + Conveyor conveyor = + runGetFeatureInfo("50", "50", "TEST FEATURE INFO", "image/png", XMLMime.gml.getMimeType(), false); + + service.handleRequest(conveyor); + // fail("Expected SecurityException"); + + MockHttpServletResponse resp = (MockHttpServletResponse) conveyor.servletResp; + assertThat(resp.getContentAsString(), equalTo("TEST FEATURE INFO")); + } + + @Test + public void testFeatureInfoInvalidColumn() throws Exception { + // one off, 255 is the actual max + checkFeatureInfoInvalidIJ("256", "50", "I"); + } + + @Test + public void testFeatureInfoInvalidRow() throws Exception { + // one off, 255 is the actual max + checkFeatureInfoInvalidIJ("50", "256", "J"); + } + + private void checkFeatureInfoInvalidIJ(String i, String j, String locator) + throws GeoWebCacheException, OWSException { + Conveyor conv = runGetFeatureInfo(i, j, "TEST RESPONSE", "image/png", XMLMime.gml.getMimeType(), false); + + OWSException exception = assertThrows(OWSException.class, () -> service.handleRequest(conv)); + assertEquals(locator, exception.getLocator()); + assertEquals("PointIJOutOfRange", exception.getExceptionCode()); + } + + @Test + public void testFeatureInfoMissingFormat() throws Exception { + OWSException exception = assertThrows( + OWSException.class, + () -> runGetFeatureInfo("20", "50", "TEST RESPONSE", null, XMLMime.gml.getMimeType(), true)); + + assertEquals("FORMAT", exception.getLocator()); + assertEquals("MissingParameterValue", exception.getExceptionCode()); + } + + private Conveyor runGetFeatureInfo( + String i, String j, String response, String tileFormat, String infoFormat, boolean citeCompliant) + throws GeoWebCacheException, OWSException { SecurityDispatcher secDisp = mock(SecurityDispatcher.class); when(secDisp.isSecurityEnabled()).thenReturn(false); @@ -1217,7 +1223,12 @@ public void testGetFeature() throws Exception { GridSetBroker gsb = mock(GridSetBroker.class); - service = new WMTSService(sb, tld, gsb, mock(RuntimeStats.class), new NullURLMangler(), gwcd); + service = new WMTSService(sb, tld, gsb, mock(RuntimeStats.class), new NullURLMangler(), gwcd) { + @Override + protected boolean isCiteCompliant() { + return citeCompliant; + } + }; service.setSecurityDispatcher(secDisp); GridSubset subset = mock(GridSubset.class); @@ -1246,20 +1257,21 @@ public void testGetFeature() throws Exception { req.addParameter("version", "1.0.0"); req.addParameter("request", "GetFeatureInfo"); req.addParameter("layer", layerName); - req.addParameter("format", "image/png"); + if (tileFormat != null) req.addParameter("format", tileFormat); req.addParameter("tilematrixset", "testGridset"); req.addParameter("tilematrix", "testGridset:2"); req.addParameter("tilerow", "3"); req.addParameter("tilecol", "4"); - req.addParameter("infoformat", XMLMime.gml.getMimeType()); - req.addParameter("i", "20"); - req.addParameter("j", "50"); + if (infoFormat != null) req.addParameter("infoformat", infoFormat); + req.addParameter("i", i); + req.addParameter("j", j); req.setRequestURI("/geowebcache/service/wmts?service=WMTS&version=1.0.0&request=GetFeatureInfo" + "&layer=" + layerName + "&format=image/png&tilematrixset=testGridset" + "&tilematrix=testGridset:2&tilerow=3&tilecol=4&infoformat=" - + XMLMime.gml.getMimeType()); + + infoFormat); + req.setPathInfo("service/wmts"); when(subset.getNumTilesHigh(2)).thenReturn(7L); when(subset.getGridIndex("testGridset:2")).thenReturn(2L); @@ -1276,19 +1288,15 @@ public void testGetFeature() throws Exception { Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt())) - .thenReturn(new ByteArrayResource("TEST FEATURE INFO".getBytes())); + .thenReturn(new ByteArrayResource(response.getBytes())); assertThat(conv, hasProperty("hint", equalTo("GetFeatureInfo".toLowerCase()))); assertThat(conv, hasProperty("requestHandler", equalTo(RequestHandler.SERVICE))); - - service.handleRequest(conv); - // fail("Expected SecurityException"); - - assertThat(resp.getContentAsString(), equalTo("TEST FEATURE INFO")); + return conv; } @Test - public void testGetFeatureSecure() throws Exception { + public void testGetFeatureInfoSecure() throws Exception { SecurityDispatcher secDisp = mock(SecurityDispatcher.class); when(secDisp.isSecurityEnabled()).thenReturn(true); @@ -1409,13 +1417,7 @@ public void testGetCapWithTileJSONDifferentUrls() throws Exception { assertTrue(result.contains("mockLayer")); Document doc = XMLUnit.buildTestDocument(result); - Map namespaces = new HashMap<>(); - namespaces.put("xlink", "http://www.w3.org/1999/xlink"); - namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); - namespaces.put("ows", "http://www.opengis.net/ows/1.1"); - namespaces.put("wmts", "http://www.opengis.net/wmts/1.0"); - XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces)); - XpathEngine xpath = XMLUnit.newXpathEngine(); + XpathEngine xpath = buildWMTSXPath(); assertEquals("1", xpath.evaluate("count(//wmts:Contents/wmts:Layer)", doc)); assertEquals("1", xpath.evaluate("count(//wmts:Contents/wmts:Layer[ows:Identifier='mockLayer'])", doc));