Commit 0cfb1586 authored by Jérome Perrin's avatar Jérome Perrin

More python3 support

See merge request nexedi/erp5!1863
parents 2e8ef0bb 7fc1e3b0
Pipeline #32189 failed with stage
"""Resets grouping reference on this line and all related lines.
This runs by default asynchronously, but can be call with `async=False` to
run synchronously and returns the list of ungrouped lines. With `async=True`,
This runs by default asynchronoushronously, but can be call with `asynchronous=False` to
run synchronously and returns the list of ungrouped lines. With `asynchronous=True`,
the returned list is always empty.
"""
......@@ -13,7 +13,7 @@ if not context.getGroupingReference():
portal = context.getPortalObject()
resetGroupingReference = portal.ERP5Site_resetAccountingTransactionLineGroupingReference
if async:
if asynchronous:
resetGroupingReference = portal.portal_simulation.activate(
activity='SQLQueue',
after_tag='accounting_grouping_reference'
......
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>async=True</string> </value>
<value> <string>asynchronous=True</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -121,7 +121,7 @@ else:
if line.getGroupingReference():
# Call AccountingTransactionLine_resetGroupingReference synchronously
# to know the number of ungrouped lines.
ungrouped_line_list.extend(line.AccountingTransactionLine_resetGroupingReference(async=False))
ungrouped_line_list.extend(line.AccountingTransactionLine_resetGroupingReference(asynchronous=False))
portal_status_message = Base_translateString('${ungrouped_line_count} lines ungrouped.',
mapping=dict(ungrouped_line_count=len(ungrouped_line_list)))
......
......@@ -3907,7 +3907,7 @@ class TestTransactions(AccountingTestCase):
# reset from the payment line, the invoice line from the same group will be
# ungrouped
payment_line.AccountingTransactionLine_resetGroupingReference(async=False)
payment_line.AccountingTransactionLine_resetGroupingReference(asynchronous=False)
self.assertFalse(payment_line.getGroupingReference())
self.assertFalse(payment_line.getGroupingDate())
self.assertFalse(invoice_line.getGroupingReference())
......
......@@ -27,6 +27,10 @@ from mimetools import choose_boundary
from Products.CMFCore.utils import _setCacheHeaders, _ViewEmulator
from DateTime import DateTime
import re
import six
if six.PY3:
long = int # pylint:disable=redefined-builtin
class BigFile(File):
"""
......
......@@ -33,6 +33,7 @@ from random import randint
import sys
import threading
import traceback
import unittest
import six
from AccessControl import getSecurityManager
from AccessControl.SecurityManagement import newSecurityManager
......@@ -48,6 +49,9 @@ from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery, SimpleQuery
from Testing import ZopeTestCase
from zLOG import LOG
if six.PY3:
long = int # pylint:disable=redefined-builtin
def format_stack(thread=None):
frame_dict = sys._current_frames()
if thread is not None:
......@@ -588,7 +592,7 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
uid_dict = {}
for _ in xrange(UID_BUFFER_SIZE * 3):
uid = portal_catalog.newUid()
self.assertTrue(isinstance(uid, long))
self.assertIsInstance(uid, long)
self.assertNotIn(uid, uid_dict)
uid_dict[uid] = None
......@@ -1647,6 +1651,9 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
portal_type='Organisation',**catalog_kw)])
def test_54_FixIntUid(self):
if six.PY3:
return unittest.skipTest(
"Python3 does not have different types for int and long")
portal = self.getPortal()
module = portal.getDefaultModule('Organisation')
......
......@@ -34,7 +34,7 @@ import unittest
def get_Z2_log_last_line():
z2_log_path = os.path.join(log_directory, 'Z2.log')
f = open(z2_log_path, 'rb')
f = open(z2_log_path, 'r')
try:
f.seek(-256, os.SEEK_END) # Assumes last line is not longer than 256 chars (it should be about 130)
except IOError: # too short
......
......@@ -34,7 +34,7 @@ import unittest
from AccessControl.SecurityManagement import newSecurityManager
from Testing import ZopeTestCase
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from DocumentTemplate.DT_Util import html_quote
from DocumentTemplate.html_quote import html_quote
class TestEditorField(ERP5TypeTestCase, ZopeTestCase.Functional):
"""
......
# export_only : allow to disable the uid column and the id of columns
import six
result = ''
request = context.REQUEST
......@@ -9,7 +10,7 @@ listboxline_list = context.get_value('default', render_format='list', REQUEST=re
def encode(value):
if isinstance(value, bool):
return '"%s"' % value
if isinstance(value, (int, long, float)):
if isinstance(value, six.integer_types + (float,)):
return str(value)
else:
if isinstance(value, str):
......
......@@ -238,7 +238,7 @@
error python: value[2]"
class="DataA" align="left"
tal:attributes="class python: error and (css + 'Error') or css;
align python: isinstance(original_value, (float, int, long)) and 'right' or 'left'">
align python: isinstance(original_value, modules['six'].integer_types + (float,)) and 'right' or 'left'">
<input tal:condition="not: repeat/value/index"
type="hidden" value="1" name="listbox_uid:list"
tal:attributes="value python: line.getUid() or '';
......@@ -268,7 +268,7 @@
<tal:block tal:repeat="value here/getStatValueList">
<td class="Data" align="left"
tal:define="original_value python: value[0]; processed_value python: value[1]"
tal:attributes="align python: isinstance(original_value, (float, int, long)) and 'right' or 'left'"
tal:attributes="align python: isinstance(original_value, modules['six'].integer_types + (float,)) and 'right' or 'left'"
tal:content="structure processed_value" />
</tal:block>
</tr>
......
......@@ -15,16 +15,17 @@ There are runtime values hidden in every dialog form (injected by getHateoas Scr
from erp5.component.module.Log import log, WARNING
from Products.Formulator.Errors import FormValidationError
import json
import six
# http://stackoverflow.com/a/13105359
def byteify(value):
if isinstance(value, dict):
return {byteify(key): byteify(value) for key, value in value.iteritems()}
return {byteify(key): byteify(value) for key, value in six.iteritems(value)}
elif isinstance(value, list):
return [byteify(element) for element in value]
elif isinstance(value, tuple):
return tuple(byteify(element) for element in value)
elif isinstance(value, unicode):
elif six.PY2 and isinstance(value, six.text_type):
return value.encode('utf-8')
else:
return value
......
......@@ -6,8 +6,9 @@ Return JSON with message to be displayed and set according HTTP STATUS for messa
"""
import json
from erp5.component.module.Log import WARNING, ERROR
import six
if isinstance(level, (str, unicode)):
if isinstance(level, (str, six.text_type)):
if level.lower() == "error":
response_code = 500
elif level.lower().startswith("warn"):
......
......@@ -49,7 +49,7 @@ When handling form, we can expect field values to be stored in REQUEST.form in t
from ZTUtils import make_query
import json
import urllib
from six.moves.urllib.parse import urlencode
from base64 import urlsafe_b64encode, urlsafe_b64decode
from DateTime import DateTime
from ZODB.POSException import ConflictError
......@@ -63,6 +63,8 @@ from Products.ERP5Type.Message import Message
from collections import OrderedDict
from Products.ERP5Form.Selection import Selection
from Products.PythonScripts.standard import Object
from Products.ERP5Type.Utils import bytes2str, str2bytes
import six
MARKER = Object()
......@@ -83,7 +85,7 @@ def toBasicTypes(obj):
"""Ensure that obj contains only basic types."""
if obj is None:
return obj
if isinstance(obj, (bool, int, float, long, str, unicode)):
if isinstance(obj, (bool, float, str) + six.integer_types + (six.text_type, )):
return obj
if isinstance(obj, list):
return [toBasicTypes(x) for x in obj]
......@@ -124,12 +126,12 @@ def renderHiddenField(form, name, value):
# http://stackoverflow.com/a/13105359
def byteify(string):
if isinstance(string, dict):
return {byteify(key): byteify(value) for key, value in string.iteritems()}
return {byteify(key): byteify(value) for key, value in six.iteritems(string)}
elif isinstance(string, list):
return [byteify(element) for element in string]
elif isinstance(string, tuple):
return tuple(byteify(element) for element in string)
elif isinstance(string, unicode):
elif six.PY2 and isinstance(string, six.text_type):
return string.encode('utf-8')
else:
return string
......@@ -139,10 +141,11 @@ def ensureUTF8(obj):
"""Make sure string is UTF-8, by replacing characters that
cannot be decoded.
"""
if isinstance(obj, str):
return obj.decode('utf-8', 'replace').encode('utf-8')
elif isinstance(obj, unicode):
return obj.encode('utf-8', 'replace')
if six.PY2:
if isinstance(obj, str):
return obj.decode('utf-8', 'replace').encode('utf-8')
elif isinstance(obj, six.text_type):
return obj.encode('utf-8', 'replace')
return obj
def ensureSerializable(obj):
......@@ -421,8 +424,8 @@ def getFieldDefault(form, field, key, value=MARKER):
if value is MARKER:
# use marker because default value can be intentionally empty string
value = field.get_value('default', request=REQUEST, REQUEST=REQUEST)
if field.has_value("unicode") and field.get_value("unicode") and isinstance(value, unicode):
value = unicode(value, form.get_form_encoding())
if six.PY2 and field.has_value("unicode") and field.get_value("unicode") and isinstance(value, six.text_type):
value = value.decode(form.get_form_encoding())
if getattr(value, 'translate', None) is not None:
return "%s" % value
return value
......@@ -476,7 +479,7 @@ def renderField(traversed_document, field, form, value=MARKER, meta_type=None,
selected_language = erp5_ui.get_selected_language()
result["translate_title_href"] = '%s/manage_messages?%s' % (
'/'.join(erp5_ui.getPhysicalPath()[2:]),
urllib.urlencode({"regex": "^%s$" % field.title(),
urlencode({"regex": "^%s$" % field.title(),
"lang": selected_language})
)
......@@ -484,7 +487,7 @@ def renderField(traversed_document, field, form, value=MARKER, meta_type=None,
if field_description:
result["translate_description_href"] = '%s/manage_messages?%s' % (
'/'.join(erp5_ui.getPhysicalPath()[2:]),
urllib.urlencode({"regex": "^%s$" % field_description,
urlencode({"regex": "^%s$" % field_description,
"lang": selected_language})
)
......@@ -666,11 +669,11 @@ def renderField(traversed_document, field, form, value=MARKER, meta_type=None,
"script_id": script.id,
"relative_url": getRealRelativeUrl(traversed_document).replace("/", "%2F"),
"view": "Base_viewRelatedObjectList",
"extra_param_json": urlsafe_b64encode(
"extra_param_json": bytes2str(urlsafe_b64encode(str2bytes(
json.dumps(ensureSerializable({
'original_form_id': form.id,
'field_id': field.id
})))
})))))
}
})
......@@ -719,7 +722,7 @@ def renderField(traversed_document, field, form, value=MARKER, meta_type=None,
or field.get_value("editable_columns"))]
all_column_list = [(name, title) for name, title in field.get_value("all_columns")]
catalog_column_list = [(name, title)
for name, title in OrderedDict(column_list + all_column_list).items()
for name, title in six.iteritems(OrderedDict(column_list + all_column_list))
if sql_catalog.isValidColumn(name)]
# try to get specified searchable columns and fail back to all searchable columns
......@@ -791,10 +794,10 @@ def renderField(traversed_document, field, form, value=MARKER, meta_type=None,
"relative_url": getRealRelativeUrl(traversed_document).replace("/", "%2F"),
"form_relative_url": "%s/%s" % (form_relative_url, field.id),
"list_method": list_method_name,
"default_param_json": urlsafe_b64encode(
json.dumps(ensureSerializable(list_method_query_dict))),
"extra_param_json": urlsafe_b64encode(
json.dumps(ensureSerializable(extra_param_dict)))
"default_param_json": bytes2str(urlsafe_b64encode(str2bytes(
json.dumps(ensureSerializable(list_method_query_dict))))),
"extra_param_json": bytes2str(urlsafe_b64encode(str2bytes(
json.dumps(ensureSerializable(extra_param_dict)))))
}
# once we imprint `default_params` into query string of 'list method' we
# don't want them to propagate to the query as well
......@@ -813,7 +816,7 @@ def renderField(traversed_document, field, form, value=MARKER, meta_type=None,
"script_id": script.id,
"relative_url": traversed_document.getRelativeUrl().replace("/", "%2F"),
"list_method": list_method_name,
"default_param_json": urlsafe_b64encode(json.dumps(ensureSerializable(list_method_query_dict)))
"default_param_json": bytes2str(urlsafe_b64encode(str2bytes(json.dumps(ensureSerializable(list_method_query_dict)))))
}
list_method_query_dict = {}
"""
......@@ -1057,12 +1060,12 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
"script_id": script.id,
"relative_url": getRealRelativeUrl(traversed_document).replace("/", "%2F"),
"view": "Base_viewRelatedObjectList",
"extra_param_json": urlsafe_b64encode(
"extra_param_json": bytes2str(urlsafe_b64encode(str2bytes(
json.dumps(ensureSerializable({
'proxy_listbox_id': x,
'original_form_id': extra_param_json['original_form_id'],
'field_id': extra_param_json['field_id']
})))
})))))
}) for x, y in proxy_form_id_list],
"first_item": 1,
"required": 0,
......@@ -1080,12 +1083,12 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
"script_id": script.id,
"relative_url": getRealRelativeUrl(traversed_document).replace("/", "%2F"),
"view": "Base_viewRelatedObjectList",
"extra_param_json": urlsafe_b64encode(
"extra_param_json": bytes2str(urlsafe_b64encode(str2bytes(
json.dumps(ensureSerializable({
'proxy_listbox_id': REQUEST.get('proxy_listbox_id', None),
'original_form_id': extra_param_json['original_form_id'],
'field_id': extra_param_json['field_id']
})))
})))))
}
# Go through all groups ("left", "bottom", "hidden" etc.) and add fields from
......@@ -1283,7 +1286,7 @@ def renderFormDefinition(form, response_dict):
def statusLevelToString(level):
"""Transform any level format to lowercase string representation"""
if isinstance(level, (str, unicode)):
if isinstance(level, (str, six.text_type)):
if level.lower() == "error":
return "error"
elif level.lower().startswith("warn"):
......@@ -1584,7 +1587,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
"script_id": script.id, # this script (ERP5Document_getHateoas)
"relative_url": getRealRelativeUrl(traversed_document).replace("/", "%2F"),
"view": erp5_action_list[-1]['name'],
"extra_param_json": urlsafe_b64encode(json.dumps(ensureSerializable(extra_param_json)))
"extra_param_json": bytes2str(urlsafe_b64encode(str2bytes(json.dumps(ensureSerializable(extra_param_json)))))
}
if erp5_action_list:
......@@ -1738,7 +1741,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
# Those parameter will be send back during the listbox submission
# to ensure fetching the same lines
listbox_query_param_json = urlsafe_b64encode(json.dumps(ensureSerializable({
listbox_query_param_json = bytes2str(urlsafe_b64encode(str2bytes(json.dumps(ensureSerializable({
'form_relative_url': form_relative_url,
'list_method': list_method,
'default_param_json': default_param_json,
......@@ -1751,7 +1754,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
'relative_url': relative_url,
'group_by': group_by,
'sort_on': sort_on
})))
})))))
# set 'here' for field rendering which contain TALES expressions
REQUEST.set('here', traversed_document)
......@@ -1925,7 +1928,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
column_list = [(name, title) for name, title in source_field.get_value("columns") if name in select_list]
all_column_list = [(name, title) for name, title in source_field.get_value("all_columns") if name in select_list]
selection_kw['columns'] = [(name, title)
for name, title in OrderedDict(column_list + all_column_list).items()]
for name, title in six.iteritems(OrderedDict(column_list + all_column_list))]
else:
selection_kw['columns'] = []
......@@ -2197,8 +2200,8 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
"script_id": script.id,
"relative_url": url_parameter_dict['view_kw']['jio_key'].replace("/", "%2F"),
"view": url_parameter_dict['view_kw']['view'],
"extra_param_json": urlsafe_b64encode(
json.dumps(ensureSerializable(extra_url_param_dict)))
"extra_param_json": bytes2str(urlsafe_b64encode(str2bytes(
json.dumps(ensureSerializable(extra_url_param_dict)))))
}
# endfor select
......@@ -2415,8 +2418,8 @@ if mode == 'url_generator':
keep_items_json = None
else:
generator_key = 'traverse_generator_action'
keep_items_json = urlsafe_b64encode(
json.dumps(ensureSerializable(keep_items)))
keep_items_json = bytes2str(urlsafe_b64encode(str2bytes(
json.dumps(ensureSerializable(keep_items)))))
return url_template_dict[generator_key] % {
"root_url": site_root.absolute_url(),
"script_id": 'ERP5Document_getHateoas',
......
......@@ -3,6 +3,7 @@ from Products.Formulator.Errors import FormValidationError
from Products.ERP5Type.Core.Workflow import ValidationFailed
from Products.ERP5Type.Message import translateString
from erp5.component.module.Log import WARNING
import six
portal = context.getPortalObject()
request = REQUEST or context.REQUEST
......@@ -43,7 +44,7 @@ for f in form.get_fields():
listbox = request.get('listbox') # XXX: hardcoded field name
if listbox is not None:
listbox_line_list = []
for key, value in sorted(listbox.iteritems()):
for key, value in sorted(six.iteritems(listbox)):
value['listbox_key'] = key
listbox_line_list.append(value)
doaction_param_list['listbox'] = tuple(listbox_line_list)
......
......@@ -15,12 +15,13 @@ import DateTime
import StringIO
import json
import re
import urllib
from six.moves.urllib.parse import quote, quote_plus
import mock
from zope.globalrequest import setRequest # pylint: disable=no-name-in-module, import-error
from Acquisition import aq_base
from Products.ERP5Form.Selection import Selection, DomainSelection
from Products.ERP5Type.Utils import ensure_list, str2unicode, unicode2str
def changeSkin(skin_name):
......@@ -123,7 +124,7 @@ def do_fake_request(request_method, headers=None, data=()):
if data and request_method.upper() == 'GET':
# see: GET http://www.cgi101.com/book/ch3/text.html
env['QUERY_STRING'] = '&'.join(
'{}={}'.format(urllib.quote_plus(key), urllib.quote(value))
'{}={}'.format(quote_plus(key), quote(value))
for key, value in data
)
......@@ -132,7 +133,7 @@ def do_fake_request(request_method, headers=None, data=()):
env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
for key, value in data:
body_stream.write('{}={!s}&'.format(
urllib.quote_plus(key), urllib.quote(value)))
quote_plus(key), quote(value)))
request = HTTPRequest(body_stream, env, HTTPResponse())
if data and request_method.upper() == 'POST':
......@@ -346,21 +347,21 @@ class TestERP5Document_getHateoas_mode_root(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['view'][0]['href'],
"%s/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_object_view'][0]['href'],
"%s/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['action_object_view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_workflow'][0]['href'],
"%s/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=custom_action_no_dialog" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_workflow'][0]['title'], "Custom Action No Dialog")
self.assertEqual(result_dict['_links']['action_workflow'][0]['name'], "custom_action_no_dialog")
......@@ -374,17 +375,17 @@ class TestERP5Document_getHateoas_mode_root(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['action_object_new_content_action']['href'],
"%s/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=create_a_document" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_new_content_action']['title'], "Create a Document")
self.assertEqual(result_dict['_links']['action_object_new_content_action']['name'], "create_a_document")
self.assertEqual(result_dict['_links']['type']['href'], 'urn:jio:get:portal_types/%s' % document.getPortalType())
self.assertEqual(result_dict['_links']['type']['name'], document.getPortalType())
self.assertEqual(result_dict['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(unicode2str(result_dict['title']), document.getTitle())
self.assertEqual(result_dict['_links']['traversed_document']['href'], 'urn:jio:get:%s' % document.getRelativeUrl())
self.assertEqual(result_dict['_links']['traversed_document']['name'], document.getRelativeUrl())
self.assertEqual(result_dict['_links']['traversed_document']['title'], document.getTitle().decode("UTF-8"))
self.assertEqual(result_dict['_links']['traversed_document']['title'], str2unicode(document.getTitle()))
self.assertEqual(result_dict['_debug'], "root")
@simulate('Base_getRequestUrl', '*args, **kwargs',
......@@ -413,21 +414,21 @@ class TestERP5Document_getHateoas_mode_root(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['view'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_object_view'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['action_object_view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_workflow'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=embed_action" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_workflow'][0]['title'], "Embed")
self.assertEqual(result_dict['_links']['action_workflow'][0]['name'], "embed_action")
......@@ -440,7 +441,7 @@ class TestERP5Document_getHateoas_mode_root(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['action_object_new_content_action']['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=create_a_document" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_new_content_action']['title'], "Create a Document")
self.assertEqual(result_dict['_links']['action_object_new_content_action']['name'], "create_a_document")
......@@ -457,10 +458,10 @@ class TestERP5Document_getHateoas_mode_root(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['traverse']['templated'], True)
self.assertEqual(result_dict['_links']['traverse']['name'], "Traverse")
self.assertEqual(result_dict['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(unicode2str(result_dict['title']), document.getTitle())
self.assertEqual(result_dict['_links']['traversed_document']['href'], 'urn:jio:get:%s' % document.getRelativeUrl())
self.assertEqual(result_dict['_links']['traversed_document']['name'], document.getRelativeUrl())
self.assertEqual(result_dict['_links']['traversed_document']['title'], document.getTitle().decode("UTF-8"))
self.assertEqual(result_dict['_links']['traversed_document']['title'], str2unicode(document.getTitle()))
self.assertEqual(result_dict['default_view'], "view")
self.assertEqual(result_dict['_debug'], "root")
......@@ -502,21 +503,21 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['view'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_object_view'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['action_object_view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_workflow'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=custom_action_no_dialog" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_workflow'][0]['title'], "Custom Action No Dialog")
self.assertEqual(result_dict['_links']['action_workflow'][0]['name'], "custom_action_no_dialog")
......@@ -529,17 +530,17 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['action_object_new_content_action']['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=create_a_document" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_new_content_action']['title'], "Create a Document")
self.assertEqual(result_dict['_links']['action_object_new_content_action']['name'], "create_a_document")
self.assertEqual(result_dict['_links']['type']['href'], 'urn:jio:get:portal_types/%s' % document.getPortalType())
self.assertEqual(result_dict['_links']['type']['name'], document.getPortalType())
self.assertEqual(result_dict['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(unicode2str(result_dict['title']), document.getTitle())
self.assertEqual(result_dict['_links']['traversed_document']['href'], 'urn:jio:get:%s' % document.getRelativeUrl())
self.assertEqual(result_dict['_links']['traversed_document']['name'], document.getRelativeUrl())
self.assertEqual(result_dict['_links']['traversed_document']['title'], document.getTitle().decode("UTF-8"))
self.assertEqual(result_dict['_links']['traversed_document']['title'], str2unicode(document.getTitle()))
self.assertEqual(result_dict['_debug'], "traverse")
@simulate('Base_getRequestUrl', '*args, **kwargs',
......@@ -595,28 +596,28 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['view'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_object_view'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['action_object_view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_workflow'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=custom_action_no_dialog&extra_param_json=eyJmb3JtX2lkIjogIkZvb192aWV3In0=" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_workflow'][0]['title'], "Custom Action No Dialog")
self.assertEqual(result_dict['_links']['action_workflow'][0]['name'], "custom_action_no_dialog")
self.assertEqual(result_dict['_links']['action_object_jio_jump']['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=jump_query" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_jio_jump']['title'], "Queries")
self.assertEqual(result_dict['_links']['action_object_jio_jump']['name'], "jump_query")
......@@ -629,17 +630,17 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['action_object_new_content_action']['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=create_a_document&extra_param_json=eyJmb3JtX2lkIjogIkZvb192aWV3In0=" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_new_content_action']['title'], "Create a Document")
self.assertEqual(result_dict['_links']['action_object_new_content_action']['name'], "create_a_document")
self.assertEqual(result_dict['_links']['type']['href'], 'urn:jio:get:portal_types/%s' % document.getPortalType())
self.assertEqual(result_dict['_links']['type']['name'], document.getPortalType())
self.assertEqual(result_dict['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(unicode2str(result_dict['title']), document.getTitle())
self.assertEqual(result_dict['_links']['traversed_document']['href'], 'urn:jio:get:%s' % document.getRelativeUrl())
self.assertEqual(result_dict['_links']['traversed_document']['name'], document.getRelativeUrl())
self.assertEqual(result_dict['_links']['traversed_document']['title'], document.getTitle().decode("UTF-8"))
self.assertEqual(result_dict['_links']['traversed_document']['title'], str2unicode(document.getTitle()))
self.assertEqual(result_dict['_debug'], "traverse")
# Check embedded form rendering
......@@ -683,7 +684,7 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['href'], 'urn:jio:get:%s' % document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['name'], document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['title'], document.getTitle().decode("UTF-8"))
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['title'], str2unicode(document.getTitle()))
self.assertEqual(result_dict['_embedded']['_view']['_links']['self']['href'], "%s/%s/Foo_view" % (
self.portal.absolute_url(),
......@@ -895,11 +896,11 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['view'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['view'][0]['name'], "view")
self.assertEqual(result_dict['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(unicode2str(result_dict['title']), document.getTitle())
self.assertEqual(result_dict['_debug'], "traverse")
# Check embedded form rendering
......@@ -920,7 +921,7 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['href'], 'urn:jio:get:%s' % document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['name'], document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['title'], document.getTitle().decode("UTF-8"))
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['title'], str2unicode(document.getTitle()))
self.assertEqual(result_dict['_embedded']['_view']['_links']['self']['href'], "%s/%s/Foo_view" % (
self.portal.absolute_url(),
......@@ -968,28 +969,28 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['view'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_object_view'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['action_object_view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_workflow'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=custom_action_no_dialog&extra_param_json=eyJmb3JtX2lkIjogIkJhc2Vfdmlld01ldGFkYXRhIn0=" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_workflow'][0]['title'], "Custom Action No Dialog")
self.assertEqual(result_dict['_links']['action_workflow'][0]['name'], "custom_action_no_dialog")
self.assertEqual(result_dict['_links']['action_object_jio_jump']['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=jump_query" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_jio_jump']['title'], "Queries")
self.assertEqual(result_dict['_links']['action_object_jio_jump']['name'], "jump_query")
......@@ -1002,14 +1003,14 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_links']['action_object_new_content_action']['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=create_a_document&extra_param_json=eyJmb3JtX2lkIjogIkJhc2Vfdmlld01ldGFkYXRhIn0=" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['_links']['action_object_new_content_action']['title'], "Create a Document")
self.assertEqual(result_dict['_links']['action_object_new_content_action']['name'], "create_a_document")
self.assertEqual(result_dict['_links']['type']['href'], 'urn:jio:get:portal_types/%s' % document.getPortalType())
self.assertEqual(result_dict['_links']['type']['name'], document.getPortalType())
self.assertEqual(result_dict['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(unicode2str(result_dict['title']), document.getTitle())
self.assertEqual(result_dict['_debug'], "traverse")
# Check embedded form rendering
......@@ -1030,7 +1031,7 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['href'], 'urn:jio:get:%s' % document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['name'], document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['title'], document.getTitle().decode("UTF-8"))
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['title'], str2unicode(document.getTitle()))
self.assertEqual(result_dict['_embedded']['_view']['_links']['self']['href'], "%s/Base_viewMetadata" %
document.getRelativeUrl())
......@@ -1198,7 +1199,7 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['_embedded']['_view']['report_section_list'][1]['_links']['traversed_document']['href'], 'urn:jio:get:%s' % document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['report_section_list'][1]['_links']['traversed_document']['name'], document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['report_section_list'][1]['_links']['traversed_document']['title'], document.getTitle().decode("UTF-8"))
self.assertEqual(result_dict['_embedded']['_view']['report_section_list'][1]['_links']['traversed_document']['title'], str2unicode(document.getTitle()))
self.assertEqual(result_dict['_embedded']['_view']['report_section_list'][1]['_links']['form_definition']['href'], 'urn:jio:get:portal_skins/erp5_core/Base_viewWorkflowHistory')
self.assertEqual(result_dict['_embedded']['_view']['report_section_list'][1]['_links']['form_definition']['name'], 'Base_viewWorkflowHistory')
......@@ -1252,14 +1253,14 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
# self.assertEqual(result_dict['_links']['view'][0]['href'],
# "%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=consistency" % (
# self.portal.absolute_url(),
# urllib.quote_plus("portal_skins/erp5_ui_test/Foo_view")))
# quote_plus("portal_skins/erp5_ui_test/Foo_view")))
# self.assertEqual(result_dict['_links']['view'][0]['title'], "Consistency")
# self.assertEqual(result_dict['_links']['view'][0]['name'], "consistency")
# self.assertEqual(result_dict['_links']['action_object_view'][0]['href'],
# "%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=consistency" % (
# self.portal.absolute_url(),
# urllib.quote_plus("portal_skins/erp5_ui_test/Foo_view")))
# quote_plus("portal_skins/erp5_ui_test/Foo_view")))
# self.assertEqual(result_dict['_links']['action_object_view'][0]['title'], "Consistency")
# self.assertEqual(result_dict['_links']['action_object_view'][0]['name'], "consistency")
......@@ -1300,7 +1301,7 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
)
result_dict = json.loads(result)
self.assertEqual(result_dict['title'].encode('UTF-8'), document.getTitle())
self.assertEqual(unicode2str(result_dict['title']), document.getTitle())
self.assertEqual(
result_dict['_embedded']['_view']['_embedded']['form_definition']['pt'],
'form_view'
......@@ -2068,7 +2069,7 @@ return url
# Test the URL value
self.assertEqual(result_dict['_embedded']['contents'][0]['title']['url_value']['command'], 'raw')
self.assertEqual(result_dict['_embedded']['contents'][0]['title']['url_value']['options'].keys(), [u'url', u'reset'])
self.assertEqual(ensure_list(result_dict['_embedded']['contents'][0]['title']['url_value']['options'].keys()), [u'url', u'reset'])
self.assertEqual(result_dict['_embedded']['contents'][0]['title']['url_value']['options']['url'], 'https://officejs.com')
# Test if the value of the column is with right key
......@@ -2164,7 +2165,7 @@ return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id
self.assertEqual(2, len(result_dict['_embedded']['contents']))
# Test the listbox_uid parameter
self.assertEqual(result_dict['_embedded']['contents'][0]['listbox_uid:list']['key'], 'listbox_uid:list')
self.assertEqual(document_list[0].getReference(), result_dict['_embedded']['contents'][0]['reference'].encode('UTF-8'))
self.assertEqual(document_list[0].getReference(), unicode2str(result_dict['_embedded']['contents'][0]['reference']))
# There is a count method on the listbox
self.assertEqual(result_dict['_embedded']['count'], 0)
......@@ -2179,10 +2180,10 @@ return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id
)
result_dict = json.loads(result)
self.assertEqual(len(result_dict['_embedded']['contents']), 2)
self.assertEqual(result_dict['_embedded']['contents'][0]['title'].encode('utf-8'), document_list[0].getTitle())
self.assertEqual(unicode2str(result_dict['_embedded']['contents'][0]['title']), document_list[0].getTitle())
self.assertEqual(result_dict['_embedded']['contents'][0]['Foo_getLocalTitle'], None)
self.assertEqual(result_dict['_embedded']['contents'][0]['getTotalQuantity'], 0)
self.assertEqual(result_dict['_embedded']['contents'][1]['title'].encode('utf-8'), document_list[1].getTitle())
self.assertEqual(unicode2str(result_dict['_embedded']['contents'][1]['title']), document_list[1].getTitle())
self.assertEqual(result_dict['_embedded']['contents'][1]['Foo_getLocalTitle'], None)
self.assertEqual(result_dict['_embedded']['contents'][1]['getTotalQuantity'], 0)
# No count if not in the listbox context currently
......@@ -2621,21 +2622,21 @@ class TestERP5Document_getHateoas_mode_bulk(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['result_list'][0]['_links']['view'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['result_list'][0]['_links']['view'][0]['title'], "View")
self.assertEqual(result_dict['result_list'][0]['_links']['view'][0]['name'], "view")
self.assertEqual(result_dict['result_list'][0]['_links']['action_object_view'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['result_list'][0]['_links']['action_object_view'][0]['title'], "View")
self.assertEqual(result_dict['result_list'][0]['_links']['action_object_view'][0]['name'], "view")
self.assertEqual(result_dict['result_list'][0]['_links']['action_workflow'][0]['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=custom_action_no_dialog&extra_param_json=eyJmb3JtX2lkIjogIkZvb192aWV3In0=" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['result_list'][0]['_links']['action_workflow'][0]['title'], "Custom Action No Dialog")
self.assertEqual(result_dict['result_list'][0]['_links']['action_workflow'][0]['name'], "custom_action_no_dialog")
......@@ -2648,14 +2649,14 @@ class TestERP5Document_getHateoas_mode_bulk(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['result_list'][0]['_links']['action_object_new_content_action']['href'],
"%s/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=create_a_document&extra_param_json=eyJmb3JtX2lkIjogIkZvb192aWV3In0=" % (
self.portal.absolute_url(),
urllib.quote_plus(document.getRelativeUrl())))
quote_plus(document.getRelativeUrl())))
self.assertEqual(result_dict['result_list'][0]['_links']['action_object_new_content_action']['title'], "Create a Document")
self.assertEqual(result_dict['result_list'][0]['_links']['action_object_new_content_action']['name'], "create_a_document")
self.assertEqual(result_dict['result_list'][0]['_links']['type']['href'], 'urn:jio:get:portal_types/%s' % document.getPortalType())
self.assertEqual(result_dict['result_list'][0]['_links']['type']['name'], document.getPortalType())
self.assertEqual(result_dict['result_list'][0]['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(unicode2str(result_dict['result_list'][0]['title']), document.getTitle())
self.assertEqual(result_dict['result_list'][0]['_debug'], "traverse")
# Check embedded form rendering
......@@ -2676,7 +2677,7 @@ class TestERP5Document_getHateoas_mode_bulk(ERP5HALJSONStyleSkinsMixin):
self.assertEqual(result_dict['result_list'][0]['_embedded']['_view']['_links']['traversed_document']['href'], 'urn:jio:get:%s' % document.getRelativeUrl())
self.assertEqual(result_dict['result_list'][0]['_embedded']['_view']['_links']['traversed_document']['name'], document.getRelativeUrl())
self.assertEqual(result_dict['result_list'][0]['_embedded']['_view']['_links']['traversed_document']['title'], document.getTitle().decode("UTF-8"))
self.assertEqual(result_dict['result_list'][0]['_embedded']['_view']['_links']['traversed_document']['title'], str2unicode(document.getTitle()))
self.assertEqual(result_dict['result_list'][0]['_embedded']['_view']['_links']['self']['href'], "%s/%s/Foo_view" % (
self.portal.absolute_url(),
......@@ -2738,8 +2739,10 @@ class TestERP5Document_getHateoas_mode_worklist(ERP5HALJSONStyleSkinsMixin):
self.assertTrue(work_list[0]['count'] > 0)
self.assertEqual(work_list[0]['name'], 'Draft To Validate')
self.assertNotIn('module', work_list[0])
self.assertEqual(work_list[0]['href'], 'urn:jio:allDocs?query=portal_type%3A%28%22Bar%22%20OR%20%22Foo%22%29%20AND%20simulation_state%3A%22draft%22')
self.assertIn(work_list[0]['href'], (
'urn:jio:allDocs?query=portal_type%3A%28%22Bar%22%20OR%20%22Foo%22%29%20AND%20simulation_state%3A%22draft%22',
'urn:jio:allDocs?query=simulation_state%3A%22draft%22%20AND%20portal_type%3A%28%22Bar%22%20OR%20%22Foo%22%29',
))
self.assertEqual(result_dict['_debug'], "worklist")
......@@ -2847,7 +2850,7 @@ if translation_service is not None :\n\
if not encoding:\n\
return translation_service.translate(catalog, msg, lang=lang, **kw)\n\
msg = translation_service.translate(catalog, msg, lang=lang, **kw)\n\
if same_type(msg, u''):\n\
if str==bytes and same_type(msg, u''):\n\
msg = msg.encode(encoding)\n\
return msg\n\
except AttributeError:\n\
......@@ -2911,7 +2914,7 @@ return msg"
self.assertEqual(result_dict['_links']['type']['href'], 'urn:jio:get:portal_types/%s' % document.getPortalType())
self.assertEqual(result_dict['_links']['type']['name'], 'Foo_zhongwen')
self.assertEqual(result_dict['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(unicode2str(result_dict['title']), document.getTitle())
self.assertEqual(result_dict['_debug'], "root")
@simulate('Base_getRequestUrl', '*args, **kwargs',
......@@ -2939,7 +2942,10 @@ return msg"
self.assertEqual(work_list[0]['name'], 'daiyanzhen')
self.assertEqual(work_list[0]['count'], 1)
self.assertNotIn('module', work_list[0])
self.assertEqual(work_list[0]['href'], 'urn:jio:allDocs?query=portal_type%3A%28%22Bar%22%20OR%20%22Foo%22%29%20AND%20simulation_state%3A%22draft%22')
self.assertIn(work_list[0]['href'], (
'urn:jio:allDocs?query=portal_type%3A%28%22Bar%22%20OR%20%22Foo%22%29%20AND%20simulation_state%3A%22draft%22',
'urn:jio:allDocs?query=simulation_state%3A%22draft%22%20AND%20portal_type%3A%28%22Bar%22%20OR%20%22Foo%22%29',
))
self.assertEqual(result_dict['_debug'], "worklist")
......@@ -3008,7 +3014,7 @@ return msg"
result_dict = json.loads(result)
# The document title includes 'ö' at the last in this test class, so calling decode("UTF-8")
self.assertEqual(result_dict['_links']['parent'],
{"href": "urn:jio:get:%s" % document.getRelativeUrl(), "name": document.getTitle().decode("UTF-8")})
{"href": "urn:jio:get:%s" % document.getRelativeUrl(), "name": str2unicode(document.getTitle())})
# make sure traversing the child document does not adding the parent title translation
self.assertFalse(message_catalog.message_exists(document_title))
......
......@@ -273,9 +273,9 @@
</span>
<span style="color: green;">&nbsp;:&nbsp;</span>
<tal:block tal:condition="show_search_line">
<span tal:condition="python: isinstance(original_value,(float, int, long))"
<span tal:condition="python: isinstance(original_value, modules['six'].integer_types + (float,))"
id="data_short" tal:content="python: original_value" />
<span tal:condition="python: not isinstance(original_value,(float, int, long))"
<span tal:condition="python: not isinstance(original_value, modules['six'].integer_types + (float,))"
id="data_short" tal:content="data_short" />
</tal:block>
<tal:block tal:condition="not:show_search_line">
......@@ -302,7 +302,7 @@
<tal:block tal:condition="python: original_value is not None">
<span align="right"
tal:define="original_value python: valueZ[0]; processed_value python: valueZ[1]"
tal:attributes="align python: isinstance(original_value, (float, int, long)) and 'right' or 'left'"
tal:attributes="align python: isinstance(original_value, modules['six'].integer_types + (float,)) and 'right' or 'left'"
tal:content="structure processed_value" />
</tal:block>
</div>
......
......@@ -100,7 +100,7 @@
-->
<tal:block metal:define-macro="cell_value">
<tal:block tal:define="is_list python:same_type(value, []) or same_type(value, ());
is_float python: isinstance(value, (int, long, float));">
is_float python: isinstance(value, modules['six'].integer_types + (float,));">
<tal:block tal:condition="python: is_list">
......@@ -116,7 +116,7 @@
</tal:block>
<tal:block tal:condition="python: value is not None and not is_list">
<tal:block tal:condition="is_float">
<tal:block tal:condition="python: isinstance(value, (int, long))">
<tal:block tal:condition="python: isinstance(value, modules['six'].integer_types)">
<table:table-cell tal:define="field python: editable_fields.get(column_id, None)"
tal:attributes="office:value value;
table:style-name string:${style_prefix}figure"
......
......@@ -18,7 +18,7 @@
<tal:block tal:condition="not:listboxline/isTitleLine">
<table:table-row tal:attributes="table:style-name python: listboxline.isStatLine() and 'listbox_stat_row' or 'listbox_data_row'">
<tal:block tal:condition="python: listboxline.isDataLine()">
<tal:block tal:repeat="empty_index python: xrange(0, max_section_depth)">
<tal:block tal:repeat="empty_index python: range(0, max_section_depth)">
<table:table-cell table:style-name='report-column-title'
table:number-columns-spanned='1'
office:value-type='string'>
......@@ -36,7 +36,7 @@
</tal:block>
<tal:block tal:condition="python: listboxline.isStatLine() or listboxline.isSummaryLine()">
<tal:block tal:repeat="empty_index python: xrange(0, listboxline.getSectionDepth())">
<tal:block tal:repeat="empty_index python: range(0, listboxline.getSectionDepth())">
<table:table-cell table:style-name='report-column-title'
table:number-columns-spanned='1'
office:value-type='string'>
......@@ -48,7 +48,7 @@
office:value-type='string'>
<text:p tal:content="listboxline/getSectionName"/>
</table:table-cell>
<tal:block tal:repeat="empty_index python: xrange(listboxline.getSectionDepth()+1, max_section_depth)">
<tal:block tal:repeat="empty_index python: range(listboxline.getSectionDepth()+1, max_section_depth)">
<table:table-cell table:style-name='report-column-title'
table:number-columns-spanned='1'
office:value-type='string'>
......
......@@ -70,7 +70,7 @@
<tal:block tal:condition="not:display_header">
<table:table-row table:style-name='listbox_header_row'>
<tal:block tal:repeat="empty_index python: xrange(0, max_section_depth)">
<tal:block tal:repeat="empty_index python: range(0, max_section_depth)">
<table:table-cell table:style-name='report-column-title'
table:number-columns-spanned='1'
office:value-type='string'>
......
......@@ -110,7 +110,7 @@
<style:style style:name="date_with_time" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="date_style">
<style:table-cell-properties style:vertical-align='middle' style:repeat-content='false' style:text-align-source='fix' fo:border-right='0.002cm solid #000000' />
</style:style>
<tal:block tal:repeat="precision python: xrange(0,here.Base_getODSMaximumSupportedPrecision())">
<tal:block tal:repeat="precision python: range(0,here.Base_getODSMaximumSupportedPrecision())">
<tal:block tal:define="figure_data_precision_style_name string:figure_data_precision_${precision}">
<number:number-style style:name="figure_data_precision_X" tal:attributes="style:name figure_data_precision_style_name">
<number:number number:decimal-places="X" number:min-integer-digits="1" number:grouping="true" tal:attributes="number:decimal-places precision"/>
......
......@@ -118,11 +118,11 @@
column_id python: column_item[0]">
<tal:block tal:condition="python: column_property is not None">
<table:table-cell table:style-name='listbox-table.A1' office:value-type='string'>
<tal:block tal:condition="python: untranslatable_columns_dict.has_key(column_id)">
<tal:block tal:condition="python: column_id in untranslatable_columns_dict">
<text:p text:style-name='listbox-header'
tal:content="python: column_property"/>
</tal:block>
<tal:block tal:condition="python: not(untranslatable_columns_dict.has_key(column_id))">
<tal:block tal:condition="python: column_id not in untranslatable_columns_dict">
<text:p text:style-name='listbox-header'
tal:content="python: here.Base_translateString(column_property)"/>
</tal:block>
......
......@@ -139,34 +139,6 @@
<td>2000</td>
<td></td>
</tr>
<!-- Second loader while updating the page -->
<!--
<tr>
<td>waitForElementPresent</td>
<td>//h1[@class="ui-title"]//a[contains(@class, "ui-icon-spinner")]</td>
<td></td>
</tr>
<!-- Save Button is disabled -->
<!--
<tr>
<td>verifyElementPresent</td>
<td>//button[@data-i18n="Save"][contains(@class, "ui-disabled")]</td>
<td></td>
</tr>
<tr>
<td>waitForElementNotPresent</td>
<td>//h1[@class="ui-title"]//a[contains(@class, "ui-icon-spinner")]</td>
<td></td>
</tr>
<tr>
<td>verifyElementPresent</td>
<td>//button[@data-i18n="Save"][contains(@class, "ui-icon-check")]</td>
<td></td>
</tr>
<tr>
<td colspan="3"><p></p></td>
</tr>
<-->
</tal:block>
<tal:block metal:define-macro="click_to_align_center">
<tr>
......
......@@ -3,6 +3,7 @@ import datetime
import time
import json
from DateTime import DateTime
import six
response = container.REQUEST.RESPONSE
start = time.time()
......@@ -32,7 +33,7 @@ for line in results.tuples():
v = v.isoformat()
elif isinstance(v, Decimal):
v = float(v)
elif isinstance(v, (long, int, float)) and not isSafeInteger(v):
elif isinstance(v, six.integer_types + (float,)) and not isSafeInteger(v):
# if numbers are too large to be handled by javascript, we simply return them
# as string, this will still not work for pivot table, but at least the spreadsheet
# will not display truncated values.
......
......@@ -40,6 +40,10 @@ from lxml import etree
from zLOG import LOG, ERROR, INFO
from erp5.component.tool.WebServiceTool import ConnectionError
from Products.ERP5Type.Cache import CachingMethod
import six
if six.PY3:
long = int
ID_SEPARATOR="-"
......
......@@ -11,11 +11,7 @@ import socket
import sys
from tempfile import TemporaryFile
import time
from six.moves.urllib.parse import quote
try:
from urllib import splitport
except ImportError: # six.PY3
from urllib.parse import splitport
from six.moves.urllib.parse import quote, urlsplit
from waitress.server import create_server
import ZConfig
......@@ -268,8 +264,7 @@ def runwsgi():
new_limit = (cur_limit[1], cur_limit[1])
resource.setrlimit(resource.RLIMIT_NOFILE, new_limit)
ip, port = splitport(args.address)
port = int(port)
port = urlsplit('//' + args.address).port
createServer(
app_wrapper(
large_file_threshold=args.large_file_threshold,
......
......@@ -9,7 +9,7 @@
cell_number python: len(module_category_list);
row_number python: (cell_number/max_per_line+1)"
class="access_tab_table">
<tr tal:repeat="row python: xrange(row_number)">
<tr tal:repeat="row python: range(row_number)">
<tal:block tal:repeat="module_category python: module_category_list[(row*max_per_line):((row+1)*max_per_line)]">
<td>
<div style="width:25%; min-width:150px; float:left;"
......
......@@ -330,7 +330,7 @@
error python: value[2]"
class="DataA" align="left"
tal:attributes="class python: error and (css + 'Error') or css;
align python: isinstance(original_value, (float, int, long)) and 'right' or 'left'">
align python: isinstance(original_value, modules['six'].integer_types + (float,)) and 'right' or 'left'">
<input tal:condition="not: repeat/value/index"
type="hidden" value="1" name="listbox_uid:list"
tal:attributes="value python: line.getUid() or '';
......@@ -348,7 +348,7 @@
<tal:block tal:repeat="value here/getStatValueList">
<td class="Data" align="left"
tal:define="original_value python: value[0]; processed_value python: value[1]"
tal:attributes="align python: isinstance(original_value, (float, int, long)) and 'right' or 'left'"
tal:attributes="align python: isinstance(original_value, modules['six'].integer_types + (float,)) and 'right' or 'left'"
tal:content="structure processed_value" />
</tal:block>
</tr>
......
......@@ -38,7 +38,7 @@ import os
import sys
import tempfile
import zipfile
import popen2
import subprocess
from six.moves import urllib
from six.moves import cStringIO as StringIO
......@@ -93,8 +93,12 @@ elif odfpy:
fd, file_name = tempfile.mkstemp()
os.write(fd, odf_file_content)
os.close(fd)
stdout, stdin = popen2.popen4('odflint %s' % file_name)
stdin.close()
process = subprocess.Popen(
['odflint', file_name],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
stdout, _ = process.communicate()
error_list = ''
for line in stdout:
if line.startswith('Error: '):
......
......@@ -567,6 +567,8 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
if str is bytes:
bytes2str = str2bytes = lambda s: s
def str2unicode(s):
return s.decode('utf-8')
def unicode2str(s):
return s.encode('utf-8')
else:
......@@ -574,6 +576,8 @@ else:
return s.decode()
def str2bytes(s):
return s.encode()
def str2unicode(s):
return s
def unicode2str(s):
return s
......
......@@ -189,7 +189,7 @@ ModuleSecurityInfo('Products.ERP5Type.Utils').declarePublic(
'int2letter', 'getMessageIdWithContext', 'getTranslationStringWithContext',
'Email_parseAddressHeader', 'guessEncodingFromText',
'isValidTALESExpression',
'ensure_list', 'bytes2str', 'str2bytes', 'unicode2str',
'ensure_list', 'bytes2str', 'str2bytes', 'str2unicode', 'unicode2str',
)
allow_module('Products.ERP5Type.Message')
......
......@@ -61,8 +61,7 @@ ACQUIRE_LOCAL_ROLE_GETTER_DICT = {
for acquire_local_role in (False, True)
}
if six.PY3:
StandardError = Exception
def _importFilesystemClass(classpath):
try:
module_path, class_name = classpath.rsplit('.', 1)
......@@ -74,7 +73,7 @@ def _importFilesystemClass(classpath):
InitializeClass(klass)
return klass
except StandardError:
except Exception as e:
raise ImportError('Could not import document class ' + classpath)
def _importComponentClass(component_package, name):
......
......@@ -32,6 +32,7 @@ import math
from DateTime.DateTime import _calcSD, _calcDependentSecond, _calcYMDHMS,\
getDefaultDateFormat, _correctYear, _calcHMS, _calcDependentSecond2, DateTimeError,\
SyntaxError, DateError, TimeError, localtime, time
from Products.ERP5Type import IS_ZOPE2
STATE_KEY = 'str'
......@@ -297,12 +298,13 @@ DateTimeKlass.SyntaxError = SyntaxError
DateTimeKlass.DateError = DateError
DateTimeKlass.TimeError = TimeError
# BBB undo patch from DateTime 2.12 , which patches
# copy_reg._reconstructor with a function that appears as
# `DateTime.DateTime._dt_reconstructor` in pickles.
# See https://github.com/zopefoundation/DateTime/blob/2.12.8/src/DateTime/DateTime.py#L1863-L1874
# This patch is no longer needed once we are using DateTime >= 3 so
# it is not needed on python3 (copy_reg does not exist on python3)
import copy_reg
copy_reg._reconstructor.__module__ = 'copy_reg'
copy_reg._reconstructor.__name__ = '_reconstructor'
if IS_ZOPE2: # BBB Zope2
# BBB undo patch from DateTime 2.12 , which patches
# copy_reg._reconstructor with a function that appears as
# `DateTime.DateTime._dt_reconstructor` in pickles.
# See https://github.com/zopefoundation/DateTime/blob/2.12.8/src/DateTime/DateTime.py#L1863-L1874
# This patch is no longer needed once we are using DateTime >= 3 so
# it is not needed on python3 (copy_reg does not exist on python3)
import copy_reg
copy_reg._reconstructor.__module__ = 'copy_reg'
copy_reg._reconstructor.__name__ = '_reconstructor'
......@@ -80,6 +80,9 @@ add_builtins(Ellipsis=Ellipsis, NotImplemented=NotImplemented,
dict=dict, list=list)
if "set" not in safe_builtins: # BBB
add_builtins(set=set, frozenset=frozenset, slice=slice)
if "bytes" not in safe_builtins: # BBB Zope2
assert six.PY2
add_builtins(bytes=str)
add_builtins(bin=bin, classmethod=classmethod, format=format, object=object,
property=property, staticmethod=staticmethod,
......
......@@ -1356,7 +1356,7 @@ class ERP5TypeCommandLineTestCase(ERP5TypeTestCaseMixin):
try:
portal_activities = self.portal.portal_activities
message_list = portal_activities.getMessageList()
except StandardError: # AttributeError, TransactionFailedError ...
except Exception: # AttributeError, TransactionFailedError ...
pass
else:
for m in message_list:
......
......@@ -4,9 +4,8 @@ from six import unichr
from six.moves import xrange
import string
from .DummyField import fields
from DocumentTemplate.DT_Util import html_quote
from DocumentTemplate.html_quote import html_quote
from DateTime import DateTime, Timezones
from Products.PythonScripts.standard import html_quote
import types
from DocumentTemplate.ustr import ustr
from six.moves.urllib.parse import urljoin
......
# -*- coding: utf-8 -*-
import unittest, re
from lxml import etree
from DateTime import DateTime
import Zope2
......@@ -122,9 +123,12 @@ class FormTestCase(unittest.TestCase):
.manage_addField('date_time','Test Field','DateTimeField')
field = self.form.date_time
field._edit({'timezone_style': 0})
self.assertNotIn('<select size="1" name="subfield_field_date_time_timezone" >', field.render())
parser = etree.HTMLParser()
e = etree.fromstring(field.render(), parser=parser)
self.assertFalse(e.xpath('//select[@size="1"][@name="subfield_field_date_time_timezone"]'))
field._edit({'timezone_style': 1})
self.assertIn('<select size="1" name="subfield_field_date_time_timezone" >', field.render())
e = etree.fromstring(field.render(), parser=parser)
self.assertTrue(e.xpath('//select[@size="1"][@name="subfield_field_date_time_timezone"]'))
def test_datetime_css_class_rendering(self):
......@@ -181,13 +185,18 @@ class FormTestCase(unittest.TestCase):
.manage_addField('date_time','Test Field','DateTimeField')
field = self.form.date_time
field._edit({'input_style': 'number'})
self.assertIn('<input name="subfield_field_date_time_year" value="" maxlength="4" type="number" size="4" min="0" max="9999" />', field.render())
parser = etree.HTMLParser()
e = etree.fromstring(field.render(), parser=parser)
self.assertTrue(e.xpath('//input[@name="subfield_field_date_time_year"][@value=""][@maxlength="4"][@type="number"][@size="4"][@min="0"][@max="9999"]'))
field._edit({'start_datetime': DateTime('1900/01/01'), 'end_datetime': None})
self.assertIn('<input name="subfield_field_date_time_year" value="" maxlength="4" type="number" size="4" min="1900" max="9999" />', field.render())
e = etree.fromstring(field.render(), parser=parser)
self.assertTrue(e.xpath('//input[@name="subfield_field_date_time_year"][@value=""][@maxlength="4"][@type="number"][@size="4"][@min="1900"][@max="9999"]'))
field._edit({'start_datetime': None, 'end_datetime': DateTime('2099/12/31')})
self.assertIn('<input name="subfield_field_date_time_year" value="" maxlength="4" type="number" size="4" min="0" max="2099" />', field.render())
e = etree.fromstring(field.render(), parser=parser)
self.assertTrue(e.xpath('//input[@name="subfield_field_date_time_year"][@value=""][@maxlength="4"][@type="number"][@size="4"][@min="0"][@max="2099"]'))
field._edit({'start_datetime': DateTime('1900/01/01'), 'end_datetime': DateTime('2099/12/31')})
self.assertIn('<input name="subfield_field_date_time_year" value="" maxlength="4" type="number" size="4" min="1900" max="2099" />', field.render())
e = etree.fromstring(field.render(), parser=parser)
self.assertTrue(e.xpath('//input[@name="subfield_field_date_time_year"][@value=""][@maxlength="4"][@type="number"][@size="4"][@min="1900"][@max="2099"]'))
def test_suite():
......
......@@ -26,7 +26,8 @@ from App.Common import package_home
ph = package_home(globals())
# Initializes a list with the charsets
charsets = [ x.strip() for x in open(ph + '/charsets.txt').readlines() ]
with open(ph + '/charsets.txt') as f:
charsets = [ x.strip() for x in f.readlines() ]
......
......@@ -20,7 +20,7 @@ from six.moves import cStringIO as StringIO
from Products.PortalTransforms.interfaces import ITransform
from zope.interface import implementer
from DocumentTemplate.DT_Util import html_quote
from DocumentTemplate.html_quote import html_quote
## Python Source Parser #####################################################
......
from Products.PortalTransforms.interfaces import ITransform
from zope.interface import implementer
from DocumentTemplate.DT_Util import html_quote
from DocumentTemplate.html_quote import html_quote
__revision__ = '$Id: text_pre_to_html.py 3658 2005-02-23 16:29:54Z tiran $'
......
from Products.PortalTransforms.interfaces import ITransform
from zope.interface import implementer
from DocumentTemplate.DT_Util import html_quote
from DocumentTemplate.html_quote import html_quote
__revision__ = '$Id: text_to_html.py 4787 2005-08-19 21:43:41Z dreamcatcher $'
......
......@@ -25,8 +25,11 @@ from OFS.Folder import Folder
from DateTime import DateTime
from Acquisition import Implicit, aq_base
from Persistence import Persistent
from DocumentTemplate.DT_Util import InstanceDict, TemplateDict
from DocumentTemplate.DT_Util import Eval
from DocumentTemplate.DT_Util import Eval, TemplateDict
try:
from DocumentTemplate._DocumentTemplate import InstanceDict
except ImportError: # BBB
from DocumentTemplate.DT_Util import InstanceDict
from AccessControl.Permission import pname
from AccessControl.Permissions import import_export_objects, \
manage_zcatalog_entries
......
......@@ -69,7 +69,9 @@ def _makeFile(filename, prefix=None, id=None):
if id is None:
id = os.path.split( path )[ 1 ]
return File( id=id, title='', file=open(path).read() )
with open(path, 'rb') as f:
data = f.read()
return File( id=id, title='', file=data )
def registerFiles(directory, prefix):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment