[testlib] introduce temporary_permissions context manager
Fix a test failure due to cached method on the way as usage of the context manager
enforce proper interaction with schema objects
--- a/devtools/test/unittest_testlib.py Fri Jun 22 15:57:05 2012 +0200
+++ b/devtools/test/unittest_testlib.py Tue Jul 10 11:11:15 2012 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""unittests for cw.devtools.testlib module"""
+from __future__ import with_statement
from cStringIO import StringIO
@@ -155,5 +156,20 @@
self.assertEqual(self.page_info.has_link_regexp('L[ai]gilab'), False)
+class CWUtilitiesTC(CubicWebTC):
+ def test_temporary_permissions_eschema(self):
+ eschema = self.schema['CWUser']
+ with self.temporary_permissions(CWUser={'read': ()}):
+ self.assertEqual(eschema.permissions['read'], ())
+ self.assertTrue(eschema.permissions['add'])
+ self.assertTrue(eschema.permissions['read'], ())
+
+ def test_temporary_permissions_rdef(self):
+ rdef = self.schema['CWUser'].rdef('in_group')
+ with self.temporary_permissions((rdef, {'read': ()})):
+ self.assertEqual(rdef.permissions['read'], ())
+ self.assertTrue(rdef.permissions['add'])
+ self.assertTrue(rdef.permissions['read'], ())
+
if __name__ == '__main__':
unittest_main()
--- a/devtools/testlib.py Fri Jun 22 15:57:05 2012 +0200
+++ b/devtools/testlib.py Tue Jul 10 11:11:15 2012 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -31,6 +31,7 @@
from contextlib import contextmanager
from warnings import warn
from types import NoneType
+from itertools import chain
import yams.schema
@@ -466,6 +467,49 @@
for obj in appobjects:
self.vreg.unregister(obj)
+ @contextmanager
+ def temporary_permissions(self, *perm_overrides, **perm_kwoverrides):
+ """Set custom schema permissions within context.
+
+ There are two ways to call this method, which may be used together :
+
+ * using positional argument(s):
+
+ .. sourcecode:: python
+ rdef = self.schema['CWUser'].rdef('login')
+ with self.temporary_permissions((rdef, {'read': ()})):
+ ...
+
+
+ * using named argument(s):
+
+ .. sourcecode:: python
+ rdef = self.schema['CWUser'].rdef('login')
+ with self.temporary_permissions(CWUser={'read': ()}):
+ ...
+
+ Usually the former will be prefered to override permissions on a
+ relation definition, while the latter is well suited for entity types.
+
+ The allowed keys in the permission dictionary depends on the schema type
+ (entity type / relation definition). Resulting permissions will be
+ similar to `orig_permissions.update(partial_perms)`.
+ """
+ torestore = []
+ for erschema, etypeperms in chain(perm_overrides, perm_kwoverrides.iteritems()):
+ if isinstance(erschema, basestring):
+ erschema = self.schema[erschema]
+ for action, actionperms in etypeperms.iteritems():
+ origperms = erschema.permissions[action]
+ erschema.set_action_permissions(action, actionperms)
+ torestore.append([erschema, action, origperms])
+ yield
+ for erschema, action, permissions in torestore:
+ if action is None:
+ erschema.permissions = permissions
+ else:
+ erschema.set_action_permissions(action, permissions)
+
def assertModificationDateGreater(self, entity, olddate):
entity.cw_attr_cache.pop('modification_date', None)
self.assertTrue(entity.modification_date > olddate)