toulouse_smart: allow to redo a failed intervention (#62012)

This commit is contained in:
Nicolas Roche 2022-07-23 19:10:41 +02:00
parent 5657d2896b
commit a8530e2806
2 changed files with 39 additions and 25 deletions

View File

@ -195,19 +195,19 @@ class ToulouseSmartResource(BaseResource, HTTPResource):
elif prop['required']:
raise APIError("'%s' field is required on '%s' block" % (varname, slug), http_status=400)
if self.wcs_requests.filter(
wcs_form_api_url=post_data['form_api_url'], wcs_form_step=post_data.get('form_step', 'initial')
):
raise APIError(
"'%s' intervention already created at step '%s'"
% (post_data['external_number'], post_data.get('form_step', 'initial')),
http_status=400,
)
wcs_request = self.wcs_requests.create(
wcs_request, created = self.wcs_requests.get_or_create(
wcs_form_api_url=post_data['form_api_url'],
wcs_form_number=post_data['external_number'],
wcs_form_step=post_data.get('form_step', 'initial'),
defaults={'wcs_form_number': post_data['external_number']},
)
wcs_request = self.wcs_requests.select_for_update().get(pk=wcs_request.pk)
if not created:
if wcs_request.status != 'failed':
return {'data': wcs_request.reply}
wcs_request.tries = 0
wcs_request.status = 'registered'
wcs_request.result = None
endpoint_url = {}
for endpoint_name in 'update-intervention', 'add-media':
endpoint_url[endpoint_name] = request.build_absolute_uri(
@ -255,17 +255,18 @@ class ToulouseSmartResource(BaseResource, HTTPResource):
return {'data': wcs_request.reply}
def create_intervention_job(self, *args, **kwargs):
wcs_request = self.wcs_requests.get(pk=kwargs['pk'])
after_timestamp = None
if not wcs_request.push():
if wcs_request.tries < 5:
if wcs_request.tries == 3:
after_timestamp = datetime.timedelta(hours=1)
if wcs_request.tries == 4:
after_timestamp = datetime.timedelta(days=1)
else:
wcs_request.status = 'failed'
wcs_request.save()
with atomic():
wcs_request = self.wcs_requests.select_for_update().get(pk=kwargs['pk'])
after_timestamp = None
if not wcs_request.push():
if wcs_request.tries < 5:
if wcs_request.tries == 3:
after_timestamp = datetime.timedelta(hours=1)
if wcs_request.tries == 4:
after_timestamp = datetime.timedelta(days=1)
else:
wcs_request.status = 'failed'
wcs_request.save()
payload = {'creation_response': wcs_request.reply}
smart_request = wcs_request.smart_requests.create(payload=payload)
self.add_job(

View File

@ -542,13 +542,17 @@ def test_create_intervention_missing_field(app, smart):
['/v1/intervention', CREATE_INTERVENTION_QUERY, None, 500],
)
@mock.patch("django.db.models.fields.UUIDField.get_default", return_value=UUID)
def test_create_intervention_twice_error(mocked_uuid4, app, smart):
def test_create_intervention_twice(mocked_uuid4, app, smart):
resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD)
assert not resp.json['err']
assert resp.json['data']['status'] == 'registered'
assert smart.wcs_requests.count() == 1
resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD, status=400)
assert resp.json['err']
assert 'already created' in resp.json['err_desc']
# re-create intervention after it success: no error is returned, but no new request is sent
resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD)
assert not resp.json['err']
assert resp.json['data']['status'] == 'registered'
assert smart.wcs_requests.count() == 1
@mock_response(
@ -682,6 +686,15 @@ def test_create_intervention_client_error(mocked_uuid, app, freezer, smart):
smart_request = wcs_request.smart_requests.latest('id')
assert smart_request.payload['creation_response']['status'] == 'failed'
# re-create intervention after it fails: a new request is sent
resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD)
assert not resp.json['err']
assert resp.json['data']['status'] == 'registered'
wcs_request = smart.wcs_requests.get(uuid=UUID)
assert '400 Client Error' in wcs_request.result
assert wcs_request.tries == 1
assert wcs_request.status == 'registered'
@mock.patch('passerelle.utils.RequestSession.request')
@mock.patch("django.db.models.fields.UUIDField.get_default", return_value=UUID)