formdef: handle base64 in xml import/export (#36515)

This commit is contained in:
Frédéric Péters 2019-11-16 12:25:59 +01:00
parent a33e8ff8b4
commit 96bf98cd7c
2 changed files with 17 additions and 17 deletions

View File

@ -6,7 +6,7 @@ import shutil
import time
import xml.etree.ElementTree as ET
from django.utils.six import StringIO
from django.utils.six import BytesIO, StringIO
from quixote import cleanup
from wcs.categories import Category
@ -199,8 +199,8 @@ def test_workflow_options_with_file():
from wcs.qommon.form import UploadedFile
upload = Upload('/foo/bar', content_type='application/vnd.oasis.opendocument.text')
file_content = '''PK\x03\x04\x14\x00\x00\x08\x00\x00\'l\x8eG^\xc62\x0c\'\x00'''
upload.fp = StringIO()
file_content = b'''PK\x03\x04\x14\x00\x00\x08\x00\x00\'l\x8eG^\xc62\x0c\'\x00'''
upload.fp = BytesIO()
upload.fp.write(file_content)
upload.fp.seek(0)
model_file = UploadedFile(pub.APP_DIR, None, upload)
@ -311,7 +311,7 @@ def test_invalid_field_type():
formdef.fields = [fields.StringField(id='1', type='XXX')]
export = ET.tostring(export_to_indented_xml(formdef))
with pytest.raises(FormdefImportError):
FormDef.import_from_xml(StringIO(export), include_id=True)
FormDef.import_from_xml(BytesIO(export), include_id=True)
def test_unknown_data_source():
formdef = FormDef()
@ -320,13 +320,13 @@ def test_unknown_data_source():
data_source={'type': 'json', 'value': 'http://example.net'})]
export = ET.tostring(export_to_indented_xml(formdef))
FormDef.import_from_xml(StringIO(export))
FormDef.import_from_xml(BytesIO(export))
formdef.fields = [fields.StringField(id='1', type='string',
data_source={'type': 'foobar'})]
export = ET.tostring(export_to_indented_xml(formdef))
with pytest.raises(FormdefImportError):
FormDef.import_from_xml(StringIO(export))
FormDef.import_from_xml(BytesIO(export))
def test_duplicated_field_ids():
formdef = FormDef()
@ -338,12 +338,12 @@ def test_duplicated_field_ids():
export = ET.tostring(export_to_indented_xml(formdef, include_id=True))
with pytest.raises(FormdefImportError):
FormDef.import_from_xml(StringIO(export))
FormDef.import_from_xml(BytesIO(export))
with pytest.raises(FormdefImportError):
FormDef.import_from_xml(StringIO(export), include_id=True)
FormDef.import_from_xml(BytesIO(export), include_id=True)
formdef2 = FormDef.import_from_xml(StringIO(export), fix_on_error=True)
formdef2 = FormDef.import_from_xml(BytesIO(export), fix_on_error=True)
assert formdef2.fields[0].id == '1'
assert formdef2.fields[1].id == '2'
assert formdef2.fields[2].id == '3'
@ -357,7 +357,7 @@ def test_wrong_max_field_id():
formdef.max_field_id = 1
export = ET.tostring(export_to_indented_xml(formdef, include_id=True))
formdef2 = FormDef.import_from_xml(StringIO(export), include_id=True)
formdef2 = FormDef.import_from_xml(BytesIO(export), include_id=True)
assert formdef2.max_field_id == 2
def test_page_condition():
@ -538,9 +538,9 @@ def test_field_validation():
# backward compatibility
formdef_xml = formdef.export_to_xml()
old_format = ET.tostring(formdef_xml).replace(
'<validation><type>regex</type><value>\\d</value></validation>',
'<validation>\\d</validation>')
f2 = FormDef.import_from_xml(StringIO(old_format))
b'<validation><type>regex</type><value>\\d</value></validation>',
b'<validation>\\d</validation>')
f2 = FormDef.import_from_xml(BytesIO(old_format))
assert len(f2.fields) == len(formdef.fields)
assert f2.fields[0].validation == {'type': 'regex', 'value': '\\d'}

View File

@ -26,7 +26,7 @@ import xml.etree.ElementTree as ET
import datetime
from django.utils import six
from django.utils.encoding import force_text
from django.utils.encoding import force_bytes, force_text
from quixote import get_request, get_publisher
from quixote.http_request import Upload
@ -855,7 +855,7 @@ class FormDef(StorableObject):
filename = option_value['filename']
upload = Upload(filename, content_type=option_value['content_type'])
new_value = UploadedFile(get_publisher().app_dir, filename, upload)
new_value.set_content(base64.decodestring(option_value['content']))
new_value.set_content(base64.decodestring(force_bytes(option_value['content'])))
formdef.workflow_options[option_key] = new_value
if value.get('geolocations'):
@ -969,7 +969,7 @@ class FormDef(StorableObject):
ET.SubElement(element, 'filename').text = option_value.base_filename
ET.SubElement(element, 'content_type').text = (
option_value.content_type or 'application/octet-stream')
ET.SubElement(element, 'content').text = base64.b64encode(option_value.get_content())
ET.SubElement(element, 'content').text = force_text(base64.b64encode(option_value.get_content()))
elif isinstance(option_value, time.struct_time):
element.text = time.strftime('%Y-%m-%d', option_value)
element.attrib['type'] = 'date'
@ -1095,7 +1095,7 @@ class FormDef(StorableObject):
filename = option.find('filename').text
upload = Upload(filename, content_type=option.find('content_type').text)
option_value = UploadedFile(get_publisher().app_dir, filename, upload)
option_value.set_content(base64.decodestring(option.find('content').text))
option_value.set_content(base64.decodestring(force_bytes(option.find('content').text)))
formdef.workflow_options[option.attrib.get('varname')] = option_value
if tree.find('last_modification') is not None: