misc: manage file fields in global interactive forms (#77955) #342

Merged
fpeters merged 1 commits from wip/77955-global-interactive-action-file-field into main 2023-05-29 06:54:49 +02:00
2 changed files with 70 additions and 2 deletions

View File

@ -21,6 +21,7 @@ from wcs.qommon.http_request import HTTPRequest
from wcs.qommon.ident.password_accounts import PasswordAccount
from wcs.qommon.upload_storage import PicklableUpload
from wcs.roles import logged_users_role
from wcs.sql_criterias import Contains
from wcs.wf.create_formdata import Mapping
from wcs.wf.form import WorkflowFormFieldsFormDef
from wcs.wf.register_comment import JournalEvolutionPart
@ -1243,6 +1244,66 @@ def test_backoffice_multi_actions_interactive_create_carddata(pub):
}
def test_backoffice_multi_actions_interactive_file_field(pub):
user = create_superuser(pub)
workflow = Workflow.get_default_workflow()
workflow.id = '2'
action = workflow.add_global_action('FOOBAR')
form_action = action.add_action('form')
form_action.varname = 'blah'
form_action.formdef = WorkflowFormFieldsFormDef(item=form_action)
form_action.formdef.fields.append(fields.FileField(id='1', label='Test', varname='test', required=True))
form_action.hide_submit_button = False
trigger = action.triggers[0]
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
form_action.by = trigger.roles
workflow.store()
formdef = FormDef()
formdef.name = 'test multi actions interactive file field'
formdef.fields = []
formdef.workflow_roles = {'_receiver': user.roles[0]}
formdef.workflow = workflow
formdef.store()
for i in range(10):
formdata = formdef.data_class()()
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get(formdef.get_url(backoffice=True))
assert 'id="multi-actions"' in resp.text # always there
resp = app.get(formdef.get_url(backoffice=True) + '?limit=20&order_by=id')
ids = []
for checkbox in resp.forms[0].fields['select[]'][1:6]:
ids.append(checkbox._value)
checkbox.checked = True
resp = resp.forms[0].submit('button-action-1')
assert '/actions/' in resp.location
resp = resp.follow()
assert '5 selected forms' in resp.text
resp.form['fblah_1$file'] = Upload('test3.txt', b'foobar3', 'text/plain')
resp = resp.form.submit('submit')
assert '?job=' in resp.location
resp = resp.follow()
assert 'Executing task "FOOBAR" on forms' in resp.text
assert '>completed<' in resp.text
for formdata in formdef.data_class().select([Contains('id', ids)]):
assert (
formdata.get_substitution_variables()['form'].workflow_form.blah.var.test.raw.get_content()
== b'foobar3'
)
def test_backoffice_map(pub):
create_user(pub)
create_environment(pub)

View File

@ -933,15 +933,19 @@ class FileWithPreviewWidget(CompositeWidget):
def set_value_from_token(self, request):
self.value = None
if self.get('token'):
if self.get('token') and get_session():
token = self.get('token')
elif self.get('file'):
elif self.get('file') and get_session():
try:
token = get_session().add_tempfile(self.get('file'), storage=self.storage)['token']
except UploadStorageError:
self.set_error(_('failed to store file (system error)'))
return
request.form[self.get_widget('token').get_name()] = token
elif self.get('file') and not get_session():
# a file field in a global interactive form being run in an afterjob
self.value = self.get('file')
return
else:
token = None
@ -977,6 +981,9 @@ class FileWithPreviewWidget(CompositeWidget):
if isinstance(self.value.fp, io.BufferedRandom):
# internally recreated file, trust supplied MIME type
filetype = self.value.content_type
elif not get_session() and isinstance(self.value.fp, io.BytesIO):
# a file field in a global interactive form being run in an afterjob
filetype = self.value.content_type
elif magic and self.value.fp:
mime = magic.Magic(mime=True)
filetype = mime.from_file(self.value.fp.name)