Projet

Général

Profil

0003-workflow-perform-action-only-on-defined-target-45653.patch

Lauréline Guérin, 08 décembre 2020 17:53

Télécharger (12,3 ko)

Voir les différences:

Subject: [PATCH 3/3] workflow: perform action only on defined target (#45653)

 tests/test_workflows.py     | 292 ++++++++++++++++++++++++++++++++++++
 wcs/wf/external_workflow.py |  24 +++
 2 files changed, 316 insertions(+)
tests/test_workflows.py
5346 5346
    assert card.data['bo0'] == 'foo@example.com'  # got called
5347 5347

  
5348 5348

  
5349
def test_call_external_workflow_manual_targeting(pub):
5350
    FormDef.wipe()
5351
    CardDef.wipe()
5352
    LoggedError.wipe()
5353

  
5354
    # carddef workflow, with global action to increment a counter in its
5355
    # backoffice fields.
5356
    carddef_wf = Workflow(name='Carddef Workflow')
5357
    carddef_wf.add_status(name='New')
5358
    carddef_wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(carddef_wf)
5359
    carddef_wf.backoffice_fields_formdef.fields = [
5360
        StringField(id='bo0', varname='bo', type='string', label='bo variable'),
5361
    ]
5362
    global_action = carddef_wf.add_global_action('Update')
5363
    global_action.append_item('set-backoffice-fields')
5364
    setbo = global_action.items[0]
5365
    setbo.fields = [{'field_id': 'bo0',
5366
                     'value': '{{ form_var_bo|default:"0"|add:1 }}'}]
5367
    trigger = global_action.append_trigger('webservice')
5368
    trigger.identifier = 'update'
5369
    carddef_wf.store()
5370

  
5371
    # associated carddef
5372
    carddef = CardDef()
5373
    carddef.name = 'Data'
5374
    carddef.fields = [
5375
        StringField(id='0', label='string', varname='card_string'),
5376
    ]
5377
    carddef.workflow = carddef_wf
5378
    carddef.store()
5379
    carddef.data_class().wipe()
5380

  
5381
    # and sample carddatas
5382
    for i in range(1, 4):
5383
        carddata = carddef.data_class()()
5384
        carddata.data = {'0': 'Text %s' % i}
5385
        carddata.store()
5386

  
5387
    # formdef workflow that will trigger the global action
5388
    wf = Workflow(name='External actions')
5389
    st1 = wf.add_status('Action')
5390

  
5391
    update_global_action = wf.add_global_action('Update linked object data')
5392
    update_action = update_global_action.append_item('external_workflow_global_action')
5393
    update_action.slug = 'carddef:%s' % carddef.url_name
5394
    update_action.target_mode = 'manual'
5395
    update_action.target_id = None  # not configured
5396
    update_action.trigger_id = 'action:update'
5397

  
5398
    # and create carddata
5399
    create_carddata = CreateCarddataWorkflowStatusItem()
5400
    create_carddata.label = 'create linked card'
5401
    create_carddata.formdef_slug = carddef.url_name
5402
    create_carddata.varname = 'created_card'
5403
    create_carddata.id = '_create_card'
5404
    create_carddata.mappings = [
5405
        Mapping(field_id='0', expression='{{ form_var_string }}')
5406
    ]
5407
    create_carddata.parent = st1
5408
    st1.items.append(create_carddata)
5409

  
5410
    wf.store()
5411

  
5412
    # associated formdef
5413
    datasource = {'type': 'carddef:%s' % carddef.url_name}
5414
    formdef = FormDef()
5415
    formdef.name = 'External action form'
5416
    formdef.fields = [
5417
        ItemField(
5418
            id='0', label='Card',
5419
            type='item', varname='card',
5420
            data_source=datasource),
5421
        StringField(id='1', label='string', varname='string'),
5422
    ]
5423
    formdef.workflow = wf
5424
    formdef.store()
5425

  
5426
    # and formdata
5427
    formdata = formdef.data_class()()
5428
    formdata.data = {
5429
        '0': '3',  # set from datasource
5430
        '1': '1',
5431
    }
5432
    # set parent
5433
    formdata.submission_context = {
5434
        'orig_object_type': 'carddef',
5435
        'orig_formdata_id': '2',
5436
        'orig_formdef_id': str(carddef.id),
5437
    }
5438
    formdata.store()
5439
    formdata.just_created()
5440
    formdata.perform_workflow()
5441
    assert carddef.data_class().count() == 4
5442
    # linked carddata
5443
    assert carddef.data_class().get(4).data['0'] == '1'
5444

  
5445
    # target not configured
5446
    perform_items([update_action], formdata)
5447
    assert 'bo0' not in carddef.data_class().get(1).data
5448
    assert 'bo0' not in carddef.data_class().get(2).data
5449
    assert 'bo0' not in carddef.data_class().get(3).data
5450
    assert 'bo0' not in carddef.data_class().get(4).data
5451
    assert LoggedError.count() == 0
5452

  
5453
    # configure target
5454
    update_action.target_id = '{{ form_var_string }}'  # == '1'
5455
    wf.store()
5456
    perform_items([update_action], formdata)
5457
    assert carddef.data_class().get(1).data['bo0'] == '1'
5458
    assert 'bo0' not in carddef.data_class().get(2).data
5459
    assert 'bo0' not in carddef.data_class().get(3).data
5460
    assert 'bo0' not in carddef.data_class().get(4).data
5461

  
5462
    # target not found
5463
    update_action.target_id = '42{{ form_var_string }}'  # == '421'
5464
    wf.store()
5465
    perform_items([update_action], formdata)
5466
    assert carddef.data_class().get(1).data['bo0'] == '1'
5467
    assert 'bo0' not in carddef.data_class().get(2).data
5468
    assert 'bo0' not in carddef.data_class().get(3).data
5469
    assert 'bo0' not in carddef.data_class().get(4).data
5470
    assert LoggedError.count() == 1
5471
    logged_error = LoggedError.select()[0]
5472
    assert logged_error.summary == 'Could not find targeted "Data" object by id 421'
5473

  
5474

  
5349 5475
def test_edit_carddata_with_data_sourced_object(pub):
5350 5476
    FormDef.wipe()
5351 5477
    CardDef.wipe()
......
5528 5654
    assert carddef.data_class().count() == 1
5529 5655
    card_data = carddef.data_class().select()[0]
5530 5656
    assert card_data.data['2'] == '3'
5657

  
5658

  
5659
def test_edit_carddata_manual_targeting(pub):
5660
    FormDef.wipe()
5661
    CardDef.wipe()
5662
    LoggedError.wipe()
5663

  
5664
    # carddef
5665
    carddef = CardDef()
5666
    carddef.name = 'Parent'
5667
    carddef.fields = [
5668
        StringField(id='0', label='First Name', varname='first_name'),
5669
        StringField(id='1', label='Last Name', varname='last_name'),
5670
        StringField(id='2', label='Kids number', varname='kids_number'),
5671
    ]
5672
    carddef.store()
5673
    carddef.data_class().wipe()
5674

  
5675
    # and sample carddatas
5676
    for i in range(1, 4):
5677
        carddata = carddef.data_class()()
5678
        carddata.data = {
5679
            '0': 'First name %s' % i,
5680
            '1': 'Last name %s' % i,
5681
            '2': '0',
5682
        }
5683
        carddata.store()
5684

  
5685
    # formdef workflow that will update carddata
5686
    wf = Workflow(name='Card create and update')
5687
    st1 = wf.add_status('Create card', 'st1')
5688
    # create linked carddata
5689
    edit = CreateCarddataWorkflowStatusItem()
5690
    edit.formdef_slug = carddef.url_name
5691
    edit.mappings = [
5692
        Mapping(field_id='0', expression='{{ form_var_first_name }}'),
5693
        Mapping(field_id='1', expression='{{ form_var_last_name }}'),
5694
        Mapping(field_id='2', expression='{{ form_var_kids_number|default:"0" }}'),
5695
    ]
5696
    st1.items.append(edit)
5697
    edit.parent = st1
5698
    jump = JumpWorkflowStatusItem()
5699
    jump.id = '_jump'
5700
    jump.by = ['_submitter', '_receiver']
5701
    jump.status = 'st2'
5702
    st1.items.append(jump)
5703
    jump.parent = st1
5704

  
5705
    st2 = wf.add_status('Update card', 'st2')
5706
    edit = EditCarddataWorkflowStatusItem()
5707
    edit.formdef_slug = carddef.url_name
5708
    edit.target_mode = 'manual'  # not configured
5709
    edit.mappings = [
5710
        Mapping(field_id='2', expression='{{ form_var_kids_number|add:"1" }}'),
5711
    ]
5712
    edit.id = 'edit'
5713
    st2.items.append(edit)
5714
    edit.parent = st2
5715
    wf.store()
5716

  
5717
    # associated formdef
5718
    formdef = FormDef()
5719
    formdef.name = 'Parents'
5720
    datasource = {'type': 'carddef:%s' % carddef.url_name}
5721
    formdef.fields = [
5722
        StringField(id='0', label='First Name',
5723
                    varname='first_name'),
5724
        StringField(id='1', label='Last Name',
5725
                    varname='last_name'),
5726
        StringField(id='2', label='Number of kids',
5727
                    varname='kids_number'),
5728
        ItemField(
5729
            id='3', label='Card',
5730
            type='item', varname='card',
5731
            data_source=datasource),
5732
        StringField(id='4', label='string', varname='string'),
5733
    ]
5734
    formdef.workflow = wf
5735
    formdef.store()
5736

  
5737
    # create formdatas
5738

  
5739
    # target not configured
5740
    formdata = formdef.data_class()()
5741
    formdata.data = {
5742
        '0': 'Parent',
5743
        '1': 'Foo',
5744
        '2': '2',
5745
        '3': '3',  # set from datasource
5746
        '4': '1',
5747
    }
5748
    # set parent
5749
    formdata.submission_context = {
5750
        'orig_object_type': 'carddef',
5751
        'orig_formdata_id': '2',
5752
        'orig_formdef_id': str(carddef.id),
5753
    }
5754
    formdata.store()
5755
    formdata.just_created()
5756
    formdata.perform_workflow()
5757

  
5758
    assert carddef.data_class().count() == 4
5759
    assert carddef.data_class().get(1).data['2'] == '0'
5760
    assert carddef.data_class().get(2).data['2'] == '0'
5761
    assert carddef.data_class().get(3).data['2'] == '0'
5762
    assert carddef.data_class().get(4).data['2'] == '2'
5763
    assert LoggedError.count() == 0
5764

  
5765
    # configure target
5766
    edit.target_id = '{{ form_var_string }}'  # == '1'
5767
    wf.store()
5768
    formdata = formdef.data_class()()
5769
    formdata.data = {
5770
        '0': 'Parent',
5771
        '1': 'Foo',
5772
        '2': '2',
5773
        '3': '3',  # set from datasource
5774
        '4': '1',
5775
    }
5776
    # set parent
5777
    formdata.submission_context = {
5778
        'orig_object_type': 'carddef',
5779
        'orig_formdata_id': '2',
5780
        'orig_formdef_id': str(carddef.id),
5781
    }
5782
    formdata.store()
5783
    formdata.just_created()
5784
    formdata.perform_workflow()
5785
    assert carddef.data_class().count() == 5
5786
    assert carddef.data_class().get(1).data['2'] == '3'  # 2 + 1
5787
    assert carddef.data_class().get(2).data['2'] == '0'
5788
    assert carddef.data_class().get(3).data['2'] == '0'
5789
    assert carddef.data_class().get(4).data['2'] == '2'
5790
    assert carddef.data_class().get(5).data['2'] == '2'
5791
    assert LoggedError.count() == 0
5792

  
5793
    # target not found
5794
    edit.target_id = '42{{ form_var_string }}'  # == '421'
5795
    wf.store()
5796
    formdata = formdef.data_class()()
5797
    formdata.data = {
5798
        '0': 'Parent',
5799
        '1': 'Foo',
5800
        '2': '2',
5801
        '3': '3',  # set from datasource
5802
        '4': '1',
5803
    }
5804
    # set parent
5805
    formdata.submission_context = {
5806
        'orig_object_type': 'carddef',
5807
        'orig_formdata_id': '2',
5808
        'orig_formdef_id': str(carddef.id),
5809
    }
5810
    formdata.store()
5811
    formdata.just_created()
5812
    formdata.perform_workflow()
5813
    assert carddef.data_class().count() == 6
5814
    assert carddef.data_class().get(1).data['2'] == '3'  # not changed
5815
    assert carddef.data_class().get(2).data['2'] == '0'
5816
    assert carddef.data_class().get(3).data['2'] == '0'
5817
    assert carddef.data_class().get(4).data['2'] == '2'
5818
    assert carddef.data_class().get(5).data['2'] == '2'
5819
    assert carddef.data_class().get(6).data['2'] == '2'
5820
    assert LoggedError.count() == 1
5821
    logged_error = LoggedError.select()[0]
5822
    assert logged_error.summary == 'Could not find targeted "Parent" object by id 421'
wcs/wf/external_workflow.py
130 130
                             'object_name': objectdef.name}
131 131
        return _('not completed')
132 132

  
133
    def get_manual_target(self, formdata):
134
        if self.target_mode != 'manual':
135
            return
136

  
137
        objectdef = self.get_object_def()
138
        target_id = self.compute(self.target_id, formdata=formdata, status_item=self)
139
        if not target_id:
140
            return
141

  
142
        try:
143
            return objectdef.data_class().get(target_id)
144
        except KeyError as e:
145
            # use custom error message depending on target type
146
            LoggedError.record(_('Could not find targeted "%(object_name)s" object by id %(object_id)s') % {
147
                'object_name': objectdef.name, 'object_id': target_id},
148
                formdata=formdata, status_item=self, exception=e)
149

  
133 150
    def iter_target_datas(self, formdata, objectdef):
151
        if self.target_mode == 'manual':
152
            # return only target
153
            target = self.get_manual_target(formdata)
154
            if target:
155
                yield target
156
            return
157

  
134 158
        yield from formdata.iter_target_datas(objectdef=objectdef, object_type=self.slug, status_item=self)
135 159

  
136 160
    def get_parameters(self):
137
-