Projet

Général

Profil

0002-toulouse_axel-endpoint-to-get-possible-days-for-an-a.patch

Lauréline Guérin, 31 mars 2020 11:22

Télécharger (13,4 ko)

Voir les différences:

Subject: [PATCH 2/2] toulouse_axel: endpoint to get possible days for an
 activity (#41168)

 passerelle/contrib/toulouse_axel/models.py |  52 +++++++--
 tests/test_toulouse_axel.py                | 121 +++++++++++++++++++++
 2 files changed, 163 insertions(+), 10 deletions(-)
passerelle/contrib/toulouse_axel/models.py
26 26
from django.core.cache import cache
27 27
from django.db import models
28 28
from django.http import HttpResponse
29
from django.utils.dates import WEEKDAYS
29 30
from django.utils.encoding import force_text
30 31
from django.utils.translation import ugettext_lazy as _
31 32

  
......
1009 1010
                      'xml_response': e.xml_response})
1010 1011
        return {'data': True}
1011 1012

  
1012
    def get_children_activities(self, dui, reference_year):
1013
    def get_children_activities(self, dui, reference_year, activity_types=None):
1014
        activity_types = activity_types or ['MAT', 'MIDI', 'SOIR', 'GARD']
1013 1015
        try:
1014 1016
            result = enfants_activites(self, {
1015 1017
                'DUI': {
1016 1018
                    'IDDUI': dui,
1017 1019
                    'ANNEEREFERENCE': str(reference_year),
1018
                    'TYPESACTIVITES': 'MAT,MIDI,SOIR,GARD',
1020
                    'TYPESACTIVITES': ','.join(activity_types),
1019 1021
                }
1020 1022
            })
1021 1023
        except AxelError as e:
......
1028 1030
        children_activities = result.json_response['DATA']['PORTAIL']['DUI'].get('ENFANT', [])
1029 1031
        return {child['IDPERSONNE']: child for child in children_activities}
1030 1032

  
1031
    def get_child_activities(self, dui, reference_year, child_id):
1032
        children_activities = self.get_children_activities(dui=dui, reference_year=reference_year)
1033
    def get_child_activities(self, dui, reference_year, child_id, activity_types=None):
1034
        children_activities = self.get_children_activities(
1035
            dui=dui, reference_year=reference_year, activity_types=activity_types)
1033 1036

  
1034 1037
        if child_id not in children_activities:
1035 1038
            raise APIError('Child not found', err_code='not-found')
......
1056 1059
            return {}
1057 1060
        return {child_id: bool(child.get('ACTIVITE', [])) for child_id, child in children_activities.items()}
1058 1061

  
1059
    def get_booking_data(self, dui, child_id, booking_date):
1062
    def get_booking_data(self, dui, child_id, booking_date, activity_types=None):
1060 1063
        reference_year = utils.get_reference_year_from_date(booking_date)
1061 1064

  
1062 1065
        # first get activities information for the child
1063 1066
        child_activities = self.get_child_activities(
1064 1067
            dui=dui,
1065 1068
            reference_year=reference_year,
1066
            child_id=child_id)
1069
            child_id=child_id,
1070
            activity_types=activity_types)
1067 1071

  
1068 1072
        # then get booking of the requested week for the child
1069 1073
        activity_ids = [act['IDACTIVITE'] for act in child_activities.get('ACTIVITE', [])]
......
1159 1163
            'idpersonne': {'description': _('Child ID')},
1160 1164
            'booking_date': {'description': _('Booking date')},
1161 1165
        })
1162
    def clae_booking_info(self, request, NameID, idpersonne, booking_date):
1166
    def clae_booking_info(self, request, NameID, idpersonne, booking_date, activity_types=None):
1163 1167
        link = self.get_link(NameID)
1164 1168
        try:
1165 1169
            booking_date = datetime.datetime.strptime(booking_date, utils.json_date_format)
1166 1170
        except ValueError:
1167 1171
            raise APIError('bad date format, should be YYYY-MM-DD', err_code='bad-request', http_status=400)
1168 1172

  
1169
        booking_data = self.get_booking_data(dui=link.dui, child_id=idpersonne, booking_date=booking_date)
1173
        booking_data = self.get_booking_data(dui=link.dui, child_id=idpersonne, booking_date=booking_date, activity_types=activity_types)
1170 1174

  
1171 1175
        return {'data': booking_data}
1172 1176

  
......
1178 1182
            'idpersonne': {'description': _('Child ID')},
1179 1183
            'booking_date': {'description': _('Booking date')},
1180 1184
        })
1181
    def clae_booking_activities_info(self, request, NameID, idpersonne, booking_date):
1182
        return {'data': self.clae_booking_info(request, NameID, idpersonne, booking_date)['data'].get('ACTIVITE', [])}
1185
    def clae_booking_activities_info(self, request, NameID, idpersonne, booking_date, activity_types=None):
1186
        return {'data': self.clae_booking_info(
1187
            request, NameID, idpersonne, booking_date, activity_types=activity_types)['data'].get('ACTIVITE', [])}
1188

  
1189
    @endpoint(
1190
        description=_("Get list of possible days for an activity"),
1191
        perm='can_access',
1192
        parameters={
1193
            'NameID': {'description': _('Publik ID')},
1194
            'idpersonne': {'description': _('Child ID')},
1195
            'activity_type': {'description': _('Activity type (MAT, MIDI, SOIR, GARD)')},
1196
            'booking_date': {'description': _('Booking date')},
1197
        })
1198
    def clae_booking_activity_possible_days(self, request, NameID, idpersonne, activity_type, booking_date):
1199
        if activity_type not in ['MAT', 'MIDI', 'SOIR', 'GARD']:
1200
            raise APIError('bad activity_type, should be MAT, MIDI, SOIR or GARD', err_code='bad-request', http_status=400)
1201
        activities = self.clae_booking_activities_info(request, NameID, idpersonne, booking_date, activity_types=[activity_type])['data']
1202
        if not activities:
1203
            return {'data': []}
1204
        activity = activities[0]
1205
        activity_days = []
1206
        for i, day in enumerate(['monday', 'tuesday', 'wednesday', 'thursday', 'friday']):
1207
            activity_days.append({
1208
                'id': '{}-{}-{}-{}'.format(idpersonne, activity_type, activity['id'], day),
1209
                'text': WEEKDAYS[i],
1210
                'disabled': activity['booking']['days'][day] is None,
1211
                'prefill': activity['booking']['days'][day],
1212
                'details': activity,
1213
            })
1214
        return {'data': activity_days}
1183 1215

  
1184 1216
    @endpoint(
1185 1217
        description=_("CLAE/Cantine booking"),
tests/test_toulouse_axel.py
2506 2506
    ]
2507 2507

  
2508 2508

  
2509
def test_clae_booking_activity_possible_days_endpoint_axel_error(app, resource):
2510
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
2511
    with mock.patch('passerelle.contrib.toulouse_axel.models.enfants_activites') as operation:
2512
        operation.side_effect = AxelError('FooBar')
2513
        resp = app.get('/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535&booking_date=2020-01-20&activity_type=MAT')
2514
    assert resp.json['err_desc'] == "Axel error: FooBar"
2515
    assert resp.json['err'] == 'error'
2516

  
2517
    filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
2518
    with open(filepath) as xml:
2519
        content = xml.read()
2520
    with mock_getdata(content, 'EnfantsActivites'):
2521
        with mock.patch('passerelle.contrib.toulouse_axel.models.reservation_periode') as operation:
2522
            operation.side_effect = AxelError('FooBar')
2523
            resp = app.get('/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535&booking_date=2020-01-20&activity_type=MAT')
2524
    assert resp.json['err_desc'] == "Axel error: FooBar"
2525
    assert resp.json['err'] == 'error'
2526

  
2527

  
2528
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
2529
def test_clae_booking_activity_possible_days_endpoint_bad_date_format(app, resource, value):
2530
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
2531
    resp = app.get('/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535&booking_date=%s&activity_type=MAT' % value, status=400)
2532
    assert resp.json['err_desc'] == "bad date format, should be YYYY-MM-DD"
2533
    assert resp.json['err'] == 'bad-request'
2534

  
2535

  
2536
def test_clae_booking_activity_possible_days_endpoint_activity_type(app, resource):
2537
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
2538
    resp = app.get('/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535&booking_date=2020-01-20&activity_type=FOO', status=400)
2539
    assert resp.json['err_desc'] == "bad activity_type, should be MAT, MIDI, SOIR or GARD"
2540
    assert resp.json['err'] == 'bad-request'
2541

  
2542

  
2543
def test_clae_booking_activity_possible_days_endpoint_no_result(app, resource, child_activities_data):
2544
    resp = app.get('/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535&booking_date=2020-01-20&activity_type=MAT')
2545
    assert resp.json['err_desc'] == "Person not found"
2546
    assert resp.json['err'] == 'not-found'
2547

  
2548
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
2549
    filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
2550
    with open(filepath) as xml:
2551
        content = xml.read()
2552
    with mock_getdata(content, 'EnfantsActivites'):
2553
        with mock.patch('passerelle.contrib.toulouse_axel.models.reservation_periode') as operation:
2554
            operation.side_effect = AxelError('FooBar')
2555
            resp = app.get('/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=4242&booking_date=2020-01-20&activity_type=MAT')
2556
    assert resp.json['err_desc'] == "Child not found"
2557
    assert resp.json['err'] == 'not-found'
2558

  
2559
    content = """<PORTAIL>
2560
  <DUI>
2561
    <IDDUI>XXX</IDDUI>
2562
    <ENFANT>
2563
      <IDPERSONNE>4242</IDPERSONNE>
2564
      <ACTIVITE>
2565
        <ANNEEREFERENCE>2019</ANNEEREFERENCE>
2566
        <IDACTIVITE>A19P1M1</IDACTIVITE>
2567
        <JOUR>00000</JOUR>
2568
      </ACTIVITE>
2569
    </ENFANT>
2570
  </DUI>
2571
</PORTAIL>"""
2572
    activities = child_activities_data['ENFANT'][0]
2573
    with mock_getdata(content, 'ReservationPeriode'):
2574
        with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities):
2575
            resp = app.get('/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535&booking_date=2020-01-20&activity_type=MAT')
2576
    assert resp.json['err_desc'] == "Child not found"
2577
    assert resp.json['err'] == 'not-found'
2578

  
2579
    with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.clae_booking_activities_info') as activities_info:
2580
        activities_info.return_value = {'data': []}
2581
        resp = app.get('/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535&booking_date=2020-01-20&activity_type=MAT')
2582
    assert resp.json['err'] == 0
2583
    assert resp.json['data'] == []
2584

  
2585

  
2586
def test_clae_booking_activity_possible_days_endpoint(app, resource, child_activities_data):
2587
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
2588
    content = """<PORTAIL>
2589
  <DUI>
2590
    <IDDUI>XXX</IDDUI>
2591
    <ENFANT>
2592
      <IDPERSONNE>3535</IDPERSONNE>
2593
      <ACTIVITE>
2594
        <ANNEEREFERENCE>2019</ANNEEREFERENCE>
2595
        <IDACTIVITE>A19P1M1</IDACTIVITE>
2596
        <JOUR>10201</JOUR>
2597
      </ACTIVITE>
2598
    </ENFANT>
2599
  </DUI>
2600
</PORTAIL>"""
2601
    activities = child_activities_data['ENFANT'][0]
2602
    with mock_getdata(content, 'ReservationPeriode'):
2603
        with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities):
2604
            resp = app.get('/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535&booking_date=2020-01-20&activity_type=MAT')
2605
    assert resp.json['err'] == 0
2606
    assert len(resp.json['data']) == 5
2607
    assert set(resp.json['data'][0].keys()) == set(['id', 'text', 'disabled', 'prefill', 'details'])
2608
    assert resp.json['data'][0]['id'] == '3535-MAT-A19P1M1-monday'
2609
    assert resp.json['data'][1]['id'] == '3535-MAT-A19P1M1-tuesday'
2610
    assert resp.json['data'][2]['id'] == '3535-MAT-A19P1M1-wednesday'
2611
    assert resp.json['data'][3]['id'] == '3535-MAT-A19P1M1-thursday'
2612
    assert resp.json['data'][4]['id'] == '3535-MAT-A19P1M1-friday'
2613
    assert resp.json['data'][0]['text'] == 'Monday'
2614
    assert resp.json['data'][1]['text'] == 'Tuesday'
2615
    assert resp.json['data'][2]['text'] == 'Wednesday'
2616
    assert resp.json['data'][3]['text'] == 'Thursday'
2617
    assert resp.json['data'][4]['text'] == 'Friday'
2618
    assert resp.json['data'][0]['disabled'] is False
2619
    assert resp.json['data'][1]['disabled'] is False
2620
    assert resp.json['data'][2]['disabled'] is True
2621
    assert resp.json['data'][3]['disabled'] is False
2622
    assert resp.json['data'][4]['disabled'] is False
2623
    assert resp.json['data'][0]['prefill'] is True
2624
    assert resp.json['data'][1]['prefill'] is False
2625
    assert resp.json['data'][2]['prefill'] is None
2626
    assert resp.json['data'][3]['prefill'] is False
2627
    assert resp.json['data'][4]['prefill'] is True
2628

  
2629

  
2509 2630
def test_are_children_registered_axel_error(resource):
2510 2631
    with mock.patch('passerelle.contrib.toulouse_axel.models.enfants_activites') as operation:
2511 2632
        operation.side_effect = AxelError('FooBar')
2512
-