testPreferences.py 20.6 KB
Newer Older
Łukasz Nowak's avatar
Łukasz Nowak committed
1
# -*- coding: utf-8 -*-
2 3
##############################################################################
#
Łukasz Nowak's avatar
Łukasz Nowak committed
4
# Copyright (c) 2005-2009 Nexedi SA and Contributors. All Rights Reserved.
5
#                    Jerome Perrin <jerome@nexedi.com>
Łukasz Nowak's avatar
Łukasz Nowak committed
6
#                    Łukasz Nowak <luke@nexedi.com>
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#
# 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.
#
##############################################################################

31
import unittest
32

33
import transaction
34 35 36
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from AccessControl.SecurityManagement import getSecurityManager
37
from zExceptions import Unauthorized
38
from DateTime import DateTime
39

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


class TestPreferences(ERP5TypeTestCase):
Łukasz Nowak's avatar
Łukasz Nowak committed
45

46 47 48 49 50
  def getTitle(self):
    return "Portal Preference"

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

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

Łukasz Nowak's avatar
Łukasz Nowak committed
62
  def createPreferences(self):
63 64 65 66 67 68 69 70 71 72 73 74 75
    """ 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)
Łukasz Nowak's avatar
Łukasz Nowak committed
76

77
    # commit transaction
78
    transaction.commit()
79
    self.getPreferenceTool().recursiveReindexObject()
80
    self.tic()
Łukasz Nowak's avatar
Łukasz Nowak committed
81

82 83 84 85 86 87 88 89 90 91
    # 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')
Łukasz Nowak's avatar
Łukasz Nowak committed
92

93 94 95 96 97
  def test_PreferenceToolTitle(self):
    """Tests that the title of the preference tool is correct.
    """
    self.assertEquals('Preferences', self.getPreferenceTool().Title())

Łukasz Nowak's avatar
Łukasz Nowak committed
98
  def test_AllowedContentTypes(self):
99 100 101 102 103
    """Tests Preference can be added in Preference Tool.
    """
    self.failUnless('Preference' in [x.getId() for x in
           self.getPortal().portal_preferences.allowedContentTypes()])

Łukasz Nowak's avatar
Łukasz Nowak committed
104
  def test_EnablePreferences(self):
105 106 107 108 109 110
    """ tests preference workflow """
    portal_workflow = self.getWorkflowTool()
    person1 = self.getPreferenceTool()['person1']
    person2 = self.getPreferenceTool()['person2']
    group = self.getPreferenceTool()['group']
    site = self.getPreferenceTool()['site']
Łukasz Nowak's avatar
Łukasz Nowak committed
111

112
    self.assertEqual(None, self.getPreferenceTool().getActivePreference())
113 114
    self.assertEqual(None,
        self.getPreferenceTool().getActiveSystemPreference())
115

116 117 118
    person1.portal_workflow.doActionFor(
       person1, 'enable_action', wf_id='preference_workflow')
    self.assertEquals(person1.getPreferenceState(), 'enabled')
Łukasz Nowak's avatar
Łukasz Nowak committed
119

120
    self.assertEqual( person1, self.getPreferenceTool().getActivePreference())
121 122
    self.assertEqual(None,
        self.getPreferenceTool().getActiveSystemPreference())
123

124 125 126
    portal_workflow.doActionFor(
       site, 'enable_action', wf_id='preference_workflow')
    self.assertEquals(person1.getPreferenceState(), 'enabled')
127
    self.assertEquals(site.getPreferenceState(),    'global')
128

129
    self.assertEqual(person1, self.getPreferenceTool().getActivePreference())
130 131
    self.assertEqual(None,
        self.getPreferenceTool().getActiveSystemPreference())
132

133 134 135 136
    portal_workflow.doActionFor(
       group, 'enable_action', wf_id='preference_workflow')
    self.assertEquals(person1.getPreferenceState(), 'enabled')
    self.assertEquals(group.getPreferenceState(),   'enabled')
137
    self.assertEquals(site.getPreferenceState(),    'global')
Łukasz Nowak's avatar
Łukasz Nowak committed
138

139
    self.assertEqual(person1, self.getPreferenceTool().getActivePreference())
140 141
    self.assertEqual(None,
        self.getPreferenceTool().getActiveSystemPreference())
142

143 144
    portal_workflow.doActionFor(
       person2, 'enable_action', wf_id='preference_workflow')
145
    self.assertEqual(person2, self.getPreferenceTool().getActivePreference())
146 147
    self.assertEqual(None,
        self.getPreferenceTool().getActiveSystemPreference())
148 149 150 151
    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')
152
    self.assertEquals(site.getPreferenceState(),    'global')
153

Łukasz Nowak's avatar
Łukasz Nowak committed
154
  def test_GetPreference(self):
155 156 157 158 159 160
    """ 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']
Łukasz Nowak's avatar
Łukasz Nowak committed
161

162 163 164 165 166 167 168 169
    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')
170
    self.assertEquals(site.getPreferenceState(),    'global')
171
    person1.setPreferredAccountingTransactionSimulationState([])
172 173
    self.assertEquals(
      person1.getPreferredAccountingTransactionSimulationState(), None)
174
    group.setPreferredAccountingTransactionSimulationState([])
175 176
    self.assertEquals(
      group.getPreferredAccountingTransactionSimulationState(), None)
177
    site.setPreferredAccountingTransactionSimulationState([])
178 179
    self.assertEquals(
      site.getPreferredAccountingTransactionSimulationState(), None)
180

181
    self.assertEquals(len(pref_tool.getPreference(
182
      'preferred_accounting_transaction_simulation_state_list')), 0)
Łukasz Nowak's avatar
Łukasz Nowak committed
183

184 185 186
    site.edit(
      preferred_accounting_transaction_simulation_state_list=
      ['stopped', 'delivered'])
187
    self.assertEquals(list(pref_tool.getPreference(
188
      'preferred_accounting_transaction_simulation_state_list')),
189
      list(site.getPreferredAccountingTransactionSimulationStateList()))
Łukasz Nowak's avatar
Łukasz Nowak committed
190

191 192 193 194 195 196 197
    # 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))
Łukasz Nowak's avatar
Łukasz Nowak committed
198

199 200
    group.edit(
      preferred_accounting_transaction_simulation_state_list=['draft'])
201
    self.assertEquals(list(pref_tool.getPreference(
202
      'preferred_accounting_transaction_simulation_state_list')),
203
      list(group.getPreferredAccountingTransactionSimulationStateList()))
Łukasz Nowak's avatar
Łukasz Nowak committed
204

205
    person1.edit(preferred_accounting_transaction_simulation_state_list=
206 207
              ['cancelled'])
    self.assertEquals(list(pref_tool.getPreference(
208
      'preferred_accounting_transaction_simulation_state_list')),
209 210 211 212 213
      list(person1.getPreferredAccountingTransactionSimulationStateList()))
    # disable person -> group is selected
    self.getWorkflowTool().doActionFor(person1,
            'disable_action', wf_id='preference_workflow')
    self.assertEquals(list(pref_tool.getPreference(
214
      'preferred_accounting_transaction_simulation_state_list')),
215 216
      list(group.getPreferredAccountingTransactionSimulationStateList()))

217 218 219 220
    self.assertEquals('default', pref_tool.getPreference(
                                        'this_does_not_exists', 'default'))


Łukasz Nowak's avatar
Łukasz Nowak committed
221
  def test_GetAttr(self):
222 223 224 225 226 227 228 229 230 231 232 233 234
    """ 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')
235
    self.assertEquals(site.getPreferenceState(),     'global')
236
    group.setPreferredAccountingTransactionSimulationStateList(['cancelled'])
Łukasz Nowak's avatar
Łukasz Nowak committed
237

238 239 240 241 242 243 244
    self.assertNotEquals( None,
      pref_tool.getPreferredAccountingTransactionSimulationStateList())
    self.assertNotEquals( [],
      list(pref_tool.getPreferredAccountingTransactionSimulationStateList()))
    self.assertEquals(
      list(pref_tool.getPreferredAccountingTransactionSimulationStateList()),
      list(pref_tool.getPreference(
245
         'preferred_accounting_transaction_simulation_state_list')))
246 247 248
    # standards attributes must not be looked up on Preferences
    self.assertNotEquals(pref_tool.getTitleOrId(), group.getTitleOrId())
    self.assertNotEquals(pref_tool.objectValues(), group.objectValues())
249
    self.assertNotEquals(pref_tool.getParentValue(), group.getParentValue())
250 251
    try :
      pref_tool.getPreferredNotExistingPreference()
252
      self.fail('Attribute error should be raised for dummy methods')
253 254
    except AttributeError :
      pass
Łukasz Nowak's avatar
Łukasz Nowak committed
255 256 257

  def test_SetPreference(self):
    """ check setting a preference modifies
258 259 260 261
     the first enabled user preference """
    portal_workflow = self.getWorkflowTool()
    pref_tool = self.getPreferenceTool()
    person1 = self.getPreferenceTool()['person1']
Łukasz Nowak's avatar
Łukasz Nowak committed
262

263 264 265 266 267 268 269 270 271 272 273 274 275 276
    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))

Łukasz Nowak's avatar
Łukasz Nowak committed
277
  def test_UserIndependance(self):
278 279 280 281 282
    """ 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
283
    uf._doAddUser('user_a', '', ['Member', ], [])
284
    user_a = uf.getUserById('user_a').__of__(uf)
285
    uf._doAddUser('user_b', '', ['Member', ], [])
286
    user_b = uf.getUserById('user_b').__of__(uf)
Łukasz Nowak's avatar
Łukasz Nowak committed
287 288

    # log as user_a
289
    newSecurityManager(None, user_a)
Łukasz Nowak's avatar
Łukasz Nowak committed
290

291 292 293 294 295
    # 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')
296
    transaction.commit(); self.tic()
297 298 299 300 301 302

    # 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')
Łukasz Nowak's avatar
Łukasz Nowak committed
303

304 305
    # log as user_b
    newSecurityManager(None, user_b)
Łukasz Nowak's avatar
Łukasz Nowak committed
306

307 308 309 310
    # 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))
311
    transaction.commit(); self.tic()
Łukasz Nowak's avatar
Łukasz Nowak committed
312

313 314 315 316
    # enable this preference
    portal_workflow.doActionFor(
       user_b_1, 'enable_action', wf_id='preference_workflow')
    self.assertEquals(user_b_1.getPreferenceState(), 'enabled')
Łukasz Nowak's avatar
Łukasz Nowak committed
317

318 319 320
    # check user_a's preference is still enabled
    self.assertEquals(user_a_1.getPreferenceState(), 'enabled')
    self.assertEquals(user_a_2.getPreferenceState(), 'disabled')
Łukasz Nowak's avatar
Łukasz Nowak committed
321

322 323 324 325
    # Checks that a manager preference doesn't disable any other user
    # preferences
    # log as manager
    newSecurityManager(None, uf.getUserById('manager').__of__(uf))
Łukasz Nowak's avatar
Łukasz Nowak committed
326

327 328
    self.assert_('Manager' in
      getSecurityManager().getUser().getRolesInContext(portal_preferences))
Łukasz Nowak's avatar
Łukasz Nowak committed
329

330 331 332 333 334
    # create a pref for manager
    manager_pref = portal_preferences.newContent(
        id='manager_pref', portal_type='Preference')
    manager_pref.setPreferredAccountingTransactionAtDate(
                                DateTime(2012, 12, 12))
335
    transaction.commit(); self.tic()
336 337 338 339
    # enable this preference
    portal_workflow.doActionFor(
       manager_pref, 'enable_action', wf_id='preference_workflow')
    self.assertEquals(manager_pref.getPreferenceState(), 'enabled')
Łukasz Nowak's avatar
Łukasz Nowak committed
340

341 342 343 344
    # 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')
345

346 347 348 349 350 351 352 353
  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())
354
    transaction.commit()
355 356 357 358
    self.tic()
    noSecurityManager()
    self.assertEquals(['this_is_visible_by_anonymous'],
        ptool.getPreferredAccountingTransactionSimulationStateList())
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373

  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')

374 375 376 377 378 379
    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')

380 381 382 383
    method = pref_tool.getPreferredAccountingTransactionSimulationStateList
    state_list = method()
    self.assertEquals(state_list, None)
    state_list = method(('default',))
384 385
    self.assertEquals(state_list, ['default',]) # getPreferredAccountingTransactionSimulationStateList
                                                # always tries to cast tuples to lists
Łukasz Nowak's avatar
Łukasz Nowak committed
386

387 388 389 390 391 392
    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',))

393 394
  def test_Permissions(self):
    # create a new site preference for later
395 396
    preference_tool = self.portal.portal_preferences
    site_pref = preference_tool.newContent(
397 398 399 400
                          portal_type='Preference',
                          priority=Priority.SITE)
    self.portal.portal_workflow.doActionFor(site_pref, 'enable_action')
    self.assertEquals(site_pref.getPreferenceState(), 'global')
Łukasz Nowak's avatar
Łukasz Nowak committed
401

402 403 404 405 406
    # Members can add new preferences
    uf = self.getPortal().acl_users
    uf._doAddUser('member', '', ['Member', ], [])
    member = uf.getUserById('member').__of__(uf)
    newSecurityManager(None, member)
407
    user_pref = preference_tool.newContent(portal_type='Preference')
408 409 410

    # Members can copy & paste existing preferences
    user_pref.Base_createCloneDocument()
411 412 413 414 415 416
    # 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())

417 418 419 420 421 422 423
    # 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))
424

Łukasz Nowak's avatar
Łukasz Nowak committed
425

426 427 428 429
  def test_SystemPreference(self):
    preference_tool = self.portal.portal_preferences
    site_pref = preference_tool.newContent(
                          portal_type='System Preference',
430
                          preferred_accounting_transaction_simulation_state_list="this_is_default",
431
                          priority=Priority.SITE)
432 433
    # check not taken into account if not enabled
    self.assertEquals(None,
Łukasz Nowak's avatar
Łukasz Nowak committed
434
                      preference_tool.getPreferredAccountingTransactionSimulationStateList())
435
    # enable it and check preference is returned
436 437
    self.portal.portal_workflow.doActionFor(site_pref, 'enable_action')
    self.assertEquals(site_pref.getPreferenceState(), 'global')
438
    transaction.commit()
439 440 441
    self.tic()
    self.assertEquals(['this_is_default'],
                      preference_tool.getPreferredAccountingTransactionSimulationStateList())
Łukasz Nowak's avatar
Łukasz Nowak committed
442

443 444 445 446 447 448 449 450 451 452 453
    # 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'])
454
    transaction.commit()
455 456 457 458
    self.tic()
    self.assertEquals(['this_is_system'],
                      preference_tool.getPreferredAccountingTransactionSimulationStateList())

459
    # create a user pref and check it doesn't outranks the system one if
460 461 462 463 464 465 466 467
    # 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')
468
    transaction.commit()
469 470
    self.tic()
    self.assertEquals(['this_is_user'],
471 472
                      user_pref.getPreferredAccountingTransactionSimulationStateList())
    self.assertEquals(['this_is_system'],
473 474
                      preference_tool.getPreferredAccountingTransactionSimulationStateList())

475 476 477
    # check a user can't edit preference which are marked for manager (only for zope2.8)
    try:
      from ZODB.Transaction import Transaction
478
    except ImportError:
479
      self.assertRaises(Unauthorized, user_pref.edit, preferred_ooodoc_server_address="localhost")
480 481 482
    # even if there is System Preference enabled getActivePreference shall return
    # user preference
    self.assertEqual(user_pref, preference_tool.getActivePreference())
483
    self.assertEqual(site_pref, preference_tool.getActiveSystemPreference())
484

485 486 487 488
def test_suite():
  suite = unittest.TestSuite()
  suite.addTest(unittest.makeSuite(TestPreferences))
  return suite