0004-toulouse_smart-allow-to-redo-a-failed-intervention-6.patch
passerelle/contrib/toulouse_smart/models.py | ||
---|---|---|
190 | 190 |
except ValueError: |
191 | 191 |
raise APIError( |
192 | 192 |
"cannot cast '%s' field to %s : '%s'" % (varname, cast[prop['type']], block[varname]), |
193 | 193 |
http_status=400, |
194 | 194 |
) |
195 | 195 |
elif prop['required']: |
196 | 196 |
raise APIError("'%s' field is required on '%s' block" % (varname, slug), http_status=400) |
197 | 197 | |
198 |
if self.wcs_requests.filter( |
|
199 |
wcs_form_api_url=post_data['form_api_url'], wcs_form_step=post_data.get('form_step', 'initial') |
|
200 |
): |
|
201 |
raise APIError( |
|
202 |
"'%s' intervention already created at step '%s'" |
|
203 |
% (post_data['external_number'], post_data.get('form_step', 'initial')), |
|
204 |
http_status=400, |
|
205 |
) |
|
206 |
wcs_request = self.wcs_requests.create( |
|
198 |
wcs_request, created = self.wcs_requests.get_or_create( |
|
207 | 199 |
wcs_form_api_url=post_data['form_api_url'], |
208 |
wcs_form_number=post_data['external_number'], |
|
209 | 200 |
wcs_form_step=post_data.get('form_step', 'initial'), |
201 |
defaults={'wcs_form_number': post_data['external_number']}, |
|
210 | 202 |
) |
203 |
wcs_request = self.wcs_requests.select_for_update().get(pk=wcs_request.pk) |
|
204 |
if not created: |
|
205 |
if wcs_request.status != 'failed': |
|
206 |
return {'data': wcs_request.reply} |
|
207 |
wcs_request.tries = 0 |
|
208 |
wcs_request.status = 'registered' |
|
209 |
wcs_request.result = None |
|
210 | ||
211 | 211 |
endpoint_url = {} |
212 | 212 |
for endpoint_name in 'update-intervention', 'add-media': |
213 | 213 |
endpoint_url[endpoint_name] = request.build_absolute_uri( |
214 | 214 |
reverse( |
215 | 215 |
'generic-endpoint', |
216 | 216 |
kwargs={'connector': 'toulouse-smart', 'endpoint': endpoint_name, 'slug': self.slug}, |
217 | 217 |
) |
218 | 218 |
) |
... | ... | |
250 | 250 |
self.add_job( |
251 | 251 |
'create_intervention_job', |
252 | 252 |
pk=str(wcs_request.pk), |
253 | 253 |
natural_id='wcs-request-%s' % wcs_request.pk, |
254 | 254 |
) |
255 | 255 |
return {'data': wcs_request.reply} |
256 | 256 | |
257 | 257 |
def create_intervention_job(self, *args, **kwargs): |
258 |
wcs_request = self.wcs_requests.get(pk=kwargs['pk']) |
|
259 |
after_timestamp = None |
|
260 |
if not wcs_request.push(): |
|
261 |
if wcs_request.tries < 5: |
|
262 |
if wcs_request.tries == 3: |
|
263 |
after_timestamp = datetime.timedelta(hours=1) |
|
264 |
if wcs_request.tries == 4: |
|
265 |
after_timestamp = datetime.timedelta(days=1) |
|
266 |
else: |
|
267 |
wcs_request.status = 'failed' |
|
268 |
wcs_request.save() |
|
258 |
wcs_request = self.wcs_requests.select_for_update().get(pk=kwargs['pk']) |
|
259 |
with atomic(): |
|
260 |
after_timestamp = None |
|
261 |
if not wcs_request.push(): |
|
262 |
if wcs_request.tries < 5: |
|
263 |
if wcs_request.tries == 3: |
|
264 |
after_timestamp = datetime.timedelta(hours=1) |
|
265 |
if wcs_request.tries == 4: |
|
266 |
after_timestamp = datetime.timedelta(days=1) |
|
267 |
else: |
|
268 |
wcs_request.status = 'failed' |
|
269 |
wcs_request.save() |
|
269 | 270 |
payload = {'creation_response': wcs_request.reply} |
270 | 271 |
smart_request = wcs_request.smart_requests.create(payload=payload) |
271 | 272 |
self.add_job( |
272 | 273 |
'update_intervention_job', |
273 | 274 |
id=smart_request.id, |
274 | 275 |
natural_id='smart-request-%s' % smart_request.id, |
275 | 276 |
) |
276 | 277 |
if wcs_request.status == 'registered': |
tests/test_toulouse_smart.py | ||
---|---|---|
537 | 537 |
assert "field is required on 'coin' block" in resp.json['err_desc'] |
538 | 538 | |
539 | 539 | |
540 | 540 |
@mock_response( |
541 | 541 |
['/v1/type-intervention', None, INTERVENTION_TYPES], |
542 | 542 |
['/v1/intervention', CREATE_INTERVENTION_QUERY, None, 500], |
543 | 543 |
) |
544 | 544 |
@mock.patch("django.db.models.fields.UUIDField.get_default", return_value=UUID) |
545 |
def test_create_intervention_twice_error(mocked_uuid4, app, smart):
|
|
545 |
def test_create_intervention_twice(mocked_uuid4, app, smart): |
|
546 | 546 |
resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD) |
547 | 547 |
assert not resp.json['err'] |
548 |
assert resp.json['data']['status'] == 'registered' |
|
549 |
assert smart.wcs_requests.count() == 1 |
|
548 | 550 | |
549 |
resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD, status=400) |
|
550 |
assert resp.json['err'] |
|
551 |
assert 'already created' in resp.json['err_desc'] |
|
551 |
# re-create intervention after it success: no error is returned, but no new request is sent |
|
552 |
resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD) |
|
553 |
assert not resp.json['err'] |
|
554 |
assert resp.json['data']['status'] == 'registered' |
|
555 |
assert smart.wcs_requests.count() == 1 |
|
552 | 556 | |
553 | 557 | |
554 | 558 |
@mock_response( |
555 | 559 |
['/v1/type-intervention', None, INTERVENTION_TYPES], |
556 | 560 |
['/v1/intervention', CREATE_INTERVENTION_QUERY, None, 500], |
557 | 561 |
) |
558 | 562 |
@mock.patch("django.db.models.fields.UUIDField.get_default", return_value=UUID) |
559 | 563 |
def test_create_intervention_transport_error(mocked_uuid, app, freezer, smart): |
... | ... | |
677 | 681 |
assert wcs_request.status == 'failed' |
678 | 682 |
job = Job.objects.get(method_name='create_intervention_job') |
679 | 683 |
assert job.status == 'failed' |
680 | 684 |
assert '400 Client Error' in job.status_details['error_summary'] |
681 | 685 |
assert wcs_request.smart_requests.count() == 4 |
682 | 686 |
smart_request = wcs_request.smart_requests.latest('id') |
683 | 687 |
assert smart_request.payload['creation_response']['status'] == 'failed' |
684 | 688 | |
689 |
# re-create intervention after it fails: a new request is sent |
|
690 |
resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD) |
|
691 |
assert not resp.json['err'] |
|
692 |
assert resp.json['data']['status'] == 'registered' |
|
693 |
wcs_request = smart.wcs_requests.get(uuid=UUID) |
|
694 |
assert '400 Client Error' in wcs_request.result |
|
695 |
assert wcs_request.tries == 1 |
|
696 |
assert wcs_request.status == 'registered' |
|
697 | ||
685 | 698 | |
686 | 699 |
@mock.patch('passerelle.utils.RequestSession.request') |
687 | 700 |
@mock.patch("django.db.models.fields.UUIDField.get_default", return_value=UUID) |
688 | 701 |
def test_create_intervention_timeout(mocked_uuid, mocked_get, app, freezer, smart): |
689 | 702 |
from tests.utils import FakedResponse |
690 | 703 | |
691 | 704 |
mocked_get.side_effect = [ |
692 | 705 |
FakedResponse( |
693 |
- |