[testlib] introduce temporary_permissions context manager stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 10 Jul 2012 11:11:15 +0200
branchstable
changeset 8460 b1f6777fc839
parent 8453 f441056a2b61
child 8461 8af7c6d86efb
[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
devtools/test/unittest_testlib.py
devtools/testlib.py
--- 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)