From e271684ad7cb741eb60db1feaf7e41fa8896f7d9 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 11 Mar 2019 09:57:41 +0100 Subject: [PATCH] mdph13: keep computed display name on Link (#31249) --- .../migrations/0002_link_display_name.py | 20 ++++ passerelle/contrib/mdph13/models.py | 95 +++++++++++++------ tests/test_mdph13.py | 13 +++ 3 files changed, 97 insertions(+), 31 deletions(-) create mode 100644 passerelle/contrib/mdph13/migrations/0002_link_display_name.py diff --git a/passerelle/contrib/mdph13/migrations/0002_link_display_name.py b/passerelle/contrib/mdph13/migrations/0002_link_display_name.py new file mode 100644 index 0000000..a9c6d07 --- /dev/null +++ b/passerelle/contrib/mdph13/migrations/0002_link_display_name.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-03-11 10:05 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mdph13', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='link', + name='display_name', + field=models.CharField(blank=True, max_length=128, verbose_name='Display name'), + ), + ] diff --git a/passerelle/contrib/mdph13/models.py b/passerelle/contrib/mdph13/models.py index f92428c..f949d14 100644 --- a/passerelle/contrib/mdph13/models.py +++ b/passerelle/contrib/mdph13/models.py @@ -214,24 +214,13 @@ class MDPH13Resource(BaseResource, HTTPResource): if not self.EMAIL_RE.match(email): raise APIError('email is not valid', http_status=400) with transaction.atomic(): - link, created = Link.objects.get_or_create( + link, created, updated = Link.create_or_update( resource=self, - name_id=NameID, + NameID=NameID, file_number=file_number, - defaults={ - 'secret': secret, - 'dob': dob - }) - updated = False - if not created: - if link.secret != secret or link.dob != dob: - link.secret = secret - link.dob = dob - updated = True - # email is necessary for audit purpose - link.get_file(email=email) - if updated: - link.save() + secret=secret, + dob=dob, + email=email) return {'link_id': link.pk, 'created': created, 'updated': updated} @endpoint(name='unlink', @@ -262,19 +251,6 @@ class MDPH13Resource(BaseResource, HTTPResource): qs.delete() return {'deleted': count} - @classmethod - def _make_display_name(cls, mdph_file): - prenom = mdph_file.get('beneficiaire', {}).get('prenom') - nom = mdph_file.get('beneficiaire', {}).get('nom') - numero = mdph_file['numero'] - parts = [] - if prenom: - parts.append(prenom) - if nom: - parts.append(nom) - parts.append(u'#%s' % numero) - return ' '.join(parts) - @endpoint(name='dossiers', description=_('Get datas for all links, or for a specified one'), perm='can_access', @@ -322,15 +298,17 @@ class MDPH13Resource(BaseResource, HTTPResource): file_data.update(to_json().err_to_response(e)) else: file_data.update({ - 'text': self._make_display_name(mdph_file), + 'err': 0, 'dossier': mdph_file, }) + file_data['text'] = six.text_type(link) data.append(file_data) if link_id: return {'data': data[0] if data else None} return {'data': data} +@six.python_2_unicode_compatible class Link(models.Model): resource = models.ForeignKey( MDPH13Resource, @@ -349,14 +327,69 @@ class Link(models.Model): created = models.DateTimeField( verbose_name=_('Creation date'), auto_now_add=True) + display_name = models.CharField( + verbose_name=_('Display name'), + max_length=128, + blank=True) def get_file(self, email=None): # email is necessary for audit purpose - return self.resource.call_situation_dossier( + mdph_file = self.resource.call_situation_dossier( file_number=self.file_number, secret=self.secret, dob=self.dob, email=email) + display_name = self._make_display_name(mdph_file) + if self.display_name != display_name: + self.display_name = display_name + self.save() + return mdph_file + + @classmethod + def create_or_update(self, resource, NameID, file_number, secret, dob, email=None): + # email is necessary for audit purpose + mdph_file = resource.call_situation_dossier( + file_number=file_number, + secret=secret, + dob=dob, + email=email) + display_name = self._make_display_name(mdph_file) + + link, created = Link.objects.get_or_create( + resource=resource, + name_id=NameID, + file_number=file_number, + defaults={ + 'secret': secret, + 'dob': dob, + 'display_name': display_name, + }) + + updated = False + if not created: + if link.secret != secret or link.dob != dob or link.display_name != display_name: + link.secret = secret + link.dob = dob + link.display_name = display_name + link.save() + updated = True + return link, created, updated + + @classmethod + def _make_display_name(cls, mdph_file): + prenom = mdph_file.get('beneficiaire', {}).get('prenom') + nom = mdph_file.get('beneficiaire', {}).get('nom') + numero = mdph_file['numero'] + parts = [] + if prenom: + parts.append(prenom) + if nom: + parts.append(nom) + parts.append(u'#%s' % numero) + return ' '.join(parts) + + def __str__(self): + return self.display_name or u'#%s' % self.file_number class Meta: unique_together = ( diff --git a/tests/test_mdph13.py b/tests/test_mdph13.py index d5fdc10..c559ad2 100644 --- a/tests/test_mdph13.py +++ b/tests/test_mdph13.py @@ -475,13 +475,26 @@ def test_dossier_partial_failure(mdph13, mock_http): secret=SECRET, dob=DOB) mock_http.add_response(VALID_RESPONSE) + VALID_RESPONSE2 = json.loads(VALID_RESPONSE).copy() + VALID_RESPONSE2['data']['numero'] = FILE_NUMBER + '2' + mock_http.add_response(json.dumps(VALID_RESPONSE2)) + # test that display_name is updated if changed after any access + link2.refresh_from_db() + assert not link2.display_name + response = mdph13.dossiers(None, NAME_ID, EMAIL) + link2.refresh_from_db() + assert link2.display_name + mock_http.add_response(VALID_RESPONSE) mock_http.add_response({'status_code': 500, 'content': ''}) response = mdph13.dossiers(None, NAME_ID, EMAIL) assert response['data'] assert response['data'][0]['id'] == str(link1.pk) assert response['data'][0]['err'] == 0 + assert response['data'][0]['text'] == 'Alfonso Martini #' + FILE_NUMBER assert response['data'][1]['id'] == str(link2.pk) assert response['data'][1]['err'] == 1 + # verify display_name is returned even in case of failure + assert response['data'][1]['text'] == 'Alfonso Martini #' + FILE_NUMBER + '2' def test_dossier_bad_date(mdph13, mock_http): -- 2.20.1