[entity/url publishing] fetch_rqlst should use 'is_instance_of' instead of 'is'
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 12 Dec 2013 12:34:38 +0100
changeset 9359 31a1813d53f3
parent 9358 1e0235478403
child 9360 eda5071e30a1
[entity/url publishing] fetch_rqlst should use 'is_instance_of' instead of 'is' We usually want to get any subclasses as well (think Training subclass of Workcase). Closes #3210365.
entity.py
test/unittest_entity.py
web/test/unittest_urlpublisher.py
web/test/unittest_urlrewrite.py
--- a/entity.py	Thu Dec 12 12:28:43 2013 +0100
+++ b/entity.py	Thu Dec 12 12:34:38 2013 +0100
@@ -287,7 +287,10 @@
         select._varmaker = rqlvar_maker(defined=select.defined_vars,
                                         aliases=select.aliases, index=26)
         if settype:
-            select.add_type_restriction(mainvar, cls.__regid__)
+            rel = select.add_type_restriction(mainvar, cls.__regid__)
+            # should use 'is_instance_of' instead of 'is' so we retrieve
+            # subclasses instances as well
+            rel.r_type = 'is_instance_of'
         if fetchattrs is None:
             fetchattrs = cls.fetch_attrs
         cls._fetch_restrictions(mainvar, select, fetchattrs, user, ordermethod)
--- a/test/unittest_entity.py	Thu Dec 12 12:28:43 2013 +0100
+++ b/test/unittest_entity.py	Thu Dec 12 12:34:38 2013 +0100
@@ -207,43 +207,43 @@
             # testing basic fetch_attrs attribute
             self.assertEqual(Personne.fetch_rql(user),
                               'Any X,AA,AB,AC ORDERBY AA '
-                              'WHERE X is Personne, X nom AA, X prenom AB, X modification_date AC')
+                              'WHERE X is_instance_of Personne, X nom AA, X prenom AB, X modification_date AC')
             # testing unknown attributes
             Personne.fetch_attrs = ('bloug', 'beep')
-            self.assertEqual(Personne.fetch_rql(user), 'Any X WHERE X is Personne')
+            self.assertEqual(Personne.fetch_rql(user), 'Any X WHERE X is_instance_of Personne')
             # testing one non final relation
             Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
             self.assertEqual(Personne.fetch_rql(user),
                               'Any X,AA,AB,AC,AD ORDERBY AA '
-                              'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD')
+                              'WHERE X is_instance_of Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD')
             # testing two non final relations
             Personne.fetch_attrs = ('nom', 'prenom', 'travaille', 'evaluee')
             self.assertEqual(Personne.fetch_rql(user),
                              'Any X,AA,AB,AC,AD,AE ORDERBY AA '
-                             'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD, '
+                             'WHERE X is_instance_of Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD, '
                              'X evaluee AE?')
             # testing one non final relation with recursion
             Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
             Societe.fetch_attrs = ('nom', 'evaluee')
             self.assertEqual(Personne.fetch_rql(user),
                               'Any X,AA,AB,AC,AD,AE,AF ORDERBY AA,AF DESC '
-                              'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD, '
+                              'WHERE X is_instance_of Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD, '
                               'AC evaluee AE?, AE modification_date AF'
                               )
             # testing symmetric relation
             Personne.fetch_attrs = ('nom', 'connait')
             self.assertEqual(Personne.fetch_rql(user), 'Any X,AA,AB ORDERBY AA '
-                              'WHERE X is Personne, X nom AA, X connait AB?')
+                              'WHERE X is_instance_of Personne, X nom AA, X connait AB?')
             # testing optional relation
             peschema.subjrels['travaille'].rdef(peschema, seschema).cardinality = '?*'
             Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
             Societe.fetch_attrs = ('nom',)
             self.assertEqual(Personne.fetch_rql(user),
-                              'Any X,AA,AB,AC,AD ORDERBY AA WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD')
+                              'Any X,AA,AB,AC,AD ORDERBY AA WHERE X is_instance_of Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD')
             # testing relation with cardinality > 1
             peschema.subjrels['travaille'].rdef(peschema, seschema).cardinality = '**'
             self.assertEqual(Personne.fetch_rql(user),
-                              'Any X,AA,AB ORDERBY AA WHERE X is Personne, X nom AA, X prenom AB')
+                              'Any X,AA,AB ORDERBY AA WHERE X is_instance_of Personne, X nom AA, X prenom AB')
             # XXX test unauthorized attribute
         finally:
             # fetch_attrs restored by generic tearDown
@@ -307,7 +307,7 @@
         rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
                          'WHERE NOT A use_email O, S eid %(x)s, '
-                         'O is EmailAddress, O address AA, O alias AB, O modification_date AC')
+                         'O is_instance_of EmailAddress, O address AA, O alias AB, O modification_date AC')
 
     def test_unrelated_rql_security_1_user(self):
         req = self.request()
@@ -317,7 +317,7 @@
         rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
                          'WHERE NOT A use_email O, S eid %(x)s, '
-                         'O is EmailAddress, O address AA, O alias AB, O modification_date AC')
+                         'O is_instance_of EmailAddress, O address AA, O alias AB, O modification_date AC')
         user = self.execute('Any X WHERE X login "admin"').get_entity(0, 0)
         rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
@@ -338,7 +338,7 @@
         email = self.execute('INSERT EmailAddress X: X address "hop"').get_entity(0, 0)
         rql = email.cw_unrelated_rql('use_email', 'CWUser', 'object')[0]
         self.assertEqual(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
-                         'WHERE NOT S use_email O, O eid %(x)s, S is CWUser, '
+                         'WHERE NOT S use_email O, O eid %(x)s, S is_instance_of CWUser, '
                          'S login AA, S firstname AB, S surname AC, S modification_date AD')
         self.login('anon')
         rperms = self.schema['EmailAddress'].permissions['read']
@@ -372,7 +372,7 @@
         rql = person.cw_unrelated_rql('connait', 'Personne', 'subject')[0]
         self.assertEqual(
             rql, 'Any O,AA,AB,AC ORDERBY AC DESC WHERE '
-            'O is Personne, O nom AA, O prenom AB, O modification_date AC')
+            'O is_instance_of Personne, O nom AA, O prenom AB, O modification_date AC')
 
     def test_unrelated_rql_constraints_creation_object(self):
         person = self.vreg['etypes'].etype_class('Personne')(self.request())
@@ -392,7 +392,7 @@
             person = self.vreg['etypes'].etype_class('Personne')(self.request())
             rql = person.cw_unrelated_rql('connait', 'Personne', 'subject')[0]
         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC WHERE '
-                         'O is Personne, O nom AA, O prenom AB, '
+                         'O is_instance_of Personne, O nom AA, O prenom AB, '
                          'O modification_date AC')
 
     def test_unrelated_rql_constraints_edition_subject(self):
@@ -435,7 +435,7 @@
         rql, args = person.cw_unrelated_rql('actionnaire', 'Societe', 'subject',
                                             lt_infos=lt_infos)
         self.assertEqual(u'Any O ORDERBY O WHERE NOT A actionnaire O, '
-                         u'O is Societe, NOT EXISTS(O eid %(O)s), '
+                         u'O is_instance_of Societe, NOT EXISTS(O eid %(O)s), '
                          u'A is Personne', rql)
         self.assertEqual({'O': soc.eid}, args)
 
@@ -448,7 +448,7 @@
         rql, args = soc.cw_unrelated_rql('actionnaire', 'Personne', 'object',
                                          lt_infos=lt_infos)
         self.assertEqual(u'Any S ORDERBY S WHERE NOT S actionnaire A, '
-                         u'S is Personne, NOT EXISTS(S eid %(S)s), '
+                         u'S is_instance_of Personne, NOT EXISTS(S eid %(S)s), '
                          u'A is Societe', rql)
         self.assertEqual({'S': person.eid}, args)
 
@@ -461,7 +461,7 @@
         rql, args = soc.cw_unrelated_rql('dirige', 'Personne', 'object',
                                          lt_infos=lt_infos)
         self.assertEqual(u'Any S ORDERBY S WHERE NOT S dirige A, '
-                         u'S is Personne, EXISTS(S eid %(S)s), '
+                         u'S is_instance_of Personne, EXISTS(S eid %(S)s), '
                          u'A is Societe', rql)
         self.assertEqual({'S': person.eid}, args)
 
@@ -471,7 +471,7 @@
         self.vreg['etypes'].etype_class('Personne').fetch_attrs = ()
         soc = req.create_entity('Societe', nom=u'logilab')
         rql, args = person.cw_unrelated_rql('associe', 'Personne', 'subject')
-        self.assertEqual(u'Any O ORDERBY O WHERE O is Personne', rql)
+        self.assertEqual(u'Any O ORDERBY O WHERE O is_instance_of Personne', rql)
         self.assertEqual({}, args)
 
     def test_unrelated_rql_s_linkto_s_unused_info(self):
@@ -482,7 +482,7 @@
         lt_infos = {('dirige', 'subject'): [other_p.eid]}
         rql, args = person.cw_unrelated_rql('associe', 'Personne', 'subject',
                                             lt_infos=lt_infos)
-        self.assertEqual(u'Any O ORDERBY O WHERE O is Personne', rql)
+        self.assertEqual(u'Any O ORDERBY O WHERE O is_instance_of Personne', rql)
 
     def test_unrelated_base(self):
         req = self.request()
--- a/web/test/unittest_urlpublisher.py	Thu Dec 12 12:28:43 2013 +0100
+++ b/web/test/unittest_urlpublisher.py	Thu Dec 12 12:34:38 2013 +0100
@@ -62,42 +62,42 @@
         self.assertEqual(ctrl, 'view')
         self.assertEqual(rset.description[0][0], 'CWEType')
         self.assertEqual(rset.printable_rql(),
-                          "Any X,AA,AB ORDERBY AA WHERE X is CWEType, X name AA, X modification_date AB")
+                          "Any X,AA,AB ORDERBY AA WHERE X is_instance_of CWEType, X name AA, X modification_date AB")
 
     def test_rest_path_by_attr(self):
         ctrl, rset = self.process('CWUser/login/admin')
         self.assertEqual(ctrl, 'view')
         self.assertEqual(len(rset), 1)
         self.assertEqual(rset.description[0][0], 'CWUser')
-        self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X login "admin"')
+        self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X login "admin"')
 
     def test_rest_path_unique_attr(self):
         ctrl, rset = self.process('cwuser/admin')
         self.assertEqual(ctrl, 'view')
         self.assertEqual(len(rset), 1)
         self.assertEqual(rset.description[0][0], 'CWUser')
-        self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X login "admin"')
+        self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X login "admin"')
 
     def test_rest_path_eid(self):
         ctrl, rset = self.process('cwuser/eid/%s' % self.user().eid)
         self.assertEqual(ctrl, 'view')
         self.assertEqual(len(rset), 1)
         self.assertEqual(rset.description[0][0], 'CWUser')
-        self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X eid %s' % rset[0][0])
+        self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X eid %s' % rset[0][0])
 
     def test_rest_path_non_ascii_paths(self):
         ctrl, rset = self.process('CWUser/login/%C3%BFsa%C3%BFe')
         self.assertEqual(ctrl, 'view')
         self.assertEqual(len(rset), 1)
         self.assertEqual(rset.description[0][0], 'CWUser')
-        self.assertEqual(rset.printable_rql(), u'Any X,AA,AB,AC,AD WHERE X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X login "\xffsa\xffe"')
+        self.assertEqual(rset.printable_rql(), u'Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X login "\xffsa\xffe"')
 
     def test_rest_path_quoted_paths(self):
         ctrl, rset = self.process('BlogEntry/title/hell%27o')
         self.assertEqual(ctrl, 'view')
         self.assertEqual(len(rset), 1)
         self.assertEqual(rset.description[0][0], 'BlogEntry')
-        self.assertEqual(rset.printable_rql(), u'Any X,AA,AB,AC WHERE X is BlogEntry, X creation_date AA, X title AB, X modification_date AC, X title "hell\'o"')
+        self.assertEqual(rset.printable_rql(), u'Any X,AA,AB,AC WHERE X is_instance_of BlogEntry, X creation_date AA, X title AB, X modification_date AC, X title "hell\'o"')
 
     def test_rest_path_errors(self):
         self.assertRaises(NotFound, self.process, 'CWUser/eid/30000')
--- a/web/test/unittest_urlrewrite.py	Thu Dec 12 12:28:43 2013 +0100
+++ b/web/test/unittest_urlrewrite.py	Thu Dec 12 12:34:38 2013 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -15,7 +15,8 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-from logilab.common.testlib import TestCase, unittest_main
+
+from logilab.common import tempattr
 
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.devtools.fake import FakeRequest
@@ -96,6 +97,24 @@
         rewriter.rewrite(req, '/add/Task/')
         self.assertEqual(req.form, {'vid' : "creation", 'etype' : "Task"})
 
+    def test_inheritance(self):
+        BaseTransition = self.vreg['etypes'].etype_class('BaseTransition')
+        req = self.request()
+        x = req.create_entity('WorkflowTransition', name=u'test')
+        ctrlid, rset = self.app.url_resolver.process(req, 'basetransition/%s' % x.eid)
+        self.assertEqual(ctrlid, 'view')
+        self.assertEqual(x.eid, rset[0][0])
+        # cw_rest_attr_info is cached but clear_cache doesn't like cached class
+        # method
+        del BaseTransition._cw_rest_attr_info_cache_
+        try:
+            with tempattr(BaseTransition, 'rest_attr', 'name'):
+
+                ctrlid, rset = self.app.url_resolver.process(req, 'basetransition/%s' % x.name)
+                self.assertEqual(ctrlid, 'view')
+                self.assertEqual(x.eid, rset[0][0])
+        finally:
+            del BaseTransition._cw_rest_attr_info_cache_
 
 
 
@@ -192,4 +211,5 @@
 
 
 if __name__ == '__main__':
+    from logilab.common.testlib import unittest_main
     unittest_main()