From 57d2209e9552356b4942ee826fcfedf62f14f9df Mon Sep 17 00:00:00 2001 From: Thomas NOEL Date: Fri, 22 Jan 2016 19:16:09 +0100 Subject: [PATCH] workflows: add target roles in display message workflow item (#9705) --- tests/test_form_pages.py | 53 +++++++++++++++++++++++++++- tests/test_workflow_import.py | 20 +++++++++++ tests/test_workflows.py | 81 +++++++++++++++++++++++++++++++++++++++++++ wcs/formdata.py | 15 ++++---- wcs/forms/common.py | 28 +++++++++------ wcs/workflows.py | 34 +++++++++++++++++- 6 files changed, 213 insertions(+), 18 deletions(-) diff --git a/tests/test_form_pages.py b/tests/test_form_pages.py index 9932c07..0ffdde5 100644 --- a/tests/test_form_pages.py +++ b/tests/test_form_pages.py @@ -14,7 +14,7 @@ from quixote.http_request import Upload as QuixoteUpload from wcs.qommon.form import UploadedFile from wcs.qommon.ident.password_accounts import PasswordAccount from wcs.formdef import FormDef -from wcs.workflows import Workflow, EditableWorkflowStatusItem +from wcs.workflows import Workflow, EditableWorkflowStatusItem, DisplayMessageWorkflowStatusItem from wcs.wf.export_to_model import ExportToModel from wcs.wf.jump import JumpWorkflowStatusItem from wcs.wf.attachment import AddAttachmentWorkflowStatusItem @@ -2270,3 +2270,54 @@ def test_form_worklow_multiple_identical_status(pub): resp = app.get(formdata.get_url()) assert resp.body.count('Status1') == 2 # once in summary and once in journal + +def test_display_message(pub): + user = create_user(pub) + + formdef = create_formdef() + formdef.fields = [] + formdef.store() + + workflow = Workflow(name='test') + st1 = workflow.add_status('Status1', 'st1') + + display1 = DisplayMessageWorkflowStatusItem() + display1.message = 'message-to-all' + display1.to = [] + st1.items.append(display1) + display1.parent = st1 + + display2 = DisplayMessageWorkflowStatusItem() + display2.message = 'message-to-submitter' + display2.to = ['_submitter'] + st1.items.append(display2) + display2.parent = st1 + + display3 = DisplayMessageWorkflowStatusItem() + display3.message = 'message-to-nobody' + display3.to = ['xxx'] + st1.items.append(display3) + display3.parent = st1 + + display4 = DisplayMessageWorkflowStatusItem() + display4.message = 'message-to-xxx-and-submitter' + display4.to = ['_submitter', 'xxx'] + st1.items.append(display4) + display4.parent = st1 + + workflow.store() + + formdef.workflow_id = workflow.id + formdef.store() + + formdef.data_class().wipe() + + page = login(get_app(pub), username='foo', password='foo').get('/test/') + page = page.forms[0].submit('submit') # form page + page = page.forms[0].submit('submit') # confirmation page + page = page.follow() + + assert 'message-to-all' in page.body + assert 'message-to-submitter' in page.body + assert 'message-to-nobody' not in page.body + assert 'message-to-xxx-and-submitter' in page.body diff --git a/tests/test_workflow_import.py b/tests/test_workflow_import.py index e4dd835..0b06360 100644 --- a/tests/test_workflow_import.py +++ b/tests/test_workflow_import.py @@ -406,3 +406,23 @@ def test_complex_dispatch_action(): assert wf2.possible_status[0].items[0].rules == [ {'value': 'a', 'role_id': role3.id}, {'value': 'b', 'role_id': role4.id}] assert wf2.possible_status[0].items[0].dispatch_type == 'automatic' + + +def test_display_message_action(): + wf = Workflow(name='status') + st1 = wf.add_status('Status1', 'st1') + + from wcs.workflows import DisplayMessageWorkflowStatusItem + + display = DisplayMessageWorkflowStatusItem() + display.message = 'hey' + display.to = ['_submitter', '1'] + st1.items.append(display) + display.parent = st1 + + wf2 = assert_import_export_works(wf) + assert wf2.possible_status[0].items[0].message == display.message + for role_id in display.to: + assert role_id in wf2.possible_status[0].items[0].to + + wf2 = assert_import_export_works(wf, include_id=True) diff --git a/tests/test_workflows.py b/tests/test_workflows.py index 1325cc9..8b7fd8e 100644 --- a/tests/test_workflows.py +++ b/tests/test_workflows.py @@ -779,6 +779,87 @@ def test_workflow_display_message(pub): display_message.message = '[foo]' assert display_message.get_message(formdata) == '1 < 3' +def test_workflow_display_message_to(pub): + workflow = Workflow(name='display message to') + st1 = workflow.add_status('Status1', 'st1') + + role = Role(name='foorole') + role.store() + role2 = Role(name='no-one-role') + role2.store() + user = pub.user_class(name='baruser') + user.roles = [] + user.store() + + FormDef.wipe() + formdef = FormDef() + formdef.url_name = 'foobar' + formdef._workflow = workflow + + formdata = formdef.data_class()() + formdata.status = 'wf-st1' + + display_message = DisplayMessageWorkflowStatusItem() + display_message.parent = st1 + st1.items.append(display_message) + + display_message.message = 'all' + display_message.to = None + assert display_message.get_message(formdata) == 'all' + assert formdata.get_workflow_messages() == ['all'] + + display_message.message = 'to-role' + display_message.to = [role.id] + assert display_message.get_message(formdata) == '' + assert formdata.get_workflow_messages() == [] + + pub._request.user = user + display_message.message = 'to-role' + display_message.to = [role.id] + assert display_message.get_message(formdata) == '' + assert formdata.get_workflow_messages() == [] + user.roles = [role.id] + assert display_message.get_message(formdata) == 'to-role' + assert formdata.get_workflow_messages() == ['to-role'] + + user.roles = [] + display_message.message = 'to-submitter' + display_message.to = ['_submitter'] + assert display_message.get_message(formdata) == '' + assert formdata.get_workflow_messages() == [] + formdata.user_id = user.id + assert display_message.get_message(formdata) == 'to-submitter' + assert formdata.get_workflow_messages() == ['to-submitter'] + + display_message.message = 'to-role-or-submitter' + display_message.to = [role.id, '_submitter'] + assert display_message.get_message(formdata) == 'to-role-or-submitter' + assert formdata.get_workflow_messages() == ['to-role-or-submitter'] + formdata.user_id = None + assert display_message.get_message(formdata) == '' + assert formdata.get_workflow_messages() == [] + user.roles = [role.id] + assert display_message.get_message(formdata) == 'to-role-or-submitter' + assert formdata.get_workflow_messages() == ['to-role-or-submitter'] + formdata.user_id = user.id + assert display_message.get_message(formdata) == 'to-role-or-submitter' + assert formdata.get_workflow_messages() == ['to-role-or-submitter'] + + display_message.to = [role2.id] + assert display_message.get_message(formdata) == '' + assert formdata.get_workflow_messages() == [] + + display_message.message = 'd1' + display_message2 = DisplayMessageWorkflowStatusItem() + display_message2.parent = st1 + st1.items.append(display_message2) + display_message2.message = 'd2' + display_message2.to = [role.id, '_submitter'] + assert formdata.get_workflow_messages() == ['d2'] + user.roles = [role.id, role2.id] + assert 'd1' in formdata.get_workflow_messages() + assert 'd2' in formdata.get_workflow_messages() + def test_workflow_roles(pub): pub.substitutions.feed(MockSubstitutionVariables()) diff --git a/wcs/formdata.py b/wcs/formdata.py index dd78074..6621bf1 100644 --- a/wcs/formdata.py +++ b/wcs/formdata.py @@ -279,14 +279,17 @@ class FormData(StorableObject): url = perform_items(wf_status.items, self) return url - def display_workflow_message(self): + def get_workflow_messages(self): wf_status = self.get_status() if not wf_status: - return '' - for status in wf_status.items: - if hasattr(status, 'get_message'): - return status.get_message(self) - return '' + return [] + messages = [] + for item in wf_status.items: + if hasattr(item, 'get_message'): + message = item.get_message(self) + if message: + messages.append(message) + return messages def get_status(self, status = None): if not status: diff --git a/wcs/forms/common.py b/wcs/forms/common.py index d3d888d..fc758a2 100644 --- a/wcs/forms/common.py +++ b/wcs/forms/common.py @@ -132,16 +132,25 @@ class FormStatusPage(Directory): self.check_auth(api_call=True) return self.export_to_json() - def receipt_message(self, mine=False): + def workflow_messages(self): if self.formdef.workflow: - workflow_message = self.filled.display_workflow_message() - if workflow_message: + workflow_messages = self.filled.get_workflow_messages() + if workflow_messages: r = TemplateIO(html=True) - if workflow_message.startswith('<'): - r += htmltext(workflow_message) - else: - r += htmltext('

%s

' % workflow_message) + r += htmltext('
') + for workflow_message in workflow_messages: + if workflow_message.startswith('<'): + r += htmltext(workflow_message) + else: + r += htmltext('

%s

' % workflow_message) + r += htmltext('
') return r.getvalue() + return '' + + def receipt_message(self, mine=False): + workflow_messages = self.workflow_messages() + if workflow_messages: + return workflow_messages r = TemplateIO(html=True) # behaviour if workflow doesn't display any message @@ -483,10 +492,9 @@ class FormStatusPage(Directory): 'date': self.filled.anonymised.strftime(misc.date_format())} r += htmltext('') - r += self.receipt(always_include_user = True) + r += htmltext(self.workflow_messages()) - if self.formdef.workflow: - r += htmltext(self.filled.display_workflow_message()) + r += self.receipt(always_include_user = True) r += self.history() diff --git a/wcs/workflows.py b/wcs/workflows.py index 946233d..b980408 100644 --- a/wcs/workflows.py +++ b/wcs/workflows.py @@ -1804,11 +1804,35 @@ class DisplayMessageWorkflowStatusItem(WorkflowStatusItem): support_substitution_variables = True ok_in_global_action = False + to = None + message = None + def render_as_line(self): + if self.to: + return _('Display message to %s') % self.render_list_of_roles(self.to) + else: + return _('Display message') + def get_message(self, filled): if not self.message: return '' + + if self.to: + if not get_request(): + return '' + user = get_request().user + for role in self.to or []: + if role == '_submitter': + if filled.is_submitter(user): + break + elif user: + role = get_role_translation(filled, role) + if role in (user.roles or []): + break + else: + return '' + tmpl = ezt.Template() tmpl.parse(self.message, base_format=ezt.FORMAT_HTML) @@ -1830,9 +1854,17 @@ class DisplayMessageWorkflowStatusItem(WorkflowStatusItem): if 'message' in parameters: form.add(TextWidget, '%smessage' % prefix, title = _('Message'), value = self.message, cols = 80, rows = 10) + if 'to' in parameters: + form.add(WidgetList, '%sto' % prefix, title=_('To'), + element_type=SingleSelectWidget, + value=self.to or [], + add_element_label=_('Add Role'), + element_kwargs={'render_br': False, + 'options': [(None, '---', None)] + + self.get_list_of_roles(include_logged_in_users=False)}) def get_parameters(self): - return ('message',) + return ('message', 'to') register_item_class(DisplayMessageWorkflowStatusItem) -- 2.7.0.rc3