Projet

Général

Profil

0001-solis_afi_mss-add-age-selections-on-children-endpoin.patch

Nicolas Roche, 11 février 2021 12:26

Télécharger (8,67 ko)

Voir les différences:

Subject: [PATCH] solis_afi_mss: add age selections on children endpoint
 (#51012)

 passerelle/contrib/solis_afi_mss/models.py | 47 +++++++++++-
 tests/test_solis_afi_mss.py                | 87 ++++++++++++++++++++++
 2 files changed, 132 insertions(+), 2 deletions(-)
passerelle/contrib/solis_afi_mss/models.py
9 9
# This program is distributed in the hope that it will be useful,
10 10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 12
# GNU Affero General Public License for more details.
13 13
#
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
from datetime import datetime
18
from dateutil.relativedelta import relativedelta
17 19
from urllib.parse import urljoin
18 20

  
19 21
from django.db import models
22
from django.utils import timezone
23
from django.utils.dateparse import parse_date
20 24
from django.utils.translation import ugettext_lazy as _
21 25

  
22 26
from passerelle.base.models import BaseResource, HTTPResource
23 27
from passerelle.utils.api import endpoint
24 28
from passerelle.utils.jsonresponse import APIError
25 29

  
26 30
TAX_SCHEMA = {
27 31
    '$schema': 'http://json-schema.org/draft-04/schema#',
......
182 186
        description=_('Retrieve adults from family composition'),
183 187
        parameters={
184 188
            'email': {'description': _("Agent's email address")},
185 189
        })
186 190
    def adults(self, request, email):
187 191
        adults = self.search_from_email(email)[1]
188 192
        return {'data': adults}
189 193

  
194
    @staticmethod
195
    def get_age(birthday_date_string, now_date_string=None):
196
        if now_date_string:
197
            try:
198
                now_date = parse_date(now_date_string)
199
            except ValueError as exc:
200
                raise APIError(
201
                    'input is well formatted but not a valid date: %s' % exc, http_status=400)
202
            if not now_date:
203
                raise APIError(
204
                    "input isn't well formatted, YYYY-MM-DD expected: %s" % birthday_date_string,
205
                    http_status=400)
206

  
207
        # ignore error we can get form Solis data
208
        try:
209
            birthday_date = parse_date(birthday_date_string)
210
        except ValueError as exc:
211
            birthday_date = None
212
        if not birthday_date:
213
            return None
214

  
215
        if not now_date_string:
216
            now_date = timezone.now().date()
217
        return relativedelta(now_date, birthday_date)
218

  
190 219
    @endpoint(
191 220
        display_category=_('Agent'), display_order=4,
192 221
        perm='can_access', methods=['get'],
193 222
        description=_('Retrieve children from family composition'),
194 223
        parameters={
195 224
            'email': {'description': _("Agent's email address")},
225
            'min_age': {'description': _("Integer to select childreen older or equal to this age")},
226
            'max_age': {'description': _("Integer to select childreen younger to this age")},
227
            'now': {'description': _("Reference date use to compute age")},
196 228
        })
197
    def children(self, request, email):
229
    def children(self, request, email, min_age=None, max_age=None, now=None):
198 230
        children = self.search_from_email(email)[2]
199
        return {'data': children}
231
        data = []
232
        for child in children:
233
            child_age = self.get_age(child.get('dateNaissance'), now)
234
            if child_age:
235
                # do not unselect childreen having no or wrongly formated dateNaissance
236
                if min_age and child_age.years < int(min_age):
237
                    continue
238
                if max_age and child_age.years >= int(max_age):
239
                    continue
240
                child['age'] = child_age.years
241
            data.append(child)
242
        return {'data': data}
200 243

  
201 244
    @endpoint(
202 245
        display_category=_('Budget'), display_order=1,
203 246
        perm='can_access', methods=['get'],
204 247
        description=_('Retrieve the list of charges for an agent'),
205 248
        parameters={
206 249
            'email': {'description': _("Agent's email address")},
207 250
            'year': {'description': _('Year of taxation (YYYY)')},
tests/test_solis_afi_mss.py
265 265
def test_children(mocked_get, app, connector, response1, children):
266 266
    mocked_get.side_effect = [response1]
267 267
    endpoint = get_endpoint('children') + '?email=foo@dummy.org'
268 268
    resp = app.get(endpoint)
269 269
    assert not resp.json['err']
270 270
    assert [(x['id'], x['text']) for x in resp.json['data']] == children
271 271

  
272 272

  
273
@pytest.mark.parametrize('index, name, birthday, age', [
274
    (123456, 'Nico', '1978-05-11', 42),
275
    (389229, 'Lola ROUSSEAU', '1995-07-25', 25),
276
    (389230, 'Nicolas ROUSSEAU', '1990-05-04', 30),
277
    (389231, 'Mélina ROUSSEAU', '1992-06-10', 28),
278
    (388413, 'KEVIN PIED', '1997-04-26', 23),
279
    (388407, 'Camille HUREL', '1991-08-24', 29),
280
    (388408, 'Valentin HUREL', '1996-08-05', 24),
281
])
282
def test_get_age(connector, index, name, birthday, age):
283
    assert connector.get_age(birthday, '2021-02-10').years == age
284

  
285

  
286
@mock.patch('passerelle.utils.Request.get')
287
@pytest.mark.parametrize('response1, children', [
288
    (RECHERCHE_PAR_EMAIL_1, []),
289
    (RECHERCHE_PAR_EMAIL_2, [
290
        (388413, 'KEVIN PIED'),
291
    ]),
292
    (RECHERCHE_PAR_EMAIL_3, []),
293
    (RECHERCHE_PAR_EMAIL_4, [
294
        (388408, 'Valentin HUREL'),
295
    ]),
296
])
297
def test_children_younger(mocked_get, freezer, app, connector, response1, children):
298
    freezer.move_to('2021-02-10')
299
    mocked_get.side_effect = [response1]
300
    endpoint = get_endpoint('children') + '?email=foo@dummy.org&max_age=25'
301
    resp = app.get(endpoint)
302
    assert not resp.json['err']
303
    assert [(x['id'], x['text']) for x in resp.json['data']] == children
304

  
305

  
306
@mock.patch('passerelle.utils.Request.get')
307
@pytest.mark.parametrize('response1, children', [
308
    (RECHERCHE_PAR_EMAIL_1, [
309
        (389229, 'Lola ROUSSEAU'),
310
        (389230, 'Nicolas ROUSSEAU'),
311
        (389231, 'Mélina ROUSSEAU'),
312
    ]),
313
    (RECHERCHE_PAR_EMAIL_2, []),
314
    (RECHERCHE_PAR_EMAIL_3, []),
315
    (RECHERCHE_PAR_EMAIL_4, [
316
        (388407, 'Camille HUREL'),
317
    ]),
318
])
319
def test_children_older(mocked_get, app, connector, response1, children):
320
    mocked_get.side_effect = [response1]
321
    endpoint = get_endpoint('children') + '?email=foo@dummy.org&min_age=25&now=2021-02-10'
322
    resp = app.get(endpoint)
323
    assert not resp.json['err']
324
    assert [(x['id'], x['text']) for x in resp.json['data']] == children
325

  
326

  
327
@mock.patch('passerelle.utils.Request.get')
328
@pytest.mark.parametrize('now, err_desc', [
329
    ('2012-02-30', 'not a valid date'),
330
    ('10/02/2012', 'YYYY-MM-DD expected'),
331
    ('tomorrow', 'YYYY-MM-DD expected'),
332
])
333
def test_children_younger_api_error(mocked_get, app, connector, now, err_desc):
334
    mocked_get.side_effect = [RECHERCHE_PAR_EMAIL_2]
335
    endpoint = get_endpoint('children') + '?email=foo@dummy.org&max_age=25&now=%s' % now
336
    resp = app.get(endpoint, status=400)
337
    assert resp.json['err']
338
    assert err_desc in resp.json['err_desc']
339

  
340

  
341
@mock.patch('passerelle.utils.Request.get')
342
@pytest.mark.parametrize('birthday, nb_selected', [
343
    ('2012-02-30', 1),
344
    ('10/02/2012', 1),
345
    ('tomorrow', 1),
346
    ('2012-02-10', 0),
347
])
348
def test_children_older_data_error(mocked_get, freezer, app, connector, birthday, nb_selected):
349
    freezer.move_to('2021-02-10')
350
    with open(os.path.join(TEST_BASE_DIR, "%s.json" % 'rechercherParEmail_388412')) as fd:
351
        content = json.load(fd)
352
    content['enfantsAgent'][0]['dateNaissance'] = birthday
353
    mocked_get.side_effect = [response(200, json.dumps(content))]
354
    endpoint = get_endpoint('children') + '?email=foo@dummy.org&min_age=99'
355
    resp = app.get(endpoint)
356
    assert not resp.json['err']
357
    assert len(resp.json['data']) == nb_selected
358

  
359

  
273 360
@mock.patch('passerelle.utils.Request.get')
274 361
@pytest.mark.parametrize('response1, response2, taxes', [
275 362
    (RECHERCHE_PAR_EMAIL_4, GET_IMPOSITION_PAR_AGENT_4,
276 363
     [(2018, '2018: 15000'), (2019, '2019: 1000')])
277 364
])
278 365
def test_taxes(mocked_get, app, connector, response1, response2, taxes):
279 366
    mocked_get.side_effect = [response1, response2]
280 367
    endpoint = get_endpoint('taxes') + '?email=foo@dummy.org'
281
-