testPreferences.py 20.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
##############################################################################
#
# Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
#                    Jerome Perrin <jerome@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.
#
##############################################################################

29
import unittest
30

31
import transaction
32 33 34
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from AccessControl.SecurityManagement import getSecurityManager
35
from zExceptions import Unauthorized
36 37 38
from zLOG import LOG
from DateTime import DateTime
from Testing import ZopeTestCase
39

40 41 42 43 44
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Form.Document.Preference import Priority


class TestPreferences(ERP5TypeTestCase):
45
  quiet = 1
46 47 48 49 50 51 52
  run_all_tests = 1
  
  def getTitle(self):
    return "Portal Preference"

  def afterSetUp(self):
    uf = self.getPortal().acl_users
53
    uf._doAddUser('manager', '', ['Manager', 'Assignor', ], [])
54 55
    user = uf.getUserById('manager').__of__(uf)
    newSecurityManager(None, user)
56
    self.createPreferences()
57

58 59 60
  def beforeTearDown(self):
    portal_preferences = self.getPreferenceTool()
    portal_preferences.manage_delObjects(list(portal_preferences.objectIds()))
61
    transaction.commit()
62
    self.tic()
63

64 65 66 67 68 69 70 71 72 73 74 75 76 77
  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)
78 79
    
    # commit transaction
80
    transaction.commit()
81
    self.getPreferenceTool().recursiveReindexObject()
82
    self.tic()
83
    
84 85 86 87 88 89 90 91 92 93
    # 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')
94
  
95 96 97 98 99
  def test_PreferenceToolTitle(self):
    """Tests that the title of the preference tool is correct.
    """
    self.assertEquals('Preferences', self.getPreferenceTool().Title())

100 101 102 103 104 105 106 107 108
  def test_AllowedContentTypes(self, quiet=quiet, run=run_all_tests):
    """Tests Preference can be added in Preference Tool.
    """
    if not run: return
    if not quiet:
      ZopeTestCase._print('\n Test allowed content types')
    self.failUnless('Preference' in [x.getId() for x in
           self.getPortal().portal_preferences.allowedContentTypes()])

109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
  def test_EnablePreferences(self, quiet=quiet, run=run_all_tests) :
    """ tests preference workflow """
    if not run: return
    if not quiet:
      ZopeTestCase._print('\n Test enabling preferences')
    
    portal_workflow = self.getWorkflowTool()
    person1 = self.getPreferenceTool()['person1']
    person2 = self.getPreferenceTool()['person2']
    group = self.getPreferenceTool()['group']
    site = self.getPreferenceTool()['site']
    
    person1.portal_workflow.doActionFor(
       person1, 'enable_action', wf_id='preference_workflow')
    self.assertEquals(person1.getPreferenceState(), 'enabled')
    
    portal_workflow.doActionFor(
       site, 'enable_action', wf_id='preference_workflow')
    self.assertEquals(person1.getPreferenceState(), 'enabled')
128
    self.assertEquals(site.getPreferenceState(),    'global')
129 130 131 132 133

    portal_workflow.doActionFor(
       group, 'enable_action', wf_id='preference_workflow')
    self.assertEquals(person1.getPreferenceState(), 'enabled')
    self.assertEquals(group.getPreferenceState(),   'enabled')
134
    self.assertEquals(site.getPreferenceState(),    'global')
135
      
136 137 138 139 140 141
    portal_workflow.doActionFor(
       person2, 'enable_action', wf_id='preference_workflow')
    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')
142
    self.assertEquals(site.getPreferenceState(),    'global')
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

  def test_GetPreference(self, quiet=quiet, run=run_all_tests):
    """ checks that getPreference returns the good preferred value"""
    if not run: return
    if not quiet:
      ZopeTestCase._print('\n Test getPreference')
   
    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')
164
    self.assertEquals(site.getPreferenceState(),    'global')
165
    person1.setPreferredAccountingTransactionSimulationState([])
166 167
    self.assertEquals(
      person1.getPreferredAccountingTransactionSimulationState(), None)
168
    group.setPreferredAccountingTransactionSimulationState([])
169 170
    self.assertEquals(
      group.getPreferredAccountingTransactionSimulationState(), None)
171
    site.setPreferredAccountingTransactionSimulationState([])
172 173
    self.assertEquals(
      site.getPreferredAccountingTransactionSimulationState(), None)
174

175
    self.assertEquals(len(pref_tool.getPreference(
176
      'preferred_accounting_transaction_simulation_state_list')), 0)
177
    
178 179 180
    site.edit(
      preferred_accounting_transaction_simulation_state_list=
      ['stopped', 'delivered'])
181
    self.assertEquals(list(pref_tool.getPreference(
182
      'preferred_accounting_transaction_simulation_state_list')),
183 184
      list(site.getPreferredAccountingTransactionSimulationStateList()))
    
185 186 187 188 189 190 191 192
    # 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))
    
193 194
    group.edit(
      preferred_accounting_transaction_simulation_state_list=['draft'])
195
    self.assertEquals(list(pref_tool.getPreference(
196
      'preferred_accounting_transaction_simulation_state_list')),
197 198
      list(group.getPreferredAccountingTransactionSimulationStateList()))
    
199
    person1.edit(preferred_accounting_transaction_simulation_state_list=
200 201
              ['cancelled'])
    self.assertEquals(list(pref_tool.getPreference(
202
      'preferred_accounting_transaction_simulation_state_list')),
203 204 205 206 207
      list(person1.getPreferredAccountingTransactionSimulationStateList()))
    # disable person -> group is selected
    self.getWorkflowTool().doActionFor(person1,
            'disable_action', wf_id='preference_workflow')
    self.assertEquals(list(pref_tool.getPreference(
208
      'preferred_accounting_transaction_simulation_state_list')),
209 210
      list(group.getPreferredAccountingTransactionSimulationStateList()))

211 212 213 214
    self.assertEquals('default', pref_tool.getPreference(
                                        'this_does_not_exists', 'default'))


215 216 217 218 219 220
  def test_GetAttr(self, quiet=quiet, run=run_all_tests) :
    """ checks that preference methods can be called directly
      on portal_preferences """
    if not run: return
    if not quiet:
      ZopeTestCase._print('\n Test methods on portal_preference')
221
    
222 223 224 225 226 227 228 229 230 231 232
    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')
233
    self.assertEquals(site.getPreferenceState(),     'global')
234 235 236 237 238 239 240 241 242
    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(
243
         'preferred_accounting_transaction_simulation_state_list')))
244 245 246
    # standards attributes must not be looked up on Preferences
    self.assertNotEquals(pref_tool.getTitleOrId(), group.getTitleOrId())
    self.assertNotEquals(pref_tool.objectValues(), group.objectValues())
247
    self.assertNotEquals(pref_tool.getParentValue(), group.getParentValue())
248 249
    try :
      pref_tool.getPreferredNotExistingPreference()
250
      self.fail('Attribute error should be raised for dummy methods')
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
    except AttributeError :
      pass
  
  def test_SetPreference(self, quiet=quiet, run=run_all_tests) :
    """ check setting a preference modifies 
     the first enabled user preference """
    if not run: return
    if not quiet:
      ZopeTestCase._print('\n Test setting preferences')
    
    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, quiet=quiet, run=run_all_tests) :
    """ check that the preferences are related to the user. """
    if not run: return
    if not quiet:
      ZopeTestCase._print(
          '\n Test different users preferences are independants')
    
    portal_workflow = self.getWorkflowTool()
    portal_preferences = self.getPreferenceTool()
    # create 2 users: user_a and user_b
    uf = self.getPortal().acl_users
290
    uf._doAddUser('user_a', '', ['Member', ], [])
291
    user_a = uf.getUserById('user_a').__of__(uf)
292
    uf._doAddUser('user_b', '', ['Member', ], [])
293 294 295 296 297 298 299 300 301 302
    user_b = uf.getUserById('user_b').__of__(uf)
    
    # log as user_a 
    newSecurityManager(None, 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')
303
    transaction.commit(); self.tic()
304 305 306 307 308 309 310 311 312 313 314 315 316 317

    # 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')
    
    # log as user_b
    newSecurityManager(None, 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))
318
    transaction.commit(); self.tic()
319 320 321 322 323 324 325 326 327
    
    # 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')
328 329 330 331 332 333 334 335 336 337 338 339 340 341
    
    # Checks that a manager preference doesn't disable any other user
    # preferences
    # log as manager
    newSecurityManager(None, uf.getUserById('manager').__of__(uf))
    
    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))
342
    transaction.commit(); self.tic()
343 344 345 346 347 348 349 350 351
    # enable this preference
    portal_workflow.doActionFor(
       manager_pref, 'enable_action', wf_id='preference_workflow')
    self.assertEquals(manager_pref.getPreferenceState(), 'enabled')
    
    # 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')
352

353 354 355 356 357 358 359 360
  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())
361
    transaction.commit()
362 363 364 365
    self.tic()
    noSecurityManager()
    self.assertEquals(['this_is_visible_by_anonymous'],
        ptool.getPreferredAccountingTransactionSimulationStateList())
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380

  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, None)
    state = method('default')
    self.assertEquals(state, 'default')

381 382 383 384 385 386
    method = lambda *args: pref_tool.getPreference('preferred_accounting_transaction_simulation_state', *args)
    state = method()
    self.assertEquals(state, None)
    state = method('default')
    self.assertEquals(state, 'default')

387 388 389 390
    method = pref_tool.getPreferredAccountingTransactionSimulationStateList
    state_list = method()
    self.assertEquals(state_list, None)
    state_list = method(('default',))
391 392
    self.assertEquals(state_list, ['default',]) # getPreferredAccountingTransactionSimulationStateList
                                                # always tries to cast tuples to lists
393
 
394 395 396 397 398 399
    method = lambda *args: pref_tool.getPreference('preferred_accounting_transaction_simulation_state_list', *args)
    state_list = method()
    self.assertEquals(state_list, None)
    state_list = method(('default',))
    self.assertEquals(state_list, ('default',))

400 401
  def test_Permissions(self):
    # create a new site preference for later
402 403
    preference_tool = self.portal.portal_preferences
    site_pref = preference_tool.newContent(
404 405 406 407 408 409 410 411 412 413
                          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)
    newSecurityManager(None, member)
414
    user_pref = preference_tool.newContent(portal_type='Preference')
415 416 417

    # Members can copy & paste existing preferences
    user_pref.Base_createCloneDocument()
418 419 420 421 422 423
    # 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())

424 425 426 427 428 429 430
    # 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))
431 432 433 434 435 436

  
  def test_SystemPreference(self):
    preference_tool = self.portal.portal_preferences
    site_pref = preference_tool.newContent(
                          portal_type='System Preference',
437
                          preferred_accounting_transaction_simulation_state_list="this_is_default",
438
                          priority=Priority.SITE)
439 440 441 442
    # check not taken into account if not enabled
    self.assertEquals(None,
                      preference_tool.getPreferredAccountingTransactionSimulationStateList())    
    # enable it and check preference is returned
443 444
    self.portal.portal_workflow.doActionFor(site_pref, 'enable_action')
    self.assertEquals(site_pref.getPreferenceState(), 'global')
445
    transaction.commit()
446 447 448
    self.tic()
    self.assertEquals(['this_is_default'],
                      preference_tool.getPreferredAccountingTransactionSimulationStateList())
449 450 451 452 453 454 455 456 457 458 459 460
    
    # Members can't add new system preferences
    uf = self.getPortal().acl_users
    uf._doAddUser('member', '', ['Member', ], [])
    member = uf.getUserById('member').__of__(uf)
    newSecurityManager(None, member)
    self.assertRaises(Unauthorized, preference_tool.newContent, portal_type='System Preference')
    # But they can see others
    site_pref.view()
    # check accessors works
    site_pref.setPreferredAccountingTransactionSimulationStateList(
      ['this_is_system'])
461
    transaction.commit()
462 463 464 465
    self.tic()
    self.assertEquals(['this_is_system'],
                      preference_tool.getPreferredAccountingTransactionSimulationStateList())

466
    # create a user pref and check it doesn't outranks the system one if
467 468 469 470 471 472 473 474
    # they both defined same pref
    user_pref = preference_tool.newContent(
                          portal_type='Preference',
                          priority=Priority.USER)
    user_pref.setPreferredAccountingTransactionSimulationStateList(
      ['this_is_user'])
    self.portal.portal_workflow.doActionFor(user_pref, 'enable_action')
    self.assertEquals(user_pref.getPreferenceState(), 'enabled')
475
    transaction.commit()
476 477
    self.tic()
    self.assertEquals(['this_is_user'],
478 479
                      user_pref.getPreferredAccountingTransactionSimulationStateList())
    self.assertEquals(['this_is_system'],
480 481
                      preference_tool.getPreferredAccountingTransactionSimulationStateList())

482 483 484
    # check a user can't edit preference which are marked for manager (only for zope2.8)
    try:
      from ZODB.Transaction import Transaction
485
    except ImportError:
486
      self.assertRaises(Unauthorized, user_pref.edit, preferred_ooodoc_server_address="localhost")
487

488 489
    

490 491 492 493
def test_suite():
  suite = unittest.TestSuite()
  suite.addTest(unittest.makeSuite(TestPreferences))
  return suite