toulouse-maelis: update-child-agenda endpoint (#72774)
gitea-wip/passerelle/pipeline/pr-main This commit looks good
Details
gitea-wip/passerelle/pipeline/pr-main This commit looks good
Details
This commit is contained in:
parent
569764da59
commit
5c40ae304d
|
@ -0,0 +1,47 @@
|
|||
# Copyright (C) 2023 Entr'ouvert
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
BOOKING_SCHEMA = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'child_id': {
|
||||
'type': 'string',
|
||||
'minLength': 1,
|
||||
'maxLength': 8,
|
||||
},
|
||||
'booking_list': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'string',
|
||||
'pattern': '[A-Za-z0-9]+:[- A-Za-z0-9]+:[0-9]{4}-[0-9]{2}-[0-9]{2}',
|
||||
},
|
||||
},
|
||||
'start_date': {
|
||||
'type': 'string',
|
||||
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
|
||||
},
|
||||
'end_date': {
|
||||
'type': 'string',
|
||||
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
|
||||
},
|
||||
},
|
||||
'required': [
|
||||
'child_id',
|
||||
'booking_list',
|
||||
'start_date',
|
||||
'end_date',
|
||||
],
|
||||
}
|
|
@ -34,7 +34,7 @@ from passerelle.utils.conversion import simplify
|
|||
from passerelle.utils.jsonresponse import APIError
|
||||
from passerelle.utils.templates import render_to_string
|
||||
|
||||
from . import family_schemas, invoice_schemas, schemas, utils
|
||||
from . import activity_schemas, family_schemas, invoice_schemas, schemas, utils
|
||||
|
||||
|
||||
class UpdateError(Exception):
|
||||
|
@ -1682,6 +1682,7 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
booking['details']['activity_label'] = activity['activityType']['libelle']
|
||||
booking['details']['child_id'] = child_id
|
||||
booking['details']['day_str'] = day['day'].strftime(utils.json_date_format)
|
||||
booking['details']['unit_id'] = unit['unit']['idUnit']
|
||||
bookings.append(booking)
|
||||
|
||||
# sort bookings
|
||||
|
@ -1726,6 +1727,121 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
},
|
||||
}
|
||||
|
||||
@endpoint(
|
||||
display_category='Réservation',
|
||||
description="Modifier l'agenda d'un enfant",
|
||||
name='update-child-agenda',
|
||||
perm='can_access',
|
||||
parameters={
|
||||
'NameID': {'description': 'Publik NameID'},
|
||||
},
|
||||
post={
|
||||
'request_body': {
|
||||
'schema': {
|
||||
'application/json': activity_schemas.BOOKING_SCHEMA,
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
def update_child_agenda(self, request, NameID, post_data):
|
||||
family_id = self.get_link(NameID).family_id
|
||||
child_id = post_data['child_id']
|
||||
start_date, end_date, dummy = self.get_start_and_end_dates(
|
||||
post_data['start_date'], post_data['end_date']
|
||||
)
|
||||
requested_bookings = post_data['booking_list']
|
||||
|
||||
# build list of existing booked days
|
||||
bookings = self.get_bookings(family_id, child_id, start_date, end_date)
|
||||
legacy_bookings = [b['id'] for b in bookings if b['prefill'] is True]
|
||||
available_bookings = [b['id'] for b in bookings if b['disabled'] is False]
|
||||
|
||||
bookings_to_update = []
|
||||
updated = []
|
||||
for booking_info in bookings:
|
||||
day_id = booking_info['id']
|
||||
booked = None
|
||||
action = booking_info['details']['action']
|
||||
if day_id not in available_bookings:
|
||||
# disabled or not available: not bookable
|
||||
booked = None
|
||||
elif (
|
||||
day_id not in legacy_bookings
|
||||
and day_id in requested_bookings
|
||||
and action in ['ADD_PRES_PREVI', 'ADD_PRES_REAL', 'DEL_ABSENCE']
|
||||
):
|
||||
booked = action
|
||||
elif (
|
||||
day_id in legacy_bookings
|
||||
and day_id not in requested_bookings
|
||||
and action in ['DEL_PRES_PREVI', 'DEL_PRES_REAL', 'ADD_ABSENCE']
|
||||
):
|
||||
booked = action
|
||||
if booked is not None:
|
||||
# no changes, don't send the day
|
||||
bookings_to_update.append(
|
||||
{
|
||||
'numPerson': child_id,
|
||||
'idAct': booking_info['details']['activity_id'],
|
||||
'idUni': booking_info['details']['unit_id'],
|
||||
'date': booking_info['details']['day_str'],
|
||||
'action': booked,
|
||||
}
|
||||
)
|
||||
updated.append(
|
||||
{
|
||||
'activity_id': booking_info['details']['activity_id'],
|
||||
'activity_type': booking_info['details']['activity_type'],
|
||||
'activity_label': booking_info['details']['activity_label'],
|
||||
'day': booking_info['details']['day_str'],
|
||||
'booked': booked in ['ADD_PRES_PREVI', 'ADD_PRES_REAL', 'DEL_ABSENCE'],
|
||||
}
|
||||
)
|
||||
if not bookings_to_update:
|
||||
# don't call maelis if no changes
|
||||
return updated
|
||||
|
||||
payload = {
|
||||
'requestBean': {
|
||||
'numDossier': family_id,
|
||||
'unitPersonDayInfoList': bookings_to_update,
|
||||
}
|
||||
}
|
||||
response = self.call('Activity', 'updatePersonSchedule', **payload)
|
||||
errors = serialize_object(response)
|
||||
if errors:
|
||||
raise APIError(' ; '.join(errors), err_code='agenda-child-error')
|
||||
|
||||
# sort changes
|
||||
activity_types = ['ACCMAT', 'RESTSCOL']
|
||||
updated = [
|
||||
(
|
||||
not u['booked'],
|
||||
activity_types.index(u['activity_type']) if u['activity_type'] in activity_types else 0,
|
||||
u['activity_label'],
|
||||
u['day'],
|
||||
u,
|
||||
)
|
||||
for u in updated
|
||||
]
|
||||
updated = sorted(updated, key=itemgetter(0, 1, 2, 3))
|
||||
updated = [u for b, a, l, d, u in updated]
|
||||
updated = [
|
||||
{
|
||||
'booked': u['booked'],
|
||||
'activity_id': u['activity_id'],
|
||||
'activity_label': u['activity_label'],
|
||||
'day': u['day'],
|
||||
}
|
||||
for u in updated
|
||||
]
|
||||
|
||||
return {
|
||||
'updated': True,
|
||||
'count': len(updated),
|
||||
'changes': updated,
|
||||
}
|
||||
|
||||
@endpoint(
|
||||
display_category='Facture',
|
||||
description="Ajout d'autorisation de prélèvement",
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<soap:Envelope
|
||||
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<soap:Body>
|
||||
<ns2:updatePersonScheduleResponse
|
||||
xmlns:ns2="activity.ws.maelis.sigec.com"
|
||||
xmlns:ns3="bean.persistence.activity.ws.maelis.sigec.com">
|
||||
<resultBean/>
|
||||
</ns2:updatePersonScheduleResponse>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
|
@ -0,0 +1,13 @@
|
|||
<soap:Envelope
|
||||
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<soap:Body>
|
||||
<ns2:updatePersonScheduleResponse
|
||||
xmlns:ns2="activity.ws.maelis.sigec.com"
|
||||
xmlns:ns3="bean.persistence.activity.ws.maelis.sigec.com">
|
||||
<resultBean>
|
||||
<errorMessages>Foo</errorMessages>
|
||||
<errorMessages>Bar</errorMessages>
|
||||
</resultBean>
|
||||
</ns2:updatePersonScheduleResponse>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
|
@ -3732,6 +3732,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 0,
|
||||
'status': 'READ_ONLY',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': True,
|
||||
'id': '613880:A10049327689:2023-01-02',
|
||||
|
@ -3753,6 +3754,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 0,
|
||||
'status': 'READ_ONLY',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': True,
|
||||
'id': '613880:A10049327682:2023-01-02',
|
||||
|
@ -3774,6 +3776,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 0,
|
||||
'status': 'READ_ONLY',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': True,
|
||||
'id': '613880:A10049327689:2023-01-03',
|
||||
|
@ -3795,6 +3798,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 1,
|
||||
'status': 'READ_ONLY',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': True,
|
||||
'id': '613880:A10049327682:2023-01-03',
|
||||
|
@ -3816,6 +3820,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-05',
|
||||
|
@ -3837,6 +3842,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-05',
|
||||
|
@ -3858,6 +3864,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-06',
|
||||
|
@ -3879,6 +3886,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 0,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-06',
|
||||
|
@ -3900,6 +3908,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 0,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-09',
|
||||
|
@ -3921,6 +3930,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 0,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-09',
|
||||
|
@ -3942,6 +3952,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 0,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-10',
|
||||
|
@ -3963,6 +3974,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-10',
|
||||
|
@ -3984,6 +3996,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-12',
|
||||
|
@ -4005,6 +4018,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-12',
|
||||
|
@ -4026,6 +4040,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-13',
|
||||
|
@ -4047,6 +4062,7 @@ def test_read_child_agenda(activity_service, con, app):
|
|||
'scheduledPresence': 0,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-13',
|
||||
|
@ -4087,3 +4103,197 @@ def test_read_child_agenda_date_error(con, app):
|
|||
)
|
||||
assert resp.json['err'] == 'bad-request'
|
||||
assert resp.json['err_desc'] == 'start_date and end_date are in different reference year (2022 != 2023)'
|
||||
|
||||
|
||||
def test_update_child_agenda(activity_service, con, app):
|
||||
activity_service.add_soap_response(
|
||||
'getPersonScheduleList', get_xml_file('R_get_person_schedule_list.xml')
|
||||
)
|
||||
url = get_endpoint('update-child-agenda')
|
||||
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||
|
||||
def request_check(request):
|
||||
assert request.numDossier == 1312
|
||||
assert len(request.unitPersonDayInfoList) == 4
|
||||
assert request.unitPersonDayInfoList[0].numPerson == 613880
|
||||
assert request.unitPersonDayInfoList[0].idAct == 'A10049327689'
|
||||
assert request.unitPersonDayInfoList[0].idUni == 'A10049327690'
|
||||
assert request.unitPersonDayInfoList[0].date == datetime.datetime(2023, 1, 5, 0, 0)
|
||||
assert request.unitPersonDayInfoList[0].action == 'ADD_ABSENCE'
|
||||
assert request.unitPersonDayInfoList[1].numPerson == 613880
|
||||
assert request.unitPersonDayInfoList[1].idAct == 'A10049327682'
|
||||
assert request.unitPersonDayInfoList[1].idUni == 'A10049327683'
|
||||
assert request.unitPersonDayInfoList[1].date == datetime.datetime(2023, 1, 6, 0, 0)
|
||||
assert request.unitPersonDayInfoList[1].action == 'ADD_PRES_REAL'
|
||||
assert request.unitPersonDayInfoList[2].numPerson == 613880
|
||||
assert request.unitPersonDayInfoList[2].idAct == 'A10049327682'
|
||||
assert request.unitPersonDayInfoList[2].idUni == 'A10049327683'
|
||||
assert request.unitPersonDayInfoList[2].date == datetime.datetime(2023, 1, 10, 0, 0)
|
||||
assert request.unitPersonDayInfoList[2].action == 'DEL_PRES_PREVI'
|
||||
assert request.unitPersonDayInfoList[3].numPerson == 613880
|
||||
assert request.unitPersonDayInfoList[3].idAct == 'A10049327682'
|
||||
assert request.unitPersonDayInfoList[3].idUni == 'A10049327683'
|
||||
assert request.unitPersonDayInfoList[3].date == datetime.datetime(2023, 1, 13, 0, 0)
|
||||
assert request.unitPersonDayInfoList[3].action == 'ADD_PRES_PREVI'
|
||||
|
||||
activity_service.add_soap_response(
|
||||
'updatePersonSchedule', get_xml_file('R_update_person_schedule.xml'), request_check=request_check
|
||||
)
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2023-01-01',
|
||||
'end_date': '2023-01-15',
|
||||
'booking_list': [
|
||||
# '613880:A10049327689:2023-01-05', # remove this one
|
||||
'613880:A10049327682:2023-01-05',
|
||||
'613880:A10049327689:2023-01-06',
|
||||
# '613880:A10049327682:2023-01-10', # and this one
|
||||
'613880:A10049327689:2023-01-12',
|
||||
'613880:A10049327682:2023-01-12',
|
||||
'613880:A10049327689:2023-01-13',
|
||||
# but add:
|
||||
'613880:A10049327682:2023-01-06',
|
||||
'613880:A10049327682:2023-01-13',
|
||||
],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params)
|
||||
assert resp.json == {
|
||||
'changes': [
|
||||
{
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'booked': True,
|
||||
'day': '2023-01-06',
|
||||
},
|
||||
{
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'booked': True,
|
||||
'day': '2023-01-13',
|
||||
},
|
||||
{
|
||||
'activity_id': 'A10049327689',
|
||||
'activity_label': 'Accueil du matin',
|
||||
'booked': False,
|
||||
'day': '2023-01-05',
|
||||
},
|
||||
{
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'booked': False,
|
||||
'day': '2023-01-10',
|
||||
},
|
||||
],
|
||||
'count': 4,
|
||||
'err': 0,
|
||||
'updated': True,
|
||||
}
|
||||
|
||||
|
||||
def test_update_child_agenda_no_changes(activity_service, con, app):
|
||||
activity_service.add_soap_response(
|
||||
'getPersonScheduleList', get_xml_file('R_get_person_schedule_list.xml')
|
||||
)
|
||||
url = get_endpoint('update-child-agenda')
|
||||
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2023-01-01',
|
||||
'end_date': '2023-01-15',
|
||||
'booking_list': [
|
||||
'613880:A10049327689:2023-01-05',
|
||||
'613880:A10049327682:2023-01-05',
|
||||
'613880:A10049327689:2023-01-06',
|
||||
'613880:A10049327682:2023-01-10',
|
||||
'613880:A10049327689:2023-01-12',
|
||||
'613880:A10049327682:2023-01-12',
|
||||
'613880:A10049327689:2023-01-13',
|
||||
],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params)
|
||||
assert resp.json == []
|
||||
|
||||
|
||||
def test_update_child_agenda_maelis_error(activity_service, con, app):
|
||||
activity_service.add_soap_response(
|
||||
'getPersonScheduleList', get_xml_file('R_get_person_schedule_list.xml')
|
||||
)
|
||||
url = get_endpoint('update-child-agenda')
|
||||
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||
|
||||
activity_service.add_soap_response(
|
||||
'updatePersonSchedule', get_xml_file('R_update_person_schedule_error.xml')
|
||||
)
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2023-01-01',
|
||||
'end_date': '2023-01-15',
|
||||
'booking_list': [
|
||||
'613880:A10049327682:2023-01-13',
|
||||
],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params)
|
||||
assert resp.json['err'] == 'agenda-child-error'
|
||||
assert resp.json['err_desc'] == 'Foo ; Bar'
|
||||
|
||||
|
||||
def test_update_child_agenda_not_linked_error(con, app):
|
||||
url = get_endpoint('update-child-agenda')
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2022-09-01',
|
||||
'end_date': '2023-08-31',
|
||||
'booking_list': [],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params)
|
||||
assert resp.json['err'] == 'not-linked'
|
||||
assert resp.json['err_desc'] == 'User not linked to family'
|
||||
|
||||
|
||||
def test_update_child_agenda_date_error(con, app):
|
||||
url = get_endpoint('update-child-agenda')
|
||||
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': 'bad',
|
||||
'end_date': '2023-08-31',
|
||||
'booking_list': [],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params, status=400)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'] == "start_date: 'bad' does not match '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'"
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2022-09-01',
|
||||
'end_date': 'bad',
|
||||
'booking_list': [],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params, status=400)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'] == "end_date: 'bad' does not match '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'"
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2023-09-01',
|
||||
'end_date': '2023-08-31',
|
||||
'booking_list': [],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params, status=400)
|
||||
assert resp.json['err'] == 'bad-request'
|
||||
assert resp.json['err_desc'] == 'start_date should be before end_date'
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2022-09-01',
|
||||
'end_date': '2024-08-31',
|
||||
'booking_list': [],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params, status=400)
|
||||
assert resp.json['err'] == 'bad-request'
|
||||
assert resp.json['err_desc'] == 'start_date and end_date are in different reference year (2022 != 2023)'
|
||||
|
|
Loading…
Reference in New Issue