workflow_tests: add support for global action in button click action (#88311)
gitea/wcs/pipeline/head This commit looks good Details

This commit is contained in:
Valentin Deniaud 2024-03-19 11:50:54 +01:00
parent 0c225cf254
commit 9afbbccb13
4 changed files with 109 additions and 10 deletions

View File

@ -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)'),

View File

@ -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'

View File

@ -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

View File

@ -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)