Commit 76060d41 authored by Jérome Perrin's avatar Jérome Perrin

Rework testXHTML to test all actions

testXHTML was testing only document contained in modules, this take another approach to test all portal types and fixes the problems found now that we test views of all portal types.

The number of tests in testXHTML also increase from 864 to 1137.

/reviewed-on nexedi/erp5!992
parents 69b88b4b 56e16adc
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
<key> <string>categories</string> </key> <key> <string>categories</string> </key>
<value> <value>
<tuple> <tuple>
<string>action_type/object_view</string> <string>action_type/object_jump</string>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>category</string> </key> <key> <string>category</string> </key>
<value> <string>object_view</string> </value> <value> <string>object_jump</string> </value>
</item> </item>
<item> <item>
<key> <string>condition</string> </key> <key> <string>condition</string> </key>
......
...@@ -4,5 +4,5 @@ ...@@ -4,5 +4,5 @@
a simple basic implementation a simple basic implementation
""" """
context.REQUEST.RESPONSE.redirect( \ context.REQUEST.RESPONSE.redirect( \
'http://www.openstreetmap.org/?lat=%s&lon=%s&zoom=17&layers=M' \ 'https://www.openstreetmap.org/?lat=%s&lon=%s&zoom=17&layers=M' \
%(context.getLatitude(), context.getLongitude())) %(context.getLatitude(), context.getLongitude()))
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
</item> </item>
<item> <item>
<key> <string>visible</string> </key> <key> <string>visible</string> </key>
<value> <int>1</int> </value> <value> <int>0</int> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -9,8 +9,7 @@ folder_id = context.getParentValue().getId() # replace aq_parent by getParentVal ...@@ -9,8 +9,7 @@ folder_id = context.getParentValue().getId() # replace aq_parent by getParentVal
history_list = [] history_list = []
business_template = None business_template = None
for bt in portal.portal_templates.searchFolder(installation_state='installed'): for bt in portal.portal_templates.contentValues():
# if installation_state not in catalog, we have to check manually
if bt.getInstallationState() != 'installed': if bt.getInstallationState() != 'installed':
continue continue
if folder_id in bt.getTemplateSkinIdList(): if folder_id in bt.getTemplateSkinIdList():
......
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Listbox</string> </value> <value> <string>History</string> </value>
</item> </item>
</dictionary> </dictionary>
</value> </value>
......
...@@ -33,6 +33,8 @@ Glossary Module | update_workflows_by_english_glossary ...@@ -33,6 +33,8 @@ Glossary Module | update_workflows_by_english_glossary
Glossary Module | view Glossary Module | view
Glossary Term | view Glossary Term | view
Preference | vcs Preference | vcs
PyData Script | repository_history_view
Python Script | repository_history_view
Template Tool | bt_vcs_history Template Tool | bt_vcs_history
Template Tool | migrate_business_template_list Template Tool | migrate_business_template_list
Template Tool | search_portal_type Template Tool | search_portal_type
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>eu_linear_amortisation_method_view_details</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Amortisation Details</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Immobilisation_euLinearAmortisationMethodViewDetails</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>object/Immobilisation_isUsingEuLinearAmortisationMethod</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>eu_no_amortisation_amortisation_method_view_details</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Amortisation Details</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Immobilisation_euNoAmortisationAmortisationMethodViewDetails</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>object/Immobilisation_isUsingEuNoAmortisationAmortisationMethod</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>fr_actual_use_amortisation_method_view_details</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Amortisation Details</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Immobilisation_frActualUseAmortisationMethodViewDetails</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>object/Immobilisation_isUsingFrActualUseAmortisationMethod</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>fr_degressive_amortisation_method_view_details</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Amortisation Details</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Immobilisation_frDegressiveAmortisationMethodViewDetails</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>object/Immobilisation_isUsingFrDegressiveAmortisationMethod</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>fr_uncontinuous_degressive_amortisation_method_view_details</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Amortisation Details</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Immobilisation_frUncontinuousDegressiveAmortisationMethodViewDetails</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>object/Immobilisation_isUsingFrUncontinuousDegressiveAmortisationMethod</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -5,11 +5,6 @@ Amortisation Transaction Line | view ...@@ -5,11 +5,6 @@ Amortisation Transaction Line | view
Amortisation Transaction | causality_report Amortisation Transaction | causality_report
Amortisation Transaction | jump_causality_items Amortisation Transaction | jump_causality_items
Amortisation Transaction | view Amortisation Transaction | view
Delivery Cell | eu_linear_amortisation_method_view_details
Delivery Cell | eu_no_amortisation_amortisation_method_view_details
Delivery Cell | fr_actual_use_amortisation_method_view_details
Delivery Cell | fr_degressive_amortisation_method_view_details
Delivery Cell | fr_uncontinuous_degressive_amortisation_method_view_details
Immobilisation Line | eu_linear_amortisation_method_view_details Immobilisation Line | eu_linear_amortisation_method_view_details
Immobilisation Line | eu_no_amortisation_amortisation_method_view_details Immobilisation Line | eu_no_amortisation_amortisation_method_view_details
Immobilisation Line | fr_actual_use_amortisation_method_view_details Immobilisation Line | fr_actual_use_amortisation_method_view_details
......
...@@ -50,6 +50,7 @@ class IdGenerator(Base): ...@@ -50,6 +50,7 @@ class IdGenerator(Base):
# Declarative property # Declarative property
property_sheets = ( PropertySheet.Base, property_sheets = ( PropertySheet.Base,
PropertySheet.DublinCore,
PropertySheet.Version, PropertySheet.Version,
PropertySheet.Reference) PropertySheet.Reference)
......
...@@ -126,5 +126,7 @@ ...@@ -126,5 +126,7 @@
</portal_type> </portal_type>
<portal_type id="Types Tool"> <portal_type id="Types Tool">
<item>Base Type</item> <item>Base Type</item>
<item>Preference Tool Type</item>
<item>Preference Type</item>
</portal_type> </portal_type>
</allowed_content_type_list> </allowed_content_type_list>
\ No newline at end of file
...@@ -137,7 +137,7 @@ ...@@ -137,7 +137,7 @@
</item> </item>
<item> <item>
<key> <string>editable</string> </key> <key> <string>editable</string> </key>
<value> <int>0</int> </value> <value> <int>1</int> </value>
</item> </item>
<item> <item>
<key> <string>enabled</string> </key> <key> <string>enabled</string> </key>
...@@ -149,7 +149,7 @@ ...@@ -149,7 +149,7 @@
</item> </item>
<item> <item>
<key> <string>extra</string> </key> <key> <string>extra</string> </key>
<value> <string></string> </value> <value> <string>disabled</string> </value>
</item> </item>
<item> <item>
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
......
...@@ -9,7 +9,10 @@ cache_stats = context.getPortalObject().portal_caches.getCacheTotalMemorySize() ...@@ -9,7 +9,10 @@ cache_stats = context.getPortalObject().portal_caches.getCacheTotalMemorySize()
cache_factory_list_stats = cache_stats['stats'] cache_factory_list_stats = cache_stats['stats']
cache_plugin_id = context.getId() cache_plugin_id = context.getId()
cache_factory_id = context.getParentValue().getId() cache_factory_id = context.getParentValue().getId()
cache_plugin_stats = cache_factory_list_stats[cache_factory_id] cache_plugin_stats = cache_factory_list_stats.get(
cache_factory_id,
{'cp_cache_keys_total_size': {},
'total': None})
cache_plugin_stats_data = cache_plugin_stats['cp_cache_keys_total_size'] cache_plugin_stats_data = cache_plugin_stats['cp_cache_keys_total_size']
if statistics_criteria == 'total': if statistics_criteria == 'total':
......
...@@ -112,12 +112,10 @@ Property Sheet | view ...@@ -112,12 +112,10 @@ Property Sheet | view
Property Type Validity Constraint | predicate Property Type Validity Constraint | predicate
Property Type Validity Constraint | view Property Type Validity Constraint | view
PyData Script | proxy_role_view PyData Script | proxy_role_view
PyData Script | repository_history_view
PyData Script | run PyData Script | run
PyData Script | view PyData Script | view
Python Script | filter_view Python Script | filter_view
Python Script | proxy_role_view Python Script | proxy_role_view
Python Script | repository_history_view
Python Script | run Python Script | run
Python Script | view Python Script | view
Ram Cache | statistics Ram Cache | statistics
......
...@@ -65,4 +65,6 @@ Simulation Movement | Applied Rule ...@@ -65,4 +65,6 @@ Simulation Movement | Applied Rule
Simulation Tool | Applied Rule Simulation Tool | Applied Rule
Template Tool | Business Template Template Tool | Business Template
Trash Tool | Trash Bin Trash Tool | Trash Bin
Types Tool | Base Type Types Tool | Base Type
\ No newline at end of file Types Tool | Preference Tool Type
Types Tool | Preference Type
\ No newline at end of file
...@@ -36,6 +36,7 @@ from requests.packages.urllib3.util.retry import Retry ...@@ -36,6 +36,7 @@ from requests.packages.urllib3.util.retry import Retry
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
from Testing import ZopeTestCase from Testing import ZopeTestCase
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import addUserToDeveloperRole
from Products.CMFCore.utils import getToolByName from Products.CMFCore.utils import getToolByName
from zLOG import LOG from zLOG import LOG
# You can invoke same tests in your favourite collection of business templates # You can invoke same tests in your favourite collection of business templates
...@@ -507,6 +508,7 @@ class TestXHTML(TestXHTMLMixin): ...@@ -507,6 +508,7 @@ class TestXHTML(TestXHTMLMixin):
uf._doAddUser('seb', '', ['Manager'], []) uf._doAddUser('seb', '', ['Manager'], [])
self.loginByUserName('seb') self.loginByUserName('seb')
addUserToDeveloperRole('seb') # required to create content in portal_components
self.enableDefaultSitePreference() self.enableDefaultSitePreference()
def enableDefaultSitePreference(self): def enableDefaultSitePreference(self):
...@@ -653,7 +655,7 @@ def validate_xhtml(validator, source, view_name, bt_name): ...@@ -653,7 +655,7 @@ def validate_xhtml(validator, source, view_name, bt_name):
return len(message) == 1, '\n'.join(message) return len(message) == 1, '\n'.join(message)
def makeTestMethod(validator, module_id, portal_type, view_name, bt_name): def makeTestMethod(validator, portal_type, view_name, bt_name):
def createSubContent(content, portal_type_list): def createSubContent(content, portal_type_list):
if not portal_type_list: if not portal_type_list:
...@@ -664,102 +666,76 @@ def makeTestMethod(validator, module_id, portal_type, view_name, bt_name): ...@@ -664,102 +666,76 @@ def makeTestMethod(validator, module_id, portal_type, view_name, bt_name):
content.newContent(portal_type=portal_type_list[0]), content.newContent(portal_type=portal_type_list[0]),
portal_type_list[1:]) portal_type_list[1:])
def testMethod(self):
module = getattr(self.portal, module_id)
portal_type_list = portal_type.split('/')
object = createSubContent(module, portal_type_list) def findContentChain(portal, target_portal_type):
view = getattr(object, view_name) # type: (erp5.portal_type.ERP5Site,str) -> Tuple[erp5.portal_type.Folder, Tuple[str, ...]]
"""Returns the module and the chain of portal types to create a document of target_portal_type.
This tries all allowed content types up to three levels and if not found, use portal_trash,
which allows anything.
"""
# These types have a special `newContent` which does not really follow the interface, we
# cannot not use them as container.
invalid_container_type_set = {
'Session Tool',
'Contribution Tool',
}
# first look modules and their content to find a real container chain.
for module in portal.contentValues():
module_type = module.getTypeInfo()
if module_type is not None:
if module_type.getId() == target_portal_type:
return module, ()
if module_type.isTypeFilterContentType() \
and module_type.getId() not in invalid_container_type_set:
for allowed_type in module.allowedContentTypes():
# Actions on portal_actions are global actions which can be rendered on any context.
# We don't test them on all portal types, only on the first type "top level document"
if target_portal_type in ('portal_actions', allowed_type.getId()):
return module, (allowed_type.getId(),)
for sub_allowed_type in allowed_type.getTypeAllowedContentTypeList():
if target_portal_type == sub_allowed_type:
return module, (allowed_type.getId(), target_portal_type)
if sub_allowed_type in portal.portal_types:
for sub_sub_allowed_type in portal.portal_types[
sub_allowed_type].getTypeAllowedContentTypeList():
if target_portal_type == sub_sub_allowed_type:
return module, (
allowed_type.getId(),
sub_allowed_type,
target_portal_type,
)
# we did not find a valid chain of containers, so we'll fallback to creating
# in portal_trash, which allow anything.
# We still make one attempt at finding a valid container.
for ti in portal.portal_types.contentValues():
if ti.getId() not in invalid_container_type_set\
and target_portal_type in ti.getTypeAllowedContentTypeList():
return portal.portal_trash, (ti.getId(), target_portal_type,)
# no suitable container found, use directly portal_trash.
ZopeTestCase._print(
'Could not find container for %s. Using portal_trash as a container\n'
% target_portal_type)
return portal.portal_trash, (target_portal_type,)
def testMethod(self):
module, portal_type_list = findContentChain(
self.portal,
portal_type)
document = createSubContent(module, portal_type_list)
view = getattr(document, view_name)
self.assert_(*validate_xhtml( validator=validator, self.assert_(*validate_xhtml( validator=validator,
source=view(), source=view(),
view_name=view_name, view_name=view_name,
bt_name=bt_name)) bt_name=bt_name))
return testMethod return testMethod
def testPortalTypeViewRecursivly(test_class, validator, module_id,
business_template_info, business_template_info_list, portal_type_list, def addTestMethodDynamically(
portal_type_path_dict, base_path, tested_portal_type_list): test_class,
''' validator,
This function go on all portal_type recursivly if the portal_type could target_business_templates,
contain other portal_types and make a test for all view that have action expected_failure_list=()):
'''
# iteration over all allowed portal_types inside the module/portal_type
for portal_type in portal_type_list:
portal_path = portal_type_path_dict[portal_type]
if portal_type not in tested_portal_type_list:
# this portal type haven't been tested yet
backuped_module_id = module_id
backuped_business_template_info = business_template_info
if not business_template_info.actions.has_key(portal_type):
# search in other bt :
business_template_info = None
for bt_info in business_template_info_list:
if bt_info.actions.has_key(portal_type):
business_template_info = bt_info
break
if not business_template_info:
LOG("Can't find the action :", 0, portal_type)
break
# create the object in portal_trash module
module_id = 'portal_trash'
for business_template_info in business_template_info_list:
if portal_type not in business_template_info.actions:
continue
for action_information in business_template_info.actions[portal_type]:
if (action_information['category'] in ('object_view', 'object_list') and
action_information['visible']==1 and
action_information['action'].startswith('string:${object_url}/') and
len(action_information['action'].split('/'))==2):
view_name = action_information['action'].split('/')[-1].split('?')[0]
method = makeTestMethod(validator,
module_id,
portal_path,
view_name,
business_template_info.title)
method_name = ('test_%s_%s_%s' %
(business_template_info.title,
str(portal_type).replace(' ','_'), # can be unicode
view_name))
method.__name__ = method_name
setattr(test_class, method_name, method)
module_id = backuped_module_id
# add the portal_type to the tested portal_types. This avoid to test many
# times a Portal Type wich is many bt.
tested_portal_type_list.append(portal_type)
new_portal_type_list = []
for tmp_business_template_info in business_template_info_list:
new_portal_type_list.extend(tmp_business_template_info.allowed_content_types.get(portal_type, ()))
new_portal_type_path_dict = {}
if base_path != '':
next_base_path = '%s/%s' % (base_path, portal_type)
# Module portal_type not to have been added to the path because
# this portal type object already existing
elif 'Module' not in portal_type:
next_base_path = portal_type
else:
next_base_path = ''
for pt in new_portal_type_list:
if next_base_path != '' and 'Module' not in pt:
new_portal_type_path_dict[pt] = '%s/%s' % (next_base_path, pt)
else:
new_portal_type_path_dict[pt] = pt
testPortalTypeViewRecursivly(test_class=test_class,
validator=validator,
module_id=module_id,
business_template_info=backuped_business_template_info,
business_template_info_list=business_template_info_list,
portal_type_list=new_portal_type_list,
portal_type_path_dict=new_portal_type_path_dict,
base_path=next_base_path,
tested_portal_type_list=tested_portal_type_list)
def addTestMethodDynamically(test_class, validator, target_business_templates):
from Products.ERP5.tests.utils import BusinessTemplateInfoTar from Products.ERP5.tests.utils import BusinessTemplateInfoTar
from Products.ERP5.tests.utils import BusinessTemplateInfoDir from Products.ERP5.tests.utils import BusinessTemplateInfoDir
business_template_info_list = [] business_template_info_list = []
...@@ -771,21 +747,27 @@ def addTestMethodDynamically(test_class, validator, target_business_templates): ...@@ -771,21 +747,27 @@ def addTestMethodDynamically(test_class, validator, target_business_templates):
business_template_info = BusinessTemplateInfoTar(url) business_template_info = BusinessTemplateInfoTar(url)
business_template_info_list.append(business_template_info) business_template_info_list.append(business_template_info)
tested_portal_type_list = []
for business_template_info in business_template_info_list: for business_template_info in business_template_info_list:
for module_id, module_portal_type in business_template_info.modules.items(): for portal_type, action_information_list in business_template_info.actions.items():
portal_type_list = [module_portal_type, ] + \ for action_information in action_information_list:
business_template_info.allowed_content_types.get(module_portal_type, []) if (action_information['category'] in ('object_view', 'object_list') and
portal_type_path_dict = dict(zip(portal_type_list, portal_type_list)) action_information['visible']==1 and
testPortalTypeViewRecursivly(test_class=test_class, action_information['action'].startswith('string:${object_url}/') and
validator=validator, len(action_information['action'].split('/'))==2):
module_id=module_id, view_name = action_information['action'].split('/')[-1].split('?')[0]
business_template_info=business_template_info, method = makeTestMethod(
business_template_info_list=business_template_info_list, validator,
portal_type_list=portal_type_list, portal_type,
portal_type_path_dict=portal_type_path_dict, view_name,
base_path = '', business_template_info.title)
tested_portal_type_list=tested_portal_type_list) method_name = ('test_%s_%s_%s' %
(business_template_info.title,
str(portal_type).replace(' ','_'), # can be unicode
view_name))
method.__name__ = method_name
if method_name in expected_failure_list:
method = unittest.expectedFailure(method)
setattr(test_class, method_name, method)
# Two validators are available : nu and tidy # Two validators are available : nu and tidy
...@@ -815,7 +797,20 @@ def test_suite(): ...@@ -815,7 +797,20 @@ def test_suite():
# add erp5_core to the list here to not return it # add erp5_core to the list here to not return it
# on getBusinessTemplateList call # on getBusinessTemplateList call
addTestMethodDynamically(TestXHTML, validator, addTestMethodDynamically(TestXHTML, validator,
('erp5_core',) + TestXHTML.getBusinessTemplateList()) ('erp5_core',) + TestXHTML.getBusinessTemplateList(),
expected_failure_list=(
# this view needs VCS preference set (this test suite does not support
# setting preferences, but this might be a way to fix this).
'test_erp5_forge_Business_Template_BusinessTemplate_viewVcsStatus',
# this view only works when solver decision has a relation to a solver.
# One way to fix this would be to allow a custom "init script" to be called
# on a portal type.
'test_erp5_simulation_Solver_Decision_SolverDecision_viewConfiguration',
# there's no container accepting delivery cell, but delivery cell has
# an interaction workflow which assumes delivery cell is contained in
# a delivery.
'test_erp5_trade_Delivery_Cell_DeliveryCell_view',
))
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestXHTML)) suite.addTest(unittest.makeSuite(TestXHTML))
return suite return suite
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