Projet

Général

Profil

0003-workflows-add-target-roles-in-commenter-workflow-ite.patch

Nicolas Roche, 22 janvier 2021 17:10

Télécharger (13,9 ko)

Voir les différences:

Subject: [PATCH 3/3] workflows: add target roles in commenter workflow item
 (#38254)

 tests/test_formdata.py        |  4 +-
 tests/test_workflow_import.py | 33 ++++++++++++++
 tests/test_workflows.py       | 86 +++++++++++++++++++++++++++++++++++
 wcs/formdata.py               |  2 +
 wcs/sql.py                    |  2 +
 wcs/wf/register_comment.py    | 18 ++++++--
 6 files changed, 140 insertions(+), 5 deletions(-)
tests/test_formdata.py
419 419
    d.user_id = local_user.id
420 420
    d.receipt_time = time.localtime()
421 421
    evo = Evolution()
422 422
    evo.time = time.localtime()
423 423
    evo.status = 'wf-%s' % st_new.id
424 424
    evo.who = '_submitter'
425 425
    d.evolution = [evo]
426 426
    d.store()
427
    evo.add_part(JournalEvolutionPart(d, "ok"))
427
    evo.add_part(JournalEvolutionPart(d, "ok", None))
428 428
    evo.add_part(JournalWsCallErrorPart("summary", "label", "data"))
429 429
    evo = Evolution()
430 430
    evo.time = time.localtime()
431 431
    evo.status = 'wf-%s' % st_finished.id
432 432
    evo.who = '_submitter'
433 433
    d.evolution.append(evo)
434 434
    d.store()
435 435

  
......
459 459
    export = d.get_json_export_dict(anonymise=True)
460 460
    assert 'evolution' in export
461 461
    assert len(export['evolution']) == 2
462 462
    assert export['evolution'][0]['status'] == st_new.id
463 463
    assert 'time' in export['evolution'][0]
464 464
    assert 'who' not in export['evolution'][0]
465 465
    assert 'parts' in export['evolution'][0]
466 466
    assert len(export['evolution'][0]['parts']) == 2
467
    assert len(export['evolution'][0]['parts'][0]) == 1
467
    assert len(export['evolution'][0]['parts'][0]) == 2
468 468
    assert export['evolution'][0]['parts'][0]['type'] == 'workflow-comment'
469 469
    assert len(export['evolution'][0]['parts'][1]) == 1
470 470
    assert export['evolution'][0]['parts'][1]['type'] == 'wscall-error'
471 471
    assert export['evolution'][1]['status'] == st_finished.id
472 472
    assert 'time' in export['evolution'][1]
473 473
    assert 'who' not in export['evolution'][0]
474 474
    assert 'parts' not in export['evolution'][1]
475 475

  
tests/test_workflow_import.py
462 462
    trigger.roles = [role.id]
463 463

  
464 464
    wf2 = assert_import_export_works(wf)
465 465
    assert wf2.global_actions[0].triggers[0].roles == [role.id]
466 466

  
467 467
    wf2 = assert_import_export_works(wf, True)
468 468

  
469 469

  
470
def test_register_comment_to(pub):
471
    role = Role()
472
    role.id = '5'
473
    role.name = 'Test Role'
474
    role.store()
475

  
476
    wf = Workflow(name='global actions')
477
    st1 = wf.add_status('Status1', 'st1')
478

  
479
    add_to_journal1 = RegisterCommenterWorkflowStatusItem()
480
    add_to_journal1.id = '_add_to_journal1'
481
    add_to_journal1.comment = 'HELLO WORLD'
482
    st1.items.append(add_to_journal1)
483
    add_to_journal1.parent = st1
484

  
485
    add_to_journal2 = RegisterCommenterWorkflowStatusItem()
486
    add_to_journal2.id = '_add_to_journal2'
487
    add_to_journal2.comment = 'OLA MUNDO'
488
    add_to_journal2.to = [role.id]
489
    st1.items.append(add_to_journal2)
490
    add_to_journal2.parent = st1
491
    assert wf.possible_status[0].items[0].to == []
492
    assert wf.possible_status[0].items[1].to == [role.id]
493

  
494
    xml_root = wf.export_to_xml()
495
    assert 'to' not in [x.tag for x in xml_root.findall('possible_status/status/items/item[1]/')]
496
    assert 'to' in [x.tag for x in xml_root.findall('possible_status/status/items/item[2]/')]
497

  
498
    wf2 = assert_import_export_works(wf)
499
    assert wf2.possible_status[0].items[0].to == []
500
    assert wf2.possible_status[0].items[1].to == [role.id]
501

  
502

  
470 503
def test_backoffice_fields(pub):
471 504
    wf = Workflow(name='bo fields')
472 505
    wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
473 506
    wf.backoffice_fields_formdef.fields = [
474 507
        StringField(id='bo1', label='1st backoffice field',
475 508
            type='string', varname='backoffice_blah'),
476 509
    ]
477 510
    wf2 = assert_import_export_works(wf, True)
tests/test_workflows.py
1104 1104
    assert formdata.evolution[-1].parts[0].orig_filename == 'hello.txt'
1105 1105

  
1106 1106
    assert isinstance(formdata.evolution[-1].parts[1], JournalEvolutionPart)
1107 1107
    assert len(formdata.evolution[-1].parts[1].content) > 0
1108 1108
    comment_view = str(formdata.evolution[-1].parts[1].view())
1109 1109
    assert comment_view == '<p>%s</p>' % comment_text
1110 1110

  
1111 1111

  
1112
def test_register_comment_to(pub):
1113
    workflow = Workflow(name='register comment to')
1114
    st1 = workflow.add_status('Status1', 'st1')
1115

  
1116
    role = Role(name='foorole')
1117
    role.store()
1118
    role2 = Role(name='no-one-role')
1119
    role2.store()
1120
    user = pub.user_class(name='baruser')
1121
    user.roles = []
1122
    user.store()
1123

  
1124
    FormDef.wipe()
1125
    formdef = FormDef()
1126
    formdef.url_name = 'foobar'
1127
    formdef._workflow = workflow
1128

  
1129
    formdata = formdef.data_class()()
1130
    formdata.just_created()
1131
    assert formdata.status == 'wf-st1'
1132
    formdata.store()
1133

  
1134
    register_commenter = RegisterCommenterWorkflowStatusItem()
1135
    register_commenter.parent = st1
1136
    st1.items.append(register_commenter)
1137

  
1138
    def display_parts():
1139
        formdata.evolution[-1]._display_parts = None  # invalidate cache
1140
        return [str(x) for x in formdata.evolution[-1].display_parts()]
1141

  
1142
    register_commenter.comment = 'all'
1143
    register_commenter.to = None
1144
    register_commenter.perform(formdata)
1145
    assert len(formdata.evolution[-1].parts) == 1
1146
    assert display_parts() == ['<p>all</p>']
1147

  
1148
    register_commenter.comment = 'to-role'
1149
    register_commenter.to = [role.id]
1150
    register_commenter.perform(formdata)
1151
    assert len(formdata.evolution[-1].parts) == 2
1152
    assert len(display_parts()) == 1
1153
    pub._request._user = user
1154
    assert display_parts() == ['<p>all</p>']
1155
    user.roles = [role.id]
1156
    assert display_parts() ==  ['<p>all</p>', '<p>to-role</p>']
1157

  
1158
    user.roles = []
1159
    register_commenter.comment = 'to-submitter'
1160
    register_commenter.to = ['_submitter']
1161
    register_commenter.perform(formdata)
1162
    assert len(formdata.evolution[-1].parts) == 3
1163
    assert display_parts() ==  ['<p>all</p>']
1164
    formdata.user_id = user.id
1165
    assert display_parts() ==  ['<p>all</p>', '<p>to-submitter</p>']
1166

  
1167
    register_commenter.comment = 'to-role-or-submitter'
1168
    register_commenter.to = [role.id, '_submitter']
1169
    register_commenter.perform(formdata)
1170
    assert len(formdata.evolution[-1].parts) == 4
1171
    assert display_parts() ==  ['<p>all</p>', '<p>to-submitter</p>', '<p>to-role-or-submitter</p>']
1172
    formdata.user_id = None
1173
    assert display_parts() ==  ['<p>all</p>']
1174
    user.roles = [role.id]
1175
    assert display_parts() ==  ['<p>all</p>', '<p>to-role</p>', '<p>to-role-or-submitter</p>']
1176
    formdata.user_id = user.id
1177
    assert display_parts() ==  [
1178
        '<p>all</p>', '<p>to-role</p>', '<p>to-submitter</p>', '<p>to-role-or-submitter</p>']
1179

  
1180
    register_commenter.comment = 'd1'
1181
    register_commenter.to = [role2.id]
1182
    register_commenter.perform(formdata)
1183
    assert len(formdata.evolution[-1].parts) == 5
1184
    assert display_parts() ==  [
1185
        '<p>all</p>', '<p>to-role</p>', '<p>to-submitter</p>', '<p>to-role-or-submitter</p>']
1186
    register_commenter2 = RegisterCommenterWorkflowStatusItem()
1187
    register_commenter2.parent = st1
1188
    st1.items.append(register_commenter2)
1189
    register_commenter2.comment = 'd2'
1190
    register_commenter2.to = [role.id, '_submitter']
1191
    user.roles = [role.id, role2.id]
1192
    register_commenter2.perform(formdata)
1193
    assert len(formdata.evolution[-1].parts) == 6
1194
    assert '<p>d1</p>' in [str(x) for x in display_parts()]
1195
    assert '<p>d2</p>' in [str(x) for x in display_parts()]
1196

  
1197

  
1112 1198
def test_email(pub, emails):
1113 1199
    pub.substitutions.feed(MockSubstitutionVariables())
1114 1200

  
1115 1201
    formdef = FormDef()
1116 1202
    formdef.name = 'baz'
1117 1203
    formdef.fields = []
1118 1204
    formdef.store()
1119 1205

  
wcs/formdata.py
149 149

  
150 150
        if not self.parts:
151 151
            return []
152 152

  
153 153
        l = []
154 154
        for p in self.parts:
155 155
            if not hasattr(p, 'view'):
156 156
                continue
157
            if hasattr(p, 'to') and not self.formdata.is_for_current_user(p.to):
158
                continue
157 159
            text = p.view()
158 160
            if text:
159 161
                l.append(text)
160 162
        self._display_parts = l
161 163
        return self._display_parts
162 164

  
163 165
    def get_json_export_dict(self, user, anonymise=False):
164 166
        data = {
wcs/sql.py
1802 1802
                elif type(value) in (tuple, list):
1803 1803
                    fts_strings.extend(value)
1804 1804
        if self._evolution:
1805 1805
            for evo in self._evolution:
1806 1806
                if evo.comment:
1807 1807
                    fts_strings.append(evo.comment)
1808 1808
                for part in evo.parts or []:
1809 1809
                    if hasattr(part, 'view'):
1810
                        if hasattr(part, 'to') and not self.is_for_current_user(part.to):
1811
                            continue
1810 1812
                        html_part = part.view()
1811 1813
                        if html_part:
1812 1814
                            fts_strings.append(qommon.misc.html2text(html_part))
1813 1815
        user = self.get_user()
1814 1816
        if user:
1815 1817
            fts_strings.append(user.get_display_name())
1816 1818

  
1817 1819
        sql_statement = '''UPDATE %s SET fts = to_tsvector( %%(fts)s)
wcs/wf/register_comment.py
22 22
from wcs.workflows import (WorkflowStatusItem, register_item_class, template_on_formdata,
23 23
                           AttachmentEvolutionPart)
24 24

  
25 25
import sys
26 26

  
27 27

  
28 28
class JournalEvolutionPart: #pylint: disable=C1001
29 29
    content = None
30
    to = []
30 31

  
31
    def __init__(self, formdata, message):
32
    def __init__(self, formdata, message, to):
32 33
        if not message:
33 34
            return
35
        self.to = to
34 36
        if '{{' in message or '{%' in message:
35 37
            # django template
36 38
            content = template_on_formdata(formdata, message)
37 39
            if content and not content.startswith('<'):
38 40
                # add <div> to mark the string as processed as HTML
39 41
                content = '<div>%s</div>' % content
40 42
            self.content = content
41 43
            return
......
59 61
            return htmltext('<p>') + \
60 62
                   htmltext('\n').join(
61 63
                            [(x or htmltext('</p><p>')) for x in self.content.splitlines()]) + \
62 64
                   htmltext('</p>')
63 65

  
64 66
    def get_json_export_dict(self, anonymise=False):
65 67
        d = {
66 68
            'type': 'workflow-comment',
69
            'to': self.to,
67 70
        }
68 71
        if not anonymise:
69 72
            d['content'] = self.content
70 73
        return d
71 74

  
72 75

  
73 76
class RegisterCommenterWorkflowStatusItem(WorkflowStatusItem):
74 77
    description = N_('History Message')
75 78
    key = 'register-comment'
76 79
    category = 'interaction'
77 80

  
78 81
    comment = None
82
    to = []
79 83
    attachments = None
80 84

  
81 85
    def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
82 86
        super(RegisterCommenterWorkflowStatusItem, self).add_parameters_widgets(
83 87
                form, parameters, prefix=prefix, formdef=formdef)
84 88
        if 'comment' in parameters:
85 89
            form.add(TextWidget, '%scomment' % prefix, title=_('Message'),
86 90
                value=self.comment, cols=80, rows=10)
91
        if 'to' in parameters:
92
            form.add(WidgetList, '%sto' % prefix, title=_('To'),
93
                     element_type=SingleSelectWidget,
94
                     value=self.to or [],
95
                     add_element_label=self.get_add_role_label(),
96
                     element_kwargs={'render_br': False,
97
                                     'options': [(None, '---', None)] +
98
                                        self.get_list_of_roles(include_logged_in_users=False)})
87 99

  
88 100
    def get_parameters(self):
89
        return ('comment', 'attachments', 'condition')
101
        return ('comment', 'to', 'attachments', 'condition')
90 102

  
91 103
    def attach_uploads_to_formdata(self, formdata, uploads):
92 104
        if not formdata.evolution[-1].parts:
93 105
            formdata.evolution[-1].parts = []
94 106
        for upload in uploads:
95 107
            try:
96 108
                # useless but required to restore upload.fp from serialized state,
97 109
                # needed by AttachmentEvolutionPart.from_upload()
......
110 122
        # (with substitution vars)
111 123
        if self.attachments:
112 124
            uploads = self.convert_attachments_to_uploads()
113 125
            self.attach_uploads_to_formdata(formdata, uploads)
114 126
            formdata.store()  # store and invalidate cache, so references can be used in the comment message.
115 127

  
116 128
        # the comment can use attachments done above
117 129
        try:
118
            formdata.evolution[-1].add_part(JournalEvolutionPart(formdata, self.comment))
130
            formdata.evolution[-1].add_part(JournalEvolutionPart(formdata, self.comment, self.to))
119 131
            formdata.store()
120 132
        except TemplateError as e:
121 133
            url = formdata.get_url()
122 134
            get_logger().error('error in template for comment [%s], '
123 135
                               'comment could not be generated: %s' % (url, str(e)))
124 136

  
125 137

  
126 138
register_item_class(RegisterCommenterWorkflowStatusItem)
127
-