Commit d362cecd authored by Jérome Perrin's avatar Jérome Perrin

Create user preference only when user configure preferences

To make it easier for users to change their preferences, so that they do not have to create the preference themselves, we tried to pre-create a user preference ready to be configured for each user.  

It was 59860df3 :  an interaction to create a user preference on `Person.setReference` which is more or less the time when this person become a user ( but not really - this was already a weakness of this approach).

This calls `Person_createUserPreference` that initialize the preference by introspecting the assignments of the person. This already had a problem that it was working only if the assignments were created before the reference was set on the person.

With the new user management introduced in !185 this interaction moved to `Person.setUserId`, which is called in Person's init script. This had the following problems:
 - All persons have a user id, so all persons have a preference. For sites with many persons that are not actually users, this create useless preferences.
 - During init, person does not have assignments yet, so `Person_createUserPreference` could not use information from assignment to create preference.

The suggested change is to create the preference only when the user click on *Edit my preferences* button.

This is done by adding a new `portal_preferences.getActiveUserPreference` method that returns the active user preference and create it if not already existing, this way we do not have to put logic in the user interface scripts.

All *Edit my preferences* links should use it like it was done in f62e6651

The `person_interaction_workflow` was completely remove, as the other interaction it was containing - clearCache when deleting the person - was useless . We had to adjust a few tests that was passing thanks to this interaction.

/cc @gabriel @vpelletier @kazuhiko @tc 

/reviewed-on nexedi/erp5!273
parents 3b1e230c 19f16a86
request = context.REQUEST portal = context.getPortalObject()
return request.RESPONSE.redirect( "%s/Preference_viewAccounting" % active_preference = portal.portal_preferences.getActiveUserPreference()
context.portal_preferences.getActivePreference().absolute_url()) if not active_preference:
active_preference = portal.portal_preferences.getActivePreference()
# vim: syntax=python return active_preference.Base_redirect(form_id='Preference_viewAccounting')
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
</chain> </chain>
<chain> <chain>
<type>Person</type> <type>Person</type>
<workflow>edit_workflow, person_interaction_workflow, user_account_workflow, validation_workflow</workflow> <workflow>edit_workflow, user_account_workflow, validation_workflow</workflow>
</chain> </chain>
<chain> <chain>
<type>Query</type> <type>Query</type>
......
...@@ -23,3 +23,5 @@ for assignment in context.contentValues(portal_type='Assignment'): ...@@ -23,3 +23,5 @@ for assignment in context.contentValues(portal_type='Assignment'):
if group: if group:
preference.setPreferredSectionCategory(group) preference.setPreferredSectionCategory(group)
preference.setPreferredAccountingTransactionSectionCategory(group) preference.setPreferredAccountingTransactionSectionCategory(group)
return preference
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionWorkflowDefinition" module="Products.ERP5.InteractionWorkflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>creation_guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>person_interaction_workflow</string> </value>
</item>
<item>
<key> <string>manager_bypass</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Interacts for Person type events</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Interaction" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>interactions</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionDefinition" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>activate_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value>
<list>
<string>Person_clearContentShortCache</string>
</list>
</value>
</item>
<item>
<key> <string>before_commit_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ClearContentShortCache_onDeleteUserLoginPerson</string> </value>
</item>
<item>
<key> <string>method_id</string> </key>
<value>
<list>
<string>delete</string>
<string>manage_beforeDelete</string>
</list>
</value>
</item>
<item>
<key> <string>once_per_transaction</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value>
<list>
<string>Person</string>
</list>
</value>
</item>
<item>
<key> <string>script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionDefinition" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>activate_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value>
<list>
<string>Person_createUserPreference</string>
</list>
</value>
</item>
<item>
<key> <string>before_commit_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>set a user id</string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>setReference</string> </value>
</item>
<item>
<key> <string>method_id</string> </key>
<value>
<list>
<string>_setUserId</string>
</list>
</value>
</item>
<item>
<key> <string>once_per_transaction</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Scripts" module="Products.DCWorkflow.Scripts"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>scripts</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
# XXX-Luke: Seb pointed out that this is very bad idea to clear cache.
document = state_change['object']
if document.Person_getUserId() is not None:
cache_tool = document.getPortalObject().portal_caches
cache_tool.clearCache(cache_factory_list=('erp5_content_short', ),
before_commit=True)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Person_clearContentShortCache</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
person = sci['object']
if person.Person_getUserId():
person.activate(after_path_and_method_id=(person.getPath(),
('immediateReindexObject',
'recursiveImmediateReindexObject'))).Person_createUserPreference()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>sci</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Person_createUserPreference</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Variables" module="Products.DCWorkflow.Variables"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variables</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Worklists" module="Products.DCWorkflow.Worklists"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklists</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -43,7 +43,6 @@ Notification Message | processing_status_workflow ...@@ -43,7 +43,6 @@ Notification Message | processing_status_workflow
Organisation | edit_workflow Organisation | edit_workflow
Organisation | validation_workflow Organisation | validation_workflow
Person | edit_workflow Person | edit_workflow
Person | person_interaction_workflow
Person | user_account_workflow Person | user_account_workflow
Person | validation_workflow Person | validation_workflow
Query | edit_workflow Query | edit_workflow
......
...@@ -13,7 +13,6 @@ local_permission_interaction_workflow ...@@ -13,7 +13,6 @@ local_permission_interaction_workflow
login_validation_workflow login_validation_workflow
movement_resource_interaction_workflow movement_resource_interaction_workflow
notification_message_workflow notification_message_workflow
person_interaction_workflow
processing_status_workflow processing_status_workflow
query_workflow query_workflow
reindex_object_interaction_workflow reindex_object_interaction_workflow
......
...@@ -80,7 +80,6 @@ class TestRunMyDocsConfiguratorWorkflowMixin(TestLiveConfiguratorWorkflowMixin): ...@@ -80,7 +80,6 @@ class TestRunMyDocsConfiguratorWorkflowMixin(TestLiveConfiguratorWorkflowMixin):
stepStartConfigurationInstallation stepStartConfigurationInstallation
stepTic stepTic
stepCheckSystemPreferenceAfterInstallation stepCheckSystemPreferenceAfterInstallation
stepCheckUserPreferenceAfterInstallation
stepCheckKnowledgePadRole stepCheckKnowledgePadRole
""" """
...@@ -190,19 +189,6 @@ class TestRunMyDocsConfiguratorWorkflowMixin(TestLiveConfiguratorWorkflowMixin): ...@@ -190,19 +189,6 @@ class TestRunMyDocsConfiguratorWorkflowMixin(TestLiveConfiguratorWorkflowMixin):
self.assertEqual(system_preference.getPreferredDocumentConversionServerUrl(), self.assertEqual(system_preference.getPreferredDocumentConversionServerUrl(),
conversion_dict['url']) conversion_dict['url'])
def stepCheckUserPreferenceAfterInstallation(self, sequence=None, sequence_list=None, **kw):
""" Check System Preference"""
portal_catalog = self.portal.portal_catalog
preference = portal_catalog.getResultValue(portal_type="Preference",
title='Preference for Person Assignor')
self.assertEqual(preference.getPreferenceState(), "enabled")
preference = portal_catalog.getResultValue(portal_type="Preference",
title='Preference for Person Assignee')
self.assertEqual(preference.getPreferenceState(), "enabled")
preference = portal_catalog.getResultValue(portal_type="Preference",
title='Preference for Person Creator')
self.assertEqual(preference.getPreferenceState(), "enabled")
def _stepCheckKnowledgePadRole(self): def _stepCheckKnowledgePadRole(self):
""" Check if Knowledge Pad is configured correctly """ """ Check if Knowledge Pad is configured correctly """
self.portal.ERP5Site_createDefaultKnowledgePadListForUser() self.portal.ERP5Site_createDefaultKnowledgePadListForUser()
......
...@@ -98,7 +98,7 @@ class TestUNGConfiguratorWorkflowMixin(TestLiveConfiguratorWorkflowMixin): ...@@ -98,7 +98,7 @@ class TestUNGConfiguratorWorkflowMixin(TestLiveConfiguratorWorkflowMixin):
stepTic stepTic
stepCheckUNGWebSiteAfterInstallation stepCheckUNGWebSiteAfterInstallation
stepCheckSystemPreferenceAfterInstallation stepCheckSystemPreferenceAfterInstallation
stepCheckUserPreferenceAfterInstallation stepCheckSitePreferenceAfterInstallation
stepCheckWebSiteRoles stepCheckWebSiteRoles
stepCheckKnowledgePadRole stepCheckKnowledgePadRole
stepCheckCreateNewEvent stepCheckCreateNewEvent
...@@ -216,18 +216,8 @@ class TestUNGConfiguratorWorkflowMixin(TestLiveConfiguratorWorkflowMixin): ...@@ -216,18 +216,8 @@ class TestUNGConfiguratorWorkflowMixin(TestLiveConfiguratorWorkflowMixin):
self.assertEqual(system_preference.getPreferredDocumentConversionServerUrl(), self.assertEqual(system_preference.getPreferredDocumentConversionServerUrl(),
conversion_dict['url']) conversion_dict['url'])
def stepCheckUserPreferenceAfterInstallation(self, sequence=None, sequence_list=None, **kw): def stepCheckSitePreferenceAfterInstallation(self, sequence=None, sequence_list=None, **kw):
""" Check System Preference""" """ Check Site Preference"""
portal_catalog = self.portal.portal_catalog
preference = portal_catalog.getResultValue(portal_type="Preference",
title='Preference for Person Assignor')
self.assertEqual(preference.getPreferenceState(), "enabled")
preference = portal_catalog.getResultValue(portal_type="Preference",
title='Preference for Person Assignee')
self.assertEqual(preference.getPreferenceState(), "enabled")
preference = portal_catalog.getResultValue(portal_type="Preference",
title='Preference for Person Creator')
self.assertEqual(preference.getPreferenceState(), "enabled")
preference = self.portal.portal_preferences.ung_preference preference = self.portal.portal_preferences.ung_preference
self.assertEqual(preference.getPreferenceState(), "global") self.assertEqual(preference.getPreferenceState(), "global")
......
...@@ -39,6 +39,8 @@ class TestUNGSecurity(ERP5TypeTestCase): ...@@ -39,6 +39,8 @@ class TestUNGSecurity(ERP5TypeTestCase):
return "Test UNG Security" return "Test UNG Security"
def beforeTearDown(self): def beforeTearDown(self):
self.abort()
self.tic()
person_module = self.getPersonModule() person_module = self.getPersonModule()
person_module.manage_delObjects(list(person_module.objectIds())) person_module.manage_delObjects(list(person_module.objectIds()))
self.tic() self.tic()
......
...@@ -4,7 +4,7 @@ if context.portal_membership.isAnonymousUser(): ...@@ -4,7 +4,7 @@ if context.portal_membership.isAnonymousUser():
return dumps(None) return dumps(None)
portal_preferences = context.portal_preferences portal_preferences = context.portal_preferences
preference = portal_preferences.getActivePreference() preference = portal_preferences.getActiveUserPreference()
preference_dict = {} preference_dict = {}
......
...@@ -14,7 +14,7 @@ if not context.Person_getUserId(): ...@@ -14,7 +14,7 @@ if not context.Person_getUserId():
from Products.ERP5Type.Message import translateString from Products.ERP5Type.Message import translateString
preference = portal.portal_preferences.createPreferenceForUser( preference = portal.portal_preferences.createPreferenceForUser(
context.getReference(), enable=True) context.Person_getUserId(), enable=True)
preference.setTitle(translateString('Preference for ${name}', preference.setTitle(translateString('Preference for ${name}',
mapping=dict(name=context.getTitle().decode('utf-8')))) mapping=dict(name=context.getTitle().decode('utf-8'))))
...@@ -24,3 +24,5 @@ for assignment in context.contentValues(portal_type='Assignment'): ...@@ -24,3 +24,5 @@ for assignment in context.contentValues(portal_type='Assignment'):
if group: if group:
preference.setPreferredSectionCategory(group) preference.setPreferredSectionCategory(group)
preference.setPreferredAccountingTransactionSectionCategory(group) preference.setPreferredAccountingTransactionSectionCategory(group)
return preference
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
preference_tool = context.getPortalObject().portal_preferences preference_tool = context.getPortalObject().portal_preferences
preference = preference_tool.getActivePreference() preference = preference_tool.getActiveUserPreference()
if preference is not None and preference.getPriority() == 3: # XXX: 3 is Priority.USER if preference is not None:
return preference.Base_redirect('view') return preference.Base_redirect('view')
return preference_tool.Base_redirect('view') return preference_tool.Base_redirect('view')
...@@ -1157,7 +1157,7 @@ class TestERP5Base(ERP5TypeTestCase): ...@@ -1157,7 +1157,7 @@ class TestERP5Base(ERP5TypeTestCase):
def test_user_creation(self): def test_user_creation(self):
person = self.portal.person_module.newContent(portal_type='Person') person = self.portal.person_module.newContent(portal_type='Person')
assignment = person.newContent(portal_type='Assignment', assignment = person.newContent(portal_type='Assignment',
group='nexedi') group='nexedi/storever')
self.assertNotEquals(None, assignment.getGroupValue()) self.assertNotEquals(None, assignment.getGroupValue())
assignment.open() assignment.open()
self.portal.portal_workflow.doActionFor(person, 'create_user_action', self.portal.portal_workflow.doActionFor(person, 'create_user_action',
...@@ -1170,13 +1170,21 @@ class TestERP5Base(ERP5TypeTestCase): ...@@ -1170,13 +1170,21 @@ class TestERP5Base(ERP5TypeTestCase):
user = self.portal.acl_users.getUser('user_login') user = self.portal.acl_users.getUser('user_login')
self.assertNotEquals(None, user) self.assertNotEquals(None, user)
# and this user has a preference created # This user does not have a preference created automatically ...
newSecurityManager(None, user.__of__(self.portal.acl_users)) newSecurityManager(None, user.__of__(self.portal.acl_users))
self.assertEquals(None,
self.portal.portal_catalog.getResultValue(portal_type='Preference',
owner=user.getId()))
# ... but only when `getActiveUserPreference`
preference = self.portal.portal_preferences.getActiveUserPreference()
self.assertNotEquals(None, preference)
self.tic()
self.assertNotEquals(None, self.assertNotEquals(None,
self.portal.portal_catalog.getResultValue(portal_type='Preference', self.portal.portal_catalog.getResultValue(portal_type='Preference',
owner=user.getId())) owner=user.getId()))
# for his assignent group
self.assertEqual('group/nexedi', # for his assignment group
self.assertEqual('group/nexedi/storever',
self.portal.portal_preferences.getPreferredSectionCategory()) self.portal.portal_preferences.getPreferredSectionCategory())
def test_default_address_acquisition(self): def test_default_address_acquisition(self):
......
...@@ -1264,6 +1264,8 @@ Hé Hé Hé!""", page.asText().strip()) ...@@ -1264,6 +1264,8 @@ Hé Hé Hé!""", page.asText().strip())
reference='NXD-Document.Cache', reference='NXD-Document.Cache',
text_content=content) text_content=content)
document.publish() document.publish()
# clear cache used in Base_getWebDocumentDrivenModificationDate
self.portal.portal_caches.clearAllCache()
self.tic() self.tic()
path = website.absolute_url_path() + '/NXD-Document.Cache' path = website.absolute_url_path() + '/NXD-Document.Cache'
# test Different Policy installed by erp5_web # test Different Policy installed by erp5_web
......
...@@ -241,19 +241,6 @@ class TestPerson(ERP5TypeTestCase): ...@@ -241,19 +241,6 @@ class TestPerson(ERP5TypeTestCase):
self.assertEqual(None, p.getPassword()) self.assertEqual(None, p.getPassword())
self.assertEqual('default', p.getPassword('default')) self.assertEqual('default', p.getPassword('default'))
def testPreferenceInteractionWorkflow(self):
""" when setting reference, a script create preference is
called by activities, check this behavior. """
person_module = self.getPersonModule()
title = "Séb"
person = person_module.newContent(portal_type='Person', title=title)
person.setReference('test_seb')
self.tic()
portal = self.getPortal()
last_id = portal.portal_preferences.getLastId()
last_preference = portal.portal_preferences[last_id]
self.assertTrue("Séb" in last_preference.getTitle())
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
......
...@@ -197,6 +197,27 @@ class PreferenceTool(BaseTool): ...@@ -197,6 +197,27 @@ class PreferenceTool(BaseTool):
Note that this preference may be read only. """ Note that this preference may be read only. """
return self._getActivePreferenceByPortalType('Preference') return self._getActivePreferenceByPortalType('Preference')
security.declareProtected(Permissions.View, 'getActiveUserPreference')
def getActiveUserPreference(self) :
""" returns the current user preference for the user.
If no preference exists, then try to create one with `createUserPreference`
type based method.
This method returns a preference that the user will be able to edit or
None, if `createUserPreference` refused to create a preference.
It is intendended for "click here to edit your preferences" actions.
"""
active_preference = self.getActivePreference()
if active_preference is None or active_preference.getPriority() != Priority.USER:
# If user does not have a preference, let's try to create one
user = self.getPortalObject().portal_membership.getAuthenticatedMember().getUserValue()
if user is not None:
createUserPreference = user.getTypeBasedMethod('createUserPreference')
if createUserPreference is not None:
active_preference = createUserPreference()
return active_preference
security.declareProtected(Permissions.View, 'getActiveSystemPreference') security.declareProtected(Permissions.View, 'getActiveSystemPreference')
def getActiveSystemPreference(self) : def getActiveSystemPreference(self) :
""" returns the current system preference for the user. """ returns the current system preference for the user.
...@@ -249,14 +270,14 @@ class PreferenceTool(BaseTool): ...@@ -249,14 +270,14 @@ class PreferenceTool(BaseTool):
security.declareProtected(Permissions.ManagePortal, security.declareProtected(Permissions.ManagePortal,
'createPreferenceForUser') 'createPreferenceForUser')
def createPreferenceForUser(self, username, enable=True): def createPreferenceForUser(self, user_id, enable=True):
"""Creates a preference for a given user, and optionnally enable the """Creates a preference for a given user, and optionnally enable the
preference. preference.
""" """
user_folder = self.acl_users user_folder = self.acl_users
user = user_folder.getUserById(username) user = user_folder.getUserById(user_id)
if user is None: if user is None:
raise ValueError("User %r not found" % (username, )) raise ValueError("User %r not found" % (user_id, ))
security_manager = getSecurityManager() security_manager = getSecurityManager()
try: try:
newSecurityManager(None, user.__of__(user_folder)) newSecurityManager(None, user.__of__(user_folder))
......
...@@ -77,9 +77,6 @@ class TestPreferences(PropertySheetTestCase): ...@@ -77,9 +77,6 @@ class TestPreferences(PropertySheetTestCase):
id='site', portal_type='Preference') id='site', portal_type='Preference')
site.setPriority(Priority.SITE) site.setPriority(Priority.SITE)
# commit transaction
self.commit()
self.getPreferenceTool().recursiveReindexObject()
self.tic() self.tic()
# check preference levels are Ok # check preference levels are Ok
...@@ -115,6 +112,7 @@ class TestPreferences(PropertySheetTestCase): ...@@ -115,6 +112,7 @@ class TestPreferences(PropertySheetTestCase):
site = self.getPreferenceTool()['site'] site = self.getPreferenceTool()['site']
self.assertEqual(None, self.getPreferenceTool().getActivePreference()) self.assertEqual(None, self.getPreferenceTool().getActivePreference())
self.assertEqual(None, self.getPreferenceTool().getActiveUserPreference())
self.assertEqual(None, self.assertEqual(None,
self.getPreferenceTool().getActiveSystemPreference()) self.getPreferenceTool().getActiveSystemPreference())
...@@ -124,6 +122,7 @@ class TestPreferences(PropertySheetTestCase): ...@@ -124,6 +122,7 @@ class TestPreferences(PropertySheetTestCase):
self.assertEqual(person1.getPreferenceState(), 'enabled') self.assertEqual(person1.getPreferenceState(), 'enabled')
self.assertEqual( person1, self.getPreferenceTool().getActivePreference()) self.assertEqual( person1, self.getPreferenceTool().getActivePreference())
self.assertEqual( person1, self.getPreferenceTool().getActiveUserPreference())
self.assertEqual(None, self.assertEqual(None,
self.getPreferenceTool().getActiveSystemPreference()) self.getPreferenceTool().getActiveSystemPreference())
...@@ -133,6 +132,7 @@ class TestPreferences(PropertySheetTestCase): ...@@ -133,6 +132,7 @@ class TestPreferences(PropertySheetTestCase):
self.assertEqual(site.getPreferenceState(), 'global') self.assertEqual(site.getPreferenceState(), 'global')
self.assertEqual(person1, self.getPreferenceTool().getActivePreference()) self.assertEqual(person1, self.getPreferenceTool().getActivePreference())
self.assertEqual(person1, self.getPreferenceTool().getActiveUserPreference())
self.assertEqual(None, self.assertEqual(None,
self.getPreferenceTool().getActiveSystemPreference()) self.getPreferenceTool().getActiveSystemPreference())
...@@ -143,6 +143,7 @@ class TestPreferences(PropertySheetTestCase): ...@@ -143,6 +143,7 @@ class TestPreferences(PropertySheetTestCase):
self.assertEqual(site.getPreferenceState(), 'global') self.assertEqual(site.getPreferenceState(), 'global')
self.assertEqual(person1, self.getPreferenceTool().getActivePreference()) self.assertEqual(person1, self.getPreferenceTool().getActivePreference())
self.assertEqual(person1, self.getPreferenceTool().getActiveUserPreference())
self.assertEqual(None, self.assertEqual(None,
self.getPreferenceTool().getActiveSystemPreference()) self.getPreferenceTool().getActiveSystemPreference())
...@@ -150,6 +151,7 @@ class TestPreferences(PropertySheetTestCase): ...@@ -150,6 +151,7 @@ class TestPreferences(PropertySheetTestCase):
person2, 'enable_action', wf_id='preference_workflow') person2, 'enable_action', wf_id='preference_workflow')
self.commit() self.commit()
self.assertEqual(person2, self.getPreferenceTool().getActivePreference()) self.assertEqual(person2, self.getPreferenceTool().getActivePreference())
self.assertEqual(person2, self.getPreferenceTool().getActiveUserPreference())
self.assertEqual(None, self.assertEqual(None,
self.getPreferenceTool().getActiveSystemPreference()) self.getPreferenceTool().getActiveSystemPreference())
self.assertEqual(person2.getPreferenceState(), 'enabled') self.assertEqual(person2.getPreferenceState(), 'enabled')
...@@ -553,6 +555,7 @@ class TestPreferences(PropertySheetTestCase): ...@@ -553,6 +555,7 @@ class TestPreferences(PropertySheetTestCase):
# even if there is System Preference enabled getActivePreference shall return # even if there is System Preference enabled getActivePreference shall return
# user preference # user preference
self.assertEqual(user_pref, preference_tool.getActivePreference()) self.assertEqual(user_pref, preference_tool.getActivePreference())
self.assertEqual(user_pref, preference_tool.getActiveUserPreference())
self.assertEqual(system_pref, preference_tool.getActiveSystemPreference()) self.assertEqual(system_pref, preference_tool.getActiveSystemPreference())
def test_boolean_accessor(self): def test_boolean_accessor(self):
......
...@@ -379,6 +379,31 @@ class TestUserManagement(ERP5TypeTestCase): ...@@ -379,6 +379,31 @@ class TestUserManagement(ERP5TypeTestCase):
user_id, user_id,
) )
def test_Preference_created_for_new_user_on_getActiveUserPreference(self):
# Creating a user will create a preference on the first time `getActiveUserPreference`
# is called
preference_tool = self.portal.portal_preferences
preference_count = len(preference_tool.contentValues())
user_id, login, password = self._makePerson()
# creating a person does not create a preference
self.assertEqual(preference_count, len(preference_tool.contentValues()))
self.loginAsUser(user_id)
# getActiveUserPreference will create a user preference
new_preference = preference_tool.getActiveUserPreference()
self.assertNotEqual(None, new_preference)
self.assertEqual(preference_count+1, len(preference_tool.contentValues()))
self.assertEqual('enabled', new_preference.getPreferenceState())
self.tic()
# subsequent calls to getActiveUserPreference returns the same preference
active_preference = preference_tool.getActiveUserPreference()
self.assertEqual(active_preference, new_preference)
self.assertEqual(preference_count+1, len(preference_tool.contentValues()))
def test_PreferenceTool_setNewPassword(self): def test_PreferenceTool_setNewPassword(self):
# Preference Tool has an action to change password # Preference Tool has an action to change password
user_id, login, password = self._makePerson() user_id, login, password = self._makePerson()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment