From 9afbbccb13a2d71db44d92e3a1ab53003ec00a6a Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Tue, 19 Mar 2024 11:50:54 +0100 Subject: [PATCH] workflow_tests: add support for global action in button click action (#88311) --- tests/admin_pages/test_workflow_tests.py | 6 ++ tests/test_workflow_tests.py | 77 +++++++++++++++++++++++- wcs/workflow_tests.py | 34 ++++++++--- wcs/workflows.py | 2 +- 4 files changed, 109 insertions(+), 10 deletions(-) diff --git a/tests/admin_pages/test_workflow_tests.py b/tests/admin_pages/test_workflow_tests.py index f949f0704..ec5974824 100644 --- a/tests/admin_pages/test_workflow_tests.py +++ b/tests/admin_pages/test_workflow_tests.py @@ -237,10 +237,16 @@ def test_workflow_tests_action_button_click(pub): jump = new_status.add_action('choice') jump.label = 'Button no target status' + workflow.add_global_action('Action 1') + + interactive_action = workflow.add_global_action('Interactive action (should not be shown)') + interactive_action.add_action('form') + workflow.store() resp = app.get('/backoffice/forms/1/tests/%s/workflow/1/' % testdef.id) assert resp.form['button_name'].options == [ + ('Action 1', False, 'Action 1'), ('Button 1', False, 'Button 1'), ('Button 2', False, 'Button 2'), ('Button 4 (not available)', True, 'Button 4 (not available)'), diff --git a/tests/test_workflow_tests.py b/tests/test_workflow_tests.py index 911342e04..c8c00679c 100644 --- a/tests/test_workflow_tests.py +++ b/tests/test_workflow_tests.py @@ -209,6 +209,65 @@ def test_workflow_tests_button_click(pub): assert str(excinfo.value) == 'Button "Go to end status" is not displayed.' +def test_workflow_tests_button_click_global_action(pub): + role = pub.role_class(name='test role') + role.store() + user = pub.user_class(name='test user') + user.roles = [role.id] + user.store() + + workflow = Workflow(name='Workflow One') + workflow.add_status(name='New status') + end_status = workflow.add_status(name='End status') + + global_action = workflow.add_global_action('Go to end status') + global_action.triggers[0].roles = [role.id] + + sendmail = global_action.add_action('sendmail') + sendmail.to = ['test@example.org'] + sendmail.subject = 'In new status' + sendmail.body = 'xxx' + + jump = global_action.add_action('jump') + jump.status = end_status.id + + workflow.store() + + formdef = FormDef() + formdef.name = 'test title' + formdef.workflow_id = workflow.id + formdef.store() + + formdata = formdef.data_class()() + formdata.just_created() + + testdef = TestDef.create_from_formdata(formdef, formdata) + testdef.agent_id = user.id + + testdef.workflow_tests.actions = [ + workflow_tests.AssertStatus(status_name='End status'), + ] + + with pytest.raises(WorkflowTestError) as excinfo: + testdef.run(formdef) + assert str(excinfo.value) == 'Form should be in status "End status" but is in status "New status".' + + testdef.workflow_tests.actions = [ + workflow_tests.ButtonClick(button_name='Go to end status'), + workflow_tests.AssertEmail(), + workflow_tests.AssertStatus(status_name='End status'), + ] + testdef.run(formdef) + + # hide button from test user + user.roles = [] + user.store() + + with pytest.raises(WorkflowTestError) as excinfo: + testdef.run(formdef) + assert str(excinfo.value) == 'Button "Go to end status" is not displayed.' + + def test_workflow_tests_button_click_who(pub): role = pub.role_class(name='test role') role.store() @@ -1063,6 +1122,7 @@ def test_workflow_tests_create_from_formdata(pub, http_requests, freezer): status_with_timeout_jump = workflow.add_status('Status with timeout jump', 'status-with-timeout-jump') status_with_button = workflow.add_status('Status with button', 'status-with-button') transition_status = workflow.add_status('Transition status', 'transition-status') + transition_status2 = workflow.add_status('Transition status 2', 'transition-status-2') end_status = workflow.add_status('End status', 'end-status') jump = new_status.add_action('jump') @@ -1104,7 +1164,13 @@ def test_workflow_tests_create_from_formdata(pub, http_requests, freezer): transition_status.add_action('modify_criticality') - jump = transition_status.add_action('jump') + global_action = workflow.add_global_action('Action 1') + global_action.triggers[0].roles = [role.id] + + jump = global_action.add_action('jump') + jump.status = transition_status2.id + + jump = transition_status2.add_action('jump') jump.status = end_status.id workflow.store() @@ -1129,6 +1195,7 @@ def test_workflow_tests_create_from_formdata(pub, http_requests, freezer): app = login(get_app(pub)) resp = app.get(formdata.get_url()) resp.form.submit('button1').follow() + resp.form.submit('button-action-1').follow() formdata.refresh_from_storage() assert formdata.status == 'wf-end-status' @@ -1136,7 +1203,7 @@ def test_workflow_tests_create_from_formdata(pub, http_requests, freezer): testdef.run(formdef) actions = testdef.workflow_tests.actions - assert len(actions) == 13 + assert len(actions) == 15 assert actions[0].key == 'assert-status' assert actions[0].status_name == 'Status with timeout jump' @@ -1159,5 +1226,11 @@ def test_workflow_tests_create_from_formdata(pub, http_requests, freezer): assert actions[10].key == 'assert-history-message' assert actions[11].key == 'assert-criticality' + assert actions[12].key == 'assert-status' + assert actions[12].status_name == 'Transition status' + + assert actions[13].key == 'button-click' + assert actions[13].button_name == 'Action 1' + assert actions[-1].key == 'assert-status' assert actions[-1].status_name == 'End status' diff --git a/wcs/workflow_tests.py b/wcs/workflow_tests.py index d49fdcf9f..ae8998e93 100644 --- a/wcs/workflow_tests.py +++ b/wcs/workflow_tests.py @@ -150,6 +150,7 @@ class WorkflowTests(XmlStorableObject): 'webservice_call': AssertWebserviceCall, 'set-backoffice-fields': AssertBackofficeFieldValues, 'button': ButtonClick, + 'global-action-button': ButtonClick, 'timeout-jump': SkipTime, 'anonymise': AssertAnonymise, 'redirect_to_url': AssertRedirect, @@ -276,14 +277,26 @@ class ButtonClick(WorkflowTestAction): return _('Click on "%(button_name)s" by %(user)s') % {'button_name': self.button_name, 'user': user} def set_attributes_from_trace(self, formdef, trace, previous_trace=None): - try: - item = [ - x for x in self.get_all_choice_actions(formdef) if x.id == trace.event_args['action_item_id'] - ][0] - except IndexError: - return + if 'action_item_id' in trace.event_args: + try: + button_name = [ + x.label + for x in self.get_all_choice_actions(formdef) + if x.id == trace.event_args['action_item_id'] + ][0] + except IndexError: + return + elif 'global_action_id' in trace.event_args: + try: + button_name = [ + x.name + for x in self.get_all_global_actions(formdef) + if x.id == trace.event_args['global_action_id'] + ][0] + except IndexError: + return - self.button_name = item.label + self.button_name = button_name def perform(self, formdata): if self.who == 'receiver': @@ -316,8 +329,15 @@ class ButtonClick(WorkflowTestAction): if isinstance(item, wf.choice.ChoiceWorkflowStatusItem) and item.status: yield item + @staticmethod + def get_all_global_actions(formdef): + for action in formdef.workflow.global_actions or []: + if not action.is_interactive(): + yield action + def fill_admin_form(self, form, formdef): possible_button_names = {x.label for x in self.get_all_choice_actions(formdef)} + possible_button_names.update(action.name for action in self.get_all_global_actions(formdef)) if not possible_button_names: return diff --git a/wcs/workflows.py b/wcs/workflows.py index 405128d5c..7e03235bd 100644 --- a/wcs/workflows.py +++ b/wcs/workflows.py @@ -2736,7 +2736,7 @@ class WorkflowStatus(SerieOfActionsMixin): if check_replay and form.get('_ts') != str(filled.last_update_time.timestamp()): raise ReplayException() for action in filled.formdef.workflow.get_global_actions_for_user(filled, user): - if 'button-action-%s' % action.id in get_request().form: + if form.get_submit() == 'button-action-%s' % action.id: if action.is_interactive(): return action.get_global_interactive_form_url(formdef=filled.formdef, ids=[filled.id]) filled.record_workflow_event('global-action-button', global_action_id=action.id)