# -*- coding: utf-8 -*- ############################################################################## # # Copyright (c) 2010 Nexedi SARL and Contributors. All Rights Reserved. # Aurelien Calonne <aurel@nexedi.com> # # 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 import shutil import unittest import transaction from App.config import getConfiguration from Products.ERP5VCS.WorkingCopy import getVcsTool from Products.ERP5.Document.BusinessTemplate import \ BusinessTemplateMissingDependency from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase class TestTemplateTool(ERP5TypeTestCase): """ Test the template tool """ run_all_test = 1 quiet = 1 def getBusinessTemplateList(self): return ('erp5_base', 'erp5_csv_style') def getTitle(self): return "Template Tool" def afterSetUp(self): self.templates_tool = self.portal.portal_templates self.templates_tool.updateRepositoryBusinessTemplateList(\ ["http://www.erp5.org/dists/snapshot/bt5/",]) def beforeTearDown(self): uninstall_bt_list = ["erp5_odt_style", "erp5_pdm", 'erp5_accounting'] for bt_name in uninstall_bt_list: bt = self.templates_tool.getInstalledBusinessTemplate(bt_name) if (bt is not None) and bt.getInstallationState() == 'installed': bt.uninstall() self.stepTic() def testUpdateBT5FromRepository(self, quiet=quiet, run=run_all_test): """ Test the list of bt5 returned for upgrade """ # edit bt5 revision so that it will be marked as updatable bt_list = self.templates_tool.searchFolder(title='erp5_base') self.assertEquals(len(bt_list), 1) erp5_base = bt_list[0].getObject() try: erp5_base.edit(revision=int(erp5_base.getRevision()) - 10) updatable_bt_list = \ self.templates_tool.getRepositoryBusinessTemplateList(update_only=True) self.assertEqual( [i.title for i in updatable_bt_list if i.title == "erp5_base"], ["erp5_base"]) erp5_base.replace() updatable_bt_list = \ self.templates_tool.getRepositoryBusinessTemplateList(update_only=True) self.assertEqual( [i.title for i in updatable_bt_list if i.title == "erp5_base"], []) finally: erp5_base.edit(revision=int(erp5_base.getRevision()) + 10) def test_download_http(self): test_web = self.portal.portal_templates.download( 'http://www.erp5.org/dists/snapshot/test_bt5/test_web.bt5') self.assertEquals(test_web.getPortalType(), 'Business Template') self.assertEquals(test_web.getTitle(), 'test_web') self.assertTrue(test_web.getRevision()) def _svn_setup_ssl(self): """ Function used to trust in svn.erp5.org. """ trust_dict = dict(realm="https://svn.erp5.org:443", hostname="roundcube.nexedi.com", issuer_dname="Nexedi SA, Marcq en Baroeul, Nord Pas de Calais, FR", valid_from="Thu, 22 May 2008 13:43:01 GMT", valid_until="Sun, 20 May 2018 13:43:01 GMT", finger_print=\ "a1:f7:c6:bb:51:69:84:28:ac:58:af:9d:05:73:de:24:45:4d:a1:bb", failures=8) getVcsTool("svn").__of__(self.portal).acceptSSLServer(trust_dict) def test_download_svn(self): # if the page looks like a svn repository, template tool will use pysvn to # get the bt5. self._svn_setup_ssl() bt5_url = 'https://svn.erp5.org/repos/public/erp5/trunk/bt5/test_web' test_web = self.portal.portal_templates.download(bt5_url) self.assertEquals(test_web.getPortalType(), 'Business Template') self.assertEquals(test_web.getTitle(), 'test_web') self.assertTrue(test_web.getRevision()) def test_updateBusinessTemplateFromUrl_simple(self): """ Test updateBusinessTemplateFromUrl method By default if a new business template has revision >= previous one the new bt5 is not installed, only imported. """ self._svn_setup_ssl() template_tool = self.portal.portal_templates old_bt = template_tool.getInstalledBusinessTemplate('erp5_csv_style') # change revision to an old revision old_bt.setRevision(0.0001) url = 'https://svn.erp5.org/repos/public/erp5/trunk/bt5/erp5_csv_style' template_tool.updateBusinessTemplateFromUrl(url) new_bt = template_tool.getInstalledBusinessTemplate('erp5_csv_style') self.assertNotEquals(old_bt, new_bt) self.assertEquals('erp5_csv_style', new_bt.getTitle()) # Test Another time with definning an ID old_bt = new_bt old_bt.setRevision(0.0002) template_tool.updateBusinessTemplateFromUrl(url, id="new_erp5_csv_style") new_bt = template_tool.getInstalledBusinessTemplate('erp5_csv_style') self.assertNotEquals(old_bt, new_bt) self.assertEquals('erp5_csv_style', new_bt.getTitle()) self.assertEquals('new_erp5_csv_style', new_bt.getId()) # Test if the new instance with same revision is not installed. old_bt = new_bt template_tool.updateBusinessTemplateFromUrl(url, id="not_installed_bt5") new_bt = template_tool.getInstalledBusinessTemplate('erp5_csv_style') self.assertEquals(old_bt, new_bt) self.assertEquals('erp5_csv_style', new_bt.getTitle()) self.assertEquals('new_erp5_csv_style', new_bt.getId()) not_installed_bt5 = getattr(template_tool, "not_installed_bt5", None) self.assertNotEquals(not_installed_bt5, None) self.assertEquals('erp5_csv_style', not_installed_bt5.getTitle()) self.assertEquals(not_installed_bt5.getInstallationState(), "not_installed") self.assertEquals(not_installed_bt5.getRevision(), new_bt.getRevision()) def test_updateBusinessTemplateFromUrl_keep_list(self): """ Test updateBusinessTemplateFromUrl method """ self._svn_setup_ssl() template_tool = self.portal.portal_templates url = 'https://svn.erp5.org/repos/public/erp5/trunk/bt5/test_core' # don't install test_file keep_original_list = ( 'portal_skins/erp5_test/test_file', ) template_tool.updateBusinessTemplateFromUrl(url, keep_original_list=keep_original_list) bt = template_tool.getInstalledBusinessTemplate('test_core') self.assertNotEquals(None, bt) erp5_test = getattr(self.portal.portal_skins, 'erp5_test', None) self.assertNotEquals(None, erp5_test) test_file = getattr(erp5_test, 'test_file', None) self.assertEquals(None, test_file) def test_updateBusinessTemplateFromUrl_after_before_script(self): """ Test updateBusinessTemplateFromUrl method """ from Products.ERP5Type.tests.utils import createZODBPythonScript portal = self.getPortal() self._svn_setup_ssl() createZODBPythonScript(portal.portal_skins.custom, 'BT_dummyA', 'scripts_params=None', '# Script body\n' 'return context.setDescription("MODIFIED")') createZODBPythonScript(portal.portal_skins.custom, 'BT_dummyB', 'scripts_params=None', '# Script body\n' 'return context.setChangeLog("MODIFIED")') createZODBPythonScript(portal.portal_skins.custom, 'BT_dummyC', 'scripts_params=None', '# Script body\n' 'return context.getPortalObject().setTitle("MODIFIED")') template_tool = self.portal.portal_templates url = 'https://svn.erp5.org/repos/public/erp5/trunk/bt5/test_html_style' # don't install test_file before_triggered_bt5_id_list = ['BT_dummyA', 'BT_dummyB'] after_triggered_bt5_id_list = ['BT_dummyC'] template_tool.updateBusinessTemplateFromUrl(url, before_triggered_bt5_id_list=before_triggered_bt5_id_list, after_triggered_bt5_id_list=after_triggered_bt5_id_list) bt = template_tool.getInstalledBusinessTemplate('test_html_style') self.assertNotEquals(None, bt) self.assertEquals(bt.getDescription(), 'MODIFIED') self.assertEquals(bt.getChangeLog(), 'MODIFIED') self.assertEquals(portal.getTitle(), 'MODIFIED') def test_updateBusinessTemplateFromUrl_stringCastingBug(self): pt = self.getTemplateTool() template = pt.newContent(portal_type='Business Template') self.failUnless(template.getBuildingState() == 'draft') self.failUnless(template.getInstallationState() == 'not_installed') title = 'install_casting_to_int_bug_check' template.edit(title=title, version='1.0', description='bt for unit_test') transaction.commit() template.build() transaction.commit() cfg = getConfiguration() template_path = os.path.join(cfg.instancehome, 'tests', '%s' % (title,)) # remove previous version of bt it exists if os.path.exists(template_path): shutil.rmtree(template_path) template.export(path=template_path, local=1) self.failUnless(os.path.exists(template_path)) # setup version '9' first_revision = '9' open(os.path.join(template_path, 'bt', 'revision'), 'w').write(first_revision) pt.updateBusinessTemplateFromUrl(template_path) new_bt = pt.getInstalledBusinessTemplate(title) self.assertEqual(new_bt.getRevision(), first_revision) # setup revision '11', becasue: '11' < '9' (string comp), but 11 > 9 (int comp) second_revision = '11' self.assertTrue(second_revision < first_revision) self.assertTrue(int(second_revision) > int(first_revision)) open(os.path.join(template_path, 'bt', 'revision'), 'w').write(second_revision) pt.updateBusinessTemplateFromUrl(template_path) newer_bt = pt.getInstalledBusinessTemplate(title) self.assertNotEqual(new_bt, newer_bt) self.assertEqual(newer_bt.getRevision(), second_revision) def test_CompareVersions(self): """Tests compare version on template tool. """ compareVersions = self.getPortal().portal_templates.compareVersions self.assertEquals(0, compareVersions('1', '1')) self.assertEquals(0, compareVersions('1.2', '1.2')) self.assertEquals(0, compareVersions('1.2rc3', '1.2rc3')) self.assertEquals(0, compareVersions('1.0.0', '1.0')) self.assertEquals(-1, compareVersions('1.0', '1.0.1')) self.assertEquals(-1, compareVersions('1.0rc1', '1.0')) self.assertEquals(-1, compareVersions('1.0a', '1.0.1')) self.assertEquals(-1, compareVersions('1.1', '2.0')) def test_CompareVersionStrings(self): """Test compareVersionStrings on template tool""" compareVersionStrings = \ self.getPortal().portal_templates.compareVersionStrings self.assertTrue(compareVersionStrings('1.1', '> 1.0')) self.assertFalse(compareVersionStrings('1.1rc1', '= 1.0')) self.assertFalse(compareVersionStrings('1.0rc1', '> 1.0')) self.assertFalse(compareVersionStrings('1.0rc1', '>= 1.0')) self.assertTrue(compareVersionStrings('1.0rc1', '>= 1.0rc1')) def test_getInstalledBusinessTemplate(self): self.assertNotEquals(None, self.getPortal()\ .portal_templates.getInstalledBusinessTemplate('erp5_core')) self.assertEquals(None, self.getPortal()\ .portal_templates.getInstalledBusinessTemplate('erp5_toto')) def test_getInstalledBusinessTemplateRevision(self): self.assertTrue(300 < self.getPortal()\ .portal_templates.getInstalledBusinessTemplateRevision('erp5_core')) self.assertEquals(None, self.getPortal()\ .portal_templates.getInstalledBusinessTemplateRevision('erp5_toto')) def test_getInstalledBusinessTemplateList(self): templates_tool = self.getPortal().portal_templates bt5_list = templates_tool.getInstalledBusinessTemplateList() another_bt_list = [ i for i in templates_tool.contentValues() \ if i.getInstallationState() == 'installed'] self.assertEquals(len(bt5_list), len(another_bt_list)) for bt in bt5_list: self.failUnless(bt in another_bt_list) self.assertEquals(bt5_list, templates_tool._getInstalledBusinessTemplateList()) def test_getInstalledBusinessTemplateTitleList(self): templates_tool = self.getPortal().portal_templates bt5_list = templates_tool.getInstalledBusinessTemplateTitleList() another_bt_list = [ i.getTitle() for i in templates_tool.contentValues() \ if i.getInstallationState() == 'installed'] bt5_list.sort() another_bt_list.sort() self.assertEquals(bt5_list, another_bt_list) for bt in bt5_list: self.failUnless(bt in another_bt_list) new_list = templates_tool._getInstalledBusinessTemplateList(only_title=1) new_list.sort() self.assertEquals(bt5_list, new_list) def test_getBusinessTemplateUrl(self): """ Test if this method can find which repository is the business template """ # How to define an existing and use INSTANCE_HOME_REPOSITORY? url_list = [ 'https://svn.erp5.org/repos/public/erp5/trunk/bt5', 'http://www.erp5.org/dists/snapshot/bt5', 'http://www.erp5.org/dists/release/5.4.5/bt5', "INSTANCE_HOME_REPOSITORY", 'file:///opt/does/not/exist'] exist_bt5 = 'erp5_base' not_exist_bt5 = "erp5_not_exist" template_tool = self.portal.portal_templates getBusinessTemplateUrl = template_tool.getBusinessTemplateUrl # Test Exists self.assertEquals(getBusinessTemplateUrl(url_list, exist_bt5), 'https://svn.erp5.org/repos/public/erp5/trunk/bt5/erp5_base') self.assertEquals(getBusinessTemplateUrl(url_list[1:], exist_bt5), 'http://www.erp5.org/dists/snapshot/bt5/erp5_base.bt5') self.assertEquals(getBusinessTemplateUrl(url_list[2:], exist_bt5), 'http://www.erp5.org/dists/release/5.4.5/bt5/erp5_base.bt5') INSTANCE_HOME = getConfiguration().instancehome local_bt = None if os.path.exists(INSTANCE_HOME + "/bt5/erp5_base"): local_bt = 'file://' + INSTANCE_HOME + "/bt5/erp5_base" self.assertEquals(getBusinessTemplateUrl(url_list[3:], exist_bt5), local_bt) self.assertEquals(getBusinessTemplateUrl(url_list[4:], exist_bt5), None) # Test Not exists self.assertEquals(getBusinessTemplateUrl(url_list, not_exist_bt5), None) self.assertEquals(getBusinessTemplateUrl(url_list[1:], not_exist_bt5), None) self.assertEquals(getBusinessTemplateUrl(url_list[2:], not_exist_bt5), None) self.assertEquals(getBusinessTemplateUrl(url_list[3:], not_exist_bt5), None) self.assertEquals(getBusinessTemplateUrl(url_list[4:], not_exist_bt5), None) def test_resolveBusinessTemplateListDependency(self): """ Test API able to return a complete list of bt5s to setup a sub set of business templates. """ repository = "http://www.erp5.org/dists/snapshot/bt5/" template_tool = self.portal.portal_templates bt5_id_list = ['erp5_accounting'] bt5_list = template_tool.resolveBusinessTemplateListDependency(bt5_id_list) self.assertEquals([(repository, 'erp5_simulation.bt5'), (repository, 'erp5_accounting.bt5')], bt5_list) bt5_id_list = ['erp5_csv_style'] bt5_list = template_tool.resolveBusinessTemplateListDependency(bt5_id_list) self.assertEquals([], bt5_list) bt5_list = template_tool.resolveBusinessTemplateListDependency( bt5_id_list, False) self.assertEquals([(repository, 'erp5_csv_style.bt5')], bt5_list) bt5_id_list = ['erp5_base'] bt5_list = template_tool.resolveBusinessTemplateListDependency( bt5_id_list, True) self.assertEquals([], bt5_list) bt5_id_list = ['erp5_configurator_ung'] bt5_list = template_tool.resolveBusinessTemplateListDependency(bt5_id_list) self.assertEquals([(repository, 'erp5_workflow.bt5'), (repository, 'erp5_configurator.bt5'), (repository, 'erp5_configurator_ung.bt5')], bt5_list) bt5_id_list = ['erp5_configurator_ung', 'erp5_accounting', 'erp5_invoicing', 'erp5_crm'] bt5_list = template_tool.resolveBusinessTemplateListDependency(bt5_id_list) self.assertEquals([(repository, 'erp5_ingestion_mysql_innodb_catalog.bt5'), (repository, 'erp5_workflow.bt5'), (repository, 'erp5_simulation.bt5'), (repository, 'erp5_pdm.bt5'), (repository, 'erp5_ingestion.bt5'), (repository, 'erp5_configurator.bt5'), (repository, 'erp5_trade.bt5'), (repository, 'erp5_accounting.bt5'), (repository, 'erp5_crm.bt5'), (repository, 'erp5_configurator_ung.bt5'), (repository, 'erp5_invoicing.bt5')], bt5_list) bt5_id_list = ['erp5_base'] self.assertRaises(BusinessTemplateMissingDependency, template_tool.resolveBusinessTemplateListDependency, bt5_id_list, False) bt5_id_list = ['erp5_dms', 'erp5_full_text_myisam_catalog', 'erp5_base'] bt5_list = template_tool.resolveBusinessTemplateListDependency(bt5_id_list, False) self.assertEquals([(repository, 'erp5_core_proxy_field_legacy.bt5'), (repository, 'erp5_full_text_myisam_catalog.bt5'), (repository, 'erp5_ingestion_mysql_innodb_catalog.bt5'), (repository, 'erp5_base.bt5'), (repository, 'erp5_jquery.bt5'), (repository, 'erp5_ingestion.bt5'), (repository, 'erp5_web.bt5'), (repository, 'erp5_dms.bt5')], bt5_list) def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestTemplateTool)) return suite