728 lines
25 KiB
Python
728 lines
25 KiB
Python
# =================================================================
|
|
#
|
|
# Authors: Tom Kralidis <tomkralidis@gmail.com>
|
|
#
|
|
# Copyright (c) 2020 Tom Kralidis
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person
|
|
# obtaining a copy of this software and associated documentation
|
|
# files (the "Software"), to deal in the Software without
|
|
# restriction, including without limitation the rights to use,
|
|
# copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the
|
|
# Software is furnished to do so, subject to the following
|
|
# conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be
|
|
# included in all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
# OTHER DEALINGS IN THE SOFTWARE.
|
|
#
|
|
# =================================================================
|
|
|
|
import json
|
|
import os
|
|
import logging
|
|
|
|
import pytest
|
|
|
|
from werkzeug.test import create_environ
|
|
from werkzeug.wrappers import Request
|
|
from pygeoapi.api import API, check_format
|
|
from pygeoapi.util import yaml_load
|
|
from pyld import jsonld
|
|
|
|
LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
def get_test_file_path(filename):
|
|
"""helper function to open test file safely"""
|
|
|
|
if os.path.isfile(filename):
|
|
return filename
|
|
else:
|
|
return 'tests/{}'.format(filename)
|
|
|
|
|
|
def make_req_headers(**kwargs):
|
|
environ = create_environ('/collections/obs/items',
|
|
'http://localhost:5000/')
|
|
environ.update(kwargs)
|
|
request = Request(environ)
|
|
return request.headers
|
|
|
|
|
|
@pytest.fixture()
|
|
def config():
|
|
with open(get_test_file_path('pygeoapi-test-config.yml')) as fh:
|
|
return yaml_load(fh)
|
|
|
|
|
|
@pytest.fixture()
|
|
def openapi():
|
|
with open(get_test_file_path('pygeoapi-test-openapi.yml')) as fh:
|
|
return yaml_load(fh)
|
|
|
|
|
|
@pytest.fixture()
|
|
def api_(config):
|
|
return API(config)
|
|
|
|
|
|
def test_api(config, api_, openapi):
|
|
assert api_.config == config
|
|
assert isinstance(api_.config, dict)
|
|
|
|
req_headers = make_req_headers(HTTP_CONTENT_TYPE='application/json')
|
|
rsp_headers, code, response = api_.openapi(req_headers, {}, openapi)
|
|
assert rsp_headers['Content-Type'] ==\
|
|
'application/vnd.oai.openapi+json;version=3.0'
|
|
root = json.loads(response)
|
|
|
|
assert isinstance(root, dict)
|
|
|
|
a = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
|
|
req_headers = make_req_headers(HTTP_ACCEPT=a)
|
|
rsp_headers, code, response = api_.openapi(req_headers, {}, openapi)
|
|
assert rsp_headers['Content-Type'] == 'text/html'
|
|
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.openapi(req_headers, {'f': 'foo'},
|
|
openapi)
|
|
assert code == 400
|
|
|
|
|
|
def test_api_exception(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.root(req_headers, {'f': 'foo'})
|
|
assert code == 400
|
|
|
|
|
|
def test_root(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.root(req_headers, {})
|
|
root = json.loads(response)
|
|
|
|
assert rsp_headers['Content-Type'] == 'application/json'
|
|
assert rsp_headers['X-Powered-By'].startswith('pygeoapi')
|
|
|
|
assert isinstance(root, dict)
|
|
assert 'links' in root
|
|
assert root['links'][0]['rel'] == 'self'
|
|
assert root['links'][0]['type'] == 'application/json'
|
|
assert root['links'][0]['href'].endswith('?f=json')
|
|
assert any(link['href'].endswith('f=jsonld') and link['rel'] == 'alternate'
|
|
for link in root['links'])
|
|
assert any(link['href'].endswith('f=html') and link['rel'] == 'alternate'
|
|
for link in root['links'])
|
|
assert len(root['links']) == 7
|
|
assert 'title' in root
|
|
assert root['title'] == 'pygeoapi default instance'
|
|
assert 'description' in root
|
|
assert root['description'] == 'pygeoapi provides an API to geospatial data'
|
|
|
|
rsp_headers, code, response = api_.root(req_headers, {'f': 'html'})
|
|
assert rsp_headers['Content-Type'] == 'text/html'
|
|
|
|
|
|
def test_root_structured_data(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.root(req_headers, {"f": "jsonld"})
|
|
root = json.loads(response)
|
|
|
|
assert rsp_headers['Content-Type'] == 'application/ld+json'
|
|
assert rsp_headers['X-Powered-By'].startswith('pygeoapi')
|
|
|
|
assert isinstance(root, dict)
|
|
assert 'description' in root
|
|
assert root['description'] == 'pygeoapi provides an API to geospatial data'
|
|
|
|
assert '@context' in root
|
|
assert root['@context'] == 'https://schema.org/docs/jsonldcontext.jsonld'
|
|
expanded = jsonld.expand(root)[0]
|
|
assert '@type' in expanded
|
|
assert 'http://schema.org/DataCatalog' in expanded['@type']
|
|
assert 'http://schema.org/description' in expanded
|
|
assert root['description'] == expanded['http://schema.org/description'][0][
|
|
'@value']
|
|
assert 'http://schema.org/keywords' in expanded
|
|
assert len(expanded['http://schema.org/keywords']) == 3
|
|
assert '@value' in expanded['http://schema.org/keywords'][0].keys()
|
|
assert 'http://schema.org/provider' in expanded
|
|
assert expanded['http://schema.org/provider'][0]['@type'][
|
|
0] == 'http://schema.org/Organization'
|
|
assert expanded['http://schema.org/name'][0]['@value'] == root['name']
|
|
|
|
|
|
def test_conformance(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.conformance(req_headers, {})
|
|
root = json.loads(response)
|
|
|
|
assert isinstance(root, dict)
|
|
assert 'conformsTo' in root
|
|
assert len(root['conformsTo']) == 4
|
|
|
|
rsp_headers, code, response = api_.conformance(req_headers, {'f': 'foo'})
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.conformance(req_headers, {'f': 'html'})
|
|
assert rsp_headers['Content-Type'] == 'text/html'
|
|
|
|
|
|
def test_describe_collections(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.describe_collections(
|
|
req_headers, {'f': 'foo'})
|
|
assert code == 400
|
|
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.describe_collections(
|
|
req_headers, {'f': 'html'})
|
|
assert rsp_headers['Content-Type'] == 'text/html'
|
|
|
|
rsp_headers, code, response = api_.describe_collections(req_headers, {})
|
|
collections = json.loads(response)
|
|
|
|
assert len(collections) == 2
|
|
assert len(collections['collections']) == 1
|
|
assert len(collections['links']) == 3
|
|
|
|
rsp_headers, code, response = api_.describe_collections(
|
|
req_headers, {}, 'foo')
|
|
collection = json.loads(response)
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.describe_collections(
|
|
req_headers, {}, 'obs')
|
|
collection = json.loads(response)
|
|
|
|
assert collection['id'] == 'obs'
|
|
assert collection['title'] == 'Observations'
|
|
assert collection['description'] == 'My cool observations'
|
|
assert len(collection['links']) == 10
|
|
assert collection['extent'] == {
|
|
'spatial': {
|
|
'bbox': [[-180, -90, 180, 90]],
|
|
'crs': 'http://www.opengis.net/def/crs/OGC/1.3/CRS84'
|
|
},
|
|
'temporal': {
|
|
'interval': [
|
|
['2000-10-30T18:24:39+00:00', '2007-10-30T08:57:29+00:00']
|
|
],
|
|
'trs': 'http://www.opengis.net/def/uom/ISO-8601/0/Gregorian'
|
|
}
|
|
}
|
|
|
|
rsp_headers, code, response = api_.describe_collections(
|
|
req_headers, {'f': 'html'}, 'obs')
|
|
assert rsp_headers['Content-Type'] == 'text/html'
|
|
|
|
|
|
def test_get_collection_queryables(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.get_collection_queryables(
|
|
req_headers, {}, 'notfound')
|
|
assert code == 400
|
|
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.get_collection_queryables(
|
|
req_headers, {'f': 'html'}, 'obs')
|
|
assert rsp_headers['Content-Type'] == 'text/html'
|
|
|
|
rsp_headers, code, response = api_.get_collection_queryables(
|
|
req_headers, {'f': 'json'}, 'obs')
|
|
queryables = json.loads(response)
|
|
|
|
assert 'queryables' in queryables
|
|
assert len(queryables['queryables']) == 6
|
|
|
|
# test with provider filtered properties
|
|
api_.config['resources']['obs']['providers'][0]['properties'] = ['stn_id']
|
|
|
|
rsp_headers, code, response = api_.get_collection_queryables(
|
|
req_headers, {'f': 'json'}, 'obs')
|
|
queryables = json.loads(response)
|
|
|
|
assert 'queryables' in queryables
|
|
assert len(queryables['queryables']) == 1
|
|
|
|
|
|
def test_describe_collections_json_ld(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.describe_collections(
|
|
req_headers, {'f': 'jsonld'}, 'obs')
|
|
collection = json.loads(response)
|
|
|
|
assert '@context' in collection
|
|
expanded = jsonld.expand(collection)[0]
|
|
# Metadata is about a schema:DataCollection that contains a schema:Dataset
|
|
assert not expanded['@id'].endswith('obs')
|
|
assert 'http://schema.org/dataset' in expanded
|
|
assert len(expanded['http://schema.org/dataset']) == 1
|
|
dataset = expanded['http://schema.org/dataset'][0]
|
|
assert dataset['@type'][0] == 'http://schema.org/Dataset'
|
|
assert len(dataset['http://schema.org/distribution']) == 10
|
|
assert all(dist['@type'][0] == 'http://schema.org/DataDownload'
|
|
for dist in dataset['http://schema.org/distribution'])
|
|
|
|
assert 'http://schema.org/Organization' in expanded[
|
|
'http://schema.org/provider'][0]['@type']
|
|
|
|
assert 'http://schema.org/Place' in dataset[
|
|
'http://schema.org/spatial'][0]['@type']
|
|
assert 'http://schema.org/GeoShape' in dataset[
|
|
'http://schema.org/spatial'][0]['http://schema.org/geo'][0]['@type']
|
|
assert dataset['http://schema.org/spatial'][0]['http://schema.org/geo'][
|
|
0]['http://schema.org/box'][0]['@value'] == '-180,-90 180,90'
|
|
|
|
assert 'http://schema.org/temporalCoverage' in dataset
|
|
assert dataset['http://schema.org/temporalCoverage'][0][
|
|
'@value'] == '2000-10-30T18:24:39+00:00/2007-10-30T08:57:29+00:00'
|
|
|
|
|
|
def test_get_collection_items(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {}, 'foo')
|
|
features = json.loads(response)
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'f': 'foo'}, 'obs')
|
|
features = json.loads(response)
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'bbox': '1,2,3'}, 'obs')
|
|
features = json.loads(response)
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'bbox': '1,2,3,4c'}, 'obs')
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'f': 'html'}, 'obs')
|
|
assert rsp_headers['Content-Type'] == 'text/html'
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {}, 'obs')
|
|
features = json.loads(response)
|
|
|
|
assert len(features['features']) == 5
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'resulttype': 'hits'}, 'obs')
|
|
features = json.loads(response)
|
|
|
|
assert len(features['features']) == 0
|
|
|
|
# Invalid limit
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'limit': 0}, 'obs')
|
|
features = json.loads(response)
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'limit': 2}, 'obs')
|
|
features = json.loads(response)
|
|
|
|
assert len(features['features']) == 2
|
|
assert features['features'][1]['properties']['stn_id'] == '35'
|
|
|
|
links = features['links']
|
|
assert len(links) == 5
|
|
assert '/collections/obs/items?f=json' in links[0]['href']
|
|
assert links[0]['rel'] == 'self'
|
|
assert '/collections/obs/items?f=jsonld' in links[1]['href']
|
|
assert links[1]['rel'] == 'alternate'
|
|
assert '/collections/obs/items?f=html' in links[2]['href']
|
|
assert links[2]['rel'] == 'alternate'
|
|
assert '/collections/obs/items?startindex=2&limit=2' in links[3]['href']
|
|
assert links[3]['rel'] == 'next'
|
|
assert '/collections/obs' in links[4]['href']
|
|
assert links[4]['rel'] == 'collection'
|
|
|
|
# Invalid startindex
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'startindex': -1}, 'obs')
|
|
features = json.loads(response)
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'startindex': 2}, 'obs')
|
|
features = json.loads(response)
|
|
|
|
assert len(features['features']) == 3
|
|
assert features['features'][1]['properties']['stn_id'] == '2147'
|
|
|
|
links = features['links']
|
|
assert len(links) == 5
|
|
assert '/collections/obs/items?f=json' in links[0]['href']
|
|
assert links[0]['rel'] == 'self'
|
|
assert '/collections/obs/items?f=jsonld' in links[1]['href']
|
|
assert links[1]['rel'] == 'alternate'
|
|
assert '/collections/obs/items?f=html' in links[2]['href']
|
|
assert links[2]['rel'] == 'alternate'
|
|
assert '/collections/obs/items?startindex=0' in links[3]['href']
|
|
assert links[3]['rel'] == 'prev'
|
|
assert '/collections/obs' in links[4]['href']
|
|
assert links[4]['rel'] == 'collection'
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {
|
|
'startindex': 1,
|
|
'limit': 1,
|
|
'bbox': '-180,90,180,90'
|
|
}, 'obs')
|
|
features = json.loads(response)
|
|
|
|
assert len(features['features']) == 1
|
|
|
|
links = features['links']
|
|
assert len(links) == 6
|
|
assert '/collections/obs/items?f=json&limit=1&bbox=-180,90,180,90' in \
|
|
links[0]['href']
|
|
assert links[0]['rel'] == 'self'
|
|
assert '/collections/obs/items?f=jsonld&limit=1&bbox=-180,90,180,90' in \
|
|
links[1]['href']
|
|
assert links[1]['rel'] == 'alternate'
|
|
assert '/collections/obs/items?f=html&limit=1&bbox=-180,90,180,90' in \
|
|
links[2]['href']
|
|
assert links[2]['rel'] == 'alternate'
|
|
assert '/collections/obs/items?startindex=0&limit=1&bbox=-180,90,180,90' \
|
|
in links[3]['href']
|
|
assert links[3]['rel'] == 'prev'
|
|
assert '/collections/obs/items?startindex=2&limit=1&bbox=-180,90,180,90' \
|
|
in links[4]['href']
|
|
assert links[4]['rel'] == 'next'
|
|
assert '/collections/obs' in links[5]['href']
|
|
assert links[5]['rel'] == 'collection'
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {
|
|
'sortby': 'bad-property',
|
|
'stn_id': '35'
|
|
}, 'obs')
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {
|
|
'sortby': 'stn_id:FOO',
|
|
'stn_id': '35',
|
|
'value': '89.9'
|
|
}, 'obs')
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'sortby': 'stn_id:A'}, 'obs')
|
|
features = json.loads(response)
|
|
# FIXME? this test errors out currently
|
|
assert code == 200
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'f': 'csv'}, 'obs')
|
|
|
|
assert rsp_headers['Content-Type'] == 'text/csv; charset=utf-8'
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'datetime': '2003'}, 'obs')
|
|
|
|
assert code == 200
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'datetime': '1999'}, 'obs')
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'datetime': '2010-04-22'}, 'obs')
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'datetime': '2001-11-11/2003-12-18'}, 'obs')
|
|
|
|
assert code == 200
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'datetime': '../2003-12-18'}, 'obs')
|
|
|
|
assert code == 200
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'datetime': '2001-11-11/..'}, 'obs')
|
|
|
|
assert code == 200
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'datetime': '1999/2005-04-22'}, 'obs')
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'datetime': '2002/2014-04-22'}, 'obs')
|
|
|
|
api_.config['resources']['obs']['extents'].pop('temporal')
|
|
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {'datetime': '2002/2014-04-22'}, 'obs')
|
|
|
|
assert code == 200
|
|
|
|
|
|
def test_get_collection_items_json_ld(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.get_collection_items(
|
|
req_headers, {
|
|
'f': 'jsonld',
|
|
'limit': 2
|
|
}, 'obs')
|
|
assert rsp_headers['Content-Type'] == 'application/ld+json'
|
|
collection = json.loads(response)
|
|
|
|
assert '@context' in collection
|
|
assert collection['@context'][
|
|
0] == 'https://geojson.org/geojson-ld/geojson-context.jsonld'
|
|
assert len(collection['@context']) > 1
|
|
assert 'schema' in collection['@context'][1]
|
|
assert collection['@context'][1]['schema'] == 'https://schema.org/'
|
|
expanded = jsonld.expand(collection)[0]
|
|
featuresUri = 'https://purl.org/geojson/vocab#features'
|
|
assert len(expanded[featuresUri]) == 2
|
|
geometryUri = 'https://purl.org/geojson/vocab#geometry'
|
|
assert all((geometryUri in f) for f in expanded[featuresUri])
|
|
assert all((f[geometryUri][0]['@type'][0] ==
|
|
'https://purl.org/geojson/vocab#Point')
|
|
for f in expanded[featuresUri])
|
|
propertiesUri = 'https://purl.org/geojson/vocab#properties'
|
|
assert all(propertiesUri in f for f in expanded[featuresUri])
|
|
assert all(
|
|
len(f[propertiesUri][0].keys()) > 0 for f in expanded[featuresUri])
|
|
assert all(('https://schema.org/observationDate' in f[propertiesUri][0])
|
|
for f in expanded[featuresUri])
|
|
assert all((f[propertiesUri][0]['https://schema.org/observationDate'][0][
|
|
'@type'] == 'https://schema.org/DateTime')
|
|
for f in expanded[featuresUri])
|
|
assert any((f[propertiesUri][0]['https://schema.org/observationDate'][0][
|
|
'@value'] == '2001-10-30T14:24:55Z') for f in expanded[featuresUri])
|
|
|
|
|
|
def test_get_collection_item(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.get_collection_item(
|
|
req_headers, {'f': 'foo'}, 'obs', '371')
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_item(
|
|
req_headers, {}, 'foo', '371')
|
|
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.get_collection_item(
|
|
req_headers, {}, 'obs', 'notfound')
|
|
|
|
assert code == 404
|
|
|
|
rsp_headers, code, response = api_.get_collection_item(
|
|
req_headers, {'f': 'html'}, 'obs', '371')
|
|
|
|
assert rsp_headers['Content-Type'] == 'text/html'
|
|
|
|
rsp_headers, code, response = api_.get_collection_item(
|
|
req_headers, {}, 'obs', '371')
|
|
feature = json.loads(response)
|
|
|
|
assert feature['properties']['stn_id'] == '35'
|
|
|
|
|
|
def test_get_collection_item_json_ld(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.get_collection_item(
|
|
req_headers, {'f': 'jsonld'}, 'obs', '371')
|
|
assert rsp_headers['Content-Type'] == 'application/ld+json'
|
|
feature = json.loads(response)
|
|
assert '@context' in feature
|
|
assert feature['@context'][
|
|
0] == 'https://geojson.org/geojson-ld/geojson-context.jsonld'
|
|
assert len(feature['@context']) > 1
|
|
assert 'schema' in feature['@context'][1]
|
|
assert feature['@context'][1]['schema'] == 'https://schema.org/'
|
|
assert feature['properties']['stn_id'] == '35'
|
|
assert feature['id'].startswith('http://')
|
|
assert feature['id'].endswith('/collections/obs/items/371')
|
|
expanded = jsonld.expand(feature)[0]
|
|
assert expanded['@id'].startswith('http://')
|
|
assert expanded['@id'].endswith('/collections/obs/items/371')
|
|
assert expanded['https://purl.org/geojson/vocab#properties'][0][
|
|
'https://schema.org/identifier'][0][
|
|
'@type'] == 'https://schema.org/Text'
|
|
assert expanded['https://purl.org/geojson/vocab#properties'][0][
|
|
'https://schema.org/identifier'][0]['@value'] == '35'
|
|
|
|
|
|
def test_describe_processes(config, api_):
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.describe_processes(
|
|
req_headers, {}, 'foo')
|
|
processes = json.loads(response)
|
|
|
|
assert code == 404
|
|
|
|
rsp_headers, code, response = api_.describe_processes(req_headers, {})
|
|
processes = json.loads(response)
|
|
|
|
assert len(processes['processes']) == 1
|
|
|
|
rsp_headers, code, response = api_.describe_processes(
|
|
req_headers, {}, 'hello-world')
|
|
process = json.loads(response)
|
|
|
|
assert process['id'] == 'hello-world'
|
|
assert process['title'] == 'Hello World process'
|
|
assert process['description'] == 'Hello World process'
|
|
assert len(process['links']) == 1
|
|
assert len(process['inputs']) == 1
|
|
assert len(process['outputs']) == 1
|
|
assert len(process['outputTransmission']) == 1
|
|
assert len(process['jobControlOptions']) == 1
|
|
|
|
api_.config['resources'] = {}
|
|
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.describe_processes(
|
|
req_headers, {}, 'foo')
|
|
processes = json.loads(response)
|
|
assert len(processes['processes']) == 0
|
|
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.describe_processes(
|
|
req_headers, {}, 'foo')
|
|
processes = json.loads(response)
|
|
assert len(processes['processes']) == 0
|
|
|
|
|
|
def test_execute_process(config, api_):
|
|
req_body = {'inputs': [{'id': 'name', 'value': 'test'}]}
|
|
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.execute_process(req_headers, {}, '',
|
|
'hello-world')
|
|
response = json.loads(response)
|
|
assert code == 400
|
|
|
|
rsp_headers, code, response = api_.execute_process(req_headers, {},
|
|
json.dumps(req_body),
|
|
'foo')
|
|
response = json.loads(response)
|
|
|
|
assert code == 404
|
|
|
|
rsp_headers, code, response = api_.execute_process(req_headers, {},
|
|
json.dumps(req_body),
|
|
'hello-world')
|
|
response = json.loads(response)
|
|
|
|
assert response['outputs'][0]['value'] == 'test'
|
|
|
|
args = {'response': 'raw'}
|
|
rsp_headers, code, response = api_.execute_process(req_headers, args,
|
|
json.dumps(req_body),
|
|
'hello-world')
|
|
response = json.loads(response)
|
|
|
|
assert response[0]['value'] == 'test'
|
|
|
|
api_.config['resources'] = {}
|
|
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.execute_process(req_headers, {},
|
|
json.dumps(req_body),
|
|
'hello-world')
|
|
response = json.loads(response)
|
|
assert response['code'] == 'NotFound'
|
|
|
|
req_headers = make_req_headers()
|
|
rsp_headers, code, response = api_.execute_process(req_headers, {},
|
|
json.dumps(req_body),
|
|
'hello-world')
|
|
response = json.loads(response)
|
|
assert response['code'] == 'NotFound'
|
|
|
|
|
|
def test_check_format():
|
|
args = {'f': 'html'}
|
|
|
|
req_headers = {}
|
|
|
|
assert check_format({}, req_headers) is None
|
|
|
|
assert check_format(args, req_headers) == 'html'
|
|
|
|
args['f'] = 'json'
|
|
assert check_format(args, req_headers) == 'json'
|
|
|
|
args['f'] = 'jsonld'
|
|
assert check_format(args, req_headers) == 'jsonld'
|
|
|
|
args['f'] = 'html'
|
|
assert check_format(args, req_headers) == 'html'
|
|
|
|
req_headers['Accept'] = 'text/html'
|
|
assert check_format({}, req_headers) == 'html'
|
|
|
|
req_headers['Accept'] = 'application/json'
|
|
assert check_format({}, req_headers) == 'json'
|
|
|
|
req_headers['Accept'] = 'application/ld+json'
|
|
assert check_format({}, req_headers) == 'jsonld'
|
|
|
|
req_headers['accept'] = 'text/html'
|
|
assert check_format({}, req_headers) == 'html'
|
|
|
|
hh = 'text/html,application/xhtml+xml,application/xml;q=0.9,'
|
|
|
|
req_headers['Accept'] = hh
|
|
assert check_format({}, req_headers) == 'html'
|
|
|
|
req_headers['accept'] = hh
|
|
assert check_format({}, req_headers) == 'html'
|
|
|
|
req_headers = make_req_headers(HTTP_ACCEPT=hh)
|
|
assert check_format({}, req_headers) == 'html'
|
|
|
|
req_headers = make_req_headers(HTTP_ACCEPT='text/html')
|
|
assert check_format({}, req_headers) == 'html'
|
|
|
|
req_headers = make_req_headers(HTTP_ACCEPT='application/json')
|
|
assert check_format({}, req_headers) == 'json'
|
|
|
|
req_headers = make_req_headers(HTTP_ACCEPT='application/ld+json')
|
|
assert check_format({}, req_headers) == 'jsonld'
|
|
|
|
# Overrule HTTP content negotiation
|
|
args['f'] = 'html'
|
|
assert check_format(args, req_headers) == 'html'
|
|
|
|
req_headers = make_req_headers(HTTP_ACCEPT='text/html')
|
|
args['f'] = 'json'
|
|
assert check_format(args, req_headers) == 'json'
|