239 lines
9.8 KiB
Python
239 lines
9.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
import pytest
|
|
import mock
|
|
import utils
|
|
|
|
from django.contrib.contenttypes.models import ContentType
|
|
|
|
from passerelle.apps.arcgis.models import ArcGIS
|
|
from passerelle.base.models import ApiUser, AccessRight
|
|
|
|
# from http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/fold/serv/MapServer/1
|
|
STATES = '''{
|
|
"fieldAliases" : {
|
|
"OBJECTID" : "OBJECTID",
|
|
"STATE_NAME" : "STATE_NAME",
|
|
"STATE_ABBR" : "STATE_ABBR"
|
|
},
|
|
"features" : [
|
|
{
|
|
"attributes" : {
|
|
"STATE_NAME" : "Texas",
|
|
"STATE_ABBR" : "TX",
|
|
"OBJECTID" : 40
|
|
},
|
|
"geometry" : {
|
|
"rings" : [
|
|
[
|
|
[-105.998886788462, 31.3939400524361],
|
|
[-106.21328556164, 31.4782464373727]
|
|
]
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"geometry" : {
|
|
"rings" : [
|
|
[
|
|
[-111.475425113078, 44.7021622250113],
|
|
[-111.480804007084, 44.6914159859524]
|
|
]
|
|
]
|
|
},
|
|
"attributes" : {
|
|
"STATE_NAME" : "Montana",
|
|
"STATE_ABBR" : "MT",
|
|
"OBJECTID" : 2
|
|
}
|
|
}
|
|
],
|
|
"spatialReference" : {
|
|
"wkid" : 4326
|
|
},
|
|
"fields" : [
|
|
{
|
|
"alias" : "OBJECTID",
|
|
"type" : "esriFieldTypeOID",
|
|
"name" : "OBJECTID"
|
|
},
|
|
{
|
|
"type" : "esriFieldTypeString",
|
|
"alias" : "STATE_NAME",
|
|
"length" : 25,
|
|
"name" : "STATE_NAME"
|
|
},
|
|
{
|
|
"length" : 2,
|
|
"alias" : "STATE_ABBR",
|
|
"type" : "esriFieldTypeString",
|
|
"name" : "STATE_ABBR"
|
|
}
|
|
],
|
|
"geometryType" : "esriGeometryPolygon",
|
|
"displayFieldName" : "STATE_NAME"
|
|
}'''
|
|
|
|
|
|
@pytest.fixture
|
|
def arcgis(db):
|
|
return ArcGIS.objects.create(slug='test',
|
|
base_url='https://arcgis.example.net/')
|
|
|
|
|
|
def test_arcgis_mapservice_query(app, arcgis):
|
|
endpoint = utils.generic_endpoint_url('arcgis', 'mapservice-query', slug=arcgis.slug)
|
|
assert endpoint == '/arcgis/test/mapservice-query'
|
|
params = {
|
|
'folder': 'fold',
|
|
'service': 'serv',
|
|
'layer': '1'
|
|
}
|
|
|
|
with mock.patch('passerelle.utils.Request.get') as requests_get:
|
|
requests_get.return_value = utils.FakedResponse(content=STATES,
|
|
status_code=200)
|
|
|
|
resp = app.get(endpoint, params=params, status=403)
|
|
assert requests_get.call_count == 0
|
|
assert resp.json['err'] == 1
|
|
assert resp.json['err_class'] == 'django.core.exceptions.PermissionDenied'
|
|
|
|
# open access
|
|
api = ApiUser.objects.create(username='all', keytype='', key='')
|
|
obj_type = ContentType.objects.get_for_model(arcgis)
|
|
AccessRight.objects.create(codename='can_access', apiuser=api, resource_type=obj_type,
|
|
resource_pk=arcgis.pk)
|
|
resp = app.get(endpoint, params=params, status=200)
|
|
assert requests_get.call_count == 1
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/fold/serv/MapServer/1/query'
|
|
args = requests_get.call_args[1]['params']
|
|
assert args['f'] == 'json'
|
|
assert args['outFields'] == '*'
|
|
assert args['where'] == '1=1'
|
|
assert 'data' in resp.json
|
|
assert resp.json['err'] == 0
|
|
assert len(resp.json['data']) == 2
|
|
assert resp.json['data'][0]['id'] == '40'
|
|
assert resp.json['data'][0]['text'] == 'Texas'
|
|
assert 'geometry' not in resp.json['data'][0]
|
|
assert 'metadata' not in resp.json
|
|
|
|
params['full'] = 'on'
|
|
resp = app.get(endpoint, params=params, status=200)
|
|
assert requests_get.call_count == 2
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/fold/serv/MapServer/1/query'
|
|
args = requests_get.call_args[1]['params']
|
|
assert args['f'] == 'json'
|
|
assert args['outFields'] == '*'
|
|
assert args['where'] == '1=1'
|
|
assert 'data' in resp.json
|
|
assert resp.json['err'] == 0
|
|
assert len(resp.json['data']) == 2
|
|
assert resp.json['data'][0]['id'] == '40'
|
|
assert resp.json['data'][0]['text'] == 'Texas'
|
|
assert resp.json['data'][0]['geometry']
|
|
assert resp.json['metadata']
|
|
|
|
params['q'] = 'Texas'
|
|
resp = app.get(endpoint, params=params, status=200)
|
|
assert requests_get.call_count == 3
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/fold/serv/MapServer/1/query'
|
|
args = requests_get.call_args[1]['params']
|
|
assert args['text'] == 'Texas'
|
|
assert 'where' not in args
|
|
|
|
params['lat'] = '9.87654'
|
|
params['lon'] = '1.12345'
|
|
resp = app.get(endpoint, params=params, status=200)
|
|
assert requests_get.call_count == 4
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/fold/serv/MapServer/1/query'
|
|
args = requests_get.call_args[1]['params']
|
|
assert args['geometry'] == '1.12345,9.87654'
|
|
assert args['geometryType'] == 'esriGeometryPoint'
|
|
|
|
del params['lat'] # missing lat, do not search by geometry
|
|
resp = app.get(endpoint, params=params, status=200)
|
|
assert requests_get.call_count == 5
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/fold/serv/MapServer/1/query'
|
|
args = requests_get.call_args[1]['params']
|
|
assert 'geometry' not in args
|
|
assert 'geometryType' not in args
|
|
|
|
params.update({'latmin': '1', 'lonmin': '2', 'latmax': '3', 'lonmax': '4'})
|
|
resp = app.get(endpoint, params=params, status=200)
|
|
assert requests_get.call_count == 6
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/fold/serv/MapServer/1/query'
|
|
args = requests_get.call_args[1]['params']
|
|
assert args['geometry'] == '2.0,1.0,4.0,3.0'
|
|
assert args['geometryType'] == 'esriGeometryEnvelope'
|
|
|
|
del params['latmin'] # incomplete box, do not search by geometry
|
|
resp = app.get(endpoint, params=params, status=200)
|
|
assert requests_get.call_count == 7
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/fold/serv/MapServer/1/query'
|
|
args = requests_get.call_args[1]['params']
|
|
assert 'geometry' not in args
|
|
assert 'geometryType' not in args
|
|
|
|
# others params are directly sent to ArcGIS
|
|
params['spatialRel'] = 'esriSpatialRelContains'
|
|
params.update({'latmin': '1', 'lonmin': '2', 'latmax': '3', 'lonmax': '4'})
|
|
resp = app.get(endpoint, params=params, status=200)
|
|
assert requests_get.call_count == 8
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/fold/serv/MapServer/1/query'
|
|
args = requests_get.call_args[1]['params']
|
|
assert args['geometry'] == '2.0,1.0,4.0,3.0'
|
|
assert args['geometryType'] == 'esriGeometryEnvelope'
|
|
assert args['spatialRel'] == 'esriSpatialRelContains'
|
|
|
|
# folder
|
|
params['folder'] = 'foo/bar'
|
|
resp = app.get(endpoint, params=params, status=200)
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/foo/bar/serv/MapServer/1/query'
|
|
del params['folder']
|
|
resp = app.get(endpoint, params=params, status=200)
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/serv/MapServer/1/query'
|
|
|
|
# minimal call
|
|
resp = app.get(endpoint, params={'service': 'srv'}, status=200)
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/srv/MapServer/0/query'
|
|
args = requests_get.call_args[1]['params']
|
|
assert args == {'f': 'json', 'inSR': '4326', 'outSR': '4326',
|
|
'outFields': '*', 'where': '1=1'}
|
|
|
|
# distance
|
|
resp = app.get(endpoint, params={'service': 'srv', 'distance': '100'}, status=200)
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/srv/MapServer/0/query'
|
|
args = requests_get.call_args[1]['params']
|
|
assert args['distance'] == '100'
|
|
assert args['units'] == 'esriSRUnit_Meter' # default unit
|
|
resp = app.get(endpoint, params={'service': 'srv', 'distance': '5', 'units':
|
|
'esriSRUnit_NauticalMile'}, status=200)
|
|
assert requests_get.call_args[0][0] == 'https://arcgis.example.net/services/srv/MapServer/0/query'
|
|
args = requests_get.call_args[1]['params']
|
|
assert args['distance'] == '5'
|
|
assert args['units'] == 'esriSRUnit_NauticalMile'
|
|
|
|
# call errors
|
|
with mock.patch('passerelle.utils.Request.get') as requests_get:
|
|
requests_get.return_value = utils.FakedResponse(content=STATES,
|
|
status_code=200)
|
|
resp = app.get(endpoint, params={}, status=400)
|
|
assert requests_get.call_count == 0
|
|
assert resp.json['err'] == 1
|
|
assert resp.json['err_class'] == 'passerelle.views.WrongParameter'
|
|
assert resp.json['err_desc'] == "missing parameters: 'service'."
|
|
|
|
resp = app.get(endpoint, params={'service': 'src', 'lat': '0', 'lon': 'y'}, status=400)
|
|
assert requests_get.call_count == 0
|
|
assert resp.json['err'] == 1
|
|
assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError'
|
|
assert resp.json['err_desc'] == '<lon> and <lat> must be floats'
|
|
|
|
resp = app.get(endpoint, params={'service': 'src', 'latmin': '0', 'lonmin': 'y',
|
|
'latmax': '0', 'lonmax': '1'}, status=400)
|
|
assert requests_get.call_count == 0
|
|
assert resp.json['err'] == 1
|
|
assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError'
|
|
assert resp.json['err_desc'] == '<lonmin> <latmin> <lonmax> and <latmax> must be floats'
|