From 00539b6e9ac9b79b440ae288315b925e01758ecc Mon Sep 17 00:00:00 2001
From: Yoshinori Okuji <yo@nexedi.com>
Date: Sat, 18 Aug 2007 18:38:21 +0000
Subject: [PATCH] Support a default value in the preference method.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@15742 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5Form/PreferenceTool.py        | 55 ++++++++++++-----------
 product/ERP5Form/tests/testPreferences.py | 20 +++++++++
 2 files changed, 49 insertions(+), 26 deletions(-)

diff --git a/product/ERP5Form/PreferenceTool.py b/product/ERP5Form/PreferenceTool.py
index 8aa843da41..48bee75c01 100644
--- a/product/ERP5Form/PreferenceTool.py
+++ b/product/ERP5Form/PreferenceTool.py
@@ -29,13 +29,12 @@
 from AccessControl import ClassSecurityInfo, getSecurityManager
 from MethodObject import Method
 from Globals import InitializeClass, DTMLFile
-from zLOG import LOG, INFO, PROBLEM
+from zLOG import LOG, PROBLEM
 
 from Products.CMFCore.utils import getToolByName
 from Products.ERP5Type.Tool.BaseTool import BaseTool
 from Products.ERP5Type import Permissions, PropertySheet
 from Products.ERP5Type.Cache import CachingMethod
-from Products.ERP5Type.Base import Base
 from Products.ERP5Type.Utils import convertToUpperCase
 from Products.ERP5Type.Accessor.TypeDefinition import list_types
 from Products.ERP5Form import _dtmldir
@@ -110,7 +109,7 @@ def createPreferenceToolAccessorList(portal) :
 
 class func_code: pass
 
-class PreferenceMethod(Method) :
+class PreferenceMethod(Method):
   """ A method object that lookup the attribute on preferences. """
   # This is required to call the method form the Web
   func_code = func_code()
@@ -118,32 +117,36 @@ class PreferenceMethod(Method) :
   func_code.co_argcount = 1
   func_defaults = ()
 
-  def __init__(self, attribute) :
+  def __init__(self, attribute):
     self._preference_name = attribute
+    self._preference_cache_id = 'PreferenceTool.CachingMethod.%s' % attribute
+    self._null = (None, '', (), [])
 
-  def __call__(self, instance, *args, **kw) :
-    # FIXME: Preference method doesn't support default parameter
-    def _getPreference(user_name="") :
-      found = 0
+  def __call__(self, instance, *args, **kw):
+    def _getPreference(user_name=None):
       MARKER = []
-      for pref in instance._getSortedPreferenceList(*args, **kw):
-        attr = getattr(pref, self._preference_name, MARKER)
-        if attr is not MARKER :
-          found = 1
-          # test the attr is set
-          if callable(attr) :
-            value = attr()
-          else :
-            value = attr
-          if value not in (None, '', (), []) :
-            return value
-      if found :
-        return value
-    _getPreference = CachingMethod( _getPreference,
-            id='PreferenceTool.CachingMethod.%s' % self._preference_name,
-                                    cache_factory='erp5_ui_short')
+      value = None
+      for pref in instance._getSortedPreferenceList():
+        value = getattr(pref, self._preference_name, MARKER)
+        if value is not MARKER:
+          # If callable, store the return value.
+          if callable(value):
+            value = value()
+          if value not in self._null:
+            break
+      return value
+    _getPreference = CachingMethod(_getPreference,
+            id=self._preference_cache_id,
+            cache_factory='erp5_ui_short')
     user_name = getSecurityManager().getUser().getId()
-    return _getPreference(user_name=user_name)
+    value = _getPreference(user_name=user_name)
+    # XXX Preference Tool has a strange assumption that, even if
+    # all values are null values, one of them must be returned.
+    # Therefore, return a default value, only if explicitly specified,
+    # instead of returning None.
+    if value in self._null and args:
+      return args[0]
+    return value
 
 class PreferenceTool(BaseTool):
   """
@@ -176,7 +179,7 @@ class PreferenceTool(BaseTool):
   def getPreference(self, pref_name, default=None) :
     """ get the preference on the most appopriate Preference object. """
     method = getattr(self, 'get%s' % convertToUpperCase(pref_name), None)
-    if method:
+    if method is not None:
       return method(default=default)
     return default
 
diff --git a/product/ERP5Form/tests/testPreferences.py b/product/ERP5Form/tests/testPreferences.py
index 277209bd45..7075d9052f 100644
--- a/product/ERP5Form/tests/testPreferences.py
+++ b/product/ERP5Form/tests/testPreferences.py
@@ -361,6 +361,26 @@ class TestPreferences(ERP5TypeTestCase):
     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, None)
+    state = method('default')
+    self.assertEquals(state, 'default')
+
+    method = pref_tool.getPreferredAccountingTransactionSimulationStateList
+    state_list = method()
+    self.assertEquals(state_list, None)
+    state_list = method(('default',))
+    self.assertEquals(state_list, ('default',))
  
     
 def test_suite():
-- 
2.30.9