Projet

Général

Profil

0002-base_adresse-add-lat-lon-type-to-address-id-to-get-b.patch

Benjamin Dauvergne, 15 juillet 2021 15:51

Télécharger (7,34 ko)

Voir les différences:

Subject: [PATCH 2/2] base_adresse: add lat/lon/type to address'id to get by id
 through reverse (#55522)

 passerelle/apps/base_adresse/models.py | 35 +++++++++++++++++++-------
 tests/test_base_adresse.py             | 28 +++++++++++++++++----
 2 files changed, 49 insertions(+), 14 deletions(-)
passerelle/apps/base_adresse/models.py
87 87
                    value = value[len(house_number) :].strip()
88 88
                result['address']['road'] = value
89 89
            elif prop == 'id':
90
                result['id'] = value
90
                result['ban_id'] = value
91
                result['id'] = '%s~%s~%s' % (value, result['lat'], result['lon'])
92
        result['id'] = '%s~%s' % (result['id'], result['text'])
91 93
        return result
92 94

  
93 95
    @endpoint(
......
117 119
        self, request, id=None, q=None, zipcode='', citycode=None, lat=None, lon=None, page_limit=5
118 120
    ):
119 121
        if id is not None:
120
            return self.get_by_id(request, id=id)
122
            return self.get_by_id(request, id=id, citycode=citycode)
121 123

  
122 124
        if not q:
123 125
            return {'data': []}
......
155 157
            data = self.format_address_data(feature)
156 158
            result.append(data)
157 159
            address, created = AddressCacheModel.objects.get_or_create(
158
                api_id=data['id'], defaults={'data': data}
160
                api_id=data['id'][:30], defaults={'data': data}
159 161
            )
160 162
            if not created:
161 163
                address.update_timestamp()
162 164

  
163 165
        return {'data': result}
164 166

  
165
    def get_by_id(self, request, id):
167
    def get_by_id(self, request, id, citycode=None):
166 168
        try:
167
            address = AddressCacheModel.objects.get(api_id=id)
169
            ban_id, lat, lon, q = id.split('~', 4)
170
        except ValueError:  # retrocompatibility with raw BAN id
171
            ban_id = id
172
            lat, lon, q = None, None, None
173
        # Try cache
174
        try:
175
            address = AddressCacheModel.objects.get(api_id=id[:30])
168 176
        except AddressCacheModel.DoesNotExist:
169
            return {'err': _('Address ID not found')}
170
        address.update_timestamp()
171
        return {'data': [address.data]}
177
            pass
178
        else:
179
            address.update_timestamp()
180
            return {'data': [address.data]}
181
        # Use search with label as q and lat/lon as geographic hint
182
        if q and lat and lon:
183
            results = self.addresses(request, q=q, lat=lat, lon=lon, citycode=citycode)['data']
184
            for result in results:  # match by id if possible
185
                if result['ban_id'] == ban_id:
186
                    return {'data': [result]}
187
            self.logger.error('get_by_id: id %s was not found', id)
188
        return {'err': _('Address ID not found')}
172 189

  
173 190
    @endpoint(
174 191
        pattern='(?P<q>.+)?$',
......
225 242
                continue  # skip unknown
226 243
            result = self.format_address_data(feature)
227 244
            address, created = AddressCacheModel.objects.get_or_create(
228
                api_id=result['id'], defaults={'data': result}
245
                api_id=result['id'][:30], defaults={'data': result}
229 246
            )
230 247
            if not created:
231 248
                address.update_timestamp()
tests/test_base_adresse.py
797 797
    assert data['lon'] == '-0.593775'
798 798
    assert data['display_name'] == 'Rue Roger Halope 49000 Angers'
799 799
    assert data['text'] == 'Rue Roger Halope 49000 Angers'
800
    assert data['id'] == '49007_6950_be54bd'
800
    assert data['id'] == '49007_6950_be54bd~47.474633~-0.593775~Rue Roger Halope 49000 Angers'
801 801
    assert data['address']['city'] == 'Angers'
802 802
    assert data['address']['postcode'] == '49000'
803 803
    assert data['address']['citycode'] == '49007'
......
833 833
    assert 'lon=43' in mocked_get.call_args[0][0]
834 834

  
835 835

  
836
def test_base_adresse_addresses_cache(app, base_adresse, mock_api_adresse_data_gouv_fr_search):
836
def test_base_adresse_addresses_cache(app, base_adresse, mock_api_adresse_data_gouv_fr_search, caplog):
837 837
    resp = app.get('/base-adresse/%s/addresses?q=plop' % base_adresse.slug)
838 838
    assert mock_api_adresse_data_gouv_fr_search.call['count'] == 1
839 839

  
......
841 841
    assert data['text'] == 'Rue Roger Halope 49000 Angers'
842 842

  
843 843
    api_id = data['id']
844
    assert AddressCacheModel.objects.filter(api_id=api_id).exists()
844
    assert AddressCacheModel.objects.filter(api_id=api_id[:30]).exists()
845 845
    assert AddressCacheModel.objects.count() == 1
846 846

  
847 847
    resp = app.get('/base-adresse/%s/addresses?id=%s' % (base_adresse.slug, api_id))
......
851 851

  
852 852
    resp = app.get('/base-adresse/%s/addresses?q=plop' % base_adresse.slug)
853 853
    assert AddressCacheModel.objects.count() == 1  # no new object has been created
854
    assert mock_api_adresse_data_gouv_fr_search.call['count'] == 2
855

  
856
    # no cache
857
    AddressCacheModel.objects.all().delete()
858
    resp = app.get('/base-adresse/%s/addresses?id=%s' % (base_adresse.slug, api_id))
859
    assert AddressCacheModel.objects.count() == 1
860
    assert mock_api_adresse_data_gouv_fr_search.call['count'] == 3
861
    assert data['text'] == 'Rue Roger Halope 49000 Angers'
862
    assert 'address' in data
863

  
864
    # no cache and id has changed
865
    AddressCacheModel.objects.all().delete()
866
    api_id = '49007_XXXX_be54bd~47.474633~-0.593775~Rue%20Roger%20Halope%2049000%20Angers'
867
    resp = app.get('/base-adresse/%s/addresses?id=%s' % (base_adresse.slug, api_id))
868
    assert resp.json['err'] == 'Address ID not found'
854 869

  
855 870

  
856 871
def test_base_adresse_addresses_cache_err(app, base_adresse, mock_api_adresse_data_gouv_fr_search):
......
882 897
    assert AddressCacheModel.objects.count() == 1
883 898

  
884 899
    freezer.move_to(datetime.timedelta(hours=1, seconds=1))
885
    resp = app.get('/base-adresse/%s/addresses?id=%s' % (base_adresse.slug, '49007_6950_be54bd'))
900
    resp = app.get(
901
        '/base-adresse/%s/addresses?id=%s'
902
        % (base_adresse.slug, '49007_6950_be54bd~47.474633~-0.593775~Rue%20Roger%20Halope%2049000%20Angers')
903
    )
886 904
    call_command('cron', 'hourly')
887 905
    assert AddressCacheModel.objects.count() == 1
888 906

  
......
924 942
    assert data['text'] == 'Rue Roger Halope 49000 Angers'
925 943

  
926 944
    api_id = data['id']
927
    assert AddressCacheModel.objects.filter(api_id=api_id).exists()
945
    assert AddressCacheModel.objects.filter(api_id=api_id[:30]).exists()
928 946
    assert AddressCacheModel.objects.count() == 1
929 947
    first_timestamp = AddressCacheModel.objects.get().timestamp
930 948

  
931
-