From 66ebeb037f1377c7cdb4ae72cf34041a4e0edc85 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Fri, 14 May 2021 11:46:24 +0200
Subject: [PATCH] photon: add a stable identifiant (#53984)

---
 passerelle/apps/photon/models.py | 8 +++++++-
 tests/test_photon.py             | 4 ++--
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/passerelle/apps/photon/models.py b/passerelle/apps/photon/models.py
index 48df7b43..230ed5d7 100644
--- a/passerelle/apps/photon/models.py
+++ b/passerelle/apps/photon/models.py
@@ -10,20 +10,23 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import datetime
+import hashlib
+import json
 
 from django.contrib.postgres.fields import JSONField
 from django.db import models
 from django.utils import timezone
+from django.utils.encoding import force_bytes
 from django.utils.http import urlencode
 from django.utils.six.moves.urllib import parse as urlparse
 from django.utils.translation import ugettext_lazy as _
 from requests import RequestException
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
@@ -87,18 +90,21 @@ class Photon(BaseResource):
         if result['address'].get('house_number'):
             result['text'] += '%s, ' % result['address']['house_number']
         if result['address'].get('road'):
             result['text'] += '%s ' % result['address']['road']
         if result['address'].get('postcode'):
             result['text'] += '%s ' % result['address']['postcode']
         if result['address'].get('city'):
             result['text'] += '%s' % result['address']['city']
+        result['text'] = result['text'].strip()
         result['display_name'] = result['text']
-        result['id'] = data['properties']['osm_id']
+
+        dict_dump = json.dumps(result, sort_keys=True)
+        result['id'] = hashlib.md5(force_bytes(dict_dump)).hexdigest()
         return result
 
     @endpoint(
         pattern='(?P<q>.+)?$',
         description=_('Addresses list'),
         parameters={
             'id': {'description': _('Address identifier')},
             'q': {'description': _('Address'), 'example_value': '169 rue du chateau, paris'},
diff --git a/tests/test_photon.py b/tests/test_photon.py
index 0f130e2f..ed10c702 100644
--- a/tests/test_photon.py
+++ b/tests/test_photon.py
@@ -189,17 +189,17 @@ def test_photon_addresses(mocked_get, app, photon):
     assert endpoint == '/photon/test/addresses'
     mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
     resp = app.get(endpoint, params={'q': 'plop'}, status=200)
     data = resp.json['data'][0]
     assert data['lat'] == '45.7587414'
     assert data['lon'] == '4.8522272'
     assert data['display_name'] == '208, Rue Garibaldi 69003 Lyon 3ème Arrondissement'
     assert data['text'] == '208, Rue Garibaldi 69003 Lyon 3ème Arrondissement'
-    assert data['id'] == 154419
+    assert data['id'] == 'bbb027ea85b5f424f2efcc2d88c1f686'
     assert data['address']['city'] == 'Lyon 3ème Arrondissement'
     assert data['address']['postcode'] == '69003'
     assert data['address']['road'] == 'Rue Garibaldi'
 
 
 @mock.patch('passerelle.utils.Request.get')
 def test_photon_addresses_qs_page_limit(mocked_get, app, photon):
     resp = app.get('/photon/%s/addresses?q=plop&page_limit=1' % photon.slug)
@@ -271,17 +271,17 @@ def test_photon_addresses_clean_cache(app, photon, freezer, mock_photon_search):
 
     # asking for the address again resets the timestamp
     freezer.move_to(datetime.timedelta(hours=1, seconds=1))
     app.get('/photon/%s/addresses?q=plop' % photon.slug)
     call_command('cron', 'hourly')
     assert AddressCacheModel.objects.count() == 2
 
     freezer.move_to(datetime.timedelta(hours=1, seconds=1))
-    app.get('/photon/%s/addresses?id=%s' % (photon.slug, '154419'))
+    app.get('/photon/%s/addresses?id=%s' % (photon.slug, 'bbb027ea85b5f424f2efcc2d88c1f686'))
     call_command('cron', 'hourly')
     assert AddressCacheModel.objects.count() == 1
 
 
 @mock.patch('passerelle.utils.Request.get')
 def test_photon_addresses_data_change(mocked_get, app, photon):
     endpoint = utils.generic_endpoint_url('photon', 'addresses', slug=photon.slug)
     mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
-- 
2.30.2

