Projet

Général

Profil

0001-formdata-always-create-a-display-identifier-9135.patch

Frédéric Péters, 03 janvier 2016 14:07

Télécharger (17,4 ko)

Voir les différences:

Subject: [PATCH] formdata: always create a display identifier (#9135)

 tests/test_backoffice_pages.py | 58 ++++++++++++++++++++----------------------
 tests/test_formdata.py         | 12 +++++++--
 tests/test_workflows.py        |  8 +++---
 wcs/formdata.py                | 17 ++++++++++++-
 wcs/formdef.py                 |  8 ++++++
 wcs/forms/common.py            |  2 +-
 wcs/sql.py                     |  6 +++++
 7 files changed, 73 insertions(+), 38 deletions(-)
tests/test_backoffice_pages.py
457 457
    create_user(pub)
458 458
    create_environment(pub)
459 459
    form_class = FormDef.get_by_urlname('form-title').data_class()
460
    number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0].id
460
    number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
461 461
    app = login(get_app(pub))
462 462
    resp = app.get('/backoffice/management/form-title/')
463 463
    assert re.findall('<tbody.*\/tbody>', resp.body, re.DOTALL)[0].count('<tr') == 17
......
471 471
    app.get('/backoffice/management/form-title/json', status=200)
472 472

  
473 473
    # click on a formdata
474
    resp = resp.click(href='%s/' % number31)
475
    assert (' with the number %s.' % number31) in resp.body
474
    resp = resp.click(href='%s/' % number31.id)
475
    assert (' with the number %s.' % number31.get_display_id()) in resp.body
476 476
    resp.forms[0]['comment'] = 'HELLO WORLD'
477 477
    resp = resp.forms[0].submit('button_accept')
478 478
    resp = resp.follow()
479
    assert FormDef.get_by_urlname('form-title').data_class().get(number31).status == 'wf-accepted'
479
    assert FormDef.get_by_urlname('form-title').data_class().get(number31.id).status == 'wf-accepted'
480 480
    assert 'HELLO WORLD' in resp.body
481 481

  
482 482
def test_backoffice_handling_global_action(pub):
......
526 526

  
527 527
    # click on a formdata
528 528
    resp = resp.click(href='%s/' % number31.id)
529
    assert (' with the number %s.' % number31.id) in resp.body
529
    assert (' with the number %s.' % number31.get_display_id()) in resp.body
530 530

  
531 531
    # check there's nothing in the sidebar
532 532
    assert not 'Channel' in resp.body
......
556 556
    formdef = FormDef.get_by_urlname('form-title')
557 557
    form_class = formdef.data_class()
558 558

  
559
    number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0].id
560
    number31_status = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0].status
559
    number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
561 560

  
562 561
    # attach a custom workflow
563 562
    workflow = Workflow(name='info texts')
564
    st1 = workflow.add_status('Status1', number31_status.split('-')[1])
563
    st1 = workflow.add_status('Status1', number31.status.split('-')[1])
565 564

  
566 565
    commentable = CommentableWorkflowStatusItem()
567 566
    commentable.id = '_commentable'
......
584 583

  
585 584
    app = login(get_app(pub))
586 585

  
587
    resp = app.get('/backoffice/management/form-title/%s/' % number31)
588
    assert (' with the number %s.' % number31) in resp.body
586
    resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
587
    assert (' with the number %s.' % number31.get_display_id()) in resp.body
589 588
    assert 'CLICK ME!' in resp.body
590 589
    assert not 'CLICK ME2!' in resp.body
591 590
    assert not 'backoffice-description' in resp.body
......
593 592
    # add an info text to the status
594 593
    st1.backoffice_info_text = '<p>Foo</p>'
595 594
    workflow.store()
596
    resp = app.get('/backoffice/management/form-title/%s/' % number31)
595
    resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
597 596
    assert 'backoffice-description' in resp.body
598 597
    assert '<p>Foo</p>' in resp.body
599 598

  
600 599
    # add an info text to the button
601 600
    commentable.backoffice_info_text = '<p>Bar</p>'
602 601
    workflow.store()
603
    resp = app.get('/backoffice/management/form-title/%s/' % number31)
602
    resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
604 603
    assert 'backoffice-description' in resp.body
605 604
    assert '<p>Foo</p>' in resp.body
606 605
    assert '<p>Bar</p>' in resp.body
......
608 607
    # remove info text from the status
609 608
    st1.backoffice_info_text = None
610 609
    workflow.store()
611
    resp = app.get('/backoffice/management/form-title/%s/' % number31)
610
    resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
612 611
    assert 'backoffice-description' in resp.body
613 612
    assert not '<p>Foo</p>' in resp.body
614 613
    assert '<p>Bar</p>' in resp.body
......
616 615
    # add info text to second button
617 616
    commentable2.backoffice_info_text = '<p>Baz</p>'
618 617
    workflow.store()
619
    resp = app.get('/backoffice/management/form-title/%s/' % number31)
618
    resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
620 619
    assert 'backoffice-description' in resp.body
621 620
    assert not '<p>Foo</p>' in resp.body
622 621
    assert '<p>Bar</p>' in resp.body
......
625 624
    # remove info text from first button
626 625
    commentable.backoffice_info_text = None
627 626
    workflow.store()
628
    resp = app.get('/backoffice/management/form-title/%s/' % number31)
627
    resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
629 628
    assert not 'backoffice-description' in resp.body
630 629

  
631 630
def test_backoffice_handling_post_dispatch(pub):
......
638 637
    user1.store()
639 638
    create_environment(pub)
640 639
    form_class = FormDef.get_by_urlname('form-title').data_class()
641
    number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0].id
640
    number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
642 641
    app = login(get_app(pub))
643 642

  
644 643
    # check there's no access at the moment
645 644
    resp = app.get('/backoffice/management/')
646 645
    assert not 'form-title/' in resp.body
647 646
    resp = app.get('/backoffice/management/form-title/', status=403)
648
    resp = app.get('/backoffice/management/form-title/%s/' % number31, status=403)
647
    resp = app.get('/backoffice/management/form-title/%s/' % number31.id, status=403)
649 648

  
650 649
    # emulate a dispatch (setting formdata.workflow_roles), receiver of that
651 650
    # formdata is now the local role we gave to the user.
652
    formdata31 = form_class.get(number31)
651
    formdata31 = form_class.get(number31.id)
653 652
    formdata31.workflow_roles = {'_receiver': role.id}
654 653
    formdata31.store()
655 654

  
......
669 668

  
670 669
    # check formdata is accessible, and that it's possible to perform an action
671 670
    # on it.
672
    resp = resp.click(href='%s/' % number31)
673
    assert (' with the number %s.' % number31) in resp.body
671
    resp = resp.click(href='%s/' % number31.id)
672
    assert (' with the number %s.' % number31.get_display_id()) in resp.body
674 673
    resp.forms[0]['comment'] = 'HELLO WORLD'
675 674
    resp = resp.forms[0].submit('button_accept')
676 675
    resp = resp.follow()
677
    assert FormDef.get_by_urlname('form-title').data_class().get(number31).status == 'wf-accepted'
676
    assert FormDef.get_by_urlname('form-title').data_class().get(number31.id).status == 'wf-accepted'
678 677
    assert 'HELLO WORLD' in resp.body
679 678

  
680 679
def test_global_statisticspub(pub):
......
1073 1072
    formdef = FormDef.get_by_urlname('form-title')
1074 1073
    form_class = formdef.data_class()
1075 1074

  
1076
    number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0].id
1077
    number31_status = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0].status
1075
    number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
1078 1076

  
1079 1077
    # attach a custom workflow
1080 1078
    workflow = Workflow(name='wscall')
1081
    st1 = workflow.add_status('Status1', number31_status.split('-')[1])
1079
    st1 = workflow.add_status('Status1', number31.status.split('-')[1])
1082 1080

  
1083 1081
    wscall = WebserviceCallStatusItem()
1084 1082
    wscall.id = '_wscall'
......
1104 1102

  
1105 1103
    app = login(get_app(pub))
1106 1104

  
1107
    resp = app.get('/backoffice/management/form-title/%s/' % number31)
1108
    assert (' with the number %s.' % number31) in resp.body
1105
    resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
1106
    assert (' with the number %s.' % number31.get_display_id()) in resp.body
1109 1107
    assert 'Again' in resp.body
1110 1108
    resp = resp.forms[0].submit('button_again')
1111 1109
    resp = resp.follow()
1112 1110
    assert 'Error during webservice call' in resp.body
1113 1111

  
1114 1112
    # the failure message shouldn't be displayed in the frontoffice
1115
    resp = app.get('/form-title/%s/' % number31)
1116
    assert (' with the number %s.' % number31) in resp.body
1113
    resp = app.get('/form-title/%s/' % number31.id)
1114
    assert (' with the number %s.' % number31.get_display_id()) in resp.body
1117 1115
    assert not 'Error during webservice call' in resp.body
1118 1116

  
1119 1117
def test_backoffice_wfedit(pub):
......
1141 1139
    app = login(get_app(pub))
1142 1140

  
1143 1141
    resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
1144
    assert (' with the number %s.' % number31.id) in resp.body
1142
    assert (' with the number %s.' % number31.get_display_id()) in resp.body
1145 1143
    resp = resp.form.submit('button_wfedit')
1146 1144
    resp = resp.follow()
1147 1145
    assert resp.form['f1'].value == number31.data['1']
......
1264 1262

  
1265 1263
    # click on a formdata
1266 1264
    resp = resp.click(href='%s/' % number31.id)
1267
    assert (' with the number %s.' % number31.id) in resp.body
1265
    assert (' with the number %s.' % number31.get_display_id()) in resp.body
1268 1266

  
1269 1267
    # check there's nothing in the sidebar
1270 1268
    assert not 'User Pending Forms' in resp.body
tests/test_formdata.py
53 53
    formdata = formdef.data_class()()
54 54
    formdata.store()
55 55
    substvars = formdata.get_substitution_variables()
56
    assert substvars.get('form_number') == '1'
56
    assert substvars.get('form_number') == '%s-1' % formdef.id
57 57
    assert substvars.get('form_number_raw') == '1'
58 58
    assert substvars.get('form_url').endswith('/foobar/1/')
59 59
    assert substvars.get('form_url_backoffice').endswith('/backoffice/management/foobar/1/')
60 60
    assert substvars.get('form_status_url').endswith('/foobar/1/status')
61 61

  
62
def test_display_id(pub):
62
def test_auto_display_id(pub):
63
    formdef.data_class().wipe()
64
    formdata = formdef.data_class()()
65
    formdata.store()
66
    substvars = formdata.get_substitution_variables()
67
    assert substvars.get('form_number') == '%s-%s' % (formdef.id, formdata.id)
68
    assert substvars.get('form_number_raw') == str(formdata.id)
69

  
70
def test_manual_display_id(pub):
63 71
    formdef.data_class().wipe()
64 72
    formdata = formdef.data_class()()
65 73
    formdata.id_display = 'bar'
tests/test_workflows.py
404 404
    assert http_requests.get_last('method') == 'POST'
405 405
    payload = json.loads(http_requests.get_last('body'))
406 406
    assert payload['url'] == 'http://example.net/baz/%s/' % formdata.id
407
    assert int(payload['display_id']) == 1
407
    assert payload['display_id'] == formdata.get_display_id()
408 408

  
409 409
    item = WebserviceCallStatusItem()
410 410
    item.url = 'http://remote.example.net'
......
423 423
    assert http_requests.get_last('url') == 'http://remote.example.net'
424 424
    assert http_requests.get_last('method') == 'POST'
425 425
    payload = json.loads(http_requests.get_last('body'))
426
    assert payload == {'one': 1, 'str': 'abcd', 'evalme': formdata.id}
426
    assert payload == {'one': 1, 'str': 'abcd', 'evalme': formdata.get_display_id()}
427 427

  
428 428
    item = WebserviceCallStatusItem()
429 429
    item.url = 'http://remote.example.net'
......
434 434
    assert http_requests.get_last('url') == 'http://remote.example.net'
435 435
    assert http_requests.get_last('method') == 'POST'
436 436
    payload = json.loads(http_requests.get_last('body'))
437
    assert payload['extra'] == {'one': 1, 'str': 'abcd', 'evalme': formdata.id}
437
    assert payload['extra'] == {'one': 1, 'str': 'abcd', 'evalme': formdata.get_display_id()}
438 438
    assert payload['url'] == 'http://example.net/baz/%s/' % formdata.id
439
    assert int(payload['display_id']) == 1
439
    assert payload['display_id'] == formdata.get_display_id()
440 440

  
441 441
    item = WebserviceCallStatusItem()
442 442
    item.url = 'http://remote.example.net/json'
wcs/formdata.py
18 18
import datetime
19 19
import json
20 20
import re
21
from cStringIO import StringIO
21 22
import sys
22 23
import time
23 24

  
......
26 27

  
27 28
from qommon.storage import StorableObject
28 29
import qommon.misc
30
from qommon import ezt
29 31
from qommon.substitution import Substitutions
30 32

  
31 33
from roles import Role
......
71 73
                                formdata.get_url(), field.id)
72 74
                elif raw_value:
73 75
                    new_data['var_%s_raw' % field.varname] = raw_value
74
            if field.store_structured_value:
76
            if field.store_structured_value and data is not None:
75 77
                structured_value = data.get('%s_structured' % field.id)
76 78
                if type(structured_value) is dict:
77 79
                    for k, v in structured_value.items():
......
211 213
        setattr(sys.modules['formdef'], self._formdef.url_name.title(), self.__class__)
212 214
        setattr(sys.modules['wcs.formdef'], self._formdef.url_name.title(), self.__class__)
213 215
        super(FormData, self).store(*args, **kwargs)
216
        if not self.id_display:
217
            self.set_auto_display_id()
218
            if self.id_display:
219
                self.store(*args, **kwargs)
214 220

  
215 221
    def get_user(self):
216 222
        if self.user_id and self.user_id != 'ultra-user':
......
256 262
        evo.status = self.status
257 263
        self.evolution = [evo]
258 264

  
265
    def set_auto_display_id(self):
266
        processor = ezt.Template(compress_whitespace=True)
267
        processor.parse(self.formdef.get_display_id_format().strip())
268
        fd = StringIO()
269
        ctx = self.get_substitution_variables(minimal=True)
270
        ctx['formdef_id'] = self.formdef.id
271
        processor.generate(fd, ctx)
272
        self.id_display = fd.getvalue()
273

  
259 274
    def perform_workflow(self):
260 275
        url = None
261 276
        get_publisher().substitutions.feed(self)
wcs/formdef.py
102 102
            'always_advertise', 'private_status_and_history',
103 103
            'has_captcha', 'skip_from_360_view']
104 104

  
105
    def __init__(self, *args, **kwargs):
106
        super(FormDef, self).__init__(*args, **kwargs)
107
        self.fields = []
108

  
105 109
    def migrate(self):
106 110
        changed = False
107 111

  
......
408 412
            base_url = get_publisher().get_frontoffice_url()
409 413
        return '%s/%s/' % (base_url, self.url_name)
410 414

  
415
    def get_display_id_format(self):
416
        return '[formdef_id]-[form_number_raw]'
411 417

  
412 418
    def create_form(self, page_no = 0, displayed_fields = None):
413 419
        form = Form(enctype = "multipart/form-data", use_tokens = False)
......
832 838
            if isinstance(field, (fields.SubtitleField, fields.TitleField, fields.CommentField,
833 839
                fields.PageField)):
834 840
                continue
841
            if data is None:
842
                continue
835 843
            if data.get(field.id) is None:
836 844
                continue
837 845
            if data.get(field.id + '_display'):
wcs/forms/common.py
462 462
            tm = '???'
463 463
        r += htmltext("<p>")
464 464
        r += _('The form has been recorded on %(date)s with the number %(number)s.') % {
465
                'date': tm, 'number': self.filled.id}
465
                'date': tm, 'number': self.filled.get_display_id()}
466 466
        r += htmltext("</p>")
467 467

  
468 468
        if self.filled.anonymised:
wcs/sql.py
1125 1125
                cur.execute(sql_statement, sql_dict)
1126 1126
                self.id = cur.fetchone()[0]
1127 1127

  
1128
        if not self.id_display:
1129
            sql_statement = '''UPDATE %s SET id_display = %%(id_display)s
1130
                                WHERE id = %%(id)s''' % self._table_name
1131
            self.set_auto_display_id()
1132
            cur.execute(sql_statement, {'id': self.id, 'id_display': self.id_display})
1133

  
1128 1134
        if self._evolution:
1129 1135
            for evo in self._evolution:
1130 1136
                sql_dict = {}
1131
-