Commit ca2febe1 authored by Arnaud Fontaine's avatar Arnaud Fontaine

Merge remote-tracking branch 'origin/zope4py2' into zope4py3

parents 326a1655 82d9aee7
...@@ -32,6 +32,7 @@ import unittest ...@@ -32,6 +32,7 @@ import unittest
from DateTime import DateTime from DateTime import DateTime
from erp5.component.module.DateUtils import addToDate, getIntervalListBetweenDates, \ from erp5.component.module.DateUtils import addToDate, getIntervalListBetweenDates, \
atTheEndOfPeriod, getClosestDate atTheEndOfPeriod, getClosestDate
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
class TestDateUtils(unittest.TestCase): class TestDateUtils(unittest.TestCase):
""" """
...@@ -175,7 +176,31 @@ class TestDateUtils(unittest.TestCase): ...@@ -175,7 +176,31 @@ class TestDateUtils(unittest.TestCase):
self.assertEqual('Sep. 10, 2008 12:00 am GMT-2', self.assertEqual('Sep. 10, 2008 12:00 am GMT-2',
getClosestDate(date=date, target_date=target_date, precision='month', before=False).pCommonZ()) getClosestDate(date=date, target_date=target_date, precision='month', before=False).pCommonZ())
class TestPinDateTime(ERP5TypeTestCase):
def test_pinDateTime(self):
actual_begin_date = DateTime()
datetime = DateTime('2001/01/01 01:01:01')
fixed_date_with_timezone = DateTime('2002/02/02 02:02:02 GMT+2')
self.pinDateTime(datetime)
self.assertEqual(DateTime(), datetime)
self.assertEqual(DateTime('2002/02/02 02:02:02 GMT+2'), fixed_date_with_timezone)
self.unpinDateTime()
self.assertGreaterEqual(DateTime(), actual_begin_date)
def test_pinDateTime_context_manager(self):
actual_begin_date = DateTime()
datetime = DateTime('2001/01/01 01:01:01')
with self.pinDateTime(datetime):
self.assertEqual(DateTime(), datetime)
self.assertGreaterEqual(DateTime(), actual_begin_date)
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestDateUtils)) suite.addTest(unittest.makeSuite(TestDateUtils))
suite.addTest(unittest.makeSuite(TestPinDateTime))
return suite return suite
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2002-2009 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
class TestFieldValueCache(ERP5TypeTestCase):
"""
A Sample Test Class
"""
def getTitle(self):
return "TestDiscussionThread"
def getBusinessTemplateList(self):
"""
Tuple of Business Templates we need to install
"""
return (
'erp5_base',
)
def setUpOnce(self):
"""
Do nothing
"""
def afterSetUp(self):
"""
This is ran before each and every test, used to set up the environment
"""
self.person_module = self.portal.getDefaultModule(portal_type='Person')
def testEditZMIFieldPurgesValueCache(self):
"""
This test makes sure that if manage_edit is called on a ZMI
field then its ValueCache is purged.
"""
person = self.person_module.newContent()
form = person.Person_view
# Render
form()
# Get form value
field = form.my_first_name
id_ = 'title'
from Products.ERP5Form.Form import field_value_cache
cache_id = ('ProxyField.get_value',
field._p_oid,
field._p_oid,
id_)
# Make sure cache has field
self.assertTrue(cache_id in field_value_cache)
# Make sure cache and field are equal
self.assertEqual(field.get_value(id_), field_value_cache[cache_id])
# Call manage_renameObject
form.manage_renameObject('my_first_name', 'my_first_name2')
form.manage_renameObject('my_first_name2', 'my_first_name')
# Make sure cache has no field
self.assertFalse(cache_id in field_value_cache)
# Render
form()
# Make sure cache has field
self.assertTrue(cache_id in field_value_cache)
# Make sure cache and field are equal
self.assertEqual(field.get_value(id_), field_value_cache[cache_id])
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testFieldValueCache</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5Form.tests.testFieldValueCache</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testFieldValueCache</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -49,7 +49,7 @@ from Products.Formulator.TALESField import TALESMethod ...@@ -49,7 +49,7 @@ from Products.Formulator.TALESField import TALESMethod
from Products.ERP5Type.Core.Folder import Folder from Products.ERP5Type.Core.Folder import Folder
from Products.ERP5Form.Form import field_value_cache from Products.ERP5Form.Form import field_value_cache
from Products.ERP5Form.Form import getFieldValue from Products.ERP5Form.Form import getFieldValue
from Products.ERP5Form import ProxyField from Products.ERP5Form.ProxyField import BrokenProxyField, ProxyField
from DateTime import DateTime from DateTime import DateTime
import lxml.html import lxml.html
...@@ -68,7 +68,7 @@ class TestRenderViewAPI(ERP5TypeTestCase): ...@@ -68,7 +68,7 @@ class TestRenderViewAPI(ERP5TypeTestCase):
for field in FieldRegistry.get_field_classes().values(): # pylint: disable=no-value-for-parameter for field in FieldRegistry.get_field_classes().values(): # pylint: disable=no-value-for-parameter
self.assertEqual(('self', 'value', 'REQUEST', 'render_prefix'), self.assertEqual(('self', 'value', 'REQUEST', 'render_prefix'),
field.render_view.__func__.__code__.co_varnames) field.render_view.__func__.__code__.co_varnames)
if field is not ProxyField.ProxyField: if field is not ProxyField:
self.assertEqual(('self', 'field', 'value', 'REQUEST'), self.assertEqual(('self', 'field', 'value', 'REQUEST'),
field.widget.render_view.__func__.__code__.co_varnames[:4], '%s %s' % (field.widget, field.widget.render_view.__func__.__code__.co_varnames[:4])) field.widget.render_view.__func__.__code__.co_varnames[:4], '%s %s' % (field.widget, field.widget.render_view.__func__.__code__.co_varnames[:4]))
...@@ -713,6 +713,9 @@ class TestMultiListField(ERP5TypeTestCase): ...@@ -713,6 +713,9 @@ class TestMultiListField(ERP5TypeTestCase):
class TestProxyField(ERP5TypeTestCase): class TestProxyField(ERP5TypeTestCase):
def getBusinessTemplateList(self):
return 'erp5_core_proxy_field_legacy',
def getTitle(self): def getTitle(self):
return "Proxy Field" return "Proxy Field"
...@@ -732,9 +735,9 @@ class TestProxyField(ERP5TypeTestCase): ...@@ -732,9 +735,9 @@ class TestProxyField(ERP5TypeTestCase):
'my_title', 'Title', 'StringField') 'my_title', 'Title', 'StringField')
proxy_field = self.addField(self.container.Base_view, proxy_field = self.addField(self.container.Base_view,
'my_title', 'Not Title', 'ProxyField') 'my_title', 'Not Title', 'ProxyField')
self.assertEqual(None, proxy_field.getTemplateField()) self.assertIsNone(proxy_field.getTemplateField())
self.assertEqual(None, proxy_field.get_value('enable')) self.assertFalse(proxy_field.get_value('enabled'))
self.assertEqual(None, proxy_field.get_value('default')) self.assertRaises(BrokenProxyField, proxy_field.get_value, 'default')
proxy_field.manage_edit_xmlrpc(dict(form_id='Base_viewProxyFieldLibrary', proxy_field.manage_edit_xmlrpc(dict(form_id='Base_viewProxyFieldLibrary',
field_id='my_title',)) field_id='my_title',))
...@@ -872,7 +875,7 @@ class TestProxyField(ERP5TypeTestCase): ...@@ -872,7 +875,7 @@ class TestProxyField(ERP5TypeTestCase):
proxy_field = self.addField(self.container.Base_view, proxy_field = self.addField(self.container.Base_view,
'my_String', '', 'ProxyField') 'my_String', '', 'ProxyField')
proxy_field.manage_edit_xmlrpc(dict(form_id='Base_viewProxyFieldLibrary', proxy_field.manage_edit_xmlrpc(dict(form_id='Base_viewProxyFieldLibrary',
field_id='my_date',)) field_id='my_string',))
proxy_field.manage_edit_surcharged_xmlrpc(dict(title='Title')) proxy_field.manage_edit_surcharged_xmlrpc(dict(title='Title'))
self.assertFalse(proxy_field.is_delegated('title')) self.assertFalse(proxy_field.is_delegated('title'))
...@@ -1107,12 +1110,12 @@ class TestFieldValueCache(ERP5TypeTestCase): ...@@ -1107,12 +1110,12 @@ class TestFieldValueCache(ERP5TypeTestCase):
'default': 'python: repr(here)'}) 'default': 'python: repr(here)'})
form.my_on_memory_field._p_oid = None form.my_on_memory_field._p_oid = None
# proxy field # proxy field
addField(ProxyField.ProxyField('proxy_field')) addField(ProxyField('proxy_field'))
form.proxy_field._p_oid = makeDummyOid() form.proxy_field._p_oid = makeDummyOid()
form.proxy_field.values['form_id'] = 'form' form.proxy_field.values['form_id'] = 'form'
form.proxy_field.values['field_id'] = 'field' form.proxy_field.values['field_id'] = 'field'
# proxy field with tales # proxy field with tales
addField(ProxyField.ProxyField('proxy_field_tales')) addField(ProxyField('proxy_field_tales'))
form.proxy_field_tales._p_oid = makeDummyOid() form.proxy_field_tales._p_oid = makeDummyOid()
form.proxy_field_tales.tales['form_id'] = TALESMethod('string:form') form.proxy_field_tales.tales['form_id'] = TALESMethod('string:form')
form.proxy_field_tales.tales['field_id'] = TALESMethod('string:field') form.proxy_field_tales.tales['field_id'] = TALESMethod('string:field')
...@@ -1142,7 +1145,7 @@ class TestFieldValueCache(ERP5TypeTestCase): ...@@ -1142,7 +1145,7 @@ class TestFieldValueCache(ERP5TypeTestCase):
# make sure that this will use cache. # make sure that this will use cache.
cache_size = self._getCacheSize('Form.get_value') cache_size = self._getCacheSize('Form.get_value')
self.root.form.field.get_value('title') self.root.form.field.get_value('title')
self.assertEqual(True, cache_size < self._getCacheSize('Form.get_value')) self.assertLess(cache_size, self._getCacheSize('Form.get_value'))
# check on-memory field # check on-memory field
# make sure that this will not use cache. # make sure that this will not use cache.
...@@ -1151,19 +1154,7 @@ class TestFieldValueCache(ERP5TypeTestCase): ...@@ -1151,19 +1154,7 @@ class TestFieldValueCache(ERP5TypeTestCase):
self.root.form.my_on_memory_tales_field.get_value('default')) self.root.form.my_on_memory_tales_field.get_value('default'))
self.assertEqual('123', self.assertEqual('123',
self.root.form.my_on_memory_field.get_value('default')) self.root.form.my_on_memory_field.get_value('default'))
self.assertEqual(True, cache_size == self._getCacheSize('Form.get_value')) self.assertEqual(cache_size, self._getCacheSize('Form.get_value'))
# check proxy field
# make sure that this will use cache.
cache_size = self._getCacheSize('ProxyField.get_value')
self.root.form.proxy_field.get_value('title')
self.assertEqual(True, cache_size < self._getCacheSize('ProxyField.get_value'))
# check proxy field with tales
# make sure that this will not use cache.
cache_size = self._getCacheSize('ProxyField.get_value')
self.root.form.proxy_field_tales.get_value('title')
self.assertEqual(True, cache_size == self._getCacheSize('ProxyField.get_value'))
class TestCaptchaField(ERP5TypeTestCase): class TestCaptchaField(ERP5TypeTestCase):
......
...@@ -26,13 +26,17 @@ ...@@ -26,13 +26,17 @@
# #
############################################################################## ##############################################################################
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase import re
from Products.Formulator.XMLToForm import XMLToForm from functools import partial
from unittest import expectedFailure
from lxml import etree
from Products.Formulator.FormToXML import formToXML from Products.Formulator.FormToXML import formToXML
from Products.Formulator.TALESField import TALESMethod from Products.Formulator.TALESField import TALESMethod
from lxml import etree
from unittest import expectedFailure
from zExceptions import BadRequest from zExceptions import BadRequest
from Products.Formulator.XMLToForm import XMLToForm
from Products.ERP5Form.ProxyField import BrokenProxyField
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
class TestProxyField(ERP5TypeTestCase): class TestProxyField(ERP5TypeTestCase):
""" """
...@@ -400,15 +404,19 @@ return printed ...@@ -400,15 +404,19 @@ return printed
form = skin_folder._getOb('Base_viewGeek', None) form = skin_folder._getOb('Base_viewGeek', None)
form.manage_addField('my_title', 'Title', 'ProxyField') form.manage_addField('my_title', 'Title', 'ProxyField')
field = getattr(form, 'my_title') field = form.my_title
self.assertFalse(form.get_fields())
self.assertEqual([field], form.get_fields(include_disabled=True))
self.assertIsNone(field.getTemplateField()) self.assertIsNone(field.getTemplateField())
self.assertEqual('', field.render())
self.assertEqual('', field.get_tales('default')) self.assertEqual('', field.get_tales('default'))
self.assertIsNone(field.get_value('default'))
with self.assertRaisesRegexp( regexp = '^%s$' % re.escape("Can't find the template field of"
AttributeError, " <ProxyField at /%s/portal_skins/erp5_geek/Base_viewGeek/my_title>"
'The proxy field <ProxyField at /%s/portal_skins/erp5_geek/Base_viewGeek/my_title> cannot find a template field' % self.portal.getId())
% self.portal.getId()): for func in ( field.render
field.get_recursive_tales('default') , partial(field.get_value, 'default')
, partial(field.get_recursive_tales, 'default')
):
self.assertRaisesRegexp(BrokenProxyField, regexp, func)
...@@ -23,7 +23,6 @@ test.erp5.testERP5Core ...@@ -23,7 +23,6 @@ test.erp5.testERP5Core
test.erp5.testERP5Type test.erp5.testERP5Type
test.erp5.testERP5TypeInterfaces test.erp5.testERP5TypeInterfaces
test.erp5.testERP5Workflow test.erp5.testERP5Workflow
test.erp5.testFieldValueCache
test.erp5.testFields test.erp5.testFields
test.erp5.testFolder test.erp5.testFolder
test.erp5.testFolderMigration test.erp5.testFolderMigration
......
...@@ -55,7 +55,7 @@ for business_field in business_field_list: ...@@ -55,7 +55,7 @@ for business_field in business_field_list:
if field.meta_type=='ProxyField': if field.meta_type=='ProxyField':
if field.is_delegated('title') is True: if field.is_delegated('title') is True:
field_note_list.append('Delegated.') field_note_list.append('Delegated.')
elif field.get_tales_expression('title') is not None: elif field.get_recursive_tales('title') is not None:
field_note_list.append('Tales is used.') field_note_list.append('Tales is used.')
if len(term_list) == 1 and \ if len(term_list) == 1 and \
......
...@@ -87,7 +87,7 @@ def WorkflowTool_listActionParameterList(self): ...@@ -87,7 +87,7 @@ def WorkflowTool_listActionParameterList(self):
for action in action_list: for action in action_list:
if (action['workflow_id'] not in workflow_dict): if (action['workflow_id'] not in workflow_dict):
workflow = self.getWorkflowById(action['workflow_id']) workflow = self._getOb(action['workflow_id'], None)
if workflow is not None: if workflow is not None:
workflow_dict[action['workflow_id']] = workflow.getWorklistVariableMatchDict(info, check_guard=False) workflow_dict[action['workflow_id']] = workflow.getWorklistVariableMatchDict(info, check_guard=False)
......
maileva_connector = context.portal_catalog.getResultValue( maileva_connector = context.portal_catalog.getResultValue(
portal_type='Maileva SOAP Connector',
reference=reference, reference=reference,
validation_state='validated') validation_state='validated')
if not maileva_connector: if not maileva_connector:
......
...@@ -67,10 +67,7 @@ ...@@ -67,10 +67,7 @@
<item> <item>
<key> <string>workflow_managed_permission</string> </key> <key> <string>workflow_managed_permission</string> </key>
<value> <value>
<tuple> <tuple/>
<string>Modify portal content</string>
<string>Add portal content</string>
</tuple>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
...@@ -9,10 +9,7 @@ ...@@ -9,10 +9,7 @@
<item> <item>
<key> <string>acquire_permission</string> </key> <key> <string>acquire_permission</string> </key>
<value> <value>
<tuple> <tuple/>
<string>Modify portal content</string>
<string>Add portal content</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
...@@ -67,42 +64,7 @@ ...@@ -67,42 +64,7 @@
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
<value> <value>
<dictionary> <dictionary/>
<item>
<key> <string>Add portal content</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Authenticated</string>
<string>Associate</string>
<string>Author</string>
<string>Member</string>
<string>Assignee</string>
<string>Manager</string>
<string>Auditor</string>
<string>Owner</string>
<string>Reviewer</string>
</tuple>
</value>
</item>
<item>
<key> <string>Modify portal content</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Authenticated</string>
<string>Author</string>
<string>Associate</string>
<string>Member</string>
<string>Assignee</string>
<string>Manager</string>
<string>Auditor</string>
<string>Owner</string>
<string>Reviewer</string>
</tuple>
</value>
</item>
</dictionary>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
...@@ -9,10 +9,7 @@ ...@@ -9,10 +9,7 @@
<item> <item>
<key> <string>acquire_permission</string> </key> <key> <string>acquire_permission</string> </key>
<value> <value>
<tuple> <tuple/>
<string>Modify portal content</string>
<string>Add portal content</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
...@@ -66,42 +63,7 @@ ...@@ -66,42 +63,7 @@
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
<value> <value>
<dictionary> <dictionary/>
<item>
<key> <string>Add portal content</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Authenticated</string>
<string>Associate</string>
<string>Author</string>
<string>Member</string>
<string>Assignee</string>
<string>Manager</string>
<string>Auditor</string>
<string>Owner</string>
<string>Reviewer</string>
</tuple>
</value>
</item>
<item>
<key> <string>Modify portal content</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Authenticated</string>
<string>Author</string>
<string>Associate</string>
<string>Member</string>
<string>Assignee</string>
<string>Manager</string>
<string>Auditor</string>
<string>Owner</string>
<string>Reviewer</string>
</tuple>
</value>
</item>
</dictionary>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
...@@ -9,10 +9,7 @@ ...@@ -9,10 +9,7 @@
<item> <item>
<key> <string>acquire_permission</string> </key> <key> <string>acquire_permission</string> </key>
<value> <value>
<tuple> <tuple/>
<string>Modify portal content</string>
<string>Add portal content</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
...@@ -66,42 +63,7 @@ ...@@ -66,42 +63,7 @@
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
<value> <value>
<dictionary> <dictionary/>
<item>
<key> <string>Add portal content</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Authenticated</string>
<string>Associate</string>
<string>Author</string>
<string>Member</string>
<string>Assignee</string>
<string>Manager</string>
<string>Auditor</string>
<string>Owner</string>
<string>Reviewer</string>
</tuple>
</value>
</item>
<item>
<key> <string>Modify portal content</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Authenticated</string>
<string>Author</string>
<string>Associate</string>
<string>Member</string>
<string>Assignee</string>
<string>Manager</string>
<string>Auditor</string>
<string>Owner</string>
<string>Reviewer</string>
</tuple>
</value>
</item>
</dictionary>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
...@@ -9,10 +9,7 @@ ...@@ -9,10 +9,7 @@
<item> <item>
<key> <string>acquire_permission</string> </key> <key> <string>acquire_permission</string> </key>
<value> <value>
<tuple> <tuple/>
<string>Modify portal content</string>
<string>Add portal content</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
...@@ -57,42 +54,7 @@ ...@@ -57,42 +54,7 @@
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
<value> <value>
<dictionary> <dictionary/>
<item>
<key> <string>Add portal content</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Authenticated</string>
<string>Associate</string>
<string>Author</string>
<string>Member</string>
<string>Assignee</string>
<string>Manager</string>
<string>Auditor</string>
<string>Owner</string>
<string>Reviewer</string>
</tuple>
</value>
</item>
<item>
<key> <string>Modify portal content</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Authenticated</string>
<string>Author</string>
<string>Associate</string>
<string>Member</string>
<string>Assignee</string>
<string>Manager</string>
<string>Auditor</string>
<string>Owner</string>
<string>Reviewer</string>
</tuple>
</value>
</item>
</dictionary>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
...@@ -26,17 +26,13 @@ ...@@ -26,17 +26,13 @@
############################################################################## ##############################################################################
import unittest import unittest
import os import os
import sys
import time import time
import mock
from unittest import expectedFailure from unittest import expectedFailure
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from DateTime import DateTime from DateTime import DateTime
# explicitly set Europe/Paris timezone
os.environ['TZ']='Europe/Paris'
time.tzset()
DateTime._localzone0 = 'GMT+1'
DateTime._localzone1 = 'GMT+2'
DateTime._multipleZones = True
class TestOpenOrder(ERP5TypeTestCase): class TestOpenOrder(ERP5TypeTestCase):
""" """
...@@ -47,6 +43,19 @@ class TestOpenOrder(ERP5TypeTestCase): ...@@ -47,6 +43,19 @@ class TestOpenOrder(ERP5TypeTestCase):
return 'Test Open Order' return 'Test Open Order'
def afterSetUp(self): def afterSetUp(self):
# explicitly set Europe/Paris timezone
# We use mock, to make sure we patch in the right place, but the stopping
# the patcher does not really work as we also have to set TZ
os.environ['TZ'] = 'Europe/Paris'
time.tzset()
for patcher in (
mock.patch.object(sys.modules['DateTime.DateTime'], '_localzone0', new='GMT+1'),
mock.patch.object(sys.modules['DateTime.DateTime'], '_localzone1', new='GMT+2'),
mock.patch.object(sys.modules['DateTime.DateTime'], '_multipleZones', new=True),
):
patcher.start()
self.addCleanup(patcher.stop)
if getattr(self.portal, '_run_after_setup', None) is not None: if getattr(self.portal, '_run_after_setup', None) is not None:
return return
......
...@@ -31,12 +31,6 @@ import time ...@@ -31,12 +31,6 @@ import time
from DateTime import DateTime from DateTime import DateTime
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
# As tests rely on documents exported in test bt5, setting up timezone allows
# consistency between test environment execution and virtual ERP5 instance
os.environ['TZ'] = 'GMT'
time.tzset()
DateTime._localzone0 = 'GMT'
class TestDSNSocialDeclarationReport(ERP5TypeTestCase): class TestDSNSocialDeclarationReport(ERP5TypeTestCase):
""" """
Test Suite for the generation of the French Social Declaration Report, Test Suite for the generation of the French Social Declaration Report,
...@@ -50,8 +44,8 @@ class TestDSNSocialDeclarationReport(ERP5TypeTestCase): ...@@ -50,8 +44,8 @@ class TestDSNSocialDeclarationReport(ERP5TypeTestCase):
""" """
This is ran before anything, used to set the environment This is ran before anything, used to set the environment
""" """
self.portal = self.getPortalObject()
self.dsn_module = self.portal.getDefaultModuleValue("DSN Monthly Report") self.dsn_module = self.portal.getDefaultModuleValue("DSN Monthly Report")
self.setTimeZoneToUTC()
self.pinDateTime(DateTime(2015, 12, 0o1)) self.pinDateTime(DateTime(2015, 12, 0o1))
# Create the id_group 'dsn_event_counter' # Create the id_group 'dsn_event_counter'
self.portal.portal_ids.generateNewId(id_group='dsn_event_counter', id_generator='continuous_integer_increasing') self.portal.portal_ids.generateNewId(id_group='dsn_event_counter', id_generator='continuous_integer_increasing')
......
...@@ -120,14 +120,13 @@ ...@@ -120,14 +120,13 @@
<tr> <tr>
<td>click</td> <td>clickAndWait</td>
<td>//input[@value='Save Changes']</td> <td>//input[@value='Save Changes']</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>assertTextPresent</td>
<td>//div[@class='system-msg']</td> <td>Content changed</td>
<td></td> <td></td>
</tr> </tr>
...@@ -170,18 +169,16 @@ ...@@ -170,18 +169,16 @@
<tr> <tr>
<td>click</td> <td>clickAndWait</td>
<td>//input[@value='Save Changes']</td> <td>//input[@value='Save Changes']</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>assertTextPresent</td>
<td>//div[@class='system-msg']</td> <td>Content changed</td>
<td></td> <td></td>
</tr> </tr>
</tbody></table> </tbody></table>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -68,14 +68,13 @@ ...@@ -68,14 +68,13 @@
</tr> </tr>
<tr> <tr>
<td>click</td> <td>clickAndWait</td>
<td>//input[@value='Save Changes']</td> <td>//input[@value='Save Changes']</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>assertTextPresent</td>
<td>//div[@class='system-msg']</td> <td>Content changed</td>
<td></td> <td></td>
</tr> </tr>
...@@ -172,18 +171,16 @@ ...@@ -172,18 +171,16 @@
</tr> </tr>
<tr> <tr>
<td>click</td> <td>clickAndWait</td>
<td>//input[@value='Save Changes']</td> <td>//input[@value='Save Changes']</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>assertTextPresent</td>
<td>//div[@class='system-msg']</td> <td>Content changed</td>
<td></td> <td></td>
</tr> </tr>
</tbody></table> </tbody></table>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -5582,8 +5582,7 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -5582,8 +5582,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
Returns the current state in building Returns the current state in building
""" """
portal_workflow = getToolByName(self, 'portal_workflow') portal_workflow = getToolByName(self, 'portal_workflow')
wf = portal_workflow.getWorkflowById( wf = portal_workflow._getOb('business_template_building_workflow')
'business_template_building_workflow')
return wf._getWorkflowStateOf(self, id_only=id_only ) return wf._getWorkflowStateOf(self, id_only=id_only )
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
...@@ -5593,8 +5592,7 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -5593,8 +5592,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
Returns the current state in installation Returns the current state in installation
""" """
portal_workflow = getToolByName(self.getPortalObject(), 'portal_workflow') portal_workflow = getToolByName(self.getPortalObject(), 'portal_workflow')
wf = portal_workflow.getWorkflowById( wf = portal_workflow._getOb('business_template_installation_workflow')
'business_template_installation_workflow')
return wf._getWorkflowStateOf(self, id_only=id_only ) return wf._getWorkflowStateOf(self, id_only=id_only )
security.declareProtected(Permissions.AccessContentsInformation, 'toxml') security.declareProtected(Permissions.AccessContentsInformation, 'toxml')
......
...@@ -30,6 +30,8 @@ from __future__ import division ...@@ -30,6 +30,8 @@ from __future__ import division
############################################################################## ##############################################################################
from past.utils import old_div from past.utils import old_div
import datetime
from DateTime import DateTime
from .TargetSolver import TargetSolver from .TargetSolver import TargetSolver
class CopyToTarget(TargetSolver): class CopyToTarget(TargetSolver):
...@@ -62,13 +64,11 @@ class CopyToTarget(TargetSolver): ...@@ -62,13 +64,11 @@ class CopyToTarget(TargetSolver):
quantity_ratio = 0 quantity_ratio = 0
if old_quantity not in (None,0.0): # XXX: What if quantity happens to be an integer ? if old_quantity not in (None,0.0): # XXX: What if quantity happens to be an integer ?
quantity_ratio = old_div(new_quantity, old_quantity) quantity_ratio = old_div(new_quantity, old_quantity)
start_date_delta = 0 stop_date_delta = start_date_delta = datetime.timedelta()
stop_date_delta = 0
# get the date delta in milliseconds, to prevent rounding issues
if new_start_date is not None and old_start_date is not None: if new_start_date is not None and old_start_date is not None:
start_date_delta = new_start_date.millis() - old_start_date.millis() start_date_delta = new_start_date.asdatetime() - old_start_date.asdatetime()
if new_stop_date is not None and old_stop_date is not None: if new_stop_date is not None and old_stop_date is not None:
stop_date_delta = new_stop_date.millis() - old_stop_date.millis() stop_date_delta = new_stop_date.asdatetime() - old_stop_date.asdatetime()
return { return {
'quantity_ratio': quantity_ratio, 'quantity_ratio': quantity_ratio,
'start_date_delta': start_date_delta, 'start_date_delta': start_date_delta,
...@@ -89,15 +89,14 @@ class CopyToTarget(TargetSolver): ...@@ -89,15 +89,14 @@ class CopyToTarget(TargetSolver):
""" """
Generate values to save on simulation movement. Generate values to save on simulation movement.
""" """
from erp5.component.module.DateUtils import createDateTimeFromMillis
value_dict = {} value_dict = {}
# Modify quantity, start_date, stop_date # Modify quantity, start_date, stop_date
start_date = simulation_movement.getStartDate() start_date = simulation_movement.getStartDate()
if start_date is not None: if start_date is not None:
value_dict['start_date'] = createDateTimeFromMillis(start_date.millis() + start_date_delta) value_dict['start_date'] = DateTime(start_date.asdatetime() + start_date_delta)
stop_date = simulation_movement.getStopDate() stop_date = simulation_movement.getStopDate()
if stop_date is not None: if stop_date is not None:
value_dict['stop_date'] = createDateTimeFromMillis(stop_date.millis() + stop_date_delta) value_dict['stop_date'] = DateTime(stop_date.asdatetime() + stop_date_delta)
value_dict['quantity'] = simulation_movement.getQuantity() * quantity_ratio value_dict['quantity'] = simulation_movement.getQuantity() * quantity_ratio
return value_dict return value_dict
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
# #
############################################################################## ##############################################################################
import six
from past.builtins import cmp from past.builtins import cmp
from hashlib import md5 from hashlib import md5
...@@ -126,8 +128,8 @@ def getDocumentGroupByWorkflowStateList(self, form_id='', **kw): ...@@ -126,8 +128,8 @@ def getDocumentGroupByWorkflowStateList(self, form_id='', **kw):
for (ptype, workflow_id, _), (doc, document_count) in\ for (ptype, workflow_id, _), (doc, document_count) in\
workflow_state_dict.items(): six.iteritems(workflow_state_dict):
workflow = wf_tool.getWorkflowById(workflow_id) workflow = wf_tool._getOb(workflow_id)
state_var = workflow.getStateVariable() state_var = workflow.getStateVariable()
translated_workflow_state_title = doc.getProperty( translated_workflow_state_title = doc.getProperty(
'translated_%s_title' % state_var) 'translated_%s_title' % state_var)
...@@ -186,7 +188,7 @@ def getWorkflowActionDocumentList(self, **kw): ...@@ -186,7 +188,7 @@ def getWorkflowActionDocumentList(self, **kw):
selection_params['uid'] = selection_uid_list selection_params['uid'] = selection_uid_list
workflow_id, action = listbox_selection['workflow_action'].split('/')[:2] workflow_id, action = listbox_selection['workflow_action'].split('/')[:2]
workflow = wtool.getWorkflowById(workflow_id) workflow = wtool._getOb(workflow_id)
for doc in selection_tool.callSelectionFor(selection_name, params=selection_params): for doc in selection_tool.callSelectionFor(selection_name, params=selection_params):
doc = doc.getObject() doc = doc.getObject()
action_list = [ai for ai in action_list = [ai for ai in
......
...@@ -455,31 +455,6 @@ def convertDateToHour(date=None): ...@@ -455,31 +455,6 @@ def convertDateToHour(date=None):
hour_ = (ordinal_date - ordinal_reference_date) * number_of_hours_in_day + number_of_hours_in_day + date.hour() hour_ = (ordinal_date - ordinal_reference_date) * number_of_hours_in_day + number_of_hours_in_day + date.hour()
return int(hour_) return int(hour_)
def createDateTimeFromMillis(millis): # pylint: disable=redefined-outer-name
"""
Returns a DateTime object, build from the number of milliseconds since epoch.
Parameter should be a int or long.
This one should be used by solvers, as DateTime.__cmp__ actually only
compares the _millis parameter of the two DateTime objects.
This is currently not perfect: DateTime only supports creating a new object
from a floating point number of seconds since epoch, so a rounding issue is
still possible, that's why _millis is explicitely set to the same value
after the DateTime object has been created from (millis / 1000.)
A better way would be to compute (yr,mo,dy,hr,mn,sc,tz,t,d,s,millisecs) from
millis, and then create the DateTime object from it (see "elif ac == 11:" in
DateTime._parse_args).
Another solution would be a DateTime implementation that relies exclusively
on integer values internally.
"""
millis = int(millis)
date = DateTime(millis / 1000.)
date._millis = millis
return date
def getNumberOfDayInMonth(date): def getNumberOfDayInMonth(date):
month = date.month() month = date.month()
mapping = { mapping = {
......
...@@ -15,8 +15,7 @@ for skin_name, skin_path_list in skins_tool.getSkinPaths(): ...@@ -15,8 +15,7 @@ for skin_name, skin_path_list in skins_tool.getSkinPaths():
): ):
for field in form.get_fields(): for field in form.get_fields():
if field.meta_type == 'ProxyField': if field.meta_type == 'ProxyField':
if field.getRecursiveTemplateField( if field.get_recursive_tales('external_validator'):
) is None or field.get_recursive_tales('external_validator'):
continue continue
try: try:
external_validator = field.get_recursive_orig_value( external_validator = field.get_recursive_orig_value(
......
...@@ -183,15 +183,6 @@ class TALESValue(StaticValue): ...@@ -183,15 +183,6 @@ class TALESValue(StaticValue):
def __call__(self, field, id, **kw): def __call__(self, field, id, **kw):
REQUEST = kw.get('REQUEST', get_request()) REQUEST = kw.get('REQUEST', get_request())
if REQUEST is not None:
# Proxyfield stores the "real" field in the request. Look if the
# corresponding field exists in request, and use it as field in the
# TALES context
field = REQUEST.get(
'field__proxyfield_%s_%s_%s' % (field.id, field._p_oid, id),
field)
kw['field'] = field
form = field.aq_parent # XXX (JPS) form for default is wrong apparently in listbox - double check form = field.aq_parent # XXX (JPS) form for default is wrong apparently in listbox - double check
obj = getattr(form, 'aq_parent', None) obj = getattr(form, 'aq_parent', None)
...@@ -200,6 +191,7 @@ class TALESValue(StaticValue): ...@@ -200,6 +191,7 @@ class TALESValue(StaticValue):
else: else:
container = None container = None
kw['field'] = field
kw['form'] = form kw['form'] = form
kw['request'] = REQUEST kw['request'] = REQUEST
kw['here'] = obj kw['here'] = obj
...@@ -343,15 +335,13 @@ def getFieldValue(self, field, id, **kw): ...@@ -343,15 +335,13 @@ def getFieldValue(self, field, id, **kw):
value = copyMethod(value) value = copyMethod(value)
cacheable = isCacheable(value) cacheable = isCacheable(value)
field_id = field.id if id == 'default':
field_id = field.id
if id == 'default' and (field_id.startswith('my_') or if field_id.startswith(('my_', 'listbox_')):
field_id.startswith('listbox_')): if (self.getRecursiveTemplateField() if self.meta_type == 'ProxyField'
if field.meta_type == 'ProxyField' and \ else self).meta_type == 'CheckBoxField':
field.getRecursiveTemplateField().meta_type == 'CheckBoxField' or \ return DefaultCheckBoxValue(field_id, value), cacheable
self.meta_type == 'CheckBoxField': return DefaultValue(field_id, value), cacheable
return DefaultCheckBoxValue(field_id, value), cacheable
return DefaultValue(field_id, value), cacheable
# For the 'editable' value, we try to get a default value # For the 'editable' value, we try to get a default value
if id == 'editable': if id == 'editable':
...@@ -362,24 +352,15 @@ def getFieldValue(self, field, id, **kw): ...@@ -362,24 +352,15 @@ def getFieldValue(self, field, id, **kw):
return StaticValue(value), cacheable return StaticValue(value), cacheable
# Return default value in non callable mode # Return default value in non callable mode
return_value = StaticValue(value)(field, id, **kw) return_value = StaticValue(value)(None, id, **kw)
return return_value, isCacheable(return_value) return return_value, isCacheable(return_value)
def get_value(self, id, REQUEST=None, **kw): def get_value(self, id, **kw):
if REQUEST is None: field = kw.pop('field', self)
REQUEST = get_request()
if REQUEST is not None:
field = REQUEST.get(
'field__proxyfield_%s_%s_%s' % (self.id, self._p_oid, id),
self)
else:
field = self
cache_id = ('Form.get_value', cache_id = ('Form.get_value',
self._p_oid, self._p_oid,
field._p_oid, field._p_oid if id == 'default' else
id) id)
try: try:
value = field_value_cache[cache_id] value = field_value_cache[cache_id]
except KeyError: except KeyError:
...@@ -390,11 +371,11 @@ def get_value(self, id, REQUEST=None, **kw): ...@@ -390,11 +371,11 @@ def get_value(self, id, REQUEST=None, **kw):
# because such field must be used for editing field in ZMI # because such field must be used for editing field in ZMI
# and caching sometimes break these field settings at initialization. # and caching sometimes break these field settings at initialization.
# As the result, we would see broken field editing screen in ZMI. # As the result, we would see broken field editing screen in ZMI.
if cacheable and self._p_oid: if cacheable and None not in cache_id:
field_value_cache[cache_id] = value field_value_cache[cache_id] = value
if callable(value): if callable(value):
return value(field, id, REQUEST=REQUEST, **kw) return value(field, id, **kw)
return value return value
psyco.bind(get_value) psyco.bind(get_value)
......
...@@ -2893,23 +2893,17 @@ class ListBox(ZMIField): ...@@ -2893,23 +2893,17 @@ class ListBox(ZMIField):
security.declareProtected('Access contents information', 'get_value') security.declareProtected('Access contents information', 'get_value')
def get_value(self, id, **kw): def get_value(self, id, **kw):
if (id == 'default'): if id == 'default':
if (kw.get('render_format') in ('list', )): render_format = kw.get('render_format')
request = kw.get('REQUEST', None) if render_format == 'list':
request = kw.get('REQUEST')
if request is None: if request is None:
request = get_request() request = get_request()
# here the field can be a a proxyfield target, in this case just find field = kw.get('field', self) # for proxy field
# back the original proxy field so that renderer's calls to .get_value
# are called on the proxyfield.
field = request.get(
'field__proxyfield_%s_%s_%s' % (self.id, self._p_oid, id),
self)
return self.widget.render(field, self.generate_field_key(), None, return self.widget.render(field, self.generate_field_key(), None,
request, request,
render_format=kw.get('render_format'), render_format=render_format,
render_prefix=kw.get('render_prefix')) render_prefix=kw.get('render_prefix'))
else:
return None
else: else:
return ZMIField.get_value(self, id, **kw) return ZMIField.get_value(self, id, **kw)
...@@ -3218,7 +3212,3 @@ allow_class(ListBoxLine) ...@@ -3218,7 +3212,3 @@ allow_class(ListBoxLine)
from Products.ERP5Type.PsycoWrapper import psyco from Products.ERP5Type.PsycoWrapper import psyco
#psyco.bind(ListBoxWidget.render) #psyco.bind(ListBoxWidget.render)
psyco.bind(ListBoxValidator.validate) psyco.bind(ListBoxValidator.validate)
# Register get_value
from Products.ERP5Form.ProxyField import registerOriginalGetValueClassAndArgument
registerOriginalGetValueClassAndArgument(ListBox, 'default')
...@@ -631,10 +631,17 @@ class MatrixBox(ZMIField): ...@@ -631,10 +631,17 @@ class MatrixBox(ZMIField):
security.declareProtected('Access contents information', 'get_value') security.declareProtected('Access contents information', 'get_value')
def get_value(self, id, **kw): def get_value(self, id, **kw):
if id=='default' and kw.get('render_format') in ('list', ): if id == 'default':
return self.widget.render(self, self.generate_field_key(), None, render_format = kw.get('render_format')
kw.get('REQUEST'), if render_format == 'list':
render_format=kw.get('render_format')) request = kw.get('REQUEST')
if request is None:
request = get_request()
field = kw.get('field', self) # for proxy field
return self.widget.render(field, self.generate_field_key(), None,
request,
render_format=render_format,
render_prefix=kw.get('render_prefix'))
else: else:
return ZMIField.get_value(self, id, **kw) return ZMIField.get_value(self, id, **kw)
...@@ -642,7 +649,3 @@ class MatrixBox(ZMIField): ...@@ -642,7 +649,3 @@ class MatrixBox(ZMIField):
from Products.ERP5Type.PsycoWrapper import psyco from Products.ERP5Type.PsycoWrapper import psyco
psyco.bind(MatrixBoxWidget.render) psyco.bind(MatrixBoxWidget.render)
psyco.bind(MatrixBoxValidator.validate) psyco.bind(MatrixBoxValidator.validate)
# Register get_value
from Products.ERP5Form.ProxyField import registerOriginalGetValueClassAndArgument
registerOriginalGetValueClassAndArgument(MatrixBox, 'default')
...@@ -774,7 +774,3 @@ class MultiRelationStringField(ZMIField): ...@@ -774,7 +774,3 @@ class MultiRelationStringField(ZMIField):
else: else:
result = ZMIField.get_value(self, id, REQUEST=REQUEST, **kw) result = ZMIField.get_value(self, id, REQUEST=REQUEST, **kw)
return result return result
# Register get_value
from Products.ERP5Form.ProxyField import registerOriginalGetValueClassAndArgument
registerOriginalGetValueClassAndArgument(MultiRelationStringField, 'items')
...@@ -225,7 +225,11 @@ class ParallelListField(ZMIField): ...@@ -225,7 +225,11 @@ class ParallelListField(ZMIField):
Optionally pass keyword arguments that get passed to TALES Optionally pass keyword arguments that get passed to TALES
expression. expression.
""" """
return paralellListFieldGetValue(self, id, REQUEST=REQUEST, **kw) if REQUEST is not None:
result = REQUEST.get(KEYWORD % id, MARKER)
if result is not MARKER:
return result
return ZMIField.get_value(self, id, REQUEST=REQUEST, **kw)
def generateSubForm(self, value, REQUEST): def generateSubForm(self, value, REQUEST):
item_list = [x for x in self.get_value('items', REQUEST=REQUEST) item_list = [x for x in self.get_value('items', REQUEST=REQUEST)
...@@ -259,21 +263,3 @@ def generateSubForm(self, value, REQUEST): ...@@ -259,21 +263,3 @@ def generateSubForm(self, value, REQUEST):
empty_sub_field_property_dict['item_list'] = item_list empty_sub_field_property_dict['item_list'] = item_list
empty_sub_field_property_dict['value'] = value_list empty_sub_field_property_dict['value'] = value_list
return [empty_sub_field_property_dict] return [empty_sub_field_property_dict]
def paralellListFieldGetValue(field, id, REQUEST=None, **kw):
result = MARKER
key = KEYWORD % id
if REQUEST is not None and key in REQUEST:
result = REQUEST.get(key)
if result is MARKER:
result = ZMIField.get_value(field, id, REQUEST=REQUEST, **kw)
return result
# Register get_value
from Products.ERP5Form.ProxyField import registerOriginalGetValueClassAndArgument
registerOriginalGetValueClassAndArgument(
ParallelListField,
('title', 'required', 'size', 'default', 'first_item', 'items'),
paralellListFieldGetValue)
...@@ -3050,9 +3050,14 @@ class PlanningBox(ZMIField): ...@@ -3050,9 +3050,14 @@ class PlanningBox(ZMIField):
XXX What is the purpose ? XXX What is the purpose ?
""" """
if id == 'default' and render_format == 'list': if id == 'default' and render_format == 'list':
return self.widget.render(self, self.generate_field_key(), None, request = kw.get('REQUEST')
kw.get('REQUEST'), if request is None:
render_format=render_format) request = get_request()
field = kw.get('field', self) # for proxy field
return self.widget.render(field, self.generate_field_key(), None,
request,
render_format=render_format,
render_prefix=kw.get('render_prefix'))
else: else:
return ZMIField.get_value(self, id, **kw) return ZMIField.get_value(self, id, **kw)
...@@ -3079,7 +3084,3 @@ for klass in (PlanningBoxWidget, BasicStructure, BasicGroup, ...@@ -3079,7 +3084,3 @@ for klass in (PlanningBoxWidget, BasicStructure, BasicGroup,
Info): Info):
InitializeClass(klass) InitializeClass(klass)
allow_class(klass) allow_class(klass)
# Register get_value
from Products.ERP5Form.ProxyField import registerOriginalGetValueClassAndArgument
registerOriginalGetValueClassAndArgument(PlanningBox, 'default')
This diff is collapsed.
...@@ -174,7 +174,3 @@ class RelationStringField(ZMIField): ...@@ -174,7 +174,3 @@ class RelationStringField(ZMIField):
else: else:
result = ZMIField.get_value(self, id, REQUEST=REQUEST, **kw) result = ZMIField.get_value(self, id, REQUEST=REQUEST, **kw)
return result return result
# Register get_value
from Products.ERP5Form.ProxyField import registerOriginalGetValueClassAndArgument
registerOriginalGetValueClassAndArgument(RelationStringField, 'items')
...@@ -1368,6 +1368,7 @@ class TestKeyAuthentication(RoleManagementTestCase): ...@@ -1368,6 +1368,7 @@ class TestKeyAuthentication(RoleManagementTestCase):
"""This test also uses web and dms """This test also uses web and dms
""" """
return super(TestKeyAuthentication, self).getBusinessTemplateList() + ( return super(TestKeyAuthentication, self).getBusinessTemplateList() + (
'erp5_core_proxy_field_legacy', # for erp5_web
'erp5_base', 'erp5_web', 'erp5_ingestion', 'erp5_dms', 'erp5_administration') 'erp5_base', 'erp5_web', 'erp5_ingestion', 'erp5_dms', 'erp5_administration')
......
...@@ -57,7 +57,7 @@ class Getter(BaseGetter): ...@@ -57,7 +57,7 @@ class Getter(BaseGetter):
def __call__(self, instance): def __call__(self, instance):
portal_workflow = instance.getPortalObject().portal_workflow portal_workflow = instance.getPortalObject().portal_workflow
wf = portal_workflow.getWorkflowById(self._key) wf = portal_workflow._getOb(self._key)
return wf._getWorkflowStateOf(instance, id_only=1) return wf._getWorkflowStateOf(instance, id_only=1)
psyco.bind(__call__) psyco.bind(__call__)
...@@ -82,7 +82,7 @@ class TitleGetter(BaseGetter): ...@@ -82,7 +82,7 @@ class TitleGetter(BaseGetter):
def __call__(self, instance): def __call__(self, instance):
portal_workflow = instance.getPortalObject().portal_workflow portal_workflow = instance.getPortalObject().portal_workflow
wf = portal_workflow.getWorkflowById(self._key) wf = portal_workflow._getOb(self._key)
return wf._getWorkflowStateOf(instance).title return wf._getWorkflowStateOf(instance).title
psyco.bind(__call__) psyco.bind(__call__)
...@@ -93,7 +93,7 @@ class TranslatedGetter(Getter): ...@@ -93,7 +93,7 @@ class TranslatedGetter(Getter):
def __call__(self, instance): def __call__(self, instance):
portal = instance.getPortalObject() portal = instance.getPortalObject()
wf = portal.portal_workflow.getWorkflowById(self._key) wf = portal.portal_workflow._getOb(self._key)
state_id = wf._getWorkflowStateOf(instance, id_only=1) state_id = wf._getWorkflowStateOf(instance, id_only=1)
warn('Translated workflow state getters, such as %s are deprecated' % warn('Translated workflow state getters, such as %s are deprecated' %
self._id, DeprecationWarning) self._id, DeprecationWarning)
...@@ -110,7 +110,7 @@ class TranslatedTitleGetter(TitleGetter): ...@@ -110,7 +110,7 @@ class TranslatedTitleGetter(TitleGetter):
portal = instance.getPortalObject() portal = instance.getPortalObject()
localizer = portal.Localizer localizer = portal.Localizer
wf_id = self._key wf_id = self._key
wf = portal.portal_workflow.getWorkflowById(wf_id) wf = portal.portal_workflow._getOb(wf_id)
selected_language = localizer.get_selected_language() selected_language = localizer.get_selected_language()
state_title = wf._getWorkflowStateOf(instance).title state_title = wf._getWorkflowStateOf(instance).title
msg_id = '%s [state in %s]' % (state_title, wf_id) msg_id = '%s [state in %s]' % (state_title, wf_id)
......
...@@ -3379,7 +3379,7 @@ class Base( ...@@ -3379,7 +3379,7 @@ class Base(
There's no check that the document is actually chained to the workflow, There's no check that the document is actually chained to the workflow,
it's caller responsability to perform this check. it's caller responsability to perform this check.
""" """
workflow = self.portal_workflow.getWorkflowById(wf_id) workflow = self.portal_workflow._getOb(wf_id, None)
if workflow is not None: if workflow is not None:
changed = workflow.updateRoleMappingsFor(self) changed = workflow.updateRoleMappingsFor(self)
if changed: if changed:
......
...@@ -114,7 +114,7 @@ class WorkflowTool(BaseTool): ...@@ -114,7 +114,7 @@ class WorkflowTool(BaseTool):
raise WorkflowException('No workflow provides the destination state %r'\ raise WorkflowException('No workflow provides the destination state %r'\
% state_id) % state_id)
else: else:
workflow = self.getWorkflowById(wf_id) workflow = self._getOb(wf_id, None)
if workflow is None: if workflow is None:
raise WorkflowException('Requested workflow definition not found.') raise WorkflowException('Requested workflow definition not found.')
...@@ -209,7 +209,7 @@ class WorkflowTool(BaseTool): ...@@ -209,7 +209,7 @@ class WorkflowTool(BaseTool):
Message(u"No workflow provides the '${action_id}' action.", Message(u"No workflow provides the '${action_id}' action.",
mapping={'action_id': action})) mapping={'action_id': action}))
else: else:
workflow = self.getWorkflowById(workflow_id) workflow = self._getOb(workflow_id, None)
if workflow is None: if workflow is None:
raise WorkflowException(Message(u'Requested workflow not found.')) raise WorkflowException(Message(u'Requested workflow not found.'))
...@@ -349,7 +349,7 @@ class WorkflowTool(BaseTool): ...@@ -349,7 +349,7 @@ class WorkflowTool(BaseTool):
worklist_dict = {} worklist_dict = {}
wf_ids = self.objectIds() wf_ids = self.objectIds()
for wf_id in wf_ids: for wf_id in wf_ids:
wf = self.getWorkflowById(wf_id) wf = self._getOb(wf_id, None)
if wf is not None: if wf is not None:
a = wf.getWorklistVariableMatchDict(info, check_guard=False) a = wf.getWorklistVariableMatchDict(info, check_guard=False)
if a is not None: if a is not None:
......
...@@ -160,7 +160,7 @@ def canDoActionFor(self, ob, action, wf_id=None, guard_kw={}): ...@@ -160,7 +160,7 @@ def canDoActionFor(self, ob, action, wf_id=None, guard_kw={}):
if wf_id is None: if wf_id is None:
workflow_list = self.getWorkflowValueListFor(ob) or () workflow_list = self.getWorkflowValueListFor(ob) or ()
else: else:
workflow = self.getWorkflowById(wf_id) workflow = self._getOb(wf_id, None)
if workflow: if workflow:
workflow_list = (workflow,) workflow_list = (workflow,)
else: else:
......
...@@ -32,6 +32,7 @@ from hashlib import md5 ...@@ -32,6 +32,7 @@ from hashlib import md5
from warnings import warn from warnings import warn
from ExtensionClass import pmc_init_of from ExtensionClass import pmc_init_of
from DateTime import DateTime from DateTime import DateTime
import mock
import Products.ZMySQLDA.DA import Products.ZMySQLDA.DA
from Products.ZMySQLDA.DA import Connection as ZMySQLDA_Connection from Products.ZMySQLDA.DA import Connection as ZMySQLDA_Connection
...@@ -376,12 +377,25 @@ class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase): ...@@ -376,12 +377,25 @@ class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase):
def pinDateTime(self, date_time): def pinDateTime(self, date_time):
# pretend time has stopped at a certain date (i.e. the test runs # pretend time has stopped at a certain date (i.e. the test runs
# infinitely fast), to avoid errors on tests that are started # infinitely fast), for example to avoid errors on tests that are started
# just before midnight. # just before midnight.
# This can be used as a context manager, otherwise use unpinDateTime to
# reset.
global _pinned_date_time global _pinned_date_time
assert date_time is None or isinstance(date_time, DateTime) assert date_time is None or isinstance(date_time, DateTime)
_pinned_date_time = date_time _pinned_date_time = date_time
unpinDateTime = self.unpinDateTime
class UnpinContextManager(object):
def __enter__(self):
return self
def __exit__(self, *args):
unpinDateTime()
return UnpinContextManager()
def unpinDateTime(self):
self.pinDateTime(None)
def setTimeZoneToUTC(self): def setTimeZoneToUTC(self):
# Make sure tests runs with UTC timezone. Some tests are checking values # Make sure tests runs with UTC timezone. Some tests are checking values
# based on now, and this could give unexpected results: # based on now, and this could give unexpected results:
...@@ -390,11 +404,11 @@ class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase): ...@@ -390,11 +404,11 @@ class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase):
# UTC # UTC
os.environ['TZ'] = "UTC" os.environ['TZ'] = "UTC"
time.tzset() time.tzset()
DateTime._isDST = False
DateTime._localzone = DateTime._localzone0 = DateTime._localzone1 = "UTC"
def unpinDateTime(self): mock.patch.object(sys.modules['DateTime.DateTime'], '_localzone0', new='UTC').start()
self.pinDateTime(None) mock.patch.object(sys.modules['DateTime.DateTime'], '_localzone1', new='UTC').start()
mock.patch.object(sys.modules['DateTime.DateTime'], '_multipleZones', new=False).start()
def getDefaultSystemPreference(self): def getDefaultSystemPreference(self):
id = 'default_system_preference' id = 'default_system_preference'
......
...@@ -406,7 +406,7 @@ class TestZodbPropertySheet(ERP5TypeTestCase): ...@@ -406,7 +406,7 @@ class TestZodbPropertySheet(ERP5TypeTestCase):
def getBusinessTemplateList(self): def getBusinessTemplateList(self):
return 'erp5_base', return 'erp5_core_proxy_field_legacy', 'erp5_base'
def _newStandardProperty(self, operation_type): def _newStandardProperty(self, operation_type):
""" """
......
# Specify user login/password used to run the tests. # Specify user login/password used to run the tests.
# <password> and <user_quantity> will be automatically replaced by testnode for each configuration # <password> and <user_quantity> will be automatically replaced by testnode for each configuration
user_tuple = tuple([('scalability_user_%i' % x, "<password>") for x in range(0, <user_quantity>)]) user_tuple = tuple([('scalability_user_%i' % x, "<password>") for x in range(0, int('<user_quantity>'))])
\ No newline at end of file
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