[Erp5-report] r15257 - in /erp5/trunk/products/ERP5/tests: testXHTML.py utils.py

nobody at svn.erp5.org nobody at svn.erp5.org
Fri Jul 20 10:32:34 CEST 2007


Author: yusei
Date: Fri Jul 20 10:32:34 2007
New Revision: 15257

URL: http://svn.erp5.org?rev=15257&view=rev
Log:
Added a xhtml validation test for content views.

Added:
    erp5/trunk/products/ERP5/tests/testXHTML.py
    erp5/trunk/products/ERP5/tests/utils.py

Added: erp5/trunk/products/ERP5/tests/testXHTML.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/tests/testXHTML.py?rev=15257&view=auto
==============================================================================
--- erp5/trunk/products/ERP5/tests/testXHTML.py (added)
+++ erp5/trunk/products/ERP5/tests/testXHTML.py Fri Jul 20 10:32:34 2007
@@ -1,0 +1,176 @@
+##############################################################################
+#
+# Copyright (c) 2007 Nexedi SARL 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.
+#
+##############################################################################
+
+import os, sys
+if __name__ == '__main__':
+  execfile(os.path.join(sys.path[0], 'framework.py'))
+
+# Needed in order to have a log file inside the current folder
+os.environ['EVENT_LOG_FILE'] = os.path.join(os.getcwd(), 'zLOG.log')
+os.environ['EVENT_LOG_SEVERITY'] = '-300'
+
+from Testing import ZopeTestCase
+from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
+from Products.CMFCore.utils import getToolByName
+from AccessControl.SecurityManagement import newSecurityManager
+from zLOG import LOG
+import time
+
+try:
+  from transaction import get as get_transaction
+except ImportError:
+  pass
+
+#
+# Test Setting
+#
+INSTANCE_HOME = os.environ['INSTANCE_HOME']
+bt5_path = os.path.join(INSTANCE_HOME, 'bt5')
+# dependency order
+target_business_templates = (
+  'erp5_base',
+  'erp5_trade',
+  'erp5_mysql_innodb_catalog',
+
+  'erp5_pdf_editor',
+  'erp5_pdf_style',
+  'erp5_pdm',
+  'erp5_accounting',
+
+  'erp5_apparel',
+
+##   'erp5_banking_core',
+##   'erp5_banking_cash',
+##   'erp5_banking_check',
+##   'erp5_banking_inventory',
+
+  'erp5_budget',
+
+  'erp5_commerce',
+
+  'erp5_consulting',
+
+  'erp5_crm',
+
+  'erp5_web',
+  'erp5_dms',
+
+  'erp5_forge',
+
+  'erp5_immobilisation',
+
+  'erp5_item',
+
+  'erp5_mrp',
+
+  'erp5_payroll',
+
+  'erp5_project',
+)
+
+
+class TestXHTML(ERP5TypeTestCase):
+
+  run_all_test = 1
+
+  def getTitle(self):
+    return "XHTML Test"
+
+  def getBusinessTemplateList(self):
+    """  """
+    return target_business_templates
+
+  def afterSetUp(self):
+    self.portal = self.getPortal()
+    self.login()
+    self.enableDefaultSitePreference()
+
+  def login(self, quiet=0, run=run_all_test):
+    uf = self.getPortal().acl_users
+    uf._doAddUser('seb', '', ['Manager'], [])
+    uf._doAddUser('ERP5TypeTestCase', '', ['Manager'], [])
+    user = uf.getUserById('seb').__of__(uf)
+    newSecurityManager(None, user)
+
+  def enableDefaultSitePreference(self):
+    portal_preferences = getToolByName(self.portal, 'portal_preferences')
+    portal_workflow = getToolByName(self.portal, 'portal_workflow')
+    default_site_preference = portal_preferences.default_site_preference
+    portal_workflow.doActionFor(default_site_preference, 'enable_action')
+
+
+def validate_xhtml(source):
+  import popen2
+  stdout, stdin, stderr = popen2.popen3('/usr/bin/tidy -e -q -utf8')
+  stdin.write(source)
+  stdin.close()
+  for i in stderr:
+    data = i.split(' - ')
+    if len(data) >= 2:
+      if data[1].startswith('Error: '):
+        return False
+  return True
+
+
+def makeTestMethod(module_id, portal_type, view_name):
+  def testMethod(self):
+    module = getattr(self.portal, module_id)
+    content = module.newContent(portal_type=portal_type)
+    view = getattr(content, view_name)
+    self.assert_(validate_xhtml(view()))
+  return testMethod
+
+
+def addTestMethodDynamically():
+  from Products.ERP5.tests.utils import BusinessTemplateInfo
+  for i in target_business_templates:
+    business_template = os.path.join(bt5_path, '%s.bt5' % i)
+    business_template_info = BusinessTemplateInfo(business_template)
+    for module_id, module_portal_type in business_template_info.modules.items():
+      for portal_type in business_template_info.allowed_content_types.get(
+        module_portal_type, ()):
+        for action_information in business_template_info.actions[portal_type]:
+          if (action_information['category']=='object_view' and
+              action_information['visible']==1 and
+              action_information['text'].startswith('string:${object_url}/') and
+              len(action_information['text'].split('/'))==2):
+            view_name = action_information['text'].split('/')[-1]
+            method = makeTestMethod(module_id, portal_type, view_name)
+            method_name = 'test%s%s' % (portal_type, view_name)
+            setattr(TestXHTML, method_name, method)
+
+addTestMethodDynamically()
+
+
+if __name__ == '__main__':
+    framework()
+else:
+    import unittest
+    def test_suite():
+        suite = unittest.TestSuite()
+        suite.addTest(unittest.makeSuite(TestXHTML))
+        return suite

Added: erp5/trunk/products/ERP5/tests/utils.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/tests/utils.py?rev=15257&view=auto
==============================================================================
--- erp5/trunk/products/ERP5/tests/utils.py (added)
+++ erp5/trunk/products/ERP5/tests/utils.py Fri Jul 20 10:32:34 2007
@@ -1,0 +1,140 @@
+##############################################################################
+#
+# Copyright (c) 2007 Nexedi SARL 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.
+#
+##############################################################################
+
+import tarfile
+import xml.parsers.expat
+import xml.dom.minidom
+from urllib import url2pathname
+
+
+class BusinessTemplateInfo:
+
+  def __init__(self, tar_path):
+    self.tar = tarfile.open(tar_path, 'r:gz')
+    self.setUp()
+
+  def setUp(self):
+    self.title = ''
+    self.modules = {}
+    self.allowed_content_types = {}
+    self.actions = {}
+
+    self.setUpTitle()
+    self.setUpModules()
+    self.setUpAllowedContentTypes()
+    self.setUpActions()
+
+  def setUpTitle(self):
+    for tarinfo in self.tar.getmembers():
+      if tarinfo.name.endswith('/bt/title'):
+        self.title = self.tar.extractfile(tarinfo).read()
+
+  def setUpModules(self):
+    name = '%s/ModuleTemplateItem/' % self.title
+    for tarinfo in self.tar.getmembers():
+      if tarinfo.name.startswith(name) and tarinfo.type==tarfile.REGTYPE:
+        source = self.tar.extractfile(tarinfo).read()
+        doc = xml.dom.minidom.parseString(source)
+        module_id = doc.getElementsByTagName('id')[0].childNodes[0].data
+        portal_type = doc.getElementsByTagName('portal_type')[0].childNodes[0].data
+        self.modules[module_id] = portal_type
+
+  def setUpAllowedContentTypes(self):
+    name = '%s/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml' % self.title
+    try:
+      tarinfo = self.tar.getmember(name)
+    except KeyError:
+      return
+    source = self.tar.extractfile(tarinfo).read()
+    doc = xml.dom.minidom.parseString(source)
+    for portal_type_node in doc.getElementsByTagName('portal_type'):
+      portal_type = portal_type_node.getAttribute('id')
+      self.allowed_content_types[portal_type] = []
+      for item in portal_type_node.getElementsByTagName('item'):
+        self.allowed_content_types[portal_type].append(item.childNodes[0].data)
+
+  def setUpActions(self):
+    class Handler:
+      cur_key = None
+      old_tag = None
+      cur_tag = None
+      key_val = None
+      value_val = None
+
+      def __init__(self):
+        self.data = {}
+
+      def start(self, name, attrs):
+        if not name in ('item', 'key', 'value', 'string', 'int', 'float'):
+          return
+        self.old_tag = self.cur_tag
+        self.cur_tag = name
+        if name=='key':
+          self.cur_key = name
+
+      def end(self, name):
+        self.cur_tag = None
+        if name=='item':
+          self.data[self.key_val] = self.value_val
+          self.cur_key = None
+          self.key_val = None
+          self.value_val = None
+
+      def char(self, data):
+        if self.cur_tag in ('string', 'int', 'float'):
+          f = getattr(self, 'to%s' % self.cur_tag)
+          if self.old_tag=='key':
+            self.key_val = f(data)
+          elif self.old_tag=='value':
+            self.value_val = f(data)
+
+      def tostring(self, value):
+        return str(value)
+
+      def toint(self, value):
+        return int(value)
+
+      def tofloat(self, value):
+        return float(value)
+
+    def parse(source):
+      handler = Handler()
+      p = xml.parsers.expat.ParserCreate()
+      p.StartElementHandler = handler.start
+      p.EndElementHandler = handler.end
+      p.CharacterDataHandler = handler.char
+      p.Parse(source)
+      return handler.data
+
+    name = '%s/ActionTemplateItem/portal_types/' % self.title
+    for tarinfo in self.tar.getmembers():
+      if tarinfo.name.startswith(name) and tarinfo.type==tarfile.REGTYPE:
+        portal_type = url2pathname(tarinfo.name.split('/')[-2])
+        if not portal_type in self.actions:
+          self.actions[portal_type] = []
+        data = parse(self.tar.extractfile(tarinfo).read())
+        self.actions[portal_type].append(data)




More information about the Erp5-report mailing list