# -*- coding: utf-8 -*- ############################################################################## # # Copyright (c) 2005-2009 Nexedi SA and Contributors. All Rights Reserved. # Jerome Perrin <jerome@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. # ############################################################################## import unittest import transaction from AccessControl.SecurityManagement import noSecurityManager from AccessControl.SecurityManagement import getSecurityManager from zExceptions import Unauthorized from DateTime import DateTime from Products.ERP5Type.tests.testERP5Type import PropertySheetTestCase from Products.ERP5Form.Document.Preference import Priority from Products.ERP5.PropertySheet.HtmlStylePreference import HtmlStylePreference default_large_image_height, = [pref.get('default') for pref in HtmlStylePreference._properties if pref['id'] == 'preferred_large_image_height'] class TestPreferences(PropertySheetTestCase): def getTitle(self): return "Portal Preferences" def afterSetUp(self): uf = self.getPortal().acl_users uf._doAddUser('manager', '', ['Manager', 'Assignor', ], []) self.login('manager') self.createPreferences() def beforeTearDown(self): portal_preferences = self.getPreferenceTool() portal_preferences.manage_delObjects(list(portal_preferences.objectIds())) transaction.commit() self.tic() def createPreferences(self): """ create some preferences objects """ portal_preferences = self.getPreferenceTool() ## create initial preferences person1 = portal_preferences.newContent( id='person1', portal_type='Preference') person2 = portal_preferences.newContent( id='person2', portal_type='Preference') group = portal_preferences.newContent( id='group', portal_type='Preference') group.setPriority(Priority.GROUP) site = portal_preferences.newContent( id='site', portal_type='Preference') site.setPriority(Priority.SITE) # commit transaction transaction.commit() self.getPreferenceTool().recursiveReindexObject() self.tic() # check preference levels are Ok self.assertEquals(person1.getPriority(), Priority.USER) self.assertEquals(person2.getPriority(), Priority.USER) self.assertEquals(group.getPriority(), Priority.GROUP) self.assertEquals(site.getPriority(), Priority.SITE) # check initial states self.assertEquals(person1.getPreferenceState(), 'disabled') self.assertEquals(person2.getPreferenceState(), 'disabled') self.assertEquals(group.getPreferenceState(), 'disabled') self.assertEquals(site.getPreferenceState(), 'disabled') def test_PreferenceToolTitle(self): """Tests that the title of the preference tool is correct. """ self.assertEquals('Preferences', self.getPreferenceTool().Title()) def test_AllowedContentTypes(self): """Tests Preference can be added in Preference Tool. """ self.failUnless('Preference' in [x.getId() for x in self.getPortal().portal_preferences.allowedContentTypes()]) def test_EnablePreferences(self): """ tests preference workflow """ portal_workflow = self.getWorkflowTool() person1 = self.getPreferenceTool()['person1'] person2 = self.getPreferenceTool()['person2'] group = self.getPreferenceTool()['group'] site = self.getPreferenceTool()['site'] self.assertEqual(None, self.getPreferenceTool().getActivePreference()) self.assertEqual(None, self.getPreferenceTool().getActiveSystemPreference()) person1.portal_workflow.doActionFor( person1, 'enable_action', wf_id='preference_workflow') self.assertEquals(person1.getPreferenceState(), 'enabled') self.assertEqual( person1, self.getPreferenceTool().getActivePreference()) self.assertEqual(None, self.getPreferenceTool().getActiveSystemPreference()) portal_workflow.doActionFor( site, 'enable_action', wf_id='preference_workflow') self.assertEquals(person1.getPreferenceState(), 'enabled') self.assertEquals(site.getPreferenceState(), 'global') self.assertEqual(person1, self.getPreferenceTool().getActivePreference()) self.assertEqual(None, self.getPreferenceTool().getActiveSystemPreference()) portal_workflow.doActionFor( group, 'enable_action', wf_id='preference_workflow') self.assertEquals(person1.getPreferenceState(), 'enabled') self.assertEquals(group.getPreferenceState(), 'enabled') self.assertEquals(site.getPreferenceState(), 'global') self.assertEqual(person1, self.getPreferenceTool().getActivePreference()) self.assertEqual(None, self.getPreferenceTool().getActiveSystemPreference()) portal_workflow.doActionFor( person2, 'enable_action', wf_id='preference_workflow') self.assertEqual(person2, self.getPreferenceTool().getActivePreference()) self.assertEqual(None, self.getPreferenceTool().getActiveSystemPreference()) self.assertEquals(person2.getPreferenceState(), 'enabled') # enabling a preference disable all other of the same level self.assertEquals(person1.getPreferenceState(), 'disabled') self.assertEquals(group.getPreferenceState(), 'enabled') self.assertEquals(site.getPreferenceState(), 'global') def test_GetPreference(self): """ checks that getPreference returns the good preferred value""" portal_workflow = self.getWorkflowTool() pref_tool = self.getPreferenceTool() person1 = self.getPreferenceTool()['person1'] group = self.getPreferenceTool()['group'] site = self.getPreferenceTool()['site'] portal_workflow.doActionFor( person1, 'enable_action', wf_id='preference_workflow') portal_workflow.doActionFor( group, 'enable_action', wf_id='preference_workflow') portal_workflow.doActionFor( site, 'enable_action', wf_id='preference_workflow') self.assertEquals(person1.getPreferenceState(), 'enabled') self.assertEquals(group.getPreferenceState(), 'enabled') self.assertEquals(site.getPreferenceState(), 'global') person1.setPreferredAccountingTransactionSimulationState([]) self.assertEquals( person1.getPreferredAccountingTransactionSimulationState(), None) group.setPreferredAccountingTransactionSimulationState([]) self.assertEquals( group.getPreferredAccountingTransactionSimulationState(), None) site.setPreferredAccountingTransactionSimulationState([]) self.assertEquals( site.getPreferredAccountingTransactionSimulationState(), None) self.assertEquals(len(pref_tool.getPreference( 'preferred_accounting_transaction_simulation_state_list')), 0) site.edit( preferred_accounting_transaction_simulation_state_list= ['stopped', 'delivered']) self.assertEquals(list(pref_tool.getPreference( 'preferred_accounting_transaction_simulation_state_list')), list(site.getPreferredAccountingTransactionSimulationStateList())) # getPreference on the tool has the same behaviour as getProperty # on the preference (unless property is unset on this pref) for prop in ['preferred_accounting_transaction_simulation_state', 'preferred_accounting_transaction_simulation_state_list']: self.assertEquals(pref_tool.getPreference(prop), site.getProperty(prop)) group.edit( preferred_accounting_transaction_simulation_state_list=['draft']) self.assertEquals(list(pref_tool.getPreference( 'preferred_accounting_transaction_simulation_state_list')), list(group.getPreferredAccountingTransactionSimulationStateList())) person1.edit(preferred_accounting_transaction_simulation_state_list= ['cancelled']) self.assertEquals(list(pref_tool.getPreference( 'preferred_accounting_transaction_simulation_state_list')), list(person1.getPreferredAccountingTransactionSimulationStateList())) # disable person -> group is selected self.getWorkflowTool().doActionFor(person1, 'disable_action', wf_id='preference_workflow') self.assertEquals(list(pref_tool.getPreference( 'preferred_accounting_transaction_simulation_state_list')), list(group.getPreferredAccountingTransactionSimulationStateList())) self.assertEquals('default', pref_tool.getPreference( 'this_does_not_exists', 'default')) def test_GetAttr(self): """ checks that preference methods can be called directly on portal_preferences """ portal_workflow = self.getWorkflowTool() pref_tool = self.getPreferenceTool() person1 = self.getPreferenceTool()['person1'] group = self.getPreferenceTool()['group'] site = self.getPreferenceTool()['site'] self.assertEquals(person1.getPreferenceState(), 'disabled') portal_workflow.doActionFor( group, 'enable_action', wf_id='preference_workflow') self.assertEquals(group.getPreferenceState(), 'enabled') portal_workflow.doActionFor( site, 'enable_action', wf_id='preference_workflow') self.assertEquals(site.getPreferenceState(), 'global') group.setPreferredAccountingTransactionSimulationStateList(['cancelled']) self.assertNotEquals( None, pref_tool.getPreferredAccountingTransactionSimulationStateList()) self.assertNotEquals( [], list(pref_tool.getPreferredAccountingTransactionSimulationStateList())) self.assertEquals( list(pref_tool.getPreferredAccountingTransactionSimulationStateList()), list(pref_tool.getPreference( 'preferred_accounting_transaction_simulation_state_list'))) # standards attributes must not be looked up on Preferences self.assertNotEquals(pref_tool.getTitleOrId(), group.getTitleOrId()) self.assertNotEquals(pref_tool.objectValues(), group.objectValues()) self.assertNotEquals(pref_tool.getParentValue(), group.getParentValue()) try : pref_tool.getPreferredNotExistingPreference() self.fail('Attribute error should be raised for dummy methods') except AttributeError : pass def test_SetPreference(self): """ check setting a preference modifies the first enabled user preference """ portal_workflow = self.getWorkflowTool() pref_tool = self.getPreferenceTool() person1 = self.getPreferenceTool()['person1'] portal_workflow.doActionFor( person1, 'enable_action', wf_id='preference_workflow') self.assertEquals(person1.getPreferenceState(), 'enabled') person1.setPreferredAccountingTransactionAtDate(DateTime(2005, 01, 01)) pref_tool.setPreference( 'preferred_accounting_transaction_at_date', DateTime(2004, 12, 31)) self.tic() self.assertEquals( pref_tool.getPreferredAccountingTransactionAtDate(), DateTime(2004, 12, 31)) self.assertEquals( person1.getPreferredAccountingTransactionAtDate(), DateTime(2004, 12, 31)) def test_UserIndependance(self): """ check that the preferences are related to the user. """ portal_workflow = self.getWorkflowTool() portal_preferences = self.getPreferenceTool() # create 2 users: user_a and user_b uf = self.getPortal().acl_users uf._doAddUser('user_a', '', ['Member', ], []) uf._doAddUser('user_b', '', ['Member', ], []) self.login('user_a') # create 2 prefs as user_a user_a_1 = portal_preferences.newContent( id='user_a_1', portal_type='Preference') user_a_2 = portal_preferences.newContent( id='user_a_2', portal_type='Preference') transaction.commit(); self.tic() # enable a pref portal_workflow.doActionFor( user_a_1, 'enable_action', wf_id='preference_workflow') self.assertEquals(user_a_1.getPreferenceState(), 'enabled') self.assertEquals(user_a_2.getPreferenceState(), 'disabled') self.login('user_b') # create a pref for user_b user_b_1 = portal_preferences.newContent( id='user_b_1', portal_type='Preference') user_b_1.setPreferredAccountingTransactionAtDate(DateTime(2002, 02, 02)) transaction.commit(); self.tic() # enable this preference portal_workflow.doActionFor( user_b_1, 'enable_action', wf_id='preference_workflow') self.assertEquals(user_b_1.getPreferenceState(), 'enabled') # check user_a's preference is still enabled self.assertEquals(user_a_1.getPreferenceState(), 'enabled') self.assertEquals(user_a_2.getPreferenceState(), 'disabled') # Checks that a manager preference doesn't disable any other user # preferences self.login('manager') self.assert_('Manager' in getSecurityManager().getUser().getRolesInContext(portal_preferences)) # create a pref for manager manager_pref = portal_preferences.newContent( id='manager_pref', portal_type='Preference') manager_pref.setPreferredAccountingTransactionAtDate( DateTime(2012, 12, 12)) transaction.commit(); self.tic() # enable this preference portal_workflow.doActionFor( manager_pref, 'enable_action', wf_id='preference_workflow') self.assertEquals(manager_pref.getPreferenceState(), 'enabled') transaction.commit(); self.tic() # check users preferences are still enabled self.assertEquals(user_a_1.getPreferenceState(), 'enabled') self.assertEquals(user_b_1.getPreferenceState(), 'enabled') self.assertEquals(user_a_2.getPreferenceState(), 'disabled') # A user with Manager and Owner can view all preferences, because this user # is Manager and Owner, but for Manager, we have an exception, only # preferences actually owned by the user are taken into account. uf._doAddUser('manager_and_owner', '', ['Manager', 'Owner'], []) self.login('manager_and_owner') self.assert_('Owner' in getSecurityManager().getUser().getRolesInContext(manager_pref)) self.assertEquals(None, portal_preferences.getPreferredAccountingTransactionAtDate()) def test_GlobalPreference(self): # globally enabled preference are preference for anonymous users. ptool = self.getPreferenceTool() ptool.site.setPreferredAccountingTransactionSimulationStateList( ['this_is_visible_by_anonymous']) self.getPortal().portal_workflow.doActionFor( ptool.site, 'enable_action', wf_id='preference_workflow') self.assertEquals('global', ptool.site.getPreferenceState()) transaction.commit() self.tic() noSecurityManager() self.assertEquals(['this_is_visible_by_anonymous'], ptool.getPreferredAccountingTransactionSimulationStateList()) def test_GetDefault(self): portal_workflow = self.getWorkflowTool() pref_tool = self.getPreferenceTool() site = self.getPreferenceTool()['site'] portal_workflow.doActionFor( site, 'enable_action', wf_id='preference_workflow') self.assertEquals(site.getPreferenceState(), 'global') method = pref_tool.getPreferredAccountingTransactionSimulationState state = method() self.assertEquals(state, []) state = method('default') self.assertEquals(state, 'default') method = lambda *args: pref_tool.getPreference('preferred_accounting_transaction_simulation_state', *args) state = method() self.assertEquals(state, []) state = method('default') self.assertEquals(state, 'default') method = pref_tool.getPreferredAccountingTransactionSimulationStateList state_list = method() self.assertEquals(state_list, []) state_list = method(('default',)) # Initially, tuples were always casted to lists. This is not the case # anymore when preference_tool.getXxxList returns the default value. self.assertEquals(state_list, ('default',)) method = lambda *args: pref_tool.getPreference('preferred_accounting_transaction_simulation_state_list', *args) state_list = method() self.assertEquals(state_list, []) state_list = method(('default',)) self.assertEquals(state_list, ('default',)) def test_Permissions(self): # create a new site preference for later preference_tool = self.portal.portal_preferences site_pref = preference_tool.newContent( portal_type='Preference', priority=Priority.SITE) self.portal.portal_workflow.doActionFor(site_pref, 'enable_action') self.assertEquals(site_pref.getPreferenceState(), 'global') # Members can add new preferences uf = self.getPortal().acl_users uf._doAddUser('member', '', ['Member', ], []) member = uf.getUserById('member').__of__(uf) self.login('member') user_pref = preference_tool.newContent(portal_type='Preference') # Members can copy & paste existing preferences user_pref.Base_createCloneDocument() # note that copy & pasting a site preference reset the priority to USER # preference. cp_data = preference_tool.manage_copyObjects(ids=[site_pref.getId()]) copy_id = preference_tool.manage_pasteObjects(cp_data)[0]['new_id'] self.assertEquals(Priority.USER, preference_tool[copy_id].getPriority()) # Globally enabled preferences can be viewed by Members self.assertTrue(member.has_permission('View', site_pref)) # Member does not have Manage properties on their own preferences, # otherwise the "Metadata" tab is shown self.assertFalse(member.has_permission( 'Manage properties', user_pref)) def test_SystemPreference(self): # We want to test a property with a default value defined self.assertTrue(default_large_image_height > 0) large_image_height = default_large_image_height + 1 preference_tool = self.portal.portal_preferences system_pref = preference_tool.newContent( portal_type='System Preference', preferred_ooodoc_server_address='127.0.0.1', priority=Priority.SITE) # check not taken into account if not enabled self.assertEqual(None, preference_tool.getPreferredOoodocServerAddress()) self.assertEqual('localhost', preference_tool.getPreferredOoodocServerAddress('localhost')) self.assertEqual(default_large_image_height, preference_tool.getPreferredLargeImageHeight()) # enable it and check preference is returned self.portal.portal_workflow.doActionFor(system_pref, 'enable_action') self.assertEqual(system_pref.getPreferenceState(), 'global') transaction.commit() self.tic() self.assertEqual('127.0.0.1', preference_tool.getPreferredOoodocServerAddress()) self.assertEqual('127.0.0.1', preference_tool.getPreferredOoodocServerAddress('localhost')) self.assertEqual(default_large_image_height, preference_tool.getPreferredLargeImageHeight()) # Default value passed by parameter has priority over the default in the # property sheet. self.assertEqual(large_image_height, preference_tool.getPreferredLargeImageHeight(large_image_height)) # Members can't add new system preferences uf = self.getPortal().acl_users uf._doAddUser('member', '', ['Member', ], []) self.login('member') self.assertRaises(Unauthorized, preference_tool.newContent, portal_type='System Preference') # But they can see others system_pref.view() # check accessors works system_pref.setPreferredOoodocServerAddress('1.2.3.4') transaction.commit() self.tic() self.assertEqual('1.2.3.4', preference_tool.getPreferredOoodocServerAddress()) self.assertEqual('1.2.3.4', preference_tool.getPreferredOoodocServerAddress('localhost')) self.assertEqual(default_large_image_height, preference_tool.getPreferredLargeImageHeight()) # create a user pref and check it doesn't outranks the system one if # they both defined same pref user_pref = preference_tool.newContent( portal_type='Preference', priority=Priority.USER) user_pref.setPreferredLargeImageHeight(large_image_height) self.portal.portal_workflow.doActionFor(user_pref, 'enable_action') self.assertEqual(user_pref.getPreferenceState(), 'enabled') transaction.commit() self.tic() self.assertEqual('1.2.3.4', preference_tool.getPreferredOoodocServerAddress('localhost')) self.assertEqual(large_image_height, preference_tool.getPreferredLargeImageHeight()) self.assertEqual(large_image_height, preference_tool.getPreferredLargeImageHeight(0)) # check a user can't edit preference which are marked for manager self.assertRaises(Unauthorized, user_pref.edit, preferred_ooodoc_server_address="localhost") # even if there is System Preference enabled getActivePreference shall return # user preference self.assertEqual(user_pref, preference_tool.getActivePreference()) self.assertEqual(system_pref, preference_tool.getActiveSystemPreference()) def test_boolean_accessor(self): self._addPropertySheet('Preference', 'DummyPreference', '''class DummyPreference: _properties= ( {'id': 'dummy', 'preference': True, 'type': 'boolean',},)''') portal_preferences = self.portal.portal_preferences self.assertFalse(portal_preferences.getDummy()) self.assertFalse(portal_preferences.isDummy()) preference = portal_preferences.newContent(portal_type='Preference', dummy=True) preference.enable() transaction.commit() self.tic() self.assertTrue(portal_preferences.getDummy()) self.assertTrue(portal_preferences.isDummy()) def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestPreferences)) return suite