# -*- coding: utf-8 -*- ############################################################################# # # Copyright (c) 2007-2009 Nexedi SA and Contributors. All Rights Reserved. # TAHARA Yusei <yusei@nexedi.com> # Ćukasz Nowak <luke@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. # ############################################################################## """Tests Template functionality""" import unittest from AccessControl.SecurityManagement import newSecurityManager from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.backportUnittest import expectedFailure from Products.ERP5Type import Permissions from Products.ERP5Form.PreferenceTool import Priority class TestTemplate(ERP5TypeTestCase): """A test for Template. """ def getTitle(self): return "Template" def getBusinessTemplateList(self): """Returns list of BT to be installed.""" return ('erp5_base', 'erp5_knowledge_pad', 'erp5_ui_test') def createUserAndLogin(self, name=None, additional_role_list=[]): """login with Member, Author and specified roles.""" uf = self.getPortal().acl_users role_list = ['Member', 'Author', 'Auditor'] role_list.extend(additional_role_list) uf._doAddUser(name, '', role_list, []) user = uf.getUserById(name).__of__(uf) newSecurityManager(None, user) def afterSetUp(self): self.login('ERP5TypeTestCase') portal_preferences = self.portal.portal_preferences portal_preferences.deleteContent(list(portal_preferences.objectIds())) self.tic() self.portal.portal_types.Preference._setTypeAllowedContentTypeList( ('Foo', 'Knowledge Pad')) def test_Template(self): self.createUserAndLogin(self.id()) preference = self.portal.portal_preferences.newContent(portal_type='Preference') preference.priority = Priority.USER preference.enable() self.tic() document = self.portal.foo_module.newContent(portal_type='Foo') document.edit(title='My Foo 1') document.newContent(portal_type='Foo Line') self.tic() document.Base_makeTemplateFromDocument(form_id=None) self.tic() self.assertEqual(len(preference.objectIds()), 1) # make sure that subobjects are not unindexed after making template. subobject_uid = document.objectValues()[0].getUid() self.assertEqual(len(self.portal.portal_catalog(uid=subobject_uid)), 1) self.portal.foo_module.manage_delObjects(ids=[document.getId()]) self.tic() template = preference.objectValues()[0] cp = preference.manage_copyObjects(ids=[template.getId()], REQUEST=None, RESPONSE=None) new_document_list = self.portal.foo_module.manage_pasteObjects(cp) new_document_id = new_document_list[0]['new_id'] new_document = self.portal.foo_module[new_document_id] new_document.makeTemplateInstance() self.tic() self.assertEqual(new_document.getTitle(), 'My Foo 1') def test_TemplateDeletable(self): self.createUserAndLogin(self.id()) preference = self.portal.portal_preferences.newContent(portal_type='Preference') preference.priority = Priority.USER preference.enable() self.tic() document = self.portal.foo_module.newContent(portal_type='Foo') document.edit(title='My Foo 1') document.newContent(portal_type='Foo Line') self.tic() document.Base_makeTemplateFromDocument(form_id=None) self.tic() self.assertEqual(len(preference.objectIds()), 1) # make sure that subobjects are not unindexed after making template. subobject_uid = document.objectValues()[0].getUid() self.assertEqual(len(self.portal.portal_catalog(uid=subobject_uid)), 1) self.portal.foo_module.manage_delObjects(ids=[document.getId()]) self.tic() template = preference.objectValues()[0] cp = preference.manage_copyObjects(ids=[template.getId()], REQUEST=None, RESPONSE=None) new_document_list = self.portal.foo_module.manage_pasteObjects(cp) new_document_id = new_document_list[0]['new_id'] new_document = self.portal.foo_module[new_document_id] new_document.makeTemplateInstance() self.tic() self.assertEqual(new_document.getTitle(), 'My Foo 1') # as templates are not indexable it is required to know, if they would # appear on Folder_getDeleteObjectList template_uid = template.getUid() self.assertEqual( 1, len(preference.Folder_getDeleteObjectList(uid = [template_uid])) ) def test_TemplateCreatePreferenceWithExistingUserPreference(self): self.createUserAndLogin(self.id()) user_preference = self.portal.portal_preferences.newContent( portal_type='Preference') user_preference.setPriority(Priority.USER) user_preference.enable() self.tic() document = self.portal.foo_module.newContent(portal_type='Foo') self.tic() document.Base_makeTemplateFromDocument(form_id=None) self.tic() # created preference is reused to store template self.assertEqual('enabled', user_preference.getPreferenceState()) self.assertEqual(len(user_preference.objectIds()), 1) def test_TemplateCreatePreferenceWithExistingNonAuthorizedPreference(self): # When there is an active preference, but without add permission in that # preference, another preference is created when making a template self.createUserAndLogin(self.id()) unauthorized_preference = self.portal.portal_preferences.newContent( portal_type='Preference') unauthorized_preference.enable() # it's not authorized to add content in this preference unauthorized_preference.manage_permission('Add portal content', (), acquire=0) preference_id_list = list(self.portal.portal_preferences.objectIds()) self.tic() document = self.portal.foo_module.newContent(portal_type='Foo') self.tic() document.Base_makeTemplateFromDocument(form_id=None) self.tic() # this preference was not used self.assertEqual(len(unauthorized_preference.objectIds()), 0) # a new preference is created new_preference_id_list = list(self.portal.portal_preferences.objectIds()) self.assertEqual(len(preference_id_list) + 1, len(new_preference_id_list)) preference_id = [x for x in new_preference_id_list if x not in preference_id_list][0] preference = self.portal.portal_preferences._getOb(preference_id) self.assertEqual('Preference', preference.getPortalType()) self.assertEqual('enabled', preference.getPreferenceState()) self.assertEqual(len(preference.objectIds()), 1) def test_TemplateCreateWithSameTitleUpdateExisting(self): # When we create a template with the same title as an existing template, it # replaces the existing one. self.createUserAndLogin(self.id()) user_preference = self.portal.portal_preferences.newContent( portal_type='Preference') user_preference.setPriority(Priority.USER) user_preference.enable() self.tic() document = self.portal.foo_module.newContent(portal_type='Foo', title='template', description='First document') self.tic() document.Base_makeTemplateFromDocument(form_id=None) self.tic() self.assertEqual(len(user_preference.objectIds()), 1) self.assertEqual(user_preference.objectValues()[0].getDescription(), 'First document') other_document = self.portal.foo_module.newContent( portal_type='Foo', title='template', description="Another document") other_document.Base_makeTemplateFromDocument(form_id=None) self.tic() self.assertEqual(len(user_preference.objectIds()), 1) self.assertEqual(user_preference.objectValues()[0].getDescription(), 'Another document') def test_TemplateCreatePreferenceWithSystemPreferenceEnabled(self): # TODO: This test *might* be removed if it is good to trust # getActivePreference to return only Preference portal type self.login('ERP5TypeTestCase') system_preference = self.portal.portal_preferences.newContent( portal_type='System Preference') system_preference.setPriority(Priority.SITE) system_preference.enable() self.tic() self.createUserAndLogin(self.id()) user_preference = self.portal.portal_preferences.newContent( portal_type='Preference') user_preference.setPriority(Priority.USER) user_preference.enable() self.tic() document = self.portal.foo_module.newContent(portal_type='Foo') self.tic() document.Base_makeTemplateFromDocument(form_id=None) self.tic() # created preference is reused to store template self.assertEqual('enabled', user_preference.getPreferenceState()) self.assertEqual(len(user_preference.objectIds()), 1) def test_TemplateCreatePreference(self): self.createUserAndLogin('another user with no active preference') active_user_preference_list = [p for p in self.portal.portal_preferences._getSortedPreferenceList() if p.getPriority() == Priority.USER] self.assertEqual([], active_user_preference_list) preference_id_list = list(self.portal.portal_preferences.objectIds()) document = self.portal.foo_module.newContent(portal_type='Foo') self.tic() document.Base_makeTemplateFromDocument(form_id=None) self.tic() # a new preference is created new_preference_id_list = list(self.portal.portal_preferences.objectIds()) self.assertEqual(len(preference_id_list) + 1, len(new_preference_id_list)) preference_id = [x for x in new_preference_id_list if x not in preference_id_list][0] preference = self.portal.portal_preferences._getOb(preference_id) self.assertEqual('Preference', preference.getPortalType()) self.assertEqual('Document Template Container', preference.getTitle()) self.assertEqual(Priority.USER, preference.getPriority()) self.assertEqual('enabled', preference.getPreferenceState()) self.assertEqual(len(preference.objectIds()), 1) # Reason for test failure: # # Base_makeTemplateFromDocument uses portal_preference.getActivePreference(), # and if the user has no preference, it creates a new preference to attach it # the template. # But getActivePreference uses the catalog, for performance reasons. Which # means that two successive calls to Base_makeTemplateFromDocument, from an # initial state where the user has no active preferences, will create wrongly # two preferences instead of one: during the second call, a preference does # exist, and is enabled for current user, but is just not yet reindexed. @expectedFailure def test_manyTemplatesWithoutReindexation(self): """Check what happen when templates are created one by one without reindexation""" self.createUserAndLogin(self.id()) active_user_preference_list = [p for p in self.portal.portal_preferences._getSortedPreferenceList() if p.getPriority() == Priority.USER] self.assertEqual([], active_user_preference_list) preference_id_list = list(self.portal.portal_preferences.objectIds()) document1 = self.portal.foo_module.newContent(portal_type='Foo') self.commit() document2 = self.portal.foo_module.newContent(portal_type='Foo') self.tic() document1.Base_makeTemplateFromDocument(form_id=None) self.commit() document2.Base_makeTemplateFromDocument(form_id=None) self.commit() self.tic() # a new preference is created new_preference_id_list = list(self.portal.portal_preferences.objectIds()) self.assertEqual(len(preference_id_list) + 1, len(new_preference_id_list)) preference_id = [x for x in new_preference_id_list if x not in preference_id_list][0] preference = self.portal.portal_preferences._getOb(preference_id) self.assertEqual('Preference', preference.getPortalType()) self.assertEqual('enabled', preference.getPreferenceState()) self.assertEqual(len(preference.objectIds()), 2) def _testTemplateNotIndexable(self, document, additional_role_list=[]): # template documents are not indexable self.portal.portal_activities.manage_enableActivityTracking() self.portal.portal_activities.manage_enableActivityTimingLogging() self.portal.portal_activities.manage_enableActivityCreationTrace() self.createUserAndLogin(self.id(), additional_role_list=additional_role_list) preference = self.portal.portal_preferences.newContent(portal_type='Preference') preference.priority = Priority.USER preference.enable() self.tic() document.Base_makeTemplateFromDocument(form_id=None) self.commit() # making a new template should not create indexing activities, # either for the new template or one of its subobjects self.assertEqual(self.portal.portal_activities.getMessageList(), []) self.tic() self.assertTrue(document.isIndexable) self.assertEqual(len(preference.objectIds()), 1) template = preference.objectValues()[0] self.assertFalse(template.isIndexable) # Because they are not indexable, they cannot be found by catalog self.assertEqual(0, len(self.portal.portal_catalog(uid=template.getUid()))) template_line = template.objectValues()[0] self.assertEqual(0, len(self.portal.portal_catalog(uid=template_line.getUid()))) # change the title, because creating another template with same title will # replace the first one document.setTitle('%sb' % document.getTitle()) # and this is still true if you create two templates from the same document # #929 document.Base_makeTemplateFromDocument(form_id=None) self.tic() self.assertTrue(document.isIndexable) self.assertEqual(len(preference.objectIds()), 2) for template in preference.objectValues(): self.assertFalse(template.isIndexable) def test_DeliveryTemplateNotIndexable(self): document = self.portal.foo_module.newContent(portal_type='Foo') document.edit(title='My Foo 1') document.newContent(portal_type='Foo Line') self.tic() self._testTemplateNotIndexable(document) def test_NonDeliveryTemplateNotIndexable(self): document = self.portal.knowledge_pad_module.newContent(portal_type='Knowledge Pad') document.edit(title='My Knowledge Pad 1') document.newContent(portal_type='Knowledge Box') self.tic() # Only Manager can Copy and Move at Knowlede Pad Document when it is # 'invisible' state. self._testTemplateNotIndexable(document, additional_role_list=['Manager']) def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestTemplate)) return suite