Projet

Général

Profil

0002-misc-split-workflow-carddata-tests.patch

Lauréline Guérin, 09 septembre 2021 15:02

Télécharger (54,6 ko)

Voir les différences:

Subject: [PATCH 2/3] misc: split workflow carddata tests

 tests/workflow/test_all.py      | 796 -----------------------------
 tests/workflow/test_carddata.py | 855 ++++++++++++++++++++++++++++++++
 2 files changed, 855 insertions(+), 796 deletions(-)
 create mode 100644 tests/workflow/test_carddata.py
tests/workflow/test_all.py
59 59
from wcs.wf.create_formdata import CreateFormdataWorkflowStatusItem, Mapping
60 60
from wcs.wf.criticality import MODE_DEC, MODE_INC, MODE_SET, ModifyCriticalityWorkflowStatusItem
61 61
from wcs.wf.dispatch import DispatchWorkflowStatusItem
62
from wcs.wf.edit_carddata import EditCarddataWorkflowStatusItem
63 62
from wcs.wf.export_to_model import ExportToModel, transform_to_pdf
64 63
from wcs.wf.form import FormWorkflowStatusItem, WorkflowFormFieldsFormDef
65 64
from wcs.wf.geolocate import GeolocateWorkflowStatusItem
......
6249 6248
    assert 'deleted' in str(formdata.evolution[-1].parts[0].view())
6250 6249

  
6251 6250

  
6252
def test_create_carddata(two_pubs):
6253
    CardDef.wipe()
6254
    FormDef.wipe()
6255
    if two_pubs.is_using_postgresql():
6256
        two_pubs.loggederror_class.wipe()
6257

  
6258
    carddef = CardDef()
6259
    carddef.name = 'My card'
6260
    carddef.fields = [
6261
        StringField(id='1', label='string'),
6262
        ItemField(id='2', label='List', items=['item1', 'item2'], varname='clist'),
6263
        DateField(id='3', label='Date', varname='cdate'),
6264
        FileField(id='4', label='File', varname='cfile'),
6265
    ]
6266
    carddef.store()
6267

  
6268
    wf = Workflow(name='create-carddata')
6269
    wf.possible_status = Workflow.get_default_workflow().possible_status[:]
6270
    create = CreateCarddataWorkflowStatusItem()
6271
    create.label = 'Create CardDef'
6272
    create.varname = 'mycard'
6273
    create.id = '_create'
6274
    create.formdef_slug = carddef.url_name
6275
    create.mappings = [
6276
        Mapping(field_id='1', expression='=form_var_undefined'),
6277
        Mapping(field_id='2', expression='{{ form_var_list }}'),
6278
        Mapping(field_id='3', expression='{{ form_var_date }}'),
6279
        Mapping(field_id='4', expression='{{ form_var_file|default_if_none:"" }}'),
6280
    ]
6281
    create.parent = wf.possible_status[1]
6282
    wf.possible_status[1].items.insert(0, create)
6283
    wf.store()
6284

  
6285
    formdef = FormDef()
6286
    formdef.name = 'source form'
6287
    formdef.fields = [
6288
        ItemField(id='1', label='List', items=['item1', 'item2'], varname='list'),
6289
        DateField(id='2', label='Date', varname='date'),
6290
        FileField(id='3', label='File', varname='file'),
6291
    ]
6292
    formdef.workflow_id = wf.id
6293
    formdef.store()
6294

  
6295
    formdata = formdef.data_class()()
6296
    formdata.data = {}
6297
    formdata.just_created()
6298

  
6299
    assert carddef.data_class().count() == 0
6300

  
6301
    formdata = formdef.data_class()()
6302
    formdata.data = {}
6303

  
6304
    formdata.just_created()
6305
    formdata.perform_workflow()
6306

  
6307
    assert carddef.data_class().count() == 1
6308

  
6309
    if two_pubs.is_using_postgresql():
6310
        errors = two_pubs.loggederror_class.select()
6311
        assert len(errors) == 2
6312
        assert any('form_var_undefined' in (error.exception_message or '') for error in errors)
6313
        assert any('invalid date value' in (error.exception_message or '') for error in errors)
6314

  
6315
    formdata = formdef.data_class()()
6316
    today = datetime.date.today()
6317

  
6318
    upload = PicklableUpload('test.jpeg', 'image/jpeg')
6319
    with open(os.path.join(os.path.dirname(__file__), 'image-with-gps-data.jpeg'), 'rb') as jpg:
6320
        upload.receive([jpg.read()])
6321

  
6322
    formdata.data = {'1': 'item1', '1_display': 'item1', '2': today.timetuple(), '3': upload}
6323
    formdata.just_created()
6324
    formdata.perform_workflow()
6325

  
6326
    assert formdata.get_substitution_variables()['form_links_mycard_form_number'] == '1-2'
6327
    carddata = carddef.data_class().get(id=2)
6328
    assert carddata.data['2'] == 'item1'
6329
    assert carddata.data['2_display'] == 'item1'
6330
    assert carddata.data['3'] == today.timetuple()
6331
    assert carddata.data['4'].base_filename == 'test.jpeg'
6332

  
6333
    create.condition = {'type': 'python', 'value': '1 == 2'}
6334
    wf.store()
6335
    del formdef._workflow
6336
    carddef.data_class().wipe()
6337
    assert carddef.data_class().count() == 0
6338
    formdata.perform_workflow()
6339
    assert carddef.data_class().count() == 0
6340

  
6341

  
6342
def test_create_carddata_with_map_field(two_pubs):
6343
    CardDef.wipe()
6344
    FormDef.wipe()
6345
    if two_pubs.is_using_postgresql():
6346
        two_pubs.loggederror_class.wipe()
6347

  
6348
    carddef = CardDef()
6349
    carddef.name = 'My card'
6350
    carddef.fields = [
6351
        MapField(id='1', label='map', varname='map'),
6352
    ]
6353
    carddef.store()
6354

  
6355
    wf = Workflow(name='create-carddata')
6356
    wf.possible_status = Workflow.get_default_workflow().possible_status[:]
6357
    create = CreateCarddataWorkflowStatusItem()
6358
    create.label = 'Create CardDef'
6359
    create.varname = 'mycard'
6360
    create.id = '_create'
6361
    create.formdef_slug = carddef.url_name
6362
    create.mappings = [
6363
        Mapping(field_id='1', expression=''),
6364
    ]
6365
    create.parent = wf.possible_status[1]
6366
    wf.possible_status[1].items.insert(0, create)
6367
    wf.store()
6368

  
6369
    formdef = FormDef()
6370
    formdef.name = 'source form'
6371
    formdef.fields = [
6372
        MapField(id='1', label='map', varname='map'),
6373
    ]
6374
    formdef.workflow_id = wf.id
6375
    formdef.store()
6376

  
6377
    formdata = formdef.data_class()()
6378
    formdata.data = {}
6379
    formdata.just_created()
6380
    assert carddef.data_class().count() == 0
6381

  
6382
    # empty value
6383
    formdata = formdef.data_class()()
6384
    formdata.data = {}
6385
    formdata.just_created()
6386
    formdata.perform_workflow()
6387
    assert carddef.data_class().count() == 1
6388
    assert not carddef.data_class().select()[0].data.get('1')
6389

  
6390
    # valid coordinates
6391
    create.mappings[0].expression = '1;2'
6392
    wf.store()
6393
    formdef.refresh_from_storage()
6394
    carddef.data_class().wipe()
6395
    formdata = formdef.data_class()()
6396
    formdata.data = {}
6397
    formdata.just_created()
6398
    formdata.perform_workflow()
6399
    assert carddef.data_class().count() == 1
6400
    assert carddef.data_class().select()[0].data.get('1') == '1;2'
6401

  
6402
    # invalid value
6403
    create.mappings[0].expression = 'plop'
6404
    wf.store()
6405
    formdef.refresh_from_storage()
6406
    carddef.data_class().wipe()
6407
    formdata = formdef.data_class()()
6408
    formdata.data = {}
6409
    formdata.just_created()
6410
    formdata.perform_workflow()
6411
    assert carddef.data_class().count() == 1
6412
    assert not carddef.data_class().select()[0].data.get('1')
6413

  
6414
    if two_pubs.is_using_postgresql():
6415
        errors = two_pubs.loggederror_class.select()
6416
        assert len(errors) == 1
6417
        assert any('invalid coordinates' in (error.exception_message or '') for error in errors)
6418

  
6419
    # value from formdata
6420
    create.mappings[0].expression = '{{ form_var_map }}'
6421
    wf.store()
6422
    formdef.refresh_from_storage()
6423
    carddef.data_class().wipe()
6424
    formdata = formdef.data_class()()
6425
    formdata.data = {'1': '2;3'}
6426
    formdata.just_created()
6427
    formdata.perform_workflow()
6428
    assert carddef.data_class().count() == 1
6429
    assert carddef.data_class().select()[0].data.get('1') == '2;3'
6430

  
6431

  
6432
def test_create_carddata_user_association(two_pubs):
6433
    CardDef.wipe()
6434
    FormDef.wipe()
6435
    two_pubs.user_class.wipe()
6436

  
6437
    user = two_pubs.user_class()
6438
    user.email = 'test@example.net'
6439
    user.name_identifiers = ['xyz']
6440
    user.store()
6441

  
6442
    carddef = CardDef()
6443
    carddef.name = 'My card'
6444
    carddef.fields = []
6445
    carddef.user_support = 'optional'
6446
    carddef.store()
6447
    carddef.data_class().wipe()
6448

  
6449
    wf = Workflow(name='create-carddata')
6450
    wf.possible_status = Workflow.get_default_workflow().possible_status[:]
6451
    create = CreateCarddataWorkflowStatusItem()
6452
    create.label = 'Create CardDef'
6453
    create.varname = 'mycard'
6454
    create.id = '_create'
6455
    create.formdef_slug = carddef.url_name
6456
    create.map_fields_by_varname = True
6457
    create.parent = wf.possible_status[1]
6458
    wf.possible_status[1].items.insert(0, create)
6459
    wf.store()
6460

  
6461
    formdef = FormDef()
6462
    formdef.name = 'source form'
6463
    formdef.fields = []
6464
    formdef.workflow_id = wf.id
6465
    formdef.store()
6466

  
6467
    formdata = formdef.data_class()()
6468
    formdata.data = {}
6469
    formdata.user_id = user.id
6470
    formdata.just_created()
6471
    formdata.perform_workflow()
6472

  
6473
    assert carddef.data_class().count() == 1
6474
    assert carddef.data_class().select()[0].user is None
6475

  
6476
    # keep user
6477
    carddef.data_class().wipe()
6478
    create.user_association_mode = 'keep-user'
6479
    wf.store()
6480

  
6481
    formdata = FormDef.get(formdef.id).data_class()()
6482
    formdata.data = {}
6483
    formdata.user_id = user.id
6484
    formdata.just_created()
6485
    formdata.perform_workflow()
6486

  
6487
    assert carddef.data_class().count() == 1
6488
    assert carddef.data_class().select()[0].user.id == user.id
6489

  
6490
    # user association on direct user
6491
    carddef.data_class().wipe()
6492
    create.user_association_mode = 'custom'
6493
    create.user_association_template = '{{ form_user }}'
6494
    wf.store()
6495

  
6496
    formdata = FormDef.get(formdef.id).data_class()()
6497
    formdata.data = {}
6498
    formdata.user_id = user.id
6499
    formdata.just_created()
6500
    formdata.perform_workflow()
6501

  
6502
    assert carddef.data_class().count() == 1
6503
    assert carddef.data_class().select()[0].user.id == user.id
6504

  
6505
    # user association on user email
6506
    carddef.data_class().wipe()
6507
    create.user_association_mode = 'custom'
6508
    create.user_association_template = 'test@example.net'
6509
    wf.store()
6510

  
6511
    formdata = FormDef.get(formdef.id).data_class()()
6512
    formdata.data = {}
6513
    formdata.user_id = user.id
6514
    formdata.just_created()
6515
    formdata.perform_workflow()
6516

  
6517
    assert carddef.data_class().count() == 1
6518
    assert carddef.data_class().select()[0].user.id == user.id
6519

  
6520
    # user association on name id
6521
    carddef.data_class().wipe()
6522
    create.user_association_mode = 'custom'
6523
    create.user_association_template = 'xyz'
6524
    wf.store()
6525

  
6526
    formdata = FormDef.get(formdef.id).data_class()()
6527
    formdata.data = {}
6528
    formdata.user_id = user.id
6529
    formdata.just_created()
6530
    formdata.perform_workflow()
6531

  
6532
    assert carddef.data_class().count() == 1
6533
    assert carddef.data_class().select()[0].user.id == user.id
6534

  
6535
    # user association on invalid user
6536
    carddef.data_class().wipe()
6537
    create.user_association_mode = 'custom'
6538
    create.user_association_template = 'zzz'
6539
    wf.store()
6540

  
6541
    formdata = FormDef.get(formdef.id).data_class()()
6542
    formdata.data = {}
6543
    formdata.user_id = user.id
6544
    formdata.just_created()
6545
    if two_pubs.loggederror_class:
6546
        two_pubs.loggederror_class.wipe()
6547
    formdata.perform_workflow()
6548

  
6549
    assert carddef.data_class().count() == 1
6550
    assert carddef.data_class().select()[0].user is None
6551
    if two_pubs.loggederror_class:
6552
        assert two_pubs.loggederror_class.count() == 1
6553
        logged_error = two_pubs.loggederror_class.select()[0]
6554
        assert logged_error.summary == 'Failed to attach user (not found: "zzz")'
6555
        assert logged_error.formdata_id == str(carddef.data_class().select()[0].id)
6556

  
6557
    # user association on invalid template
6558
    carddef.data_class().wipe()
6559
    create.user_association_mode = 'custom'
6560
    create.user_association_template = '{% %}'
6561
    wf.store()
6562

  
6563
    formdata = FormDef.get(formdef.id).data_class()()
6564
    formdata.data = {}
6565
    formdata.user_id = user.id
6566
    formdata.just_created()
6567
    formdata.perform_workflow()
6568

  
6569
    assert carddef.data_class().count() == 1
6570
    assert carddef.data_class().select()[0].user is None
6571

  
6572

  
6573 6251
def test_call_external_workflow_with_evolution_linked_object(two_pubs):
6574 6252
    FormDef.wipe()
6575 6253
    CardDef.wipe()
......
7089 6767
    assert carddef.data_class().get(2).data['bo0'] is None
7090 6768
    assert carddef.data_class().get(3).data['bo0'] is None
7091 6769
    assert carddef.data_class().get(4).data['bo0'] is None
7092

  
7093

  
7094
def test_edit_carddata_with_data_sourced_object(pub):
7095
    FormDef.wipe()
7096
    CardDef.wipe()
7097

  
7098
    datasource = {
7099
        'type': 'formula',
7100
        'value': repr(
7101
            [
7102
                {'id': 'b', 'text': 'baker', 'extra': 'plop'},
7103
                {'id': 'c', 'text': 'cook', 'extra': 'plop2'},
7104
                {'id': 'l', 'text': 'lawyer', 'extra': 'plop3'},
7105
            ]
7106
        ),
7107
    }
7108
    carddef = CardDef()
7109
    carddef.name = 'Person'
7110
    carddef.fields = [
7111
        StringField(id='0', label='First Name', varname='first_name'),
7112
        StringField(id='1', label='Last Name', varname='last_name'),
7113
        ItemField(id='2', label='Profession', type='item', varname='profession', data_source=datasource),
7114
    ]
7115
    carddef.digest_templates = {'default': '{{ form_var_first_name }} {{ form_var_last_name }}'}
7116
    carddef.store()
7117

  
7118
    carddata = carddef.data_class()()
7119
    carddata.data = {'0': 'Foo', '1': 'Bar', '2': 'l'}
7120
    carddata.data['2_display'] = carddef.fields[2].store_display_value(carddata.data, '2')
7121
    carddata.data['2_structured'] = carddef.fields[2].store_structured_value(carddata.data, '2')
7122
    carddata.store()
7123

  
7124
    wf = Workflow(name='Card update')
7125
    st1 = wf.add_status('Update card', 'st1')
7126

  
7127
    edit = EditCarddataWorkflowStatusItem()
7128
    edit.formdef_slug = carddef.url_name
7129
    edit.mappings = [
7130
        Mapping(field_id='2', expression='{{ form_var_new_profession }}'),
7131
    ]
7132
    edit.id = 'edit'
7133
    st1.items.append(edit)
7134
    edit.parent = st1
7135
    wf.store()
7136

  
7137
    datasource = {'type': 'carddef:%s' % carddef.url_name}
7138
    formdef = FormDef()
7139
    formdef.name = 'Persons'
7140
    formdef.fields = [
7141
        ItemField(id='0', label='Person', type='item', varname='person', data_source=datasource),
7142
        StringField(id='1', label='New profession', varname='new_profession'),
7143
    ]
7144
    formdef.workflow = wf
7145
    formdef.store()
7146

  
7147
    formdata = formdef.data_class()()
7148
    formdata.data = {'0': '1', '1': 'c'}
7149
    formdata.store()
7150
    formdata.just_created()
7151
    formdata.perform_workflow()
7152

  
7153
    data = carddef.data_class().select()[0]
7154
    assert data.data['2'] == 'c'
7155
    assert data.data['2_display'] == 'cook'
7156
    assert data.data['2_structured'] == {'id': 'c', 'text': 'cook', 'extra': 'plop2'}
7157

  
7158
    formdata = formdef.data_class()()
7159
    formdata.data = {'0': '1', '1': 'b'}
7160
    formdata.store()
7161
    formdata.just_created()
7162
    formdata.perform_workflow()
7163

  
7164
    data = carddef.data_class().select()[0]
7165
    assert data.data['2'] == 'b'
7166
    assert data.data['2_display'] == 'baker'
7167
    assert data.data['2_structured'] == {'id': 'b', 'text': 'baker', 'extra': 'plop'}
7168

  
7169
    # reset data
7170
    for expression in ('=None', '', '""'):
7171
        edit.mappings = [
7172
            Mapping(field_id='2', expression=expression),
7173
        ]
7174
        wf.store()
7175

  
7176
        formdata = formdef.data_class()()
7177
        formdata.data = {'0': '1', '1': 'b'}
7178
        formdata.store()
7179
        formdata.just_created()
7180
        formdata.perform_workflow()
7181

  
7182
        carddata = carddef.data_class().select()[0]
7183
        assert carddata.data['2'] in [None, '', '""']
7184
        assert carddata.data.get('2_display') is None
7185
        assert carddata.data.get('2_structured') is None
7186

  
7187
        # restore initial data
7188
        carddata.data = data.data
7189
        carddata.store()
7190

  
7191

  
7192
def test_edit_carddata_with_linked_object(pub):
7193
    FormDef.wipe()
7194
    CardDef.wipe()
7195

  
7196
    carddef = CardDef()
7197
    carddef.name = 'Parent'
7198
    carddef.fields = [
7199
        StringField(id='0', label='First Name', varname='first_name'),
7200
        StringField(id='1', label='Last Name', varname='last_name'),
7201
        StringField(id='2', label='Kids number', varname='kids_number'),
7202
    ]
7203
    carddef.store()
7204

  
7205
    wf = Workflow(name='Card create and update')
7206
    st1 = wf.add_status('Create card', 'st1')
7207
    edit = CreateCarddataWorkflowStatusItem()
7208
    edit.formdef_slug = carddef.url_name
7209
    edit.mappings = [
7210
        Mapping(field_id='0', expression='{{ form_var_first_name }}'),
7211
        Mapping(field_id='1', expression='{{ form_var_last_name }}'),
7212
        Mapping(field_id='2', expression='{{ form_var_kids_number|default:"0" }}'),
7213
    ]
7214
    st1.items.append(edit)
7215
    edit.parent = st1
7216
    jump = JumpWorkflowStatusItem()
7217
    jump.id = '_jump'
7218
    jump.by = ['_submitter', '_receiver']
7219
    jump.status = 'st2'
7220
    st1.items.append(jump)
7221
    jump.parent = st1
7222

  
7223
    st2 = wf.add_status('Update card', 'st2')
7224
    edit = EditCarddataWorkflowStatusItem()
7225
    edit.formdef_slug = carddef.url_name
7226
    edit.mappings = [
7227
        Mapping(field_id='2', expression='{{ form_var_kids_number|add:"1" }}'),
7228
    ]
7229
    edit.id = 'edit'
7230
    st2.items.append(edit)
7231
    edit.parent = st2
7232
    wf.store()
7233

  
7234
    formdef = FormDef()
7235
    formdef.name = 'Parents'
7236
    formdef.fields = [
7237
        StringField(id='0', label='First Name', varname='first_name'),
7238
        StringField(id='1', label='Last Name', varname='last_name'),
7239
        StringField(id='2', label='Number of kids', varname='kids_number'),
7240
    ]
7241
    formdef.workflow = wf
7242
    formdef.store()
7243

  
7244
    formdata = formdef.data_class()()
7245
    formdata.data = {'0': 'Parent', '1': 'Foo', '2': '2'}
7246
    formdata.store()
7247
    formdata.just_created()
7248
    formdata.perform_workflow()
7249

  
7250
    assert carddef.data_class().count() == 1
7251
    card_data = carddef.data_class().select()[0]
7252
    assert card_data.data['2'] == '3'
7253

  
7254

  
7255
def test_edit_carddata_manual_targeting(two_pubs):
7256
    if not two_pubs.is_using_postgresql():
7257
        pytest.skip('this requires SQL')
7258
        return
7259

  
7260
    FormDef.wipe()
7261
    CardDef.wipe()
7262
    two_pubs.loggederror_class.wipe()
7263

  
7264
    # carddef
7265
    carddef = CardDef()
7266
    carddef.name = 'Parent'
7267
    carddef.fields = [
7268
        StringField(id='0', label='First Name', varname='first_name'),
7269
        StringField(id='1', label='Last Name', varname='last_name'),
7270
        StringField(id='2', label='Kids number', varname='kids_number'),
7271
    ]
7272
    carddef.store()
7273
    carddef.data_class().wipe()
7274

  
7275
    # and sample carddatas
7276
    for i in range(1, 4):
7277
        carddata = carddef.data_class()()
7278
        carddata.data = {
7279
            '0': 'First name %s' % i,
7280
            '1': 'Last name %s' % i,
7281
            '2': '0',
7282
        }
7283
        carddata.store()
7284

  
7285
    # formdef workflow that will update carddata
7286
    wf = Workflow(name='Card create and update')
7287
    st1 = wf.add_status('Create card', 'st1')
7288
    # create linked carddata
7289
    edit = CreateCarddataWorkflowStatusItem()
7290
    edit.formdef_slug = carddef.url_name
7291
    edit.mappings = [
7292
        Mapping(field_id='0', expression='{{ form_var_first_name }}'),
7293
        Mapping(field_id='1', expression='{{ form_var_last_name }}'),
7294
        Mapping(field_id='2', expression='{{ form_var_kids_number|default:"0" }}'),
7295
    ]
7296
    st1.items.append(edit)
7297
    edit.parent = st1
7298
    jump = JumpWorkflowStatusItem()
7299
    jump.id = '_jump'
7300
    jump.by = ['_submitter', '_receiver']
7301
    jump.status = 'st2'
7302
    st1.items.append(jump)
7303
    jump.parent = st1
7304

  
7305
    st2 = wf.add_status('Update card', 'st2')
7306
    edit = EditCarddataWorkflowStatusItem()
7307
    edit.formdef_slug = carddef.url_name
7308
    edit.target_mode = 'manual'  # not configured
7309
    edit.mappings = [
7310
        Mapping(field_id='2', expression='{{ form_var_kids_number|add:"1" }}'),
7311
    ]
7312
    edit.id = 'edit'
7313
    st2.items.append(edit)
7314
    edit.parent = st2
7315
    wf.store()
7316

  
7317
    # associated formdef
7318
    formdef = FormDef()
7319
    formdef.name = 'Parents'
7320
    datasource = {'type': 'carddef:%s' % carddef.url_name}
7321
    formdef.fields = [
7322
        StringField(id='0', label='First Name', varname='first_name'),
7323
        StringField(id='1', label='Last Name', varname='last_name'),
7324
        StringField(id='2', label='Number of kids', varname='kids_number'),
7325
        ItemField(id='3', label='Card', type='item', varname='card', data_source=datasource),
7326
        StringField(id='4', label='string', varname='string'),
7327
    ]
7328
    formdef.workflow = wf
7329
    formdef.store()
7330

  
7331
    # create formdatas
7332

  
7333
    # target not configured
7334
    formdata = formdef.data_class()()
7335
    formdata.data = {
7336
        '0': 'Parent',
7337
        '1': 'Foo',
7338
        '2': '2',
7339
        '3': '3',  # set from datasource
7340
        '4': '1',
7341
    }
7342
    # set parent
7343
    formdata.submission_context = {
7344
        'orig_object_type': 'carddef',
7345
        'orig_formdata_id': '2',
7346
        'orig_formdef_id': str(carddef.id),
7347
    }
7348
    formdata.store()
7349
    formdata.just_created()
7350
    formdata.perform_workflow()
7351

  
7352
    assert carddef.data_class().count() == 4
7353
    assert carddef.data_class().get(1).data['2'] == '0'
7354
    assert carddef.data_class().get(2).data['2'] == '0'
7355
    assert carddef.data_class().get(3).data['2'] == '0'
7356
    assert carddef.data_class().get(4).data['2'] == '2'
7357
    assert two_pubs.loggederror_class.count() == 0
7358

  
7359
    # configure target
7360
    edit.target_id = '{{ form_var_string }}'  # == '1'
7361
    wf.store()
7362
    formdata = formdef.data_class()()
7363
    formdata.data = {
7364
        '0': 'Parent',
7365
        '1': 'Foo',
7366
        '2': '2',
7367
        '3': '3',  # set from datasource
7368
        '4': '1',
7369
    }
7370
    # set parent
7371
    formdata.submission_context = {
7372
        'orig_object_type': 'carddef',
7373
        'orig_formdata_id': '2',
7374
        'orig_formdef_id': str(carddef.id),
7375
    }
7376
    formdata.store()
7377
    formdata.just_created()
7378
    formdata.perform_workflow()
7379
    assert carddef.data_class().count() == 5
7380
    assert carddef.data_class().get(1).data['2'] == '3'  # 2 + 1
7381
    assert carddef.data_class().get(2).data['2'] == '0'
7382
    assert carddef.data_class().get(3).data['2'] == '0'
7383
    assert carddef.data_class().get(4).data['2'] == '2'
7384
    assert carddef.data_class().get(5).data['2'] == '2'
7385
    assert two_pubs.loggederror_class.count() == 0
7386

  
7387
    # target not found
7388
    edit.target_id = '42{{ form_var_string }}'  # == '421'
7389
    wf.store()
7390
    formdata = formdef.data_class()()
7391
    formdata.data = {
7392
        '0': 'Parent',
7393
        '1': 'Foo',
7394
        '2': '2',
7395
        '3': '3',  # set from datasource
7396
        '4': '1',
7397
    }
7398
    # set parent
7399
    formdata.submission_context = {
7400
        'orig_object_type': 'carddef',
7401
        'orig_formdata_id': '2',
7402
        'orig_formdef_id': str(carddef.id),
7403
    }
7404
    formdata.store()
7405
    formdata.just_created()
7406
    formdata.perform_workflow()
7407
    assert carddef.data_class().count() == 6
7408
    assert carddef.data_class().get(1).data['2'] == '3'  # not changed
7409
    assert carddef.data_class().get(2).data['2'] == '0'
7410
    assert carddef.data_class().get(3).data['2'] == '0'
7411
    assert carddef.data_class().get(4).data['2'] == '2'
7412
    assert carddef.data_class().get(5).data['2'] == '2'
7413
    assert carddef.data_class().get(6).data['2'] == '2'
7414
    assert two_pubs.loggederror_class.count() == 1
7415
    logged_error = two_pubs.loggederror_class.select()[0]
7416
    assert logged_error.summary == 'Could not find targeted "Parent" object by id 421'
7417

  
7418
    # slug not or badly configured
7419
    edit.target_id = '{{ form_var_string }}'  # == '1'
7420
    edit.formdef_slug = None
7421
    wf.store()
7422
    formdata = formdef.data_class()()
7423
    formdata.data = {
7424
        '0': 'Parent',
7425
        '1': 'Foo',
7426
        '2': '3',
7427
        '3': '3',  # set from datasource
7428
        '4': '1',
7429
    }
7430
    # set parent
7431
    formdata.submission_context = {
7432
        'orig_object_type': 'carddef',
7433
        'orig_formdata_id': '2',
7434
        'orig_formdef_id': str(carddef.id),
7435
    }
7436
    formdata.store()
7437
    formdata.just_created()
7438
    formdata.perform_workflow()
7439
    assert carddef.data_class().count() == 7
7440
    assert carddef.data_class().get(1).data['2'] == '3'  # not changed
7441
    assert carddef.data_class().get(2).data['2'] == '0'
7442
    assert carddef.data_class().get(3).data['2'] == '0'
7443
    assert carddef.data_class().get(4).data['2'] == '2'
7444
    assert carddef.data_class().get(5).data['2'] == '2'
7445
    assert carddef.data_class().get(6).data['2'] == '2'
7446
    assert carddef.data_class().get(7).data['2'] == '3'
7447

  
7448

  
7449
def test_edit_carddata_targeting_itself(pub):
7450
    CardDef.wipe()
7451
    carddef = CardDef()
7452
    carddef.name = 'Foo Card'
7453
    carddef.fields = [
7454
        StringField(id='0', label='foo', varname='foo'),
7455
    ]
7456
    carddef.store()
7457
    carddef.data_class().wipe()
7458

  
7459
    # card workflow: update itself then jump to second status
7460
    card_wf = Workflow(name='Card workflow')
7461
    st1 = card_wf.add_status('Status1')
7462
    st2 = card_wf.add_status('Status2')
7463

  
7464
    edit = EditCarddataWorkflowStatusItem()
7465
    edit.id = '_edit'
7466
    edit.formdef_slug = carddef.url_name
7467
    edit.target_mode = 'manual'
7468
    edit.target_id = '{{ form_internal_id }}'  # itself
7469
    edit.mappings = [
7470
        Mapping(field_id='0', expression='bar {{ form_internal_id }}'),
7471
    ]
7472
    edit.parent = st1
7473
    st1.items.append(edit)
7474

  
7475
    jump = JumpWorkflowStatusItem()
7476
    jump.id = '_jump'
7477
    jump.status = st2.id
7478
    st1.items.append(jump)
7479
    jump.parent = st1
7480

  
7481
    card_wf.store()
7482

  
7483
    carddef.workflow = card_wf
7484
    carddef.store()
7485

  
7486
    # create some cardata
7487
    for i in range(1, 4):
7488
        carddata = carddef.data_class()()
7489
        carddata.data = {
7490
            '0': 'foo %s' % i,
7491
        }
7492
        carddata.store()
7493
        # run workflow, verify that carddata is modified
7494
        carddata.just_created()
7495
        carddata.perform_workflow()
7496
        assert carddata.data['0'] == 'bar %s' % carddata.id
7497
        assert carddata.status == 'wf-%s' % st2.id
7498

  
7499

  
7500
def test_edit_carddata_from_created_object(pub):
7501
    FormDef.wipe()
7502
    CardDef.wipe()
7503

  
7504
    carddef = CardDef()
7505
    carddef.name = 'Card'
7506
    carddef.fields = [
7507
        StringField(id='0', label='Card Field', varname='card_field'),
7508
    ]
7509
    carddef.store()
7510

  
7511
    formdef = FormDef()
7512
    formdef.name = 'Form'
7513
    formdef.fields = [
7514
        StringField(id='0', label='Form Field', varname='form_field'),
7515
    ]
7516
    formdef.store()
7517

  
7518
    # card workflow: create formdata then jump to second status
7519
    card_wf = Workflow(name='Card workflow')
7520
    st1 = card_wf.add_status('Status1')
7521
    st2 = card_wf.add_status('Status2')
7522

  
7523
    create = CreateFormdataWorkflowStatusItem()
7524
    create.id = '_create'
7525
    create.formdef_slug = formdef.url_name
7526
    create.mappings = [
7527
        Mapping(field_id='0', expression='...'),
7528
    ]
7529
    create.parent = st1
7530
    st1.items.append(create)
7531

  
7532
    jump = JumpWorkflowStatusItem()
7533
    jump.id = '_jump'
7534
    jump.status = st2.id
7535
    st1.items.append(jump)
7536
    jump.parent = st1
7537

  
7538
    # form workflow: edit parent card data
7539
    form_wf = Workflow(name='Form workflow')
7540
    st1 = form_wf.add_status('Status1')
7541
    edit = EditCarddataWorkflowStatusItem()
7542
    edit.formdef_slug = carddef.url_name
7543
    edit.mappings = [
7544
        Mapping(field_id='0', expression='HELLO'),
7545
    ]
7546
    edit.id = 'edit'
7547
    st1.items.append(edit)
7548
    edit.parent = st1
7549
    form_wf.store()
7550

  
7551
    carddef.workflow = card_wf
7552
    carddef.store()
7553

  
7554
    formdef.workflow = form_wf
7555
    formdef.store()
7556

  
7557
    carddata = carddef.data_class()()
7558
    carddata.data = {'0': 'Foo'}
7559
    carddata.store()
7560
    carddata.just_created()
7561
    carddata.perform_workflow()
7562

  
7563
    carddata_reloaded = carddata.get(carddata.id)
7564
    assert carddata_reloaded.data['0'] == 'HELLO'
7565
    assert carddata_reloaded.status == 'wf-2'
tests/workflow/test_carddata.py
1
import datetime
2
import os
3

  
4
import pytest
5
from quixote import cleanup
6

  
7
from wcs import sessions
8
from wcs.carddef import CardDef
9
from wcs.fields import DateField, FileField, ItemField, MapField, StringField
10
from wcs.formdef import FormDef
11
from wcs.qommon.http_request import HTTPRequest
12
from wcs.qommon.upload_storage import PicklableUpload
13
from wcs.wf.create_carddata import CreateCarddataWorkflowStatusItem
14
from wcs.wf.create_formdata import CreateFormdataWorkflowStatusItem, Mapping
15
from wcs.wf.edit_carddata import EditCarddataWorkflowStatusItem
16
from wcs.wf.jump import JumpWorkflowStatusItem
17
from wcs.workflows import Workflow
18

  
19
from ..utilities import clean_temporary_pub, create_temporary_pub
20

  
21

  
22
def setup_module(module):
23
    cleanup()
24

  
25

  
26
def teardown_module(module):
27
    clean_temporary_pub()
28

  
29

  
30
def pytest_generate_tests(metafunc):
31
    if 'two_pubs' in metafunc.fixturenames:
32
        metafunc.parametrize('two_pubs', ['pickle', 'sql'], indirect=True)
33

  
34

  
35
@pytest.fixture
36
def pub(request):
37
    pub = create_temporary_pub()
38
    pub.cfg['language'] = {'language': 'en'}
39
    pub.write_cfg()
40
    req = HTTPRequest(None, {'SERVER_NAME': 'example.net', 'SCRIPT_NAME': ''})
41
    req.response.filter = {}
42
    req._user = None
43
    pub._set_request(req)
44
    req.session = sessions.BasicSession(id=1)
45
    pub.set_config(req)
46
    return pub
47

  
48

  
49
@pytest.fixture
50
def two_pubs(request):
51
    pub = create_temporary_pub(sql_mode=(request.param == 'sql'))
52
    pub.cfg['language'] = {'language': 'en'}
53
    pub.write_cfg()
54
    req = HTTPRequest(None, {'SERVER_NAME': 'example.net', 'SCRIPT_NAME': ''})
55
    req.response.filter = {}
56
    req._user = None
57
    pub._set_request(req)
58
    req.session = sessions.BasicSession(id=1)
59
    pub.set_config(req)
60
    return pub
61

  
62

  
63
def test_create_carddata(two_pubs):
64
    CardDef.wipe()
65
    FormDef.wipe()
66
    if two_pubs.is_using_postgresql():
67
        two_pubs.loggederror_class.wipe()
68

  
69
    carddef = CardDef()
70
    carddef.name = 'My card'
71
    carddef.fields = [
72
        StringField(id='1', label='string'),
73
        ItemField(id='2', label='List', items=['item1', 'item2'], varname='clist'),
74
        DateField(id='3', label='Date', varname='cdate'),
75
        FileField(id='4', label='File', varname='cfile'),
76
    ]
77
    carddef.store()
78

  
79
    wf = Workflow(name='create-carddata')
80
    wf.possible_status = Workflow.get_default_workflow().possible_status[:]
81
    create = CreateCarddataWorkflowStatusItem()
82
    create.label = 'Create CardDef'
83
    create.varname = 'mycard'
84
    create.id = '_create'
85
    create.formdef_slug = carddef.url_name
86
    create.mappings = [
87
        Mapping(field_id='1', expression='=form_var_undefined'),
88
        Mapping(field_id='2', expression='{{ form_var_list }}'),
89
        Mapping(field_id='3', expression='{{ form_var_date }}'),
90
        Mapping(field_id='4', expression='{{ form_var_file|default_if_none:"" }}'),
91
    ]
92
    create.parent = wf.possible_status[1]
93
    wf.possible_status[1].items.insert(0, create)
94
    wf.store()
95

  
96
    formdef = FormDef()
97
    formdef.name = 'source form'
98
    formdef.fields = [
99
        ItemField(id='1', label='List', items=['item1', 'item2'], varname='list'),
100
        DateField(id='2', label='Date', varname='date'),
101
        FileField(id='3', label='File', varname='file'),
102
    ]
103
    formdef.workflow_id = wf.id
104
    formdef.store()
105

  
106
    formdata = formdef.data_class()()
107
    formdata.data = {}
108
    formdata.just_created()
109

  
110
    assert carddef.data_class().count() == 0
111

  
112
    formdata = formdef.data_class()()
113
    formdata.data = {}
114

  
115
    formdata.just_created()
116
    formdata.perform_workflow()
117

  
118
    assert carddef.data_class().count() == 1
119

  
120
    if two_pubs.is_using_postgresql():
121
        errors = two_pubs.loggederror_class.select()
122
        assert len(errors) == 2
123
        assert any('form_var_undefined' in (error.exception_message or '') for error in errors)
124
        assert any('invalid date value' in (error.exception_message or '') for error in errors)
125

  
126
    formdata = formdef.data_class()()
127
    today = datetime.date.today()
128

  
129
    upload = PicklableUpload('test.jpeg', 'image/jpeg')
130
    with open(os.path.join(os.path.dirname(__file__), '..', 'image-with-gps-data.jpeg'), 'rb') as jpg:
131
        upload.receive([jpg.read()])
132

  
133
    formdata.data = {'1': 'item1', '1_display': 'item1', '2': today.timetuple(), '3': upload}
134
    formdata.just_created()
135
    formdata.perform_workflow()
136

  
137
    assert formdata.get_substitution_variables()['form_links_mycard_form_number'] == '1-2'
138
    carddata = carddef.data_class().get(id=2)
139
    assert carddata.data['2'] == 'item1'
140
    assert carddata.data['2_display'] == 'item1'
141
    assert carddata.data['3'] == today.timetuple()
142
    assert carddata.data['4'].base_filename == 'test.jpeg'
143

  
144
    create.condition = {'type': 'python', 'value': '1 == 2'}
145
    wf.store()
146
    del formdef._workflow
147
    carddef.data_class().wipe()
148
    assert carddef.data_class().count() == 0
149
    formdata.perform_workflow()
150
    assert carddef.data_class().count() == 0
151

  
152

  
153
def test_create_carddata_with_map_field(two_pubs):
154
    CardDef.wipe()
155
    FormDef.wipe()
156
    if two_pubs.is_using_postgresql():
157
        two_pubs.loggederror_class.wipe()
158

  
159
    carddef = CardDef()
160
    carddef.name = 'My card'
161
    carddef.fields = [
162
        MapField(id='1', label='map', varname='map'),
163
    ]
164
    carddef.store()
165

  
166
    wf = Workflow(name='create-carddata')
167
    wf.possible_status = Workflow.get_default_workflow().possible_status[:]
168
    create = CreateCarddataWorkflowStatusItem()
169
    create.label = 'Create CardDef'
170
    create.varname = 'mycard'
171
    create.id = '_create'
172
    create.formdef_slug = carddef.url_name
173
    create.mappings = [
174
        Mapping(field_id='1', expression=''),
175
    ]
176
    create.parent = wf.possible_status[1]
177
    wf.possible_status[1].items.insert(0, create)
178
    wf.store()
179

  
180
    formdef = FormDef()
181
    formdef.name = 'source form'
182
    formdef.fields = [
183
        MapField(id='1', label='map', varname='map'),
184
    ]
185
    formdef.workflow_id = wf.id
186
    formdef.store()
187

  
188
    formdata = formdef.data_class()()
189
    formdata.data = {}
190
    formdata.just_created()
191
    assert carddef.data_class().count() == 0
192

  
193
    # empty value
194
    formdata = formdef.data_class()()
195
    formdata.data = {}
196
    formdata.just_created()
197
    formdata.perform_workflow()
198
    assert carddef.data_class().count() == 1
199
    assert not carddef.data_class().select()[0].data.get('1')
200

  
201
    # valid coordinates
202
    create.mappings[0].expression = '1;2'
203
    wf.store()
204
    formdef.refresh_from_storage()
205
    carddef.data_class().wipe()
206
    formdata = formdef.data_class()()
207
    formdata.data = {}
208
    formdata.just_created()
209
    formdata.perform_workflow()
210
    assert carddef.data_class().count() == 1
211
    assert carddef.data_class().select()[0].data.get('1') == '1;2'
212

  
213
    # invalid value
214
    create.mappings[0].expression = 'plop'
215
    wf.store()
216
    formdef.refresh_from_storage()
217
    carddef.data_class().wipe()
218
    formdata = formdef.data_class()()
219
    formdata.data = {}
220
    formdata.just_created()
221
    formdata.perform_workflow()
222
    assert carddef.data_class().count() == 1
223
    assert not carddef.data_class().select()[0].data.get('1')
224

  
225
    if two_pubs.is_using_postgresql():
226
        errors = two_pubs.loggederror_class.select()
227
        assert len(errors) == 1
228
        assert any('invalid coordinates' in (error.exception_message or '') for error in errors)
229

  
230
    # value from formdata
231
    create.mappings[0].expression = '{{ form_var_map }}'
232
    wf.store()
233
    formdef.refresh_from_storage()
234
    carddef.data_class().wipe()
235
    formdata = formdef.data_class()()
236
    formdata.data = {'1': '2;3'}
237
    formdata.just_created()
238
    formdata.perform_workflow()
239
    assert carddef.data_class().count() == 1
240
    assert carddef.data_class().select()[0].data.get('1') == '2;3'
241

  
242

  
243
def test_create_carddata_user_association(two_pubs):
244
    CardDef.wipe()
245
    FormDef.wipe()
246
    two_pubs.user_class.wipe()
247

  
248
    user = two_pubs.user_class()
249
    user.email = 'test@example.net'
250
    user.name_identifiers = ['xyz']
251
    user.store()
252

  
253
    carddef = CardDef()
254
    carddef.name = 'My card'
255
    carddef.fields = []
256
    carddef.user_support = 'optional'
257
    carddef.store()
258
    carddef.data_class().wipe()
259

  
260
    wf = Workflow(name='create-carddata')
261
    wf.possible_status = Workflow.get_default_workflow().possible_status[:]
262
    create = CreateCarddataWorkflowStatusItem()
263
    create.label = 'Create CardDef'
264
    create.varname = 'mycard'
265
    create.id = '_create'
266
    create.formdef_slug = carddef.url_name
267
    create.map_fields_by_varname = True
268
    create.parent = wf.possible_status[1]
269
    wf.possible_status[1].items.insert(0, create)
270
    wf.store()
271

  
272
    formdef = FormDef()
273
    formdef.name = 'source form'
274
    formdef.fields = []
275
    formdef.workflow_id = wf.id
276
    formdef.store()
277

  
278
    formdata = formdef.data_class()()
279
    formdata.data = {}
280
    formdata.user_id = user.id
281
    formdata.just_created()
282
    formdata.perform_workflow()
283

  
284
    assert carddef.data_class().count() == 1
285
    assert carddef.data_class().select()[0].user is None
286

  
287
    # keep user
288
    carddef.data_class().wipe()
289
    create.user_association_mode = 'keep-user'
290
    wf.store()
291

  
292
    formdata = FormDef.get(formdef.id).data_class()()
293
    formdata.data = {}
294
    formdata.user_id = user.id
295
    formdata.just_created()
296
    formdata.perform_workflow()
297

  
298
    assert carddef.data_class().count() == 1
299
    assert carddef.data_class().select()[0].user.id == user.id
300

  
301
    # user association on direct user
302
    carddef.data_class().wipe()
303
    create.user_association_mode = 'custom'
304
    create.user_association_template = '{{ form_user }}'
305
    wf.store()
306

  
307
    formdata = FormDef.get(formdef.id).data_class()()
308
    formdata.data = {}
309
    formdata.user_id = user.id
310
    formdata.just_created()
311
    formdata.perform_workflow()
312

  
313
    assert carddef.data_class().count() == 1
314
    assert carddef.data_class().select()[0].user.id == user.id
315

  
316
    # user association on user email
317
    carddef.data_class().wipe()
318
    create.user_association_mode = 'custom'
319
    create.user_association_template = 'test@example.net'
320
    wf.store()
321

  
322
    formdata = FormDef.get(formdef.id).data_class()()
323
    formdata.data = {}
324
    formdata.user_id = user.id
325
    formdata.just_created()
326
    formdata.perform_workflow()
327

  
328
    assert carddef.data_class().count() == 1
329
    assert carddef.data_class().select()[0].user.id == user.id
330

  
331
    # user association on name id
332
    carddef.data_class().wipe()
333
    create.user_association_mode = 'custom'
334
    create.user_association_template = 'xyz'
335
    wf.store()
336

  
337
    formdata = FormDef.get(formdef.id).data_class()()
338
    formdata.data = {}
339
    formdata.user_id = user.id
340
    formdata.just_created()
341
    formdata.perform_workflow()
342

  
343
    assert carddef.data_class().count() == 1
344
    assert carddef.data_class().select()[0].user.id == user.id
345

  
346
    # user association on invalid user
347
    carddef.data_class().wipe()
348
    create.user_association_mode = 'custom'
349
    create.user_association_template = 'zzz'
350
    wf.store()
351

  
352
    formdata = FormDef.get(formdef.id).data_class()()
353
    formdata.data = {}
354
    formdata.user_id = user.id
355
    formdata.just_created()
356
    if two_pubs.loggederror_class:
357
        two_pubs.loggederror_class.wipe()
358
    formdata.perform_workflow()
359

  
360
    assert carddef.data_class().count() == 1
361
    assert carddef.data_class().select()[0].user is None
362
    if two_pubs.loggederror_class:
363
        assert two_pubs.loggederror_class.count() == 1
364
        logged_error = two_pubs.loggederror_class.select()[0]
365
        assert logged_error.summary == 'Failed to attach user (not found: "zzz")'
366
        assert logged_error.formdata_id == str(carddef.data_class().select()[0].id)
367

  
368
    # user association on invalid template
369
    carddef.data_class().wipe()
370
    create.user_association_mode = 'custom'
371
    create.user_association_template = '{% %}'
372
    wf.store()
373

  
374
    formdata = FormDef.get(formdef.id).data_class()()
375
    formdata.data = {}
376
    formdata.user_id = user.id
377
    formdata.just_created()
378
    formdata.perform_workflow()
379

  
380
    assert carddef.data_class().count() == 1
381
    assert carddef.data_class().select()[0].user is None
382

  
383

  
384
def test_edit_carddata_with_data_sourced_object(pub):
385
    FormDef.wipe()
386
    CardDef.wipe()
387

  
388
    datasource = {
389
        'type': 'formula',
390
        'value': repr(
391
            [
392
                {'id': 'b', 'text': 'baker', 'extra': 'plop'},
393
                {'id': 'c', 'text': 'cook', 'extra': 'plop2'},
394
                {'id': 'l', 'text': 'lawyer', 'extra': 'plop3'},
395
            ]
396
        ),
397
    }
398
    carddef = CardDef()
399
    carddef.name = 'Person'
400
    carddef.fields = [
401
        StringField(id='0', label='First Name', varname='first_name'),
402
        StringField(id='1', label='Last Name', varname='last_name'),
403
        ItemField(id='2', label='Profession', type='item', varname='profession', data_source=datasource),
404
    ]
405
    carddef.digest_templates = {'default': '{{ form_var_first_name }} {{ form_var_last_name }}'}
406
    carddef.store()
407

  
408
    carddata = carddef.data_class()()
409
    carddata.data = {'0': 'Foo', '1': 'Bar', '2': 'l'}
410
    carddata.data['2_display'] = carddef.fields[2].store_display_value(carddata.data, '2')
411
    carddata.data['2_structured'] = carddef.fields[2].store_structured_value(carddata.data, '2')
412
    carddata.store()
413

  
414
    wf = Workflow(name='Card update')
415
    st1 = wf.add_status('Update card', 'st1')
416

  
417
    edit = EditCarddataWorkflowStatusItem()
418
    edit.formdef_slug = carddef.url_name
419
    edit.mappings = [
420
        Mapping(field_id='2', expression='{{ form_var_new_profession }}'),
421
    ]
422
    edit.id = 'edit'
423
    st1.items.append(edit)
424
    edit.parent = st1
425
    wf.store()
426

  
427
    datasource = {'type': 'carddef:%s' % carddef.url_name}
428
    formdef = FormDef()
429
    formdef.name = 'Persons'
430
    formdef.fields = [
431
        ItemField(id='0', label='Person', type='item', varname='person', data_source=datasource),
432
        StringField(id='1', label='New profession', varname='new_profession'),
433
    ]
434
    formdef.workflow = wf
435
    formdef.store()
436

  
437
    formdata = formdef.data_class()()
438
    formdata.data = {'0': '1', '1': 'c'}
439
    formdata.store()
440
    formdata.just_created()
441
    formdata.perform_workflow()
442

  
443
    data = carddef.data_class().select()[0]
444
    assert data.data['2'] == 'c'
445
    assert data.data['2_display'] == 'cook'
446
    assert data.data['2_structured'] == {'id': 'c', 'text': 'cook', 'extra': 'plop2'}
447

  
448
    formdata = formdef.data_class()()
449
    formdata.data = {'0': '1', '1': 'b'}
450
    formdata.store()
451
    formdata.just_created()
452
    formdata.perform_workflow()
453

  
454
    data = carddef.data_class().select()[0]
455
    assert data.data['2'] == 'b'
456
    assert data.data['2_display'] == 'baker'
457
    assert data.data['2_structured'] == {'id': 'b', 'text': 'baker', 'extra': 'plop'}
458

  
459
    # reset data
460
    for expression in ('=None', '', '""'):
461
        edit.mappings = [
462
            Mapping(field_id='2', expression=expression),
463
        ]
464
        wf.store()
465

  
466
        formdata = formdef.data_class()()
467
        formdata.data = {'0': '1', '1': 'b'}
468
        formdata.store()
469
        formdata.just_created()
470
        formdata.perform_workflow()
471

  
472
        carddata = carddef.data_class().select()[0]
473
        assert carddata.data['2'] in [None, '', '""']
474
        assert carddata.data.get('2_display') is None
475
        assert carddata.data.get('2_structured') is None
476

  
477
        # restore initial data
478
        carddata.data = data.data
479
        carddata.store()
480

  
481

  
482
def test_edit_carddata_with_linked_object(pub):
483
    FormDef.wipe()
484
    CardDef.wipe()
485

  
486
    carddef = CardDef()
487
    carddef.name = 'Parent'
488
    carddef.fields = [
489
        StringField(id='0', label='First Name', varname='first_name'),
490
        StringField(id='1', label='Last Name', varname='last_name'),
491
        StringField(id='2', label='Kids number', varname='kids_number'),
492
    ]
493
    carddef.store()
494

  
495
    wf = Workflow(name='Card create and update')
496
    st1 = wf.add_status('Create card', 'st1')
497
    edit = CreateCarddataWorkflowStatusItem()
498
    edit.formdef_slug = carddef.url_name
499
    edit.mappings = [
500
        Mapping(field_id='0', expression='{{ form_var_first_name }}'),
501
        Mapping(field_id='1', expression='{{ form_var_last_name }}'),
502
        Mapping(field_id='2', expression='{{ form_var_kids_number|default:"0" }}'),
503
    ]
504
    st1.items.append(edit)
505
    edit.parent = st1
506
    jump = JumpWorkflowStatusItem()
507
    jump.id = '_jump'
508
    jump.by = ['_submitter', '_receiver']
509
    jump.status = 'st2'
510
    st1.items.append(jump)
511
    jump.parent = st1
512

  
513
    st2 = wf.add_status('Update card', 'st2')
514
    edit = EditCarddataWorkflowStatusItem()
515
    edit.formdef_slug = carddef.url_name
516
    edit.mappings = [
517
        Mapping(field_id='2', expression='{{ form_var_kids_number|add:"1" }}'),
518
    ]
519
    edit.id = 'edit'
520
    st2.items.append(edit)
521
    edit.parent = st2
522
    wf.store()
523

  
524
    formdef = FormDef()
525
    formdef.name = 'Parents'
526
    formdef.fields = [
527
        StringField(id='0', label='First Name', varname='first_name'),
528
        StringField(id='1', label='Last Name', varname='last_name'),
529
        StringField(id='2', label='Number of kids', varname='kids_number'),
530
    ]
531
    formdef.workflow = wf
532
    formdef.store()
533

  
534
    formdata = formdef.data_class()()
535
    formdata.data = {'0': 'Parent', '1': 'Foo', '2': '2'}
536
    formdata.store()
537
    formdata.just_created()
538
    formdata.perform_workflow()
539

  
540
    assert carddef.data_class().count() == 1
541
    card_data = carddef.data_class().select()[0]
542
    assert card_data.data['2'] == '3'
543

  
544

  
545
def test_edit_carddata_manual_targeting(two_pubs):
546
    if not two_pubs.is_using_postgresql():
547
        pytest.skip('this requires SQL')
548
        return
549

  
550
    FormDef.wipe()
551
    CardDef.wipe()
552
    two_pubs.loggederror_class.wipe()
553

  
554
    # carddef
555
    carddef = CardDef()
556
    carddef.name = 'Parent'
557
    carddef.fields = [
558
        StringField(id='0', label='First Name', varname='first_name'),
559
        StringField(id='1', label='Last Name', varname='last_name'),
560
        StringField(id='2', label='Kids number', varname='kids_number'),
561
    ]
562
    carddef.store()
563
    carddef.data_class().wipe()
564

  
565
    # and sample carddatas
566
    for i in range(1, 4):
567
        carddata = carddef.data_class()()
568
        carddata.data = {
569
            '0': 'First name %s' % i,
570
            '1': 'Last name %s' % i,
571
            '2': '0',
572
        }
573
        carddata.store()
574

  
575
    # formdef workflow that will update carddata
576
    wf = Workflow(name='Card create and update')
577
    st1 = wf.add_status('Create card', 'st1')
578
    # create linked carddata
579
    edit = CreateCarddataWorkflowStatusItem()
580
    edit.formdef_slug = carddef.url_name
581
    edit.mappings = [
582
        Mapping(field_id='0', expression='{{ form_var_first_name }}'),
583
        Mapping(field_id='1', expression='{{ form_var_last_name }}'),
584
        Mapping(field_id='2', expression='{{ form_var_kids_number|default:"0" }}'),
585
    ]
586
    st1.items.append(edit)
587
    edit.parent = st1
588
    jump = JumpWorkflowStatusItem()
589
    jump.id = '_jump'
590
    jump.by = ['_submitter', '_receiver']
591
    jump.status = 'st2'
592
    st1.items.append(jump)
593
    jump.parent = st1
594

  
595
    st2 = wf.add_status('Update card', 'st2')
596
    edit = EditCarddataWorkflowStatusItem()
597
    edit.formdef_slug = carddef.url_name
598
    edit.target_mode = 'manual'  # not configured
599
    edit.mappings = [
600
        Mapping(field_id='2', expression='{{ form_var_kids_number|add:"1" }}'),
601
    ]
602
    edit.id = 'edit'
603
    st2.items.append(edit)
604
    edit.parent = st2
605
    wf.store()
606

  
607
    # associated formdef
608
    formdef = FormDef()
609
    formdef.name = 'Parents'
610
    datasource = {'type': 'carddef:%s' % carddef.url_name}
611
    formdef.fields = [
612
        StringField(id='0', label='First Name', varname='first_name'),
613
        StringField(id='1', label='Last Name', varname='last_name'),
614
        StringField(id='2', label='Number of kids', varname='kids_number'),
615
        ItemField(id='3', label='Card', type='item', varname='card', data_source=datasource),
616
        StringField(id='4', label='string', varname='string'),
617
    ]
618
    formdef.workflow = wf
619
    formdef.store()
620

  
621
    # create formdatas
622

  
623
    # target not configured
624
    formdata = formdef.data_class()()
625
    formdata.data = {
626
        '0': 'Parent',
627
        '1': 'Foo',
628
        '2': '2',
629
        '3': '3',  # set from datasource
630
        '4': '1',
631
    }
632
    # set parent
633
    formdata.submission_context = {
634
        'orig_object_type': 'carddef',
635
        'orig_formdata_id': '2',
636
        'orig_formdef_id': str(carddef.id),
637
    }
638
    formdata.store()
639
    formdata.just_created()
640
    formdata.perform_workflow()
641

  
642
    assert carddef.data_class().count() == 4
643
    assert carddef.data_class().get(1).data['2'] == '0'
644
    assert carddef.data_class().get(2).data['2'] == '0'
645
    assert carddef.data_class().get(3).data['2'] == '0'
646
    assert carddef.data_class().get(4).data['2'] == '2'
647
    assert two_pubs.loggederror_class.count() == 0
648

  
649
    # configure target
650
    edit.target_id = '{{ form_var_string }}'  # == '1'
651
    wf.store()
652
    formdata = formdef.data_class()()
653
    formdata.data = {
654
        '0': 'Parent',
655
        '1': 'Foo',
656
        '2': '2',
657
        '3': '3',  # set from datasource
658
        '4': '1',
659
    }
660
    # set parent
661
    formdata.submission_context = {
662
        'orig_object_type': 'carddef',
663
        'orig_formdata_id': '2',
664
        'orig_formdef_id': str(carddef.id),
665
    }
666
    formdata.store()
667
    formdata.just_created()
668
    formdata.perform_workflow()
669
    assert carddef.data_class().count() == 5
670
    assert carddef.data_class().get(1).data['2'] == '3'  # 2 + 1
671
    assert carddef.data_class().get(2).data['2'] == '0'
672
    assert carddef.data_class().get(3).data['2'] == '0'
673
    assert carddef.data_class().get(4).data['2'] == '2'
674
    assert carddef.data_class().get(5).data['2'] == '2'
675
    assert two_pubs.loggederror_class.count() == 0
676

  
677
    # target not found
678
    edit.target_id = '42{{ form_var_string }}'  # == '421'
679
    wf.store()
680
    formdata = formdef.data_class()()
681
    formdata.data = {
682
        '0': 'Parent',
683
        '1': 'Foo',
684
        '2': '2',
685
        '3': '3',  # set from datasource
686
        '4': '1',
687
    }
688
    # set parent
689
    formdata.submission_context = {
690
        'orig_object_type': 'carddef',
691
        'orig_formdata_id': '2',
692
        'orig_formdef_id': str(carddef.id),
693
    }
694
    formdata.store()
695
    formdata.just_created()
696
    formdata.perform_workflow()
697
    assert carddef.data_class().count() == 6
698
    assert carddef.data_class().get(1).data['2'] == '3'  # not changed
699
    assert carddef.data_class().get(2).data['2'] == '0'
700
    assert carddef.data_class().get(3).data['2'] == '0'
701
    assert carddef.data_class().get(4).data['2'] == '2'
702
    assert carddef.data_class().get(5).data['2'] == '2'
703
    assert carddef.data_class().get(6).data['2'] == '2'
704
    assert two_pubs.loggederror_class.count() == 1
705
    logged_error = two_pubs.loggederror_class.select()[0]
706
    assert logged_error.summary == 'Could not find targeted "Parent" object by id 421'
707

  
708
    # slug not or badly configured
709
    edit.target_id = '{{ form_var_string }}'  # == '1'
710
    edit.formdef_slug = None
711
    wf.store()
712
    formdata = formdef.data_class()()
713
    formdata.data = {
714
        '0': 'Parent',
715
        '1': 'Foo',
716
        '2': '3',
717
        '3': '3',  # set from datasource
718
        '4': '1',
719
    }
720
    # set parent
721
    formdata.submission_context = {
722
        'orig_object_type': 'carddef',
723
        'orig_formdata_id': '2',
724
        'orig_formdef_id': str(carddef.id),
725
    }
726
    formdata.store()
727
    formdata.just_created()
728
    formdata.perform_workflow()
729
    assert carddef.data_class().count() == 7
730
    assert carddef.data_class().get(1).data['2'] == '3'  # not changed
731
    assert carddef.data_class().get(2).data['2'] == '0'
732
    assert carddef.data_class().get(3).data['2'] == '0'
733
    assert carddef.data_class().get(4).data['2'] == '2'
734
    assert carddef.data_class().get(5).data['2'] == '2'
735
    assert carddef.data_class().get(6).data['2'] == '2'
736
    assert carddef.data_class().get(7).data['2'] == '3'
737

  
738

  
739
def test_edit_carddata_targeting_itself(pub):
740
    CardDef.wipe()
741
    carddef = CardDef()
742
    carddef.name = 'Foo Card'
743
    carddef.fields = [
744
        StringField(id='0', label='foo', varname='foo'),
745
    ]
746
    carddef.store()
747
    carddef.data_class().wipe()
748

  
749
    # card workflow: update itself then jump to second status
750
    card_wf = Workflow(name='Card workflow')
751
    st1 = card_wf.add_status('Status1')
752
    st2 = card_wf.add_status('Status2')
753

  
754
    edit = EditCarddataWorkflowStatusItem()
755
    edit.id = '_edit'
756
    edit.formdef_slug = carddef.url_name
757
    edit.target_mode = 'manual'
758
    edit.target_id = '{{ form_internal_id }}'  # itself
759
    edit.mappings = [
760
        Mapping(field_id='0', expression='bar {{ form_internal_id }}'),
761
    ]
762
    edit.parent = st1
763
    st1.items.append(edit)
764

  
765
    jump = JumpWorkflowStatusItem()
766
    jump.id = '_jump'
767
    jump.status = st2.id
768
    st1.items.append(jump)
769
    jump.parent = st1
770

  
771
    card_wf.store()
772

  
773
    carddef.workflow = card_wf
774
    carddef.store()
775

  
776
    # create some cardata
777
    for i in range(1, 4):
778
        carddata = carddef.data_class()()
779
        carddata.data = {
780
            '0': 'foo %s' % i,
781
        }
782
        carddata.store()
783
        # run workflow, verify that carddata is modified
784
        carddata.just_created()
785
        carddata.perform_workflow()
786
        assert carddata.data['0'] == 'bar %s' % carddata.id
787
        assert carddata.status == 'wf-%s' % st2.id
788

  
789

  
790
def test_edit_carddata_from_created_object(pub):
791
    FormDef.wipe()
792
    CardDef.wipe()
793

  
794
    carddef = CardDef()
795
    carddef.name = 'Card'
796
    carddef.fields = [
797
        StringField(id='0', label='Card Field', varname='card_field'),
798
    ]
799
    carddef.store()
800

  
801
    formdef = FormDef()
802
    formdef.name = 'Form'
803
    formdef.fields = [
804
        StringField(id='0', label='Form Field', varname='form_field'),
805
    ]
806
    formdef.store()
807

  
808
    # card workflow: create formdata then jump to second status
809
    card_wf = Workflow(name='Card workflow')
810
    st1 = card_wf.add_status('Status1')
811
    st2 = card_wf.add_status('Status2')
812

  
813
    create = CreateFormdataWorkflowStatusItem()
814
    create.id = '_create'
815
    create.formdef_slug = formdef.url_name
816
    create.mappings = [
817
        Mapping(field_id='0', expression='...'),
818
    ]
819
    create.parent = st1
820
    st1.items.append(create)
821

  
822
    jump = JumpWorkflowStatusItem()
823
    jump.id = '_jump'
824
    jump.status = st2.id
825
    st1.items.append(jump)
826
    jump.parent = st1
827

  
828
    # form workflow: edit parent card data
829
    form_wf = Workflow(name='Form workflow')
830
    st1 = form_wf.add_status('Status1')
831
    edit = EditCarddataWorkflowStatusItem()
832
    edit.formdef_slug = carddef.url_name
833
    edit.mappings = [
834
        Mapping(field_id='0', expression='HELLO'),
835
    ]
836
    edit.id = 'edit'
837
    st1.items.append(edit)
838
    edit.parent = st1
839
    form_wf.store()
840

  
841
    carddef.workflow = card_wf
842
    carddef.store()
843

  
844
    formdef.workflow = form_wf
845
    formdef.store()
846

  
847
    carddata = carddef.data_class()()
848
    carddata.data = {'0': 'Foo'}
849
    carddata.store()
850
    carddata.just_created()
851
    carddata.perform_workflow()
852

  
853
    carddata_reloaded = carddata.get(carddata.id)
854
    assert carddata_reloaded.data['0'] == 'HELLO'
855
    assert carddata_reloaded.status == 'wf-2'
0
-