Projet

Général

Profil

0001-caluire-axel-set_activity_agenda_typical_week-endpoi.patch

Lauréline Guérin, 18 juin 2021 09:44

Télécharger (16,9 ko)

Voir les différences:

Subject: [PATCH] caluire-axel: set_activity_agenda_typical_week endpoint
 (#54383)

 passerelle/contrib/caluire_axel/models.py  |  88 +++++++
 passerelle/contrib/caluire_axel/schemas.py |  32 +++
 tests/test_caluire_axel.py                 | 254 +++++++++++++++++++++
 3 files changed, 374 insertions(+)
passerelle/contrib/caluire_axel/models.py
34 34

  
35 35
from . import schemas, utils
36 36

  
37
WEEKDAYS = {
38
    0: 'monday',
39
    1: 'tuesday',
40
    2: 'wednesday',
41
    3: 'thursday',
42
    4: 'friday',
43
    5: 'saturday',
44
    6: 'sunday',
45
}
46

  
37 47

  
38 48
class CaluireAxel(BaseResource):
39 49

  
......
811 821
            'count': updated,
812 822
        }
813 823

  
824
    @endpoint(
825
        display_category=_('Schooling'),
826
        display_order=7,
827
        description=_("Set activity agenda for a child with a typical week"),
828
        perm='can_access',
829
        parameters={
830
            'NameID': {'description': _('Publik ID')},
831
        },
832
        post={
833
            'request_body': {
834
                'schema': {
835
                    'application/json': schemas.TYPICAL_WEEK_BOOKING_SCHEMA,
836
                }
837
            }
838
        },
839
    )
840
    def set_activity_agenda_typical_week(self, request, NameID, post_data):
841
        link = self.get_link(NameID)
842
        child_id = post_data['child_id']
843
        child_data = self.get_child_data(link.family_id, child_id)
844
        if child_data is None:
845
            raise APIError('Child not found', err_code='not-found')
846
        start_date, end_date, reference_year = self.get_start_and_end_dates(
847
            post_data['start_date'], post_data['end_date']
848
        )
849
        activity_id = post_data['activity_id']
850
        activity_data = self.get_child_activity(child_id, activity_id, reference_year)
851
        if activity_data is None:
852
            raise APIError('Activity not found', err_code='not-found')
853

  
854
        if activity_id.startswith('CJ'):
855
            raise APIError('Not available for this activity', err_code='bad-request', http_status=400)
856

  
857
        booking_date = start_date
858
        bookings = []
859
        while booking_date <= end_date:
860
            if WEEKDAYS[booking_date.weekday()] in post_data['booking_list']:
861
                bookings.append(
862
                    {
863
                        'JOURDATE': booking_date.strftime(axel.json_date_format),
864
                        'MATIN': 'X',
865
                        'MIDI': None,
866
                        'APRESMIDI': None,
867
                    }
868
                )
869
            booking_date += datetime.timedelta(days=1)
870

  
871
        if bookings:
872
            # don't call axel if no changes
873
            try:
874
                data = {
875
                    'PORTAIL': {
876
                        'SETAGENDA': {
877
                            'IDENTINDIVIDU': child_id,
878
                            'ACTIVITE': {
879
                                'IDENTACTIVITE': activity_id,
880
                                'JOUR': bookings,
881
                            },
882
                        }
883
                    }
884
                }
885
                result = schemas.set_agenda(self, data)
886
            except axel.AxelError as e:
887
                raise APIError(
888
                    'Axel error: %s' % e,
889
                    err_code='error',
890
                    data={'xml_request': e.xml_request, 'xml_response': e.xml_response},
891
                )
892

  
893
            code = result.json_response['DATA']['PORTAIL']['SETAGENDA']['CODE']
894
            if code != 0:
895
                raise APIError('Wrong agenda status', err_code='agenda-code-error-%s' % code)
896

  
897
        return {
898
            'updated': True,
899
            'count': len(bookings),
900
        }
901

  
814 902
    def get_invoices(self, regie_id, family_id):
815 903
        try:
816 904
            result = schemas.get_factures_a_payer(
passerelle/contrib/caluire_axel/schemas.py
147 147
    ],
148 148
}
149 149

  
150
TYPICAL_WEEK_BOOKING_SCHEMA = {
151
    'type': 'object',
152
    'properties': {
153
        'child_id': {
154
            'type': 'string',
155
            'minLength': 1,
156
            'maxLength': 8,
157
        },
158
        'activity_id': {
159
            'type': 'string',
160
            'minLength': 1,
161
            'maxLength': 10,
162
        },
163
        'booking_list': {
164
            'type': 'array',
165
            'items': {
166
                'type': 'string',
167
                'pattern': '(monday|tuesday|thursday|friday)',
168
            },
169
        },
170
        'start_date': copy.deepcopy(axel.date_type),
171
        'end_date': copy.deepcopy(axel.date_type),
172
    },
173
    'required': [
174
        'child_id',
175
        'activity_id',
176
        'booking_list',
177
        'start_date',
178
        'end_date',
179
    ],
180
}
181

  
150 182

  
151 183
PAYMENT_SCHEMA = {
152 184
    'type': 'object',
tests/test_caluire_axel.py
147 147
    }
148 148

  
149 149

  
150
@pytest.fixture
151
def week_booking_params():
152
    return {
153
        'child_id': '50632',
154
        'activity_id': 'ELEM',
155
        'booking_list': [],
156
        'start_date': '2020-09-01',
157
        'end_date': '2021-08-31',
158
    }
159

  
160

  
150 161
@pytest.fixture
151 162
def upload_attachments_params():
152 163
    return {
......
2020 2031
    assert resp.json['err'] == 'agenda-code-error-%s' % code
2021 2032

  
2022 2033

  
2034
@freezegun.freeze_time('2020-09-01')
2035
def test_set_activity_agenda_typical_week_endpoint_axel_error(
2036
    app, resource, family_data, activities, week_booking_params
2037
):
2038
    week_booking_params['booking_list'] = ['monday']
2039
    Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
2040
    with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
2041
        operation.side_effect = AxelError('FooBar')
2042
        resp = app.post_json(
2043
            '/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy', params=week_booking_params
2044
        )
2045
    assert resp.json['err_desc'] == "Axel error: FooBar"
2046
    assert resp.json['err'] == 'error'
2047

  
2048
    filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
2049
    with open(filepath) as xml:
2050
        content = xml.read()
2051
    with mock_data(content, 'GetFamilleIndividus'):
2052
        with mock.patch('passerelle.contrib.caluire_axel.schemas.get_list_activites') as operation:
2053
            operation.side_effect = AxelError('FooBar')
2054
            resp = app.post_json(
2055
                '/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy', params=week_booking_params
2056
            )
2057
    assert resp.json['err_desc'] == "Axel error: FooBar"
2058
    assert resp.json['err'] == 'error'
2059

  
2060
    with mock.patch(
2061
        'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
2062
        return_value=family_data,
2063
    ):
2064
        with mock.patch(
2065
            'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
2066
            return_value=activities,
2067
        ):
2068
            with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
2069
                operation.side_effect = AxelError('FooBar')
2070
                resp = app.post_json(
2071
                    '/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
2072
                    params=week_booking_params,
2073
                )
2074
    assert resp.json['err_desc'] == "Axel error: FooBar"
2075
    assert resp.json['err'] == 'error'
2076

  
2077

  
2078
def test_set_activity_agenda_typical_week_endpoint_no_result(app, resource, week_booking_params):
2079
    week_booking_params['child_id'] = 'zzz'
2080
    resp = app.post_json(
2081
        '/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy', params=week_booking_params
2082
    )
2083
    assert resp.json['err_desc'] == "Person not found"
2084
    assert resp.json['err'] == 'not-found'
2085

  
2086
    Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
2087
    filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
2088
    with open(filepath) as xml:
2089
        content = xml.read()
2090
    with mock_data(content, 'GetFamilleIndividus'):
2091
        resp = app.post_json(
2092
            '/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy', params=week_booking_params
2093
        )
2094
        assert resp.json['err_desc'] == "Child not found"
2095
        assert resp.json['err'] == 'not-found'
2096

  
2097

  
2098
def test_set_activity_agenda_typical_week_endpoint_date_error(app, resource, week_booking_params):
2099
    Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
2100
    filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
2101
    with open(filepath) as xml:
2102
        content = xml.read()
2103
    with mock_data(content, 'GetFamilleIndividus'):
2104
        week_booking_params['start_date'] = '2021-09-01'
2105
        week_booking_params['end_date'] = '2021-08-31'
2106
        resp = app.post_json(
2107
            '/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
2108
            params=week_booking_params,
2109
            status=400,
2110
        )
2111
        assert resp.json['err_desc'] == "start_date should be before end_date"
2112
        assert resp.json['err'] == 'bad-request'
2113

  
2114
        week_booking_params['end_date'] = '2022-09-01'
2115
        resp = app.post_json(
2116
            '/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
2117
            params=week_booking_params,
2118
            status=400,
2119
        )
2120
        assert (
2121
            resp.json['err_desc'] == "start_date and end_date are in different reference year (2021 != 2022)"
2122
        )
2123
        assert resp.json['err'] == 'bad-request'
2124

  
2125

  
2126
def test_set_activity_agenda_typical_week_endpoint(
2127
    app, resource, family_data, activities, week_booking_params
2128
):
2129
    Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
2130
    week_booking_params['end_date'] = '2020-09-01'
2131
    with mock.patch(
2132
        'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
2133
        return_value=family_data,
2134
    ):
2135
        with mock.patch(
2136
            'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
2137
            return_value=activities,
2138
        ):
2139
            resp = app.post_json(
2140
                '/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
2141
                params=week_booking_params,
2142
            )
2143
    assert resp.json['err'] == 0
2144
    assert resp.json['updated'] is True
2145
    assert resp.json['count'] == 0
2146

  
2147

  
2148
@freezegun.freeze_time('2020-08-01')
2149
def test_set_activity_agenda_typical_week_endpoint_periscolaire(
2150
    app, resource, family_data, week_booking_params
2151
):
2152
    Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
2153
    week_booking_params['end_date'] = '2020-09-30'
2154
    for activity_id in ['ACCMAT', 'GARDERIES', 'ETUDES', 'CANTINE', 'FOOBAR']:
2155
        activity = {
2156
            'ENTREE': '2020-09-02',
2157
            'SORTIE': '2021-08-31',
2158
            'IDENTACTIVITE': activity_id,
2159
            'LIBELLEACTIVITE': 'FOOBAR',
2160
        }
2161
        week_booking_params['activity_id'] = activity_id
2162
        week_booking_params['booking_list'] = ['thursday']
2163
        with mock.patch(
2164
            'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
2165
            return_value=family_data,
2166
        ):
2167
            with mock.patch(
2168
                'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
2169
                return_value={'ACTIVITE': [activity]},
2170
            ):
2171
                with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
2172
                    operation.return_value = OperationResult(
2173
                        json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
2174
                        xml_request='',
2175
                        xml_response='',
2176
                    )
2177
                    resp = app.post_json(
2178
                        '/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
2179
                        params=week_booking_params,
2180
                    )
2181
    assert resp.json['err'] == 0
2182
    assert resp.json['updated'] is True
2183
    assert resp.json['count'] == 4
2184
    assert len(operation.call_args_list) == 1
2185

  
2186
    assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['IDENTINDIVIDU'] == '50632'
2187
    assert (
2188
        operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['IDENTACTIVITE'] == activity_id
2189
    )
2190
    assert len(operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR']) == 4
2191
    assert (
2192
        operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['JOURDATE']
2193
        == '2020-09-03'
2194
    )
2195
    assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['MATIN'] == 'X'
2196
    assert (
2197
        operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][1]['JOURDATE']
2198
        == '2020-09-10'
2199
    )
2200
    assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][1]['MATIN'] == 'X'
2201
    assert (
2202
        operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][2]['JOURDATE']
2203
        == '2020-09-17'
2204
    )
2205
    assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][2]['MATIN'] == 'X'
2206
    assert (
2207
        operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][3]['JOURDATE']
2208
        == '2020-09-24'
2209
    )
2210
    assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][3]['MATIN'] == 'X'
2211

  
2212

  
2213
@freezegun.freeze_time('2020-08-01')
2214
def test_set_activity_agenda_typical_week_endpoint_extrascolaire(
2215
    app, resource, family_data, week_booking_params
2216
):
2217
    Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
2218
    week_booking_params['end_date'] = '2020-09-30'
2219
    for activity_id in ['CJ MER', 'CJ VAC']:
2220
        activity = {
2221
            'ENTREE': '2020-09-02',
2222
            'SORTIE': '2021-08-31',
2223
            'IDENTACTIVITE': activity_id,
2224
            'LIBELLEACTIVITE': 'FOOBAR',
2225
        }
2226
        week_booking_params['activity_id'] = activity_id
2227
        week_booking_params['booking_list'] = ['friday']
2228
        with mock.patch(
2229
            'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
2230
            return_value=family_data,
2231
        ):
2232
            with mock.patch(
2233
                'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
2234
                return_value={'ACTIVITE': [activity]},
2235
            ):
2236
                resp = app.post_json(
2237
                    '/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
2238
                    params=week_booking_params,
2239
                    status=400,
2240
                )
2241
    assert resp.json['err_desc'] == "Not available for this activity"
2242
    assert resp.json['err'] == 'bad-request'
2243

  
2244

  
2245
@pytest.mark.parametrize('code', [-1, -2, -3, -4])
2246
def test_set_activity_agenda_typical_week_endpoint_wrong_code(
2247
    app, resource, family_data, activities, week_booking_params, code
2248
):
2249
    Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
2250
    week_booking_params['end_date'] = '2020-09-30'
2251
    week_booking_params['booking_list'] = ['monday']
2252
    content = (
2253
        '''<PORTAIL>
2254
    <SETAGENDA>
2255
        <CODE>%s</CODE>
2256
    </SETAGENDA>
2257
</PORTAIL>'''
2258
        % code
2259
    )
2260
    with mock_data(content, 'SetAgenda', data_method='setData'):
2261
        with mock.patch(
2262
            'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
2263
            return_value=family_data,
2264
        ):
2265
            with mock.patch(
2266
                'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
2267
                return_value=activities,
2268
            ):
2269
                resp = app.post_json(
2270
                    '/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
2271
                    params=week_booking_params,
2272
                )
2273
    assert resp.json['err_desc'] == "Wrong agenda status"
2274
    assert resp.json['err'] == 'agenda-code-error-%s' % code
2275

  
2276

  
2023 2277
def test_invoices_endpoint_axel_error(app, resource):
2024 2278
    Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
2025 2279
    with mock.patch('passerelle.contrib.caluire_axel.schemas.get_factures_a_payer') as operation:
2026
-