Skip to content
Snippets Groups Projects
testScenario.py 12.6 KiB
Newer Older
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#                                                                       #
#   MapServer REST API is a python wrapper around MapServer which       #
#   allows to manipulate a mapfile in a RESTFul way. It has been        #
#   developped to match as close as possible the way the GeoServer      #
#   REST API acts.                                                      #
#                                                                       #
#   Copyright (C) 2011-2013 Neogeo Technologies.                        #
#                                                                       #
#   This file is part of MapServer Rest API.                            #
#                                                                       #
#   MapServer Rest API is free software: you can redistribute it        #
#   and/or modify it under the terms of the GNU General Public License  #
#   as published by the Free Software Foundation, either version 3 of   #
#   the License, or (at your option) any later version.                 #
#                                                                       #
#   MapServer Rest API is distributed in the hope that it will be       #
#   useful, but WITHOUT ANY WARRANTY; without even the implied warranty #
#   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the     #
#   GNU General Public License for more details.                        #
#                                                                       #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

from utils import APIRequest

import sys
def _test_workspaces(target, map_name, delete=True):
    wss = APIRequest("GET", target + "/maps/" + map_name + "/workspaces")["workspaces"]
    assert len(wss) == 1
    assert wss[0]["name"] == "default"

    # GET workspaceName

    ws = APIRequest("GET", wss[0]["href"])["workspace"]
    assert ws["name"] == wss[0]["name"]

    # GET dataStores

    dss = APIRequest("GET", ws["dataStores"]["href"])["dataStores"]
    assert len(dss) == 0

    # POST a datastore and GET it

    name, title = "testDS1", "test datastore 1"
    _, r = APIRequest("POST", ws["dataStores"]["href"], {"dataStore":{"name":name, "title":title}},
                      get_response=True)
    ds_link = r.getheader("Location").rsplit(".", 1)[0]

    ds = APIRequest("GET", ds_link)["dataStore"]
    assert ds["name"] == name
    assert ds["title"] == title

    # PUT a datastore

    ds["title"] = title.upper()
    del ds["href"]
    APIRequest("PUT", ds_link, {"dataStore":ds})

    ds = APIRequest("GET", ds_link)["dataStore"]
    assert ds["title"] == title.upper()

    # GET featuretypes

    fts = APIRequest("GET", ds["href"])["featureTypes"]
    assert len(fts) == 0


    # PUT file, and check if datastore is updated.

    APIRequest("PUT", ds_link + "/file.shp", open("./files/timezones_shp.zip", "rb"),
               encode=None, content_type="application/zip")

    ds = APIRequest("GET", ds_link)["dataStore"]
    assert ds["connectionParameters"]["url"] == "file:workspaces/%s/datastores/%s/timezones.shp" % (ws["name"], ds["name"])
    name, title = "timezones", "test feature type 1"
    _, r = APIRequest("POST", ds["href"], {"featureType":{"name":name, "title":title}},
                      get_response=True)
    ft_link = r.getheader("Location").rsplit(".", 1)[0]

    ft = APIRequest("GET", ft_link)["featureType"]
    assert ft["name"] == name
    assert ft["title"] == title

    # PUT a featuretype

    ft["title"] = title.upper()
    APIRequest("PUT", ft_link, {"featureType":ft})

    ft = APIRequest("GET", ft_link)["featureType"]
    assert ft["title"] == title.upper()

    # DELETE stuff

        APIRequest("DELETE", ft_link)
        fts = APIRequest("GET", ds_link + "/featuretypes")["featureTypes"]
        assert len(fts) == 0

        APIRequest("DELETE", ds_link)
        dss = APIRequest("GET", ws["dataStores"]["href"])["dataStores"]
        assert len(dss) == 0



    #
    # Test CoverageStores.
    #

    # GET coverageStores

    css = APIRequest("GET", ws["coverageStores"]["href"])["coverageStores"]
    assert len(css) == 0

    # POST a coverageStore and GET it

    name, title = "testCS1", "test coverageStore 1"
    _, r = APIRequest("POST", ws["coverageStores"]["href"], {"coverageStore":{"name":name, "title":title}},
                      get_response=True)
    cs_link = r.getheader("Location").rsplit(".", 1)[0]

    cs = APIRequest("GET", cs_link)["coverageStore"]
    assert cs["name"] == name
    assert cs["title"] == title

    # PUT a coverageStore

    cs["title"] = title.upper()
    del cs["href"]
    APIRequest("PUT", cs_link, {"coverageStore":cs})

    cs = APIRequest("GET", cs_link)["coverageStore"]
    assert cs["title"] == title.upper()

    # GET coverages

    fts = APIRequest("GET", cs["href"])["coverages"]
    assert len(fts) == 0


    # PUT file, and check if coverageStore is updated.

    APIRequest("PUT", cs_link + "/file.tif", open("./files/HYP_LR.zip", "rb"),
               encode=None, content_type="application/zip")

    cs = APIRequest("GET", cs_link)["coverageStore"]
    assert cs["connectionParameters"]["url"] == "file:workspaces/%s/coveragestores/%s/HYP_LR/HYP_LR.tif" % (ws["name"], cs["name"])

    # POST a coverage and GET it

    name, title = "HYP_LR", "test coverage 1"
    _, r = APIRequest("POST", cs["href"], {"coverage":{"name":name, "title":title}},
                      get_response=True)
    c_link = r.getheader("Location").rsplit(".", 1)[0]
    ft = APIRequest("GET", c_link)["coverage"]
    assert ft["name"] == name
    assert ft["title"] == title

    # PUT a coverage

    ft["title"] = title.upper()
    APIRequest("PUT", c_link, {"coverage":ft})
    ft = APIRequest("GET", c_link)["coverage"]
    if delete:

        APIRequest("DELETE", c_link)
        fts = APIRequest("GET", cs_link + "/coverages")["coverages"]
        assert len(fts) == 0

        APIRequest("DELETE", cs_link)
        css = APIRequest("GET", ws["coverageStores"]["href"])["coverageStores"]
        assert len(css) == 0


    return ws

def _test_styles(target, map_name):

    # Lets DELETE all the styles.
    styles = APIRequest("GET", target + "/maps/" + map_name + "/styles")["styles"]
    for style in styles:
        if style["name"].startswith("__test_"):
            APIRequest("DELETE", style["href"])
    styles = APIRequest("GET", target + "/maps/" + map_name + "/styles")["styles"]
    assert len([style for style in styles if style["name"].startswith("__test_")]) == 0

    # Lets POST a style and GET it.
    name = "__test_awesome_style_name"
    data = open("./files/style.sld").read()
    noise = "".join(map(str, random.sample(xrange(10000000), 60)))
    # We add some noise, so we can check PUT later.

    styles = APIRequest("POST", target + "/maps/" + map_name + "/styles?name=" + name,
                        encode=None, content_type="application/vnd.ogc.sld+xml", data=data+noise)

    styles = APIRequest("GET", target + "/maps/" + map_name + "/styles")["styles"]
    assert len(styles) == 1
    assert styles[0]["name"] == name

    st_link = styles[0]["href"].rsplit(".", 1)[0]
    style = APIRequest("GET", st_link)

    content = APIRequest("GET", style["href"], encode=None, decode=None)
    assert content == data+noise

    # Use PUT to remove the noise in the file.
    styles = APIRequest("PUT", style["href"], encode=None, content_type="application/vnd.ogc.sld+xml", data=data)
    content = APIRequest("GET", style["href"], encode=None, decode=None)
    assert content == data


def _test_layers(target, map_name):
    # We need to setup something to work with first.

    # GET workspaces.
    wss = APIRequest("GET", target + "/maps/" + map_name + "/workspaces")["workspaces"]
    ws = APIRequest("GET", wss[0]["href"])["workspace"]
    # DataStores.
    name, title = "testDS1", "test datastore 1"
    _, r = APIRequest("POST", ws["dataStores"]["href"], {"dataStore":{"name":name, "title":title}},
                      get_response=True)
    ds_link = r.getheader("Location").rsplit(".", 1)[0]
    # PUT file
    APIRequest("PUT", ds_link + "/file.shp", open("./files/timezones_shp.zip", "rb"),
               encode=None, content_type="application/zip")
    ds = APIRequest("GET", ds_link)["dataStore"]
    # POST a featuretype
    name, title = "timezones", "test feature type 1"
    _, r = APIRequest("POST", ds["href"], {"featureType":{"name":name, "title":title}},
                      get_response=True)
    ft_link = r.getheader("Location").rsplit(".", 1)[0]
    # CoverageStores.
    name, title = "testCS1", "test coverageStore 1"
    _, r = APIRequest("POST", ws["coverageStores"]["href"], {"coverageStore":{"name":name, "title":title}},
                      get_response=True)
    cs_link = r.getheader("Location").rsplit(".", 1)[0]
    # PUT file
    APIRequest("PUT", cs_link + "/file.tif", open("./files/HYP_LR.zip", "rb"),
               encode=None, content_type="application/zip")
    cs = APIRequest("GET", cs_link)["coverageStore"]
    # POST a coverage
    name, title = "HYP_LR", "test coverage 1"
    _, r = APIRequest("POST", cs["href"], {"coverage":{"name":name, "title":title}},
                      get_response=True)
    c_link = r.getheader("Location").rsplit(".", 1)[0]

    #
    # OK, now the actual layer tests.
    #

    layers = APIRequest("GET", target + "/maps/" + map_name + "/layers")["layers"]
    assert len(layers) == 0

    # A first layer for featuretype

    name = "FTlayerTest"
    _, r = APIRequest("POST", target + "/maps/" + map_name + "/layers",
                      {"layer":{"name":name, "resource":{"href":ft_link}}},
                      get_response=True)
    ftl_link = r.getheader("Location").rsplit(".", 1)[0]

    # Check GET.
    ftl = APIRequest("GET", ftl_link)["layer"]
    assert ftl["name"] == name
    assert ftl["type"] == "POLYGON"

    # check GET fields
    fields = APIRequest("GET", ftl_link + "/fields")["fields"]
    assert len(fields) == 15

    # check GET layerstyles
    styles = APIRequest("GET", ftl_link + "/styles")["styles"]
    assert len(styles) == 1

    APIRequest("POST", ftl_link + "/styles", {"style":{"resource":{"href":styles[0]["href"]}}})

    # A second layer for coverage

    name = "ClayerTest"
    _, r = APIRequest("POST", target + "/maps/" + map_name + "/layers",
                      {"layer":{"name":name, "resource":{"href":c_link}}},
                      get_response=True)
    cl_link = r.getheader("Location").rsplit(".", 1)[0]
    cl = APIRequest("GET", cl_link)["layer"]
    assert cl["name"] == name
    assert cl["type"] == "RASTER"

    # Check GET.
    layers = APIRequest("GET", target + "/maps/" + map_name + "/layers")["layers"]
    assert len(layers) == 2

    # check GET fields
    fields = APIRequest("GET", cl_link + "/fields")["fields"]
    fields = APIRequest("GET", cl_link + "/styles")["styles"]
    # Now lets try layer groups.

    layers = APIRequest("GET", target + "/maps/" + map_name + "/layergroups")["layerGroups"]
    assert len(layers) == 0

    # POST an empty group
    name = "test_group"
    _, r = APIRequest("POST", target + "/maps/" + map_name + "/layergroups", {"layerGroup":{"name":name}}, get_response=True)
    g_link = r.getheader("Location").rsplit(".", 1)[0]

    # GET it.
    group = APIRequest("GET", g_link)["layerGroup"]
    assert group["name"] == name
    assert len(group["layers"]) == 0

    # PUT some new layers in it.
    group["layers"] = [x["name"] for x in group["layers"]] + [ftl["name"]]
    del group["bounds"]
    APIRequest("PUT", g_link, {"layerGroup":group})

    # GET it.
    group = APIRequest("GET", g_link)["layerGroup"]
    assert len(group["layers"]) == 1

    # PUT some new layers in it.
    group["layers"] = [x["name"] for x in group["layers"]] + [cl["name"]]
    del group["bounds"]
    APIRequest("PUT", g_link, {"layerGroup":group})

    # GET it.
    group = APIRequest("GET", g_link)["layerGroup"]
    assert len(group["layers"]) == 2


    target = "http://localhost:8080"
    map_name = "tests"

    # Clean the test file, now we are sure it is empty.
    APIRequest("DELETE", target + "/maps/" + map_name)
    APIRequest("POST", target + "/maps", {"mapfile":{"name":map_name}})

    # _test_workspaces(target, map_name)
    # _test_styles(target, map_name)