[facet] add safety belt to rql path facet init (closes #1965481) stable
authorAurelien Campeas <aurelien.campeas@logilab.fr>
Tue, 27 Sep 2011 16:04:30 +0200
branchstable
changeset 7874 be04706eacc9
parent 7873 975d6f51cfab
child 7879 9aae456abab5
[facet] add safety belt to rql path facet init (closes #1965481)
web/facet.py
web/test/unittest_facet.py
--- a/web/facet.py	Tue Sep 27 14:57:41 2011 +0200
+++ b/web/facet.py	Tue Sep 27 16:04:30 2011 +0200
@@ -64,7 +64,7 @@
 from cubicweb import Unauthorized, typed_eid
 from cubicweb.schema import display_name
 from cubicweb.utils import make_uid
-from cubicweb.selectors import match_context_prop, partial_relation_possible
+from cubicweb.selectors import match_context_prop, partial_relation_possible, yes
 from cubicweb.appobject import AppObject
 from cubicweb.web import RequestError, htmlwidgets
 
@@ -1015,6 +1015,7 @@
     (e.g when you want to filter on entities where are not directly linked to
     the filtered entities).
     """
+    __select__ = yes() # we don't want RelationFacet's selector
     # must be specified
     path = None
     filter_variable = None
@@ -1031,8 +1032,11 @@
 
     def __init__(self, *args, **kwargs):
         super(RQLPathFacet, self).__init__(*args, **kwargs)
+        assert self.filter_variable != self.label_variable, \
+            ('filter_variable and label_variable should be different. '
+             'You may want to let label_variable undefined (ie None).')
         assert self.path and isinstance(self.path, (list, tuple)), \
-               'path should be a list of 3-uples, not %s' % self.path
+            'path should be a list of 3-uples, not %s' % self.path
         for part in self.path:
             if isinstance(part, basestring):
                 part = part.split()
@@ -1044,8 +1048,7 @@
                             ','.join(str(p) for p in self.path))
 
     def vocabulary(self):
-        """return vocabulary for this facet, eg a list of 2-uple (label, value)
-        """
+        """return vocabulary for this facet, eg a list of (label, value)"""
         select = self.select
         select.save_state()
         if self.rql_sort:
--- a/web/test/unittest_facet.py	Tue Sep 27 14:57:41 2011 +0200
+++ b/web/test/unittest_facet.py	Tue Sep 27 16:04:30 2011 +0200
@@ -197,13 +197,12 @@
 
     def test_rql_path_eid(self):
         req, rset, rqlst, filtered_variable = self.prepare_rqlst()
-        facet.RQLPathFacet.path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
-        f = facet.RQLPathFacet(req, rset=rset,
-                               select=rqlst.children[0],
-                               filtered_variable=filtered_variable)
-        f.filter_variable = 'O'
-        f.label_variable = 'OL'
-
+        class RPF(facet.RQLPathFacet):
+            path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
+            filter_variable = 'O'
+            label_variable = 'OL'
+        f = RPF(req, rset=rset, select=rqlst.children[0],
+                filtered_variable=filtered_variable)
         self.assertEqual(f.vocabulary(), [(u'admin', self.user().eid),])
         # ensure rqlst is left unmodified
         self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
@@ -219,18 +218,26 @@
         self.assertEqual(f.select.as_string(),
                          "DISTINCT Any  WHERE X is CWUser, X created_by F, F owned_by G, G eid 1")
 
+    def test_rql_path_eid_no_label(self):
+        req, rset, rqlst, filtered_variable = self.prepare_rqlst()
+        class RPF(facet.RQLPathFacet):
+            path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
+            filter_variable = 'O'
+        f = RPF(req, rset=rset, select=rqlst.children[0],
+                filtered_variable=filtered_variable)
+        self.assertEqual(f.vocabulary(), [(str(self.user().eid), self.user().eid),])
+
     def test_rql_path_attr(self):
         req, rset, rqlst, filtered_variable = self.prepare_rqlst()
-        facet.RQLPathFacet.path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
-        f = facet.RQLPathFacet(req, rset=rset,
-                               select=rqlst.children[0],
-                               filtered_variable=filtered_variable)
-        f.filter_variable = 'OL'
+        class RPF(facet.RQLPathFacet):
+            path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
+            filter_variable = 'OL'
+        f = RPF(req, rset=rset, select=rqlst.children[0],
+                filtered_variable=filtered_variable)
 
         self.assertEqual(f.vocabulary(), [(u'admin', 'admin'),])
         # ensure rqlst is left unmodified
         self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
-        #rqlst = rset.syntax_tree()
         self.assertEqual(f.possible_values(), ['admin',])
         # ensure rqlst is left unmodified
         self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
@@ -241,6 +248,16 @@
         self.assertEqual(f.select.as_string(),
                          "DISTINCT Any  WHERE X is CWUser, X created_by G, G owned_by H, H login 'admin'")
 
+    def test_rql_path_check_filter_label_variable(self):
+        req, rset, rqlst, filtered_variable = self.prepareg_aggregat_rqlst()
+        class RPF(facet.RQLPathFacet):
+            path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
+            filter_variable = 'OL'
+            label_variable = 'OL'
+        self.assertRaises(AssertionError, RPF, req, rset=rset,
+                          select=rqlst.children[0],
+                          filtered_variable=filtered_variable)
+
     def prepareg_aggregat_rqlst(self):
         return self.prepare_rqlst(
             'Any 1, COUNT(X) WHERE X is CWUser, X creation_date XD, '
@@ -265,11 +282,11 @@
 
     def test_aggregat_query_rql_path(self):
         req, rset, rqlst, filtered_variable = self.prepareg_aggregat_rqlst()
-        facet.RQLPathFacet.path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
-        f = facet.RQLPathFacet(req, rset=rset,
-                               select=rqlst.children[0],
-                               filtered_variable=filtered_variable)
-        f.filter_variable = 'OL'
+        class RPF(facet.RQLPathFacet):
+            path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
+            filter_variable = 'OL'
+        f = RPF(req, rset=rset, select=rqlst.children[0],
+                filtered_variable=filtered_variable)
         self.assertEqual(f.vocabulary(), [(u'admin', u'admin')])
         self.assertEqual(f.possible_values(), ['admin'])
         req.form[f.__regid__] = 'admin'