/* (c) 2016 Open Source Geospatial Foundation - all rights reserved * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wms.ncwms; import static org.junit.Assert.assertEquals; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.InputStream; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.imageio.ImageIO; import javax.xml.namespace.QName; import org.custommonkey.xmlunit.XMLUnit; import org.custommonkey.xmlunit.XpathEngine; import org.custommonkey.xmlunit.exceptions.XpathException; import org.geoserver.catalog.CoverageInfo; import org.geoserver.catalog.LayerInfo; import org.geoserver.data.test.MockTestData; import org.geoserver.data.test.SystemTestData; import org.geoserver.data.test.SystemTestData.StyleProperty; import org.geoserver.wms.WMSTestSupport; import org.geoserver.wms.style.PaletteStyleHandler; import org.geotools.util.NumberRange; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockHttpServletResponse; import org.w3c.dom.Document; public class NcwmsIntegrationTest extends WMSTestSupport { QName RAIN = new QName(MockTestData.CITE_URI, "rain", MockTestData.CITE_PREFIX); String GRAY_BLUE_STYLE = "grayToBlue"; XpathEngine xpath; // @Override // protected String getLogConfiguration() { // return "/GEOTOOLS_DEVELOPER_LOGGING.properties"; // } @Before public void setupXpath() { this.xpath = XMLUnit.newXpathEngine(); } @Override protected void registerNamespaces(Map<String, String> namespaces) { namespaces.put("wms", "http://www.opengis.net/wms"); namespaces.put("ows", "http://www.opengis.net/ows"); } @Override protected void onSetUp(SystemTestData testData) throws Exception { testData.addRasterLayer(RAIN, "rain.tif", ".tif", null, NcwmsIntegrationTest.class, getCatalog()); testData.addStyle(getCatalog().getDefaultWorkspace(), GRAY_BLUE_STYLE, "grayToBlue.palette", NcwmsIntegrationTest.class, getCatalog(), Collections.singletonMap(StyleProperty.FORMAT, PaletteStyleHandler.FORMAT)); CoverageInfo ci = getCatalog().getCoverageByName(getLayerId(RAIN)); ci.getDimensions().get(0).setRange(NumberRange.create(0d, 7000d)); getCatalog().save(ci); } @Test public void testPlain() throws Exception { BufferedImage image = getAsImage(requestBase(), "image/png"); // RenderedImageBrowser.showChain(image); // System.in.read(); // heavy rain here assertPixel(image, 32, 74, new Color(37, 37, 236)); // mid value here assertPixel(image, 120, 74, new Color(129, 129, 191)); // dry here assertPixel(image, 160, 60, new Color(170, 170, 170)); } @Test public void testOpacity() throws Exception { BufferedImage image = getAsImage(requestBase() + "&OPACITY=50", "image/png"); // RenderedImageBrowser.showChain(image); // System.in.read(); // heavy rain here assertPixel(image, 32, 74, new Color(37, 37, 236, 128)); // mid value here assertPixel(image, 120, 74, new Color(129, 129, 191, 128)); // dry here assertPixel(image, 160, 60, new Color(170, 170, 170, 128)); } @Test public void testLogarithmic() throws Exception { // the log application skews the map a lot towards the blues BufferedImage image = getAsImage(requestBase() + "&COLORSCALERANGE=1,6000&LOGSCALE=true", "image/png"); // RenderedImageBrowser.showChain(image); // System.in.read(); // heavy rain here assertPixel(image, 32, 74, new Color(3, 3, 253)); // mid value here assertPixel(image, 120, 74, new Color(25, 25, 243)); // dry here assertPixel(image, 160, 60, new Color(91, 91, 209)); } @Test public void testRange() throws Exception { BufferedImage image = getAsImage(requestBase() + "&COLORSCALERANGE=100,5000", "image/png"); // RenderedImageBrowser.showChain(image); // cut away both low and high // heavy rain here assertPixelIsTransparent(image, 32, 74); // almost dry here assertPixelIsTransparent(image, 160, 60); } @Test public void testBeforeAfterColor() throws Exception { BufferedImage image = getAsImage( requestBase() + "&COLORSCALERANGE=100,4000&BELOWMINCOLOR=0xFF0000&ABOVEMAXCOLOR=0x00FF00", "image/png"); // RenderedImageBrowser.showChain(image); // System.in.read(); // cut away both low and high // heavy rain here assertPixel(image, 32, 74, Color.GREEN); // dry here assertPixel(image, 160, 60, Color.RED); } @Test public void testNumberColors() throws Exception { BufferedImage image = getAsImage(requestBase() + "&NUMCOLORBANDS=3", "image/png"); assertUniqueColorCount(image, 3); } private String requestBase() { return "wms?service=WMS&version=1.1.1&request=GetMap&layers=" + getLayerId(RAIN) + "&styles=" + GRAY_BLUE_STYLE + "&format=image/png&srs=EPSG:4326&bbox=-180,-90,180,90&transparent=true&width=320&height=160"; } private void assertUniqueColorCount(BufferedImage image, int count) { int[] rgb = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth()); Set<Integer> colors = new HashSet<>(); for (int i = 0; i < rgb.length; i++) { int curr = rgb[i]; colors.add(curr); } assertEquals("Expected amount of colors not found", count, colors.size()); } @Test public void testDatasetFiltering() throws Exception { // filter by workspace Document dom = getAsDOM( "wms?service=WMS&version=1.3.0&request=GetCapabilities&dataset=cite"); assertDatasetWithCapabilities(dom); } @Test public void testDatasetFilteringPOST() throws Exception { // filter by workspace Document dom = postAsDOM( "wms?service=WMS&version=1.3.0&request=GetCapabilities&dataset=cite"); assertDatasetWithCapabilities(dom); } private void assertDatasetWithCapabilities(Document dom) throws XpathException, Exception { // check only the layers in that workspace are there, and are not qualified for (LayerInfo layer : getCatalog().getLayers()) { if ("cite".equals(layer.getResource().getStore().getWorkspace().getName()) && !"Geometryless".equals(layer.getName())) { assertEquals("Did not find " + layer.getName(), 1, xpath .getMatchingNodes( "//wms:Layer[wms:Name = '" + layer.getName() + "']", dom) .getLength()); } else { assertEquals("Found unexpected " + layer.getName(), 0, xpath .getMatchingNodes( "//wms:Layer[wms:Name = '" + layer.getName() + "']", dom) .getLength()); } } // filter by layer dom = getAsDOM("wms?service=WMS&version=1.3.0&request=GetCapabilities&dataset=cite:rain"); assertEquals(1, xpath.getMatchingNodes("//wms:Layer[wms:Name = 'rain']", dom).getLength()); // root container and the layer itself assertEquals(2, xpath.getMatchingNodes("//wms:Layer", dom).getLength()); } @Test public void testPostRequest() throws Exception { String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<ogc:GetMap xmlns:ogc=\"http://www.opengis.net/ows\"\n" + " xmlns:gml=\"http://www.opengis.net/gml\"\n" + " version=\"1.1.1\" service=\"WMS\">\n" + " <StyledLayerDescriptor version=\"1.0.0\">\n" + " <NamedLayer>\n" + " <Name>" + getLayerId(RAIN) + "</Name>\n" + " <NamedStyle><Name>" + GRAY_BLUE_STYLE + "</Name></NamedStyle> \n" + " </NamedLayer> \n" + " </StyledLayerDescriptor>\n" + " <BoundingBox srsName=\"http://www.opengis.net/gml/srs/epsg.xml#4326\">\n" + " <gml:coord><gml:X>-180</gml:X><gml:Y>-90</gml:Y></gml:coord>\n" + " <gml:coord><gml:X>180</gml:X><gml:Y>90</gml:Y></gml:coord>\n" + " </BoundingBox>\n" + " <Output>\n" + " <Format>image/png</Format>\n" + " <Size><Width>320</Width><Height>160</Height></Size>\n" + " </Output>\n" + "</ogc:GetMap>"; MockHttpServletResponse resp = postAsServletResponse("wms", xml); assertEquals("image/png", resp.getContentType()); InputStream is = getBinaryInputStream(resp); BufferedImage image = ImageIO.read(is); // heavy rain here assertPixel(image, 32, 74, new Color(37, 37, 236)); // mid value here assertPixel(image, 120, 74, new Color(129, 129, 191)); // dry here assertPixel(image, 160, 60, new Color(170, 170, 170)); } @Test public void testWfsCapabilitiesPostRequest() throws Exception { // run a WFS 2.0 capabilities request, used to NPE in the NcWmsDatasetCallback String xml = "<GetCapabilities xmlns=\"http://www.opengis.net/wfs/2.0\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "service=\"WFS\" " + "xsi:schemaLocation=\"http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd\"/>"; Document dom = postAsDOM("wfs", xml); // print(dom); assertEquals("wfs:WFS_Capabilities", dom.getDocumentElement().getNodeName()); } }