From 0321055c46e4a8002b0244e73be3ffb1295ef2b5 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Fri, 14 May 2021 12:33:15 +0200
Subject: [PATCH] base_adresse: add reverse endpoint result into address cache
 model (#53989)

---
 passerelle/apps/base_adresse/models.py |  5 +++++
 tests/conftest.py                      |  3 ++-
 tests/test_base_adresse.py             | 27 ++++++++++++++++++++++++++
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/passerelle/apps/base_adresse/models.py b/passerelle/apps/base_adresse/models.py
index af1eda32..2ce1b704 100644
--- a/passerelle/apps/base_adresse/models.py
+++ b/passerelle/apps/base_adresse/models.py
@@ -216,16 +216,21 @@ class BaseAdresse(BaseResource):
         except RequestException as e:
             raise APIError('failed to get %s: %s' % (url, e))
         result = None
 
         for feature in result_response.json().get('features'):
             if not feature['geometry']['type'] == 'Point':
                 continue  # skip unknown
             result = self.format_address_data(feature)
+            address, created = AddressCacheModel.objects.get_or_create(
+                api_id=result['id'], defaults={'data': result}
+            )
+            if not created:
+                address.update_timestamp()
             break
         return result
 
     @endpoint(
         description=_('Streets from zipcode'),
         parameters={
             'id': {'description': _('Street identifier')},
             'q': {'description': _("Street name")},
diff --git a/tests/conftest.py b/tests/conftest.py
index 4565f594..5453a2fc 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -57,16 +57,17 @@ def api_adresse_data_gouv_fr_search(url, request):
                 }
             ],
         },
         request=request,
     )
 
 
 @urlmatch(netloc='^api-adresse.data.gouv.fr$', path='^/reverse/$')
+@remember_called
 def api_adresse_data_gouv_fr_reverse(url, request):
     return response(
         200,
         {
             "limit": 1,
             "attribution": "BAN",
             "version": "draft",
             "licence": "ODbL 1.0",
@@ -98,17 +99,17 @@ def api_adresse_data_gouv_fr_reverse(url, request):
 def mock_api_adresse_data_gouv_fr_search():
     with HTTMock(api_adresse_data_gouv_fr_search):
         yield api_adresse_data_gouv_fr_search
 
 
 @pytest.fixture
 def mock_api_adresse_data_gouv_fr_reverse():
     with HTTMock(api_adresse_data_gouv_fr_reverse):
-        yield None
+        yield api_adresse_data_gouv_fr_reverse
 
 
 @pytest.fixture
 def endpoint_dummy_cache(monkeypatch):
     from django.core.cache import caches
 
     import passerelle.views
 
diff --git a/tests/test_base_adresse.py b/tests/test_base_adresse.py
index 334e64d6..18f90f36 100644
--- a/tests/test_base_adresse.py
+++ b/tests/test_base_adresse.py
@@ -906,8 +906,35 @@ def test_base_adresse_addresses_data_change(mocked_get, app, base_adresse):
     # first user saves the form, data should not have changed
     resp = app.get(endpoint, params={'id': address_id}, status=200)
     assert resp.json['data'][0]['text'] == address_text
 
     # when cache is cleared, we get the updated data
     AddressCacheModel.objects.all().delete()
     resp = app.get(endpoint, params={'q': 'plop'}, status=200)
     assert resp.json['data'][0]['text'] == 'changed'
+
+
+def test_base_adresse_reverse_cache(
+    app, base_adresse, freezer, mock_api_adresse_data_gouv_fr_reverse, mock_api_adresse_data_gouv_fr_search
+):
+    assert AddressCacheModel.objects.count() == 0
+    resp = app.get('/base-adresse/%s/reverse?lon=-0.593775&lat=47.474633' % base_adresse.slug)
+    assert mock_api_adresse_data_gouv_fr_reverse.call['count'] == 1
+
+    data = resp.json
+    assert data['text'] == 'Rue Roger Halope 49000 Angers'
+
+    api_id = data['id']
+    assert AddressCacheModel.objects.filter(api_id=api_id).exists()
+    assert AddressCacheModel.objects.count() == 1
+    first_timestamp = AddressCacheModel.objects.get().timestamp
+
+    resp = app.get('/base-adresse/%s/addresses?id=%s' % (base_adresse.slug, api_id))
+    assert mock_api_adresse_data_gouv_fr_search.call['count'] == 0
+    assert data['text'] == 'Rue Roger Halope 49000 Angers'
+    assert 'address' in data
+
+    # check caching timestamp update
+    freezer.move_to(datetime.timedelta(hours=1, seconds=1))
+    resp = app.get('/base-adresse/%s/reverse?lon=-0.593775&lat=47.474633' % base_adresse.slug)
+    assert mock_api_adresse_data_gouv_fr_reverse.call['count'] == 2
+    assert AddressCacheModel.objects.get().timestamp > first_timestamp
-- 
2.30.2

