Projet

Général

Profil

0001-toulouse_smart-allow-to-redo-a-failed-intervention-6.patch

Nicolas Roche, 21 février 2022 12:53

Télécharger (8,06 ko)

Voir les différences:

Subject: [PATCH] toulouse_smart: allow to redo a failed intervention (#62012)

 passerelle/contrib/toulouse_smart/models.py | 56 ++++++++++-----------
 tests/test_toulouse_smart.py                | 15 ++++--
 2 files changed, 38 insertions(+), 33 deletions(-)
passerelle/contrib/toulouse_smart/models.py
187 187
                except ValueError:
188 188
                    raise APIError(
189 189
                        "cannot cast '%s' field to %s : '%s'" % (varname, cast[prop['type']], block[varname]),
190 190
                        http_status=400,
191 191
                    )
192 192
            elif prop['required']:
193 193
                raise APIError("'%s' field is required on '%s' block" % (varname, slug), http_status=400)
194 194

  
195
        if self.wcs_requests.filter(wcs_form_api_url=post_data['form_api_url']):
196
            raise APIError(
197
                "'%s' intervention already created" % post_data['external_number'],
198
                http_status=400,
195
        try:
196
            wcs_request = self.wcs_requests.get(wcs_form_api_url=post_data['form_api_url'])
197
        except WcsRequest.DoesNotExist:
198
            wcs_request = self.wcs_requests.create(
199
                wcs_form_api_url=post_data['form_api_url'],
200
                wcs_form_number=post_data['external_number'],
199 201
            )
200
        wcs_request = self.wcs_requests.create(
201
            wcs_form_api_url=post_data['form_api_url'],
202
            wcs_form_number=post_data['external_number'],
203
        )
202
        else:
203
            if wcs_request.status != 'failed':
204
                return {'data': wcs_request.reply}
205
            wcs_request.tries = 0
206
            wcs_request.status = 'registered'
207
            wcs_request.result = None
204 208
        endpoint_url = {}
205 209
        for endpoint_name in 'update-intervention', 'add-media':
206 210
            endpoint_url[endpoint_name] = request.build_absolute_uri(
207 211
                reverse(
208 212
                    'generic-endpoint',
209 213
                    kwargs={'connector': 'toulouse-smart', 'endpoint': endpoint_name, 'slug': self.slug},
210 214
                )
211 215
            )
......
240 244
            wcs_request.payload[label] = utils.localtz_to_utc(post_data[label])
241 245
        wcs_request.save()
242 246
        if not wcs_request.push():
243 247
            self.add_job(
244 248
                'create_intervention_job',
245 249
                pk=wcs_request.pk,
246 250
                natural_id='wcs-request-%s' % wcs_request.pk,
247 251
            )
248
        return {
249
            'data': {
250
                'wcs_form_api_url': wcs_request.wcs_form_api_url,
251
                'wcs_form_number': wcs_request.wcs_form_number,
252
                'uuid': wcs_request.uuid,
253
                'payload': wcs_request.payload,
254
                'result': wcs_request.result,
255
                'status': wcs_request.status,
256
                'tries': wcs_request.tries,
257
            }
258
        }
252
        return {'data': wcs_request.reply}
259 253

  
260 254
    def create_intervention_job(self, *args, **kwargs):
261 255
        wcs_request = self.wcs_requests.get(pk=kwargs['pk'])
262 256
        after_timestamp = None
263 257
        if not wcs_request.push():
264 258
            if wcs_request.tries < 5:
265 259
                if wcs_request.tries == 3:
266 260
                    after_timestamp = datetime.timedelta(hours=1)
267 261
                if wcs_request.tries == 4:
268 262
                    after_timestamp = datetime.timedelta(days=1)
269 263
            else:
270 264
                wcs_request.status = 'failed'
271 265
                wcs_request.save()
272
        payload = {
273
            'creation_response': {
274
                'wcs_form_api_url': wcs_request.wcs_form_api_url,
275
                'wcs_form_number': wcs_request.wcs_form_number,
276
                'uuid': str(wcs_request.uuid),
277
                'payload': wcs_request.payload,
278
                'result': wcs_request.result,
279
                'status': wcs_request.status,
280
                'tries': wcs_request.tries,
281
            }
282
        }
266
        payload = {'creation_response': wcs_request.reply}
283 267
        smart_request = wcs_request.smart_requests.create(payload=payload)
284 268
        self.add_job(
285 269
            'update_intervention_job',
286 270
            id=smart_request.id,
287 271
            natural_id='smart-request-%s' % smart_request.id,
288 272
        )
289 273
        if wcs_request.status == 'registered':
290 274
            raise SkipJob(after_timestamp)
......
429 413
            self.save()
430 414
            return False
431 415
        for label in 'interventionCreated', 'interventionDesired':
432 416
            self.result[label] = utils.utc_to_localtz(self.result[label])
433 417
        self.status = 'sent'
434 418
        self.save()
435 419
        return True
436 420

  
421
    @property
422
    def reply(self):
423
        return {
424
            'wcs_form_api_url': self.wcs_form_api_url,
425
            'wcs_form_number': self.wcs_form_number,
426
            'uuid': str(self.uuid),
427
            'payload': self.payload,
428
            'result': self.result,
429
            'status': self.status,
430
            'tries': self.tries,
431
        }
432

  
437 433

  
438 434
def upload_to(wcs_request_file, filename):
439 435
    instance = wcs_request_file.resource.resource
440 436
    uuid = wcs_request_file.resource.uuid
441 437
    return '%s/%s/%s/%s' % (instance.get_connector_slug(), instance.slug, uuid, filename)
442 438

  
443 439

  
444 440
class WcsRequestFile(models.Model):
tests/test_toulouse_smart.py
538 538
@mock_response(
539 539
    ['/v1/type-intervention', None, INTERVENTION_TYPES],
540 540
    ['/v1/intervention', CREATE_INTERVENTION_QUERY, None, 500],
541 541
)
542 542
@mock.patch("django.db.models.fields.UUIDField.get_default", return_value=UUID)
543 543
def test_create_intervention_twice_error(mocked_uuid4, app, smart):
544 544
    resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD)
545 545
    assert not resp.json['err']
546
    assert resp.json['data']['status'] == 'registered'
547
    assert smart.wcs_requests.count() == 1
546 548

  
547
    resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD, status=400)
548
    assert resp.json['err']
549
    assert 'already created' in resp.json['err_desc']
549
    resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD)
550
    assert not resp.json['err']
551
    assert resp.json['data']['status'] == 'registered'
552
    assert smart.wcs_requests.count() == 1
550 553

  
551 554

  
552 555
@mock_response(
553 556
    ['/v1/type-intervention', None, INTERVENTION_TYPES],
554 557
    ['/v1/intervention', CREATE_INTERVENTION_QUERY, None, 500],
555 558
)
556 559
@mock.patch("django.db.models.fields.UUIDField.get_default", return_value=UUID)
557 560
def test_create_intervention_transport_error(mocked_uuid, app, freezer, smart):
......
672 675
    assert wcs_request.status == 'failed'
673 676
    job = Job.objects.get(method_name='create_intervention_job')
674 677
    assert job.status == 'failed'
675 678
    assert '400 Client Error' in job.status_details['error_summary']
676 679
    assert wcs_request.smart_requests.count() == 4
677 680
    smart_request = wcs_request.smart_requests.latest('id')
678 681
    assert smart_request.payload['creation_response']['status'] == 'failed'
679 682

  
683
    # re-sent creation query
684
    resp = app.post_json(URL + 'create-intervention/', params=CREATE_INTERVENTION_PAYLOAD)
685
    wcs_request = smart.wcs_requests.get(uuid=UUID)
686
    assert '400 Client Error' in wcs_request.result
687
    assert wcs_request.tries == 1
688

  
680 689

  
681 690
UPDATE_INTERVENTION_PAYLOAD = {
682 691
    'data': {
683 692
        'status': 'close manque info',
684 693
        'type_retour_cloture': 'Smart non Fait',
685 694
        'libelle_cloture': "rien à l'adresse indiquée",
686 695
        'commentaire_cloture': 'le commentaire',
687 696
    }
688
-