# HG changeset patch # User Sylvain Thénault # Date 1386848078 -3600 # Node ID 31a1813d53f3f18e468217aa21f4f5630fc3825f # Parent 1e0235478403fa4f442d8c8471f88de79edfdd47 [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. diff -r 1e0235478403 -r 31a1813d53f3 entity.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) diff -r 1e0235478403 -r 31a1813d53f3 test/unittest_entity.py --- 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() diff -r 1e0235478403 -r 31a1813d53f3 web/test/unittest_urlpublisher.py --- 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') diff -r 1e0235478403 -r 31a1813d53f3 web/test/unittest_urlrewrite.py --- 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 . -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()