From ccfdc8deab61d3cb12da0a649a0a097460baf245 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 20 Jan 2022 12:18:22 +0100 Subject: [PATCH] toulouse_smart: replace - by _ in field varname (#60870) --- passerelle/contrib/toulouse_smart/models.py | 10 ++++---- .../templates/toulouse_smart/wcs_block.wcs | 2 +- passerelle/contrib/toulouse_smart/views.py | 6 ++++- tests/test_toulouse_smart.py | 24 +++++++++---------- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/passerelle/contrib/toulouse_smart/models.py b/passerelle/contrib/toulouse_smart/models.py index 22e489e7..c3f69046 100644 --- a/passerelle/contrib/toulouse_smart/models.py +++ b/passerelle/contrib/toulouse_smart/models.py @@ -175,17 +175,17 @@ class ToulouseSmartResource(BaseResource, HTTPResource): data = {} cast = {'string': str, 'int': int, 'boolean': bool, 'item': str} for prop in intervention_type.get('properties') or []: - name = prop['name'].lower() - if block.get(name): + varname = slugify(prop['name']).replace('-', '_') + if block.get(varname): try: - data[prop['name']] = cast[prop['type']](block[name]) + data[prop['name']] = cast[prop['type']](block[varname]) except ValueError: raise APIError( - "cannot cast '%s' field to %s : '%s'" % (name, cast[prop['type']], block[name]), + "cannot cast '%s' field to %s : '%s'" % (varname, cast[prop['type']], block[varname]), http_status=400, ) elif prop['required']: - raise APIError("'%s' field is required on '%s' block" % (name, slug), http_status=400) + raise APIError("'%s' field is required on '%s' block" % (varname, slug), http_status=400) if self.wcs_requests.filter(wcs_form_api_url=post_data['form_api_url']): raise APIError( diff --git a/passerelle/contrib/toulouse_smart/templates/toulouse_smart/wcs_block.wcs b/passerelle/contrib/toulouse_smart/templates/toulouse_smart/wcs_block.wcs index 68fa3a1b..7dd1d321 100644 --- a/passerelle/contrib/toulouse_smart/templates/toulouse_smart/wcs_block.wcs +++ b/passerelle/contrib/toulouse_smart/templates/toulouse_smart/wcs_block.wcs @@ -8,7 +8,7 @@ {{ property.type }} {{ property.required }} - {{ property.name|slugify }} + {{ property.varname }} validation summary diff --git a/passerelle/contrib/toulouse_smart/views.py b/passerelle/contrib/toulouse_smart/views.py index 53eb31dc..e4524df5 100644 --- a/passerelle/contrib/toulouse_smart/views.py +++ b/passerelle/contrib/toulouse_smart/views.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import copy import hashlib import uuid import zipfile @@ -42,7 +43,9 @@ class TypeInterventionAsBlocks(DetailView): # generate file contents files = {} - for intervention_type in self.object.get_intervention_types(): + # do not alter the cached intervention_types + intervention_types = copy.deepcopy(self.object.get_intervention_types()) + for intervention_type in intervention_types: slug = slugify(intervention_type['name']) # only export intervention_type with properties if not intervention_type.get('properties'): @@ -50,6 +53,7 @@ class TypeInterventionAsBlocks(DetailView): for prop in intervention_type['properties']: # generate a natural id for fields prop['id'] = make_id(slug + slugify(prop['name'])) + prop['varname'] = slugify(prop['name']).replace('-', '_') # adapt types prop.setdefault('type', 'string') if prop['type'] == 'boolean': diff --git a/tests/test_toulouse_smart.py b/tests/test_toulouse_smart.py index 8827cc79..28028e8f 100644 --- a/tests/test_toulouse_smart.py +++ b/tests/test_toulouse_smart.py @@ -139,7 +139,7 @@ INTERVENTION_TYPES = ''' coin - FIELD1 + TYPE-OBJET Champ 1 string false @@ -174,7 +174,7 @@ def test_model_intervention_types(smart): 'order': 1, 'properties': [ { - 'name': 'FIELD1', + 'name': 'TYPE-OBJET', 'displayName': 'Champ 1', 'required': False, 'type': 'item', @@ -220,7 +220,7 @@ def test_manage_intervention_types(app, smart, admin_user): assert [[td.text for td in tr.cssselect('td,th')] for tr in resp.pyquery('tr')] == [ ["Nom du type d'intervention", 'Nom', 'Type', 'Requis', 'Valeur par défaut'], ['1 - coin'], - [None, 'FIELD1', 'item («Candélabre», «Mât», «Ne sait pas»)', '✘', 'Ne sait pas'], + [None, 'TYPE-OBJET', 'item («Candélabre», «Mât», «Ne sait pas»)', '✘', 'Ne sait pas'], [None, 'FIELD2', 'int', '✔', None], ['2 - empty'], ] @@ -236,11 +236,11 @@ def test_manage_intervention_types(app, smart, admin_user): coin - 038a8c2e-14de-4d4f-752f-496eb7fe90d7 + 522697a9-de01-b198-9e37-58c35718203a item False - field1 + type_objet validation summary @@ -338,8 +338,8 @@ CREATE_INTERVENTION_PAYLOAD_EXTRA = { FIELDS_PAYLOAD = { 'coin_raw': [ { - 'field1': 'Candélabre', - 'field1_raw': 'Candélabre', + 'type_objet': 'Candélabre', + 'type_objet_raw': 'Candélabre', 'field2': '42', }, ], @@ -369,7 +369,7 @@ CREATE_INTERVENTION_QUERY = { 'external_number': '42-2', 'external_status': 'statut-1-wcs', 'address': 'https://wcs.example.com/backoffice/management/foo/2/', - 'interventionData': {'FIELD1': 'Candélabre', 'FIELD2': 42}, + 'interventionData': {'TYPE-OBJET': 'Candélabre', 'FIELD2': 42}, 'geom': {'type': 'Point', 'coordinates': [2.323349, 48.833708], 'crs': 'EPSG:4326'}, 'interventionTypeId': '1234', 'notificationUrl': 'http://testserver/toulouse-smart/test/update-intervention?uuid=%s' % str(UUID), @@ -494,8 +494,8 @@ def test_create_intervention_missing_value(app, smart): field_payload = { 'coin_raw': [ { - 'field1': 'Candélabre', - 'field1_raw': 'Candélabre', + 'type_objet': 'Candélabre', + 'type_objet_raw': 'Candélabre', 'field2': None, }, ], @@ -514,8 +514,8 @@ def test_create_intervention_missing_field(app, smart): field_payload = { 'coin_raw': [ { - 'field1': 'Candélabre', - 'field1_raw': 'Candélabre', + 'type_objet': 'Candélabre', + 'type_objet_raw': 'Candélabre', }, ], } -- 2.34.1