Commit 98a0ddb4 authored by Jérome Perrin's avatar Jérome Perrin

Merge remote-tracking branch 'upstream/master' into zope4py3

parents 14a2a922 dfd1873b
Pipeline #39372 failed with stage
in 0 seconds
line_list = []
for line in context.contentValues(
portal_type=context.getPortalAccountingMovementTypeList()):
has_amount = True
if side == 'source':
account = line.getSourceValue(portal_type='Account')
if test_compta_demat_compatibility:
has_amount = bool(
line.getSourceTotalAssetPrice()
if line.hasSourceTotalAssetPrice() else line.getQuantity())
else:
assert side == 'destination'
account = line.getDestinationValue(portal_type='Account')
if test_compta_demat_compatibility:
has_amount = bool(
line.getDestinationTotalAssetPrice()
if line.hasDestinationTotalAssetPrice() else line.getQuantity())
if account is not None and has_amount:
line_list.append(line)
return line_list
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>side, test_compta_demat_compatibility</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>AccountingTransaction_getFECXMLAccountingTransactionLineList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<ecriture xmlns:tal="http://xml.zope.org/namespaces/tal"> <ecriture
xmlns:tal="http://xml.zope.org/namespaces/tal"
tal:define="line_list python:context.AccountingTransaction_getFECXMLAccountingTransactionLineList('destination', options['test_compta_demat_compatibility'])"
tal:condition="line_list">
<EcritureNum tal:content="context/getDestinationReference">Specific Reference</EcritureNum> <EcritureNum tal:content="context/getDestinationReference">Specific Reference</EcritureNum>
<EcritureDate tal:content="python: context.getStopDate().strftime('%Y-%m-%d')">Specific Date</EcritureDate> <EcritureDate tal:content="python: context.getStopDate().strftime('%Y-%m-%d')">Specific Date</EcritureDate>
<EcritureLib tal:content="context/getTitle">Title</EcritureLib> <EcritureLib tal:content="context/getTitle">Title</EcritureLib>
...@@ -7,9 +10,8 @@ ...@@ -7,9 +10,8 @@
<tal:block tal:replace="nothing"><EcritureLet></EcritureLet> <tal:block tal:replace="nothing"><EcritureLet></EcritureLet>
<DateLet></DateLet></tal:block> <DateLet></DateLet></tal:block>
<ValidDate tal:content="python: context.AccountingTransaction_getDeliverDate().strftime('%Y-%m-%d')">Modification Date</ValidDate> <ValidDate tal:content="python: context.AccountingTransaction_getDeliverDate().strftime('%Y-%m-%d')">Modification Date</ValidDate>
<tal:block tal:repeat="line python:context.contentValues(portal_type=context.getPortalAccountingMovementTypeList())"><ligne <tal:block tal:repeat="line line_list"><ligne
tal:define="account python:line.getDestinationValue(portal_type='Account')" tal:define="account python:line.getDestinationValue(portal_type='Account')">
tal:condition="python: account is not None and ((line.getDestinationTotalAssetPrice() if line.hasDestinationTotalAssetPrice() else line.getQuantity()) or not options['test_compta_demat_compatibility'])">
<CompteNum tal:content="account/Account_getGapId">Reference Compte (Account_getGapId)</CompteNum> <CompteNum tal:content="account/Account_getGapId">Reference Compte (Account_getGapId)</CompteNum>
<CompteLib tal:content="line/Movement_getDestinationCompteLib">Translated Title Compte</CompteLib> <CompteLib tal:content="line/Movement_getDestinationCompteLib">Translated Title Compte</CompteLib>
<tal:block tal:condition="python: account.getAccountType() in ('asset/receivable', 'liability/payable')" <tal:block tal:condition="python: account.getAccountType() in ('asset/receivable', 'liability/payable')"
......
<ecriture xmlns:tal="http://xml.zope.org/namespaces/tal"> <ecriture
xmlns:tal="http://xml.zope.org/namespaces/tal"
tal:define="line_list python:context.AccountingTransaction_getFECXMLAccountingTransactionLineList('source', options['test_compta_demat_compatibility'])"
tal:condition="line_list">
<EcritureNum tal:content="context/getSourceReference">Specific Reference</EcritureNum> <EcritureNum tal:content="context/getSourceReference">Specific Reference</EcritureNum>
<EcritureDate tal:content="python: context.getStartDate().strftime('%Y-%m-%d')">Specific Date</EcritureDate> <EcritureDate tal:content="python: context.getStartDate().strftime('%Y-%m-%d')">Specific Date</EcritureDate>
<EcritureLib tal:content="context/getTitle">Title</EcritureLib> <EcritureLib tal:content="context/getTitle">Title</EcritureLib>
...@@ -7,9 +10,8 @@ ...@@ -7,9 +10,8 @@
<tal:block tal:replace="nothing"><EcritureLet></EcritureLet> <tal:block tal:replace="nothing"><EcritureLet></EcritureLet>
<DateLet></DateLet></tal:block> <DateLet></DateLet></tal:block>
<ValidDate tal:content="python: context.AccountingTransaction_getDeliverDate().strftime('%Y-%m-%d')">Modification Date</ValidDate> <ValidDate tal:content="python: context.AccountingTransaction_getDeliverDate().strftime('%Y-%m-%d')">Modification Date</ValidDate>
<tal:block tal:repeat="line python:context.contentValues(portal_type=context.getPortalAccountingMovementTypeList())"><ligne <tal:block tal:repeat="line line_list"><ligne
tal:define="account python:line.getSourceValue(portal_type='Account')" tal:define="account python:line.getSourceValue(portal_type='Account')">
tal:condition="python: account is not None and ((line.getSourceTotalAssetPrice() if line.hasSourceTotalAssetPrice() else line.getQuantity()) or not options['test_compta_demat_compatibility'])">
<CompteNum tal:content="account/Account_getGapId">Reference Compte (Account_getGapId)</CompteNum> <CompteNum tal:content="account/Account_getGapId">Reference Compte (Account_getGapId)</CompteNum>
<CompteLib tal:content="line/Movement_getSourceCompteLib">Translated Title Compte</CompteLib> <CompteLib tal:content="line/Movement_getSourceCompteLib">Translated Title Compte</CompteLib>
<tal:block tal:condition="python: account.getAccountType() in ('asset/receivable', 'liability/payable')" <tal:block tal:condition="python: account.getAccountType() in ('asset/receivable', 'liability/payable')"
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
""" """
import six import six
import unittest
import zipfile import zipfile
if six.PY2: if six.PY2:
from email import message_from_string as message_from_bytes from email import message_from_string as message_from_bytes
...@@ -46,6 +45,7 @@ from AccessControl.SecurityManagement import newSecurityManager ...@@ -46,6 +45,7 @@ from AccessControl.SecurityManagement import newSecurityManager
from erp5.component.test.testAccounting import AccountingTestCase from erp5.component.test.testAccounting import AccountingTestCase
class TestAccounting_l10n_fr(AccountingTestCase): class TestAccounting_l10n_fr(AccountingTestCase):
"""Test Accounting L10N FR """Test Accounting L10N FR
""" """
...@@ -405,7 +405,29 @@ class TestAccounting_l10n_fr(AccountingTestCase): ...@@ -405,7 +405,29 @@ class TestAccounting_l10n_fr(AccountingTestCase):
def test_ValidDate(self): def test_ValidDate(self):
account_module = self.portal.account_module account_module = self.portal.account_module
invoice = self._makeOne( invoice_source = self._makeOne(
portal_type='Purchase Invoice Transaction',
title='Premiere Ecriture',
simulation_state='delivered',
reference='1',
source_section_value=self.organisation_module.supplier,
stop_date=DateTime(2014, 2, 2),
lines=(dict(source_value=account_module.payable,
source_debit=132.00),
dict(source_value=account_module.refundable_vat,
source_credit=22.00),
dict(source_value=account_module.goods_purchase,
source_credit=110.00)))
assert invoice_source.workflow_history['accounting_workflow'][-1]['action'] == 'deliver'
invoice_source.workflow_history['accounting_workflow'][-1]['time'] = DateTime(2001, 2, 3)
tree = etree.fromstring(
invoice_source.AccountingTransaction_viewAsSourceFECXML(
test_compta_demat_compatibility=True))
self.assertEqual(tree.xpath('//ValidDate/text()'), ['2001-02-03'])
invoice_destination = self._makeOne(
portal_type='Purchase Invoice Transaction', portal_type='Purchase Invoice Transaction',
title='Premiere Ecriture', title='Premiere Ecriture',
simulation_state='delivered', simulation_state='delivered',
...@@ -419,15 +441,11 @@ class TestAccounting_l10n_fr(AccountingTestCase): ...@@ -419,15 +441,11 @@ class TestAccounting_l10n_fr(AccountingTestCase):
dict(destination_value=account_module.goods_purchase, dict(destination_value=account_module.goods_purchase,
destination_credit=110.00))) destination_credit=110.00)))
assert invoice.workflow_history['accounting_workflow'][-1]['action'] == 'deliver' assert invoice_destination.workflow_history['accounting_workflow'][-1]['action'] == 'deliver'
invoice.workflow_history['accounting_workflow'][-1]['time'] = DateTime(2001, 2, 3) invoice_destination.workflow_history['accounting_workflow'][-1]['time'] = DateTime(2001, 2, 3)
tree = etree.fromstring( tree = etree.fromstring(
invoice.AccountingTransaction_viewAsSourceFECXML( invoice_destination.AccountingTransaction_viewAsDestinationFECXML(
test_compta_demat_compatibility=True))
self.assertEqual(tree.xpath('//ValidDate/text()'), ['2001-02-03'])
tree = etree.fromstring(
invoice.AccountingTransaction_viewAsDestinationFECXML(
test_compta_demat_compatibility=True)) test_compta_demat_compatibility=True))
self.assertEqual(tree.xpath('//ValidDate/text()'), ['2001-02-03']) self.assertEqual(tree.xpath('//ValidDate/text()'), ['2001-02-03'])
...@@ -551,9 +569,92 @@ class TestAccounting_l10n_fr(AccountingTestCase): ...@@ -551,9 +569,92 @@ class TestAccounting_l10n_fr(AccountingTestCase):
'//ecriture/PieceRef[text()="source"]/../ligne/Credit/text()'), '//ecriture/PieceRef[text()="source"]/../ligne/Credit/text()'),
['0.00', '40.00', '200.00']) ['0.00', '40.00', '200.00'])
def test_SkipEmptyTransactions(self):
# Don't include transactions without lines, because they are
# reported as invalid by Test Compta Demat
account_module = self.portal.account_module
self._makeOne(
portal_type='Purchase Invoice Transaction',
title='destination 0',
simulation_state='delivered',
reference='destination_0_lines',
source_section_value=self.organisation_module.supplier,
stop_date=DateTime(2014, 2, 2),
lines=(
dict(
destination_value=account_module.payable, destination_debit=0.00),
dict(
destination_value=account_module.payable,
destination_debit=10000.00,
destination_asset_debit=0.00),
dict(
destination_value=account_module.refundable_vat,
destination_credit=0.00),
dict(
destination_value=account_module.refundable_vat,
destination_credit=10000.00,
destination_asset_credit=0.00)))
self._makeOne(
portal_type='Purchase Invoice Transaction',
title='destination no',
simulation_state='delivered',
reference='destination_no_lines',
source_section_value=self.organisation_module.supplier,
stop_date=DateTime(2014, 2, 2),
lines=())
self._makeOne(
portal_type='Sale Invoice Transaction',
title='source 0',
simulation_state='delivered',
reference='source_0_lines',
destination_section_value=self.organisation_module.client_2,
start_date=DateTime(2014, 3, 1),
lines=(
dict(source_value=account_module.receivable, source_debit=0.00),
dict(source_value=account_module.collected_vat, source_credit=0.00)))
self._makeOne(
portal_type='Sale Invoice Transaction',
title='source no',
simulation_state='delivered',
reference='source_no_lines',
destination_section_value=self.organisation_module.client_2,
start_date=DateTime(2014, 3, 1),
lines=())
self.tic()
self.portal.accounting_module.AccountingTransactionModule_viewFrenchAccountingTransactionFile(
section_category='group/demo_group',
section_category_strict=False,
at_date=DateTime(2014, 12, 31),
simulation_state=['delivered'])
self.tic()
tree = etree.fromstring(self.getFECFromMailMessage())
self.validateFECXML(tree)
self.assertEqual(tree.xpath('//ecriture'), [])
def test_PieceRefDefaultValue(self): def test_PieceRefDefaultValue(self):
account_module = self.portal.account_module account_module = self.portal.account_module
invoice = self._makeOne( invoice_source = self._makeOne(
portal_type='Purchase Invoice Transaction',
title='Premiere Ecriture',
simulation_state='delivered',
source_section_value=self.organisation_module.supplier,
stop_date=DateTime(2014, 2, 2),
lines=(
dict(
source_value=account_module.payable, source_debit=132.00),
dict(
source_value=account_module.refundable_vat,
source_credit=22.00),
dict(
source_value=account_module.goods_purchase,
source_credit=110.00)))
invoice_source.setSourceReference('source_reference')
invoice_destination = self._makeOne(
portal_type='Purchase Invoice Transaction', portal_type='Purchase Invoice Transaction',
title='Premiere Ecriture', title='Premiere Ecriture',
simulation_state='delivered', simulation_state='delivered',
...@@ -568,16 +669,14 @@ class TestAccounting_l10n_fr(AccountingTestCase): ...@@ -568,16 +669,14 @@ class TestAccounting_l10n_fr(AccountingTestCase):
dict( dict(
destination_value=account_module.goods_purchase, destination_value=account_module.goods_purchase,
destination_credit=110.00))) destination_credit=110.00)))
invoice_destination.setDestinationReference('destination_reference')
invoice.setSourceReference('source_reference')
invoice.setDestinationReference('destination_reference')
tree = etree.fromstring( tree = etree.fromstring(
invoice.AccountingTransaction_viewAsSourceFECXML( invoice_source.AccountingTransaction_viewAsSourceFECXML(
test_compta_demat_compatibility=True)) test_compta_demat_compatibility=True))
self.assertEqual(tree.xpath('//EcritureNum/text()'), ['source_reference']) self.assertEqual(tree.xpath('//EcritureNum/text()'), ['source_reference'])
self.assertEqual(tree.xpath('//PieceRef/text()'), ['source_reference']) self.assertEqual(tree.xpath('//PieceRef/text()'), ['source_reference'])
tree = etree.fromstring( tree = etree.fromstring(
invoice.AccountingTransaction_viewAsDestinationFECXML( invoice_destination.AccountingTransaction_viewAsDestinationFECXML(
test_compta_demat_compatibility=True)) test_compta_demat_compatibility=True))
self.assertEqual( self.assertEqual(
tree.xpath('//EcritureNum/text()'), ['destination_reference']) tree.xpath('//EcritureNum/text()'), ['destination_reference'])
...@@ -585,12 +684,12 @@ class TestAccounting_l10n_fr(AccountingTestCase): ...@@ -585,12 +684,12 @@ class TestAccounting_l10n_fr(AccountingTestCase):
tree.xpath('//PieceRef/text()'), ['destination_reference']) tree.xpath('//PieceRef/text()'), ['destination_reference'])
tree = etree.fromstring( tree = etree.fromstring(
invoice.AccountingTransaction_viewAsSourceFECXML( invoice_source.AccountingTransaction_viewAsSourceFECXML(
test_compta_demat_compatibility=False)) test_compta_demat_compatibility=False))
self.assertEqual(tree.xpath('//EcritureNum/text()'), ['source_reference']) self.assertEqual(tree.xpath('//EcritureNum/text()'), ['source_reference'])
self.assertEqual([n.text for n in tree.xpath('//PieceRef')], [None]) self.assertEqual([n.text for n in tree.xpath('//PieceRef')], [None])
tree = etree.fromstring( tree = etree.fromstring(
invoice.AccountingTransaction_viewAsDestinationFECXML( invoice_destination.AccountingTransaction_viewAsDestinationFECXML(
test_compta_demat_compatibility=False)) test_compta_demat_compatibility=False))
self.assertEqual( self.assertEqual(
tree.xpath('//EcritureNum/text()'), ['destination_reference']) tree.xpath('//EcritureNum/text()'), ['destination_reference'])
...@@ -661,9 +760,3 @@ class TestAccounting_l10n_fr(AccountingTestCase): ...@@ -661,9 +760,3 @@ class TestAccounting_l10n_fr(AccountingTestCase):
tree.xpath( tree.xpath(
'//ecriture/PieceRef[text()="source"]/../ligne/Credit/text()'), '//ecriture/PieceRef[text()="source"]/../ligne/Credit/text()'),
['0.00', '345.00']) ['0.00', '345.00'])
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestAccounting_l10n_fr))
return suite
from Products.ERP5Type.Document import newTempBase
from DateTime import DateTime
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
portal = context.getPortalObject()
# Use only the first entry. This prevents change the rss content
# too often whenever multiple activities are failing over time.
message_list = portal.portal_activities.getMessageTempObjectList(processing_node=-2,
count=1)
if not len(message_list):
return []
message = portal.Base_translateString('You have one or more activity failures.')
# Make compatible with renderjs_runner
web_site = context.getWebSiteValue()
if web_site is None:
web_site_url = portal.absolute_url()
else:
web_site_url = web_site.absolute_url() + "/#"
return [
newTempBase(portal, "rss_entry",
uid=message_list[0].uid,
date=DateTime().earliestTime(),
link="%s/portal_activities" % web_site_url,
title=message)]
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None, **kw</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_getPendingErrorList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>action_title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string>application/x-www-form-urlencoded</string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_viewPendingErrorListAsRSS</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>ERP5Site_viewPendingErrorListAsRSS</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>rss_view</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Pending Errors</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>all_columns</string>
<string>columns</string>
<string>count_method</string>
<string>editable_columns</string>
<string>hide_rows_on_no_search_criterion</string>
<string>lines</string>
<string>list_method</string>
<string>portal_types</string>
<string>search_columns</string>
<string>selection_name</string>
<string>sort</string>
<string>sort_columns</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>all_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>title</string>
<string>title</string>
</tuple>
<tuple>
<string>link</string>
<string>link</string>
</tuple>
<tuple>
<string>uid</string>
<string>guid</string>
</tuple>
<tuple>
<string>date</string>
<string>pubDate</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>count_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_list_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>hide_rows_on_no_search_criterion</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>lines</string> </key>
<value> <int>30</int> </value>
</item>
<item>
<key> <string>list_method</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>search_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string>pending_failure_selection</string> </value>
</item>
<item>
<key> <string>sort</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>sort_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Pending Errors</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Method" module="Products.Formulator.MethodField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>method_name</string> </key>
<value> <string>ERP5Site_getPendingErrorList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
# #
############################################################################## ##############################################################################
import random
import transaction import transaction
from Products.ERP5Type.tests.SecurityTestCase import SecurityTestCase from Products.ERP5Type.tests.SecurityTestCase import SecurityTestCase
from Products.ERP5Type.tests.utils import DummyMailHost from Products.ERP5Type.tests.utils import DummyMailHost
...@@ -67,11 +66,6 @@ class TestOfficeJSSDKConfigurator(SecurityTestCase): ...@@ -67,11 +66,6 @@ class TestOfficeJSSDKConfigurator(SecurityTestCase):
# Execute the business configuration if not installed # Execute the business configuration if not installed
business_configuration = self.getBusinessConfiguration() business_configuration = self.getBusinessConfiguration()
if (business_configuration.getSimulationState() != 'installed'): if (business_configuration.getSimulationState() != 'installed'):
self.portal.portal_caches.erp5_site_global_id = '%s' % random.random()
self.portal.portal_caches._p_changed = 1
self.commit()
self.portal.portal_caches.updateCache()
self.bootstrapSite() self.bootstrapSite()
self.commit() self.commit()
......
...@@ -35,7 +35,6 @@ MAIN FILE: generate book in different output formats ...@@ -35,7 +35,6 @@ MAIN FILE: generate book in different output formats
import re import re
import six import six
from Products.PythonScripts.standard import html_quote
from Products.ERP5Type.Utils import str2bytes, bytes2str, unicode2str from Products.ERP5Type.Utils import str2bytes, bytes2str, unicode2str
from base64 import b64encode from base64 import b64encode
...@@ -75,15 +74,15 @@ if not book_content: ...@@ -75,15 +74,15 @@ if not book_content:
return return
book_aggregate_list = [] book_aggregate_list = []
book_revision = book.getRevision() book_revision = book.getRevision()
book_modification_date = book.getModificationDate() book_modification_date = book.getEffectiveDate() or book.getModificationDate()
book_language = book.getLanguage() book_language = book.getLanguage()
# XXX sigh for passing "" around # XXX sigh for passing "" around
book_reference = html_quote(override_document_reference) if override_document_reference else book.getReference() book_reference = override_document_reference if override_document_reference else book.getReference()
book_short_title = html_quote(override_document_short_title) if override_document_short_title else book.getShortTitle() book_short_title = override_document_short_title if override_document_short_title else book.getShortTitle()
book_version = html_quote(override_document_version) if override_document_version else book.getVersion() or "001" book_version = override_document_version if override_document_version else book.getVersion() or "001"
book_description = html_quote(override_document_description) if override_document_description else book.getDescription() book_description = override_document_description if override_document_description else book.getDescription()
book_title = html_quote(override_document_title) if override_document_title else book.getTitle() book_title = override_document_title if override_document_title else book.getTitle()
if six.PY2 and isinstance(book_content, six.text_type): if six.PY2 and isinstance(book_content, six.text_type):
book_content = unicode2str(book_content) book_content = unicode2str(book_content)
...@@ -99,7 +98,7 @@ if override_batch_mode: ...@@ -99,7 +98,7 @@ if override_batch_mode:
book_revision = "1" book_revision = "1"
book_short_date = book_modification_date.strftime('%Y-%m-%d') book_short_date = book_modification_date.strftime('%Y-%m-%d')
if book_language: if book_language and 'AcceptLanguage' in book.REQUEST:
book.REQUEST['AcceptLanguage'].set(book_language, 10) book.REQUEST['AcceptLanguage'].set(book_language, 10)
else: else:
book_language = blank book_language = blank
......
...@@ -497,3 +497,13 @@ class TestCorporateIdentityMethod(ERP5TypeTestCase): ...@@ -497,3 +497,13 @@ class TestCorporateIdentityMethod(ERP5TypeTestCase):
) )
self.assertEqual(output, None) self.assertEqual(output, None)
def test_escapeOverridden(self):
book_export = self.portal.web_page_module.template_test_book_input_003_en_html.WebPage_viewAsBook(
format="html",
override_document_description='<script>alert("description");</script>',
override_document_short_title='<script>alert("short title");</script>',
override_document_title='<script>alert("title");</script>',
override_document_version='<script>alert("001");</script>',
override_document_reference='<script>alert("reference");</script>',
)
self.assertNotIn("<script>alert", book_export)
...@@ -127,7 +127,7 @@ ...@@ -127,7 +127,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: here.getResourceValue().getVariationBaseCategoryItemList(omit_optional_variation=1, display_id=\'translated_title\')</string> </value> <value> <string>python: here.getResourceValue().getVariationBaseCategoryItemList(display_id=\'translated_title\')</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
# #
############################################################################## ##############################################################################
import random
import unittest import unittest
from Products.ERP5Type.tests.ERP5TypeFunctionalTestCase import \ from Products.ERP5Type.tests.ERP5TypeFunctionalTestCase import \
...@@ -91,11 +90,6 @@ class TestZeleniumStandaloneUserTutorial(ERP5TypeFunctionalTestCase): ...@@ -91,11 +90,6 @@ class TestZeleniumStandaloneUserTutorial(ERP5TypeFunctionalTestCase):
# Execute the business configuration if not installed # Execute the business configuration if not installed
business_configuration = self.getBusinessConfiguration() business_configuration = self.getBusinessConfiguration()
if (business_configuration.getSimulationState() != 'installed'): if (business_configuration.getSimulationState() != 'installed'):
self.portal.portal_caches.erp5_site_global_id = '%s' % random.random()
self.portal.portal_caches._p_changed = 1
self.commit()
self.portal.portal_caches.updateCache()
self.bootstrapSite() self.bootstrapSite()
self.commit() self.commit()
......
...@@ -1775,7 +1775,9 @@ class ActivityTool (BaseTool): ...@@ -1775,7 +1775,9 @@ class ActivityTool (BaseTool):
return RESPONSE.redirect(self.absolute_url_path() + return RESPONSE.redirect(self.absolute_url_path() +
'/manageActivitiesAdvanced?manage_tabs_message=Activities%20Cleared') '/manageActivitiesAdvanced?manage_tabs_message=Activities%20Cleared')
security.declarePublic('getMessageTempObjectList')
security.declareProtected( CMFCorePermissions.ManagePortal,
'getMessageTempObjectList')
def getMessageTempObjectList(self, **kw): def getMessageTempObjectList(self, **kw):
""" """
Get object list of messages waiting in queues Get object list of messages waiting in queues
......
...@@ -315,6 +315,7 @@ class Test(ERP5TypeTestCase): ...@@ -315,6 +315,7 @@ class Test(ERP5TypeTestCase):
except ImportError: except ImportError:
import traceback import traceback
traceback.print_exc(file=global_stream) traceback.print_exc(file=global_stream)
traceback.print_exc() # also print on stderr
global_stream.seek(0) global_stream.seek(0)
return global_stream.read() return global_stream.read()
finally: finally:
......
...@@ -300,9 +300,6 @@ if memcache is not None: ...@@ -300,9 +300,6 @@ if memcache is not None:
if memcached_plugin is None: if memcached_plugin is None:
raise ValueError('Memcached Plugin does not exists: %r' % ( raise ValueError('Memcached Plugin does not exists: %r' % (
plugin_path, )) plugin_path, ))
global_prefix = self.erp5_site_global_id
if global_prefix:
key_prefix = global_prefix + '_' + key_prefix
return SharedDict(memcached_plugin.getConnection(), prefix=key_prefix) return SharedDict(memcached_plugin.getConnection(), prefix=key_prefix)
InitializeClass(MemcachedTool) InitializeClass(MemcachedTool)
......
...@@ -291,12 +291,18 @@ def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, ** ...@@ -291,12 +291,18 @@ def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, **
output = stream output = stream
if stream is None: if stream is None:
output = StringIO() output = StringIO()
def print_and_write(data): class StderrIOWrapper:
sys.stderr.write(data) def __init__(self, wrapped):
sys.stderr.flush() self._wrapped_io = wrapped
return output.write(data) def write(self, data):
print_and_write("**Running Live Test:\n") sys.stderr.write(data)
ZopeTestCase._print = print_and_write return self._wrapped_io.write(data)
def __getattr__(self, attr):
return getattr(self._wrapped_io, attr)
output = StderrIOWrapper(output)
output.write("**Running Live Test:\n")
ZopeTestCase._print = output.write
with warnings.catch_warnings(): with warnings.catch_warnings():
warnings.simplefilter(kw['warnings']) warnings.simplefilter(kw['warnings'])
...@@ -306,6 +312,6 @@ def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, ** ...@@ -306,6 +312,6 @@ def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, **
from AccessControl.SecurityManagement import getSecurityManager, setSecurityManager from AccessControl.SecurityManagement import getSecurityManager, setSecurityManager
sm = getSecurityManager() sm = getSecurityManager()
try: try:
result = TestRunner(stream=output, verbosity=verbosity).run(suite) TestRunner(stream=output, verbosity=verbosity).run(suite)
finally: finally:
setSecurityManager(sm) setSecurityManager(sm)
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
__version__ = '0.3.0' __version__ = '0.3.0'
import base64
import errno import errno
import os import os
import random import random
...@@ -17,6 +16,7 @@ import string ...@@ -17,6 +16,7 @@ import string
import sys import sys
import time import time
import traceback import traceback
import warnings
from six.moves import configparser from six.moves import configparser
from contextlib import contextmanager from contextlib import contextmanager
from io import BytesIO from io import BytesIO
...@@ -273,6 +273,10 @@ class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase, functional.F ...@@ -273,6 +273,10 @@ class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase, functional.F
def newPassword(self): def newPassword(self):
""" Generate a password """ """ Generate a password """
forced_password = os.environ.get('insecure_erp5_test_password')
if forced_password:
warnings.warn("Using password set from environment variable")
return forced_password
return ''.join(random.SystemRandom().sample(string.ascii_letters + string.digits, 20)) return ''.join(random.SystemRandom().sample(string.ascii_letters + string.digits, 20))
def login(self, user_name=None, quiet=0): def login(self, user_name=None, quiet=0):
...@@ -1317,10 +1321,6 @@ class ERP5TypeCommandLineTestCase(ERP5TypeTestCaseMixin): ...@@ -1317,10 +1321,6 @@ class ERP5TypeCommandLineTestCase(ERP5TypeTestCaseMixin):
reindex=reindex, reindex=reindex,
create_activities=create_activities, create_activities=create_activities,
**kw) **kw)
sql = kw.get('erp5_sql_connection_string')
if sql:
app[portal_name]._setProperty('erp5_site_global_id',
base64.standard_b64encode(str2bytes(sql)))
if not quiet: if not quiet:
ZopeTestCase._print('done (%.3fs)\n' % (time.time() - _start)) ZopeTestCase._print('done (%.3fs)\n' % (time.time() - _start))
# Release locks # Release locks
...@@ -1637,7 +1637,7 @@ optimize() ...@@ -1637,7 +1637,7 @@ optimize()
@onsetup @onsetup
def fortify(): def fortify():
'''Add some extra checks that we don't have at runtime, not to slow down the '''Add some extra checks that we don't have at runtime, not to slow down the
system. system and adjust the system for unit test environment.
''' '''
# check that we don't store persistent objects in cache # check that we don't store persistent objects in cache
from Products.ERP5Type.CachePlugins.BaseCache import CacheEntry from Products.ERP5Type.CachePlugins.BaseCache import CacheEntry
...@@ -1662,5 +1662,15 @@ def fortify(): ...@@ -1662,5 +1662,15 @@ def fortify():
activity_kw, *args, **kw) activity_kw, *args, **kw)
Message.__init__ = __init__ Message.__init__ = __init__
# Inject a prefix to keys used by memcached, so that when we are running
# multiple runUnitTest process using the same memcached instance they don't
# have conflicting keys.
import Products.ERP5Type.Tool.MemcachedTool
original_encodeKey = Products.ERP5Type.Tool.MemcachedTool.encodeKey
prefix = str2bytes(''.join(random.sample(string.ascii_letters + string.digits, 6)))
def encodeKey(key):
return prefix + original_encodeKey(key)
Products.ERP5Type.Tool.MemcachedTool.encodeKey = encodeKey
fortify() fortify()
...@@ -11,6 +11,8 @@ class SetupSiteError(Exception): ...@@ -11,6 +11,8 @@ class SetupSiteError(Exception):
def patch(): def patch():
import six import six
import contextlib
import sys
import traceback import traceback
from unittest import TestCase, TextTestResult, TextTestRunner from unittest import TestCase, TextTestResult, TextTestRunner
...@@ -21,6 +23,20 @@ def patch(): ...@@ -21,6 +23,20 @@ def patch():
TestCase.assertRaisesRegex = getattr(TestCase, 'assertRaisesRegexp') TestCase.assertRaisesRegex = getattr(TestCase, 'assertRaisesRegexp')
TestCase.assertRegex = getattr(TestCase, 'assertRegexpMatches') TestCase.assertRegex = getattr(TestCase, 'assertRegexpMatches')
TestCase.assertCountEqual = TestCase.assertItemsEqual TestCase.assertCountEqual = TestCase.assertItemsEqual
@contextlib.contextmanager
def subTest(self, msg='', **params):
yield
TestCase.subTest = subTest
if sys.version_info < (3, 11):
def enterContext(self, cm):
cls = type(cm)
enter = cls.__enter__
exit = cls.__exit__
result = enter(cm)
self.addCleanup(exit, cm, None, None, None)
return result
TestCase.enterContext = enterContext
TextTestResult_addError = six.get_unbound_function(TextTestResult.addError) TextTestResult_addError = six.get_unbound_function(TextTestResult.addError)
def addError(self, test, err): def addError(self, test, err):
......
...@@ -150,6 +150,7 @@ Options: ...@@ -150,6 +150,7 @@ Options:
timer service. timer service.
This option only makes sense with --activity_node= This option only makes sense with --activity_node=
or when not specifying a test to run. or when not specifying a test to run.
--insecure_password=PWD Use `PWD` instead of generating random passwords for users.
--zserver=ADDRESS[,...] Make ZServer listen on given IPv4 address. --zserver=ADDRESS[,...] Make ZServer listen on given IPv4 address.
Addresses can be given in the following syntaxs: Addresses can be given in the following syntaxs:
- HOST:PORT - HOST:PORT
...@@ -793,7 +794,8 @@ def main(argument_list=None): ...@@ -793,7 +794,8 @@ def main(argument_list=None):
"sys_path=", "sys_path=",
"instance_home=", "instance_home=",
"log_directory=", "log_directory=",
"with_wendelin_core" "with_wendelin_core",
"insecure_password=",
]) ])
except getopt.GetoptError as msg: except getopt.GetoptError as msg:
usage(sys.stderr, msg) usage(sys.stderr, msg)
...@@ -914,6 +916,8 @@ def main(argument_list=None): ...@@ -914,6 +916,8 @@ def main(argument_list=None):
_log_directory = os.path.abspath(arg) _log_directory = os.path.abspath(arg)
elif opt == "--with_wendelin_core": elif opt == "--with_wendelin_core":
os.environ["with_wendelin_core"] = "1" os.environ["with_wendelin_core"] = "1"
elif opt == "--insecure_password":
os.environ["insecure_erp5_test_password"] = arg
setupWarnings() setupWarnings()
......
...@@ -3255,17 +3255,9 @@ class Test(ERP5TypeTestCase): ...@@ -3255,17 +3255,9 @@ class Test(ERP5TypeTestCase):
self.assertNotEqual(os, None) self.assertNotEqual(os, None)
''' '''
def testRunLiveTest(self): def _runLiveTest(self, test_name):
""" """Runs a live test from portal_components
Create a new ZODB Test Component and try to run it as a live tests and
check the expected output
""" """
# First try with a test which run successfully
source_code = self._getValidSourceCode()
component = self._newComponent('testRunLiveTest', source_code)
component.validate()
self.tic()
from Products.ERP5Type.tests.runUnitTest import ERP5TypeTestLoader from Products.ERP5Type.tests.runUnitTest import ERP5TypeTestLoader
ERP5TypeTestLoader_loadTestsFromNames = ERP5TypeTestLoader.loadTestsFromNames ERP5TypeTestLoader_loadTestsFromNames = ERP5TypeTestLoader.loadTestsFromNames
def loadTestsFromNames(self, *args, **kwargs): def loadTestsFromNames(self, *args, **kwargs):
...@@ -3287,6 +3279,35 @@ class Test(ERP5TypeTestCase): ...@@ -3287,6 +3279,35 @@ class Test(ERP5TypeTestCase):
return ret return ret
# ERP5TypeLiveTestCase.runLiveTest patches ERP5TypeTestCase bases, thus it
# needs to be restored after calling runLiveTest
base_tuple = ERP5TypeTestCase.__bases__
ERP5TypeTestLoader.loadTestsFromNames = loadTestsFromNames
from six.moves import cStringIO as StringIO
stderr = StringIO()
_real_stderr = sys.stderr
sys.stderr = stderr
try:
self._component_tool.runLiveTest(test_name)
finally:
ERP5TypeTestCase.__bases__ = base_tuple
ERP5TypeTestLoader.loadTestsFromNames = ERP5TypeTestLoader_loadTestsFromNames
sys.stderr = _real_stderr
test_output = self._component_tool.readTestOutput()
self.assertEqual(stderr.getvalue(), test_output)
return test_output
def testRunLiveTest(self):
"""
Create a new ZODB Test Component and try to run it as a live tests and
check the expected output
"""
# First try with a test which run successfully
source_code = self._getValidSourceCode()
component = self._newComponent('testRunLiveTest', source_code)
component.validate()
self.tic()
self.assertEqual(component.getValidationState(), 'validated') self.assertEqual(component.getValidationState(), 'validated')
self.assertModuleImportable('testRunLiveTest') self.assertModuleImportable('testRunLiveTest')
self._component_tool.reset(force=True, self._component_tool.reset(force=True,
...@@ -3295,19 +3316,7 @@ class Test(ERP5TypeTestCase): ...@@ -3295,19 +3316,7 @@ class Test(ERP5TypeTestCase):
# set a request key, that should not be set from the test request # set a request key, that should not be set from the test request
self.portal.REQUEST.set('foo', 'something from main request') self.portal.REQUEST.set('foo', 'something from main request')
def runLiveTest(test_name): output = self._runLiveTest('testRunLiveTest')
# ERP5TypeLiveTestCase.runLiveTest patches ERP5TypeTestCase bases, thus it
# needs to be restored after calling runLiveTest
base_tuple = ERP5TypeTestCase.__bases__
ERP5TypeTestLoader.loadTestsFromNames = loadTestsFromNames
try:
self._component_tool.runLiveTest(test_name)
finally:
ERP5TypeTestCase.__bases__ = base_tuple
ERP5TypeTestLoader.loadTestsFromNames = ERP5TypeTestLoader_loadTestsFromNames
return self._component_tool.readTestOutput()
output = runLiveTest('testRunLiveTest')
expected_msg_re = re.compile('Ran 1 test.*OK', re.DOTALL) expected_msg_re = re.compile('Ran 1 test.*OK', re.DOTALL)
self.assertRegex(output, expected_msg_re) self.assertRegex(output, expected_msg_re)
...@@ -3325,7 +3334,7 @@ class Test(ERP5TypeTestCase): ...@@ -3325,7 +3334,7 @@ class Test(ERP5TypeTestCase):
self._component_tool.reset(force=True, self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True) reset_portal_type_at_transaction_boundary=True)
output = runLiveTest('testRunLiveTest') output = self._runLiveTest('testRunLiveTest')
expected_msg_re = re.compile(r'Ran 2 tests.*FAILED \(failures=1\)', re.DOTALL) expected_msg_re = re.compile(r'Ran 2 tests.*FAILED \(failures=1\)', re.DOTALL)
self.assertRegex(output, expected_msg_re) self.assertRegex(output, expected_msg_re)
...@@ -3350,7 +3359,7 @@ class Test(ERP5TypeTestCase): ...@@ -3350,7 +3359,7 @@ class Test(ERP5TypeTestCase):
self._component_tool.reset(force=True, self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True) reset_portal_type_at_transaction_boundary=True)
output = runLiveTest('testRunLiveTest') output = self._runLiveTest('testRunLiveTest')
expected_msg_re = re.compile('Ran 3 test.*OK', re.DOTALL) expected_msg_re = re.compile('Ran 3 test.*OK', re.DOTALL)
self.assertRegex(output, expected_msg_re) self.assertRegex(output, expected_msg_re)
...@@ -3364,44 +3373,11 @@ break_at_import() ...@@ -3364,44 +3373,11 @@ break_at_import()
component.validate() component.validate()
self.tic() self.tic()
from Products.ERP5Type.tests.runUnitTest import ERP5TypeTestLoader
ERP5TypeTestLoader_loadTestsFromNames = ERP5TypeTestLoader.loadTestsFromNames
def loadTestsFromNames(self, *args, **kwargs):
"""
Monkey patched to simulate a reset right after importing the ZODB Test
Component whose Unit Tests are going to be executed
"""
ret = ERP5TypeTestLoader_loadTestsFromNames(self, *args, **kwargs)
from Products.ERP5.ERP5Site import getSite
getSite().portal_components.reset(force=True)
# Simulate a new REQUEST while the old one has been GC'ed
import erp5.component
erp5.component.ref_manager.clear()
import gc
gc.collect()
return ret
self.assertEqual(component.getValidationState(), 'validated') self.assertEqual(component.getValidationState(), 'validated')
self._component_tool.reset(force=True, self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True) reset_portal_type_at_transaction_boundary=True)
def runLiveTest(test_name): output = self._runLiveTest('testRunLiveTestImportError')
# ERP5TypeLiveTestCase.runLiveTest patches ERP5TypeTestCase bases, thus it
# needs to be restored after calling runLiveTest
base_tuple = ERP5TypeTestCase.__bases__
ERP5TypeTestLoader.loadTestsFromNames = loadTestsFromNames
try:
self._component_tool.runLiveTest(test_name)
finally:
ERP5TypeTestCase.__bases__ = base_tuple
ERP5TypeTestLoader.loadTestsFromNames = ERP5TypeTestLoader_loadTestsFromNames
return self._component_tool.readTestOutput()
output = runLiveTest('testRunLiveTestImportError')
relative_url = 'portal_components/test.erp5.testRunLiveTestImportError' relative_url = 'portal_components/test.erp5.testRunLiveTestImportError'
if six.PY2: if six.PY2:
module_file = '<' + relative_url + '>' module_file = '<' + relative_url + '>'
...@@ -3417,7 +3393,7 @@ break_at_import() ...@@ -3417,7 +3393,7 @@ break_at_import()
%(error_message)s %(error_message)s
''' % dict(module_file=module_file, error_message=error_message), output) ''' % dict(module_file=module_file, error_message=error_message), output)
output = runLiveTest('testDoesNotExist_import_error_because_module_does_not_exist') output = self._runLiveTest('testDoesNotExist_import_error_because_module_does_not_exist')
if six.PY2: if six.PY2:
expected_output = "ImportError: No module named testDoesNotExist_import_error_because_module_does_not_exist" expected_output = "ImportError: No module named testDoesNotExist_import_error_because_module_does_not_exist"
else: else:
......
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