From ba1a4f1366728846aafd30b657c0c99dab5afcbb Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Thu, 9 Jan 2020 16:49:10 +0100
Subject: [PATCH] opengis: adapt tyename parameter to servr version (#38851)

---
 passerelle/apps/opengis/models.py | 12 ++++++++++--
 tests/test_opengis.py             | 29 +++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/passerelle/apps/opengis/models.py b/passerelle/apps/opengis/models.py
index c5707ad1..882e3643 100644
--- a/passerelle/apps/opengis/models.py
+++ b/passerelle/apps/opengis/models.py
@@ -93,6 +93,14 @@ class OpenGIS(BaseResource):
     def get_wfs_service_version(self, renew=False):
         return self.get_service_version('wfs', self.wfs_service_url, renew=renew)
 
+    def get_typename_label(self, renew=False):
+        version_str = self.get_wfs_service_version(renew=renew)
+        version_tuple = tuple(int(x) for x in version_str.split('.'))
+        if version_tuple <= (1, 1, 0):
+            return 'TYPENAME'
+        else:
+            return 'TYPENAMES'
+
     def check_status(self):
         if self.wms_service_url:
             response = self.requests.get(
@@ -144,7 +152,7 @@ class OpenGIS(BaseResource):
             'VERSION': self.get_wfs_service_version(),
             'SERVICE': 'WFS',
             'REQUEST': 'GetFeature',
-            'TYPENAMES': type_names,
+            self.get_typename_label(): type_names,
             'PROPERTYNAME': property_name,
             'OUTPUTFORMAT': 'json',
         }
@@ -297,7 +305,7 @@ class OpenGIS(BaseResource):
             'VERSION': self.get_wfs_service_version(),
             'SERVICE': 'WFS',
             'REQUEST': 'GetFeature',
-            'TYPENAMES': self.query_layer,
+            self.get_typename_label(): self.query_layer,
             'OUTPUTFORMAT': 'json',
             'CQL_FILTER': cql_filter
         }
diff --git a/tests/test_opengis.py b/tests/test_opengis.py
index 9c65803e..71354356 100644
--- a/tests/test_opengis.py
+++ b/tests/test_opengis.py
@@ -41,6 +41,17 @@ FAKE_SERVICE_CAPABILITIES = '''<?xml version="1.0" encoding="UTF-8"?>
     </ows:ServiceIdentification>
 </wfs:WFS_Capabilities>'''
 
+FAKE_SERVICE_CAPABILITIES_V1_0_0 = '''<?xml version="1.0" encoding="UTF-8"?>
+<wfs:WFS_Capabilities version="1.0.0"
+       xmlns:wfs="http://www.opengis.net/wfs/2.0"
+       xmlns:ows="http://www.opengis.net/ows/1.1">
+    <ows:ServiceIdentification>
+        <ows:Title/><ows:Abstract/>
+        <ows:ServiceType>WFS</ows:ServiceType><ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion><ows:Fees/>
+        <ows:AccessConstraints/>
+    </ows:ServiceIdentification>
+</wfs:WFS_Capabilities>'''
+
 FAKE_FEATURES_JSON = '''
 {
     "features": [
@@ -227,6 +238,10 @@ def geoserver_responses(url, **kwargs):
         return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
     return utils.FakedResponse(status_code=200, content=FAKE_FEATURES_JSON)
 
+def geoserver_responses_v1_0_0(url, **kwargs):
+    if kwargs['params'].get('request') == 'GetCapabilities':
+        return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES_V1_0_0)
+    return utils.FakedResponse(status_code=200, content=FAKE_FEATURES_JSON)
 
 def geoserver_responses_errors(url, **kwargs):
     if kwargs['params'].get('request') == 'GetCapabilities':
@@ -395,6 +410,20 @@ def test_get_feature_error2(mocked_get, app, connector):
     assert '<ows:' in result['data']['content']
 
 
+@pytest.mark.parametrize("server_responses, version, typename_label", [
+    (geoserver_responses_v1_0_0, '1.0.0', 'TYPENAME'),
+    (geoserver_responses, '2.0.0', 'TYPENAMES')])
+@mock.patch('passerelle.utils.Request.get')
+def test_typename_parameter_upgrade(mocked_get, server_responses, version, typename_label, app, connector):
+    endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
+    assert endpoint == '/opengis/test/features'
+    mocked_get.side_effect = server_responses
+    resp = app.get(endpoint, params={'type_names': '...', 'property_name': '...'})
+    assert mocked_get.call_args[1]['params']['REQUEST'] == 'GetFeature'
+    assert mocked_get.call_args[1]['params']['VERSION'] == version
+    assert typename_label in mocked_get.call_args[1]['params'].keys()
+
+
 @mock.patch('passerelle.utils.Request.get')
 def test_reverse_geocoding(mocked_get, app, connector):
     connector.search_radius = 45
-- 
2.24.1

