test/unittest_entity.py
brancholdstable
changeset 8462 a14b6562082b
parent 8286 8b0146e31baa
child 8307 8be58694f416
equal deleted inserted replaced
8231:1bb43e31032d 8462:a14b6562082b
    23 from cubicweb import Binary, Unauthorized
    23 from cubicweb import Binary, Unauthorized
    24 from cubicweb.devtools.testlib import CubicWebTC
    24 from cubicweb.devtools.testlib import CubicWebTC
    25 from cubicweb.mttransforms import HAS_TAL
    25 from cubicweb.mttransforms import HAS_TAL
    26 from cubicweb.entities import fetch_config
    26 from cubicweb.entities import fetch_config
    27 from cubicweb.uilib import soup2xhtml
    27 from cubicweb.uilib import soup2xhtml
    28 
    28 from cubicweb.schema import RQLVocabularyConstraint
    29 
    29 
    30 class EntityTC(CubicWebTC):
    30 class EntityTC(CubicWebTC):
    31 
    31 
    32     def setUp(self):
    32     def setUp(self):
    33         super(EntityTC, self).setUp()
    33         super(EntityTC, self).setUp()
    34         self.backup_dict = {}
    34         self.backup_dict = {}
    35         for cls in self.vreg['etypes'].iter_classes():
    35         for cls in self.vreg['etypes'].iter_classes():
    36             self.backup_dict[cls] = (cls.fetch_attrs, cls.fetch_order)
    36             self.backup_dict[cls] = (cls.fetch_attrs, cls.cw_fetch_order)
    37 
    37 
    38     def tearDown(self):
    38     def tearDown(self):
    39         super(EntityTC, self).tearDown()
    39         super(EntityTC, self).tearDown()
    40         for cls in self.vreg['etypes'].iter_classes():
    40         for cls in self.vreg['etypes'].iter_classes():
    41             cls.fetch_attrs, cls.fetch_order = self.backup_dict[cls]
    41             cls.fetch_attrs, cls.cw_fetch_order = self.backup_dict[cls]
    42 
    42 
    43     def test_boolean_value(self):
    43     def test_boolean_value(self):
    44         e = self.vreg['etypes'].etype_class('CWUser')(self.request())
    44         e = self.vreg['etypes'].etype_class('CWUser')(self.request())
    45         self.failUnless(e)
    45         self.assertTrue(e)
    46 
    46 
    47     def test_yams_inheritance(self):
    47     def test_yams_inheritance(self):
    48         from entities import Note
    48         from entities import Note
    49         e = self.vreg['etypes'].etype_class('SubNote')(self.request())
    49         e = self.vreg['etypes'].etype_class('SubNote')(self.request())
    50         self.assertIsInstance(e, Note)
    50         self.assertIsInstance(e, Note)
    85         self.schema['ecrit_par'].rdef('Note', 'Personne').composite = 'subject'
    85         self.schema['ecrit_par'].rdef('Note', 'Personne').composite = 'subject'
    86         self.execute('SET T ecrit_par U WHERE T eid %(t)s, U eid %(u)s',
    86         self.execute('SET T ecrit_par U WHERE T eid %(t)s, U eid %(u)s',
    87                      {'t': oe.eid, 'u': p.eid})
    87                      {'t': oe.eid, 'u': p.eid})
    88         e = req.create_entity('Note', type=u'z')
    88         e = req.create_entity('Note', type=u'z')
    89         e.copy_relations(oe.eid)
    89         e.copy_relations(oe.eid)
    90         self.failIf(e.ecrit_par)
    90         self.assertFalse(e.ecrit_par)
    91         self.failUnless(oe.ecrit_par)
    91         self.assertTrue(oe.ecrit_par)
    92 
    92 
    93     def test_copy_with_composite(self):
    93     def test_copy_with_composite(self):
    94         user = self.user()
    94         user = self.user()
    95         adeleid = self.execute('INSERT EmailAddress X: X address "toto@logilab.org", U use_email X WHERE U login "admin"')[0][0]
    95         adeleid = self.execute('INSERT EmailAddress X: X address "toto@logilab.org", U use_email X WHERE U login "admin"')[0][0]
    96         e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
    96         e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
    98         self.assertEqual(e.use_email[0].eid, adeleid)
    98         self.assertEqual(e.use_email[0].eid, adeleid)
    99         usereid = self.execute('INSERT CWUser X: X login "toto", X upassword "toto", X in_group G '
    99         usereid = self.execute('INSERT CWUser X: X login "toto", X upassword "toto", X in_group G '
   100                                'WHERE G name "users"')[0][0]
   100                                'WHERE G name "users"')[0][0]
   101         e = self.execute('Any X WHERE X eid %(x)s', {'x': usereid}).get_entity(0, 0)
   101         e = self.execute('Any X WHERE X eid %(x)s', {'x': usereid}).get_entity(0, 0)
   102         e.copy_relations(user.eid)
   102         e.copy_relations(user.eid)
   103         self.failIf(e.use_email)
   103         self.assertFalse(e.use_email)
   104         self.failIf(e.primary_email)
   104         self.assertFalse(e.primary_email)
   105 
   105 
   106     def test_copy_with_non_initial_state(self):
   106     def test_copy_with_non_initial_state(self):
   107         user = self.user()
   107         user = self.user()
   108         user = self.execute('INSERT CWUser X: X login "toto", X upassword %(pwd)s, X in_group G WHERE G name "users"',
   108         user = self.execute('INSERT CWUser X: X login "toto", X upassword %(pwd)s, X in_group G WHERE G name "users"',
   109                            {'pwd': 'toto'}).get_entity(0, 0)
   109                            {'pwd': 'toto'}).get_entity(0, 0)
   126         self.assertEqual(sorted(user._cw_related_cache), ['primary_email_subject'])
   126         self.assertEqual(sorted(user._cw_related_cache), ['primary_email_subject'])
   127         self.assertEqual(email._cw_related_cache.keys(), ['primary_email_object'])
   127         self.assertEqual(email._cw_related_cache.keys(), ['primary_email_object'])
   128         groups = user.in_group
   128         groups = user.in_group
   129         self.assertEqual(sorted(user._cw_related_cache), ['in_group_subject', 'primary_email_subject'])
   129         self.assertEqual(sorted(user._cw_related_cache), ['in_group_subject', 'primary_email_subject'])
   130         for group in groups:
   130         for group in groups:
   131             self.failIf('in_group_subject' in group._cw_related_cache, group._cw_related_cache.keys())
   131             self.assertFalse('in_group_subject' in group._cw_related_cache, group._cw_related_cache.keys())
   132 
   132 
   133     def test_related_limit(self):
   133     def test_related_limit(self):
   134         req = self.request()
   134         req = self.request()
   135         p = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
   135         p = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
   136         for tag in u'abcd':
   136         for tag in u'abcd':
   141 
   141 
   142     def test_cw_instantiate_relation(self):
   142     def test_cw_instantiate_relation(self):
   143         req = self.request()
   143         req = self.request()
   144         p1 = req.create_entity('Personne', nom=u'di')
   144         p1 = req.create_entity('Personne', nom=u'di')
   145         p2 = req.create_entity('Personne', nom=u'mascio')
   145         p2 = req.create_entity('Personne', nom=u'mascio')
       
   146         t = req.create_entity('Tag', name=u't0', tags=[])
       
   147         self.assertItemsEqual(t.tags, [])
   146         t = req.create_entity('Tag', name=u't1', tags=p1)
   148         t = req.create_entity('Tag', name=u't1', tags=p1)
   147         self.assertItemsEqual(t.tags, [p1])
   149         self.assertItemsEqual(t.tags, [p1])
   148         t = req.create_entity('Tag', name=u't2', tags=p1.eid)
   150         t = req.create_entity('Tag', name=u't2', tags=p1.eid)
   149         self.assertItemsEqual(t.tags, [p1])
   151         self.assertItemsEqual(t.tags, [p1])
   150         t = req.create_entity('Tag', name=u't3', tags=[p1, p2.eid])
   152         t = req.create_entity('Tag', name=u't3', tags=[p1, p2.eid])
   177             cm.__enter__()
   179             cm.__enter__()
   178             torestore.append(cm)
   180             torestore.append(cm)
   179         try:
   181         try:
   180             # testing basic fetch_attrs attribute
   182             # testing basic fetch_attrs attribute
   181             self.assertEqual(Personne.fetch_rql(user),
   183             self.assertEqual(Personne.fetch_rql(user),
   182                               'Any X,AA,AB,AC ORDERBY AA ASC '
   184                               'Any X,AA,AB,AC ORDERBY AA '
   183                               'WHERE X is Personne, X nom AA, X prenom AB, X modification_date AC')
   185                               'WHERE X is Personne, X nom AA, X prenom AB, X modification_date AC')
   184             # testing unknown attributes
   186             # testing unknown attributes
   185             Personne.fetch_attrs = ('bloug', 'beep')
   187             Personne.fetch_attrs = ('bloug', 'beep')
   186             self.assertEqual(Personne.fetch_rql(user), 'Any X WHERE X is Personne')
   188             self.assertEqual(Personne.fetch_rql(user), 'Any X WHERE X is Personne')
   187             # testing one non final relation
   189             # testing one non final relation
   188             Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
   190             Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
   189             self.assertEqual(Personne.fetch_rql(user),
   191             self.assertEqual(Personne.fetch_rql(user),
   190                               'Any X,AA,AB,AC,AD ORDERBY AA ASC '
   192                               'Any X,AA,AB,AC,AD ORDERBY AA '
   191                               'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD')
   193                               'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD')
   192             # testing two non final relations
   194             # testing two non final relations
   193             Personne.fetch_attrs = ('nom', 'prenom', 'travaille', 'evaluee')
   195             Personne.fetch_attrs = ('nom', 'prenom', 'travaille', 'evaluee')
   194             self.assertEqual(Personne.fetch_rql(user),
   196             self.assertEqual(Personne.fetch_rql(user),
   195                              'Any X,AA,AB,AC,AD,AE ORDERBY AA ASC '
   197                              'Any X,AA,AB,AC,AD,AE ORDERBY AA '
   196                              'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD, '
   198                              'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD, '
   197                              'X evaluee AE?')
   199                              'X evaluee AE?')
   198             # testing one non final relation with recursion
   200             # testing one non final relation with recursion
   199             Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
   201             Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
   200             Societe.fetch_attrs = ('nom', 'evaluee')
   202             Societe.fetch_attrs = ('nom', 'evaluee')
   201             self.assertEqual(Personne.fetch_rql(user),
   203             self.assertEqual(Personne.fetch_rql(user),
   202                               'Any X,AA,AB,AC,AD,AE,AF ORDERBY AA ASC,AF DESC '
   204                               'Any X,AA,AB,AC,AD,AE,AF ORDERBY AA,AF DESC '
   203                               'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD, '
   205                               'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD, '
   204                               'AC evaluee AE?, AE modification_date AF'
   206                               'AC evaluee AE?, AE modification_date AF'
   205                               )
   207                               )
   206             # testing symmetric relation
   208             # testing symmetric relation
   207             Personne.fetch_attrs = ('nom', 'connait')
   209             Personne.fetch_attrs = ('nom', 'connait')
   208             self.assertEqual(Personne.fetch_rql(user), 'Any X,AA,AB ORDERBY AA ASC '
   210             self.assertEqual(Personne.fetch_rql(user), 'Any X,AA,AB ORDERBY AA '
   209                               'WHERE X is Personne, X nom AA, X connait AB?')
   211                               'WHERE X is Personne, X nom AA, X connait AB?')
   210             # testing optional relation
   212             # testing optional relation
   211             peschema.subjrels['travaille'].rdef(peschema, seschema).cardinality = '?*'
   213             peschema.subjrels['travaille'].rdef(peschema, seschema).cardinality = '?*'
   212             Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
   214             Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
   213             Societe.fetch_attrs = ('nom',)
   215             Societe.fetch_attrs = ('nom',)
   214             self.assertEqual(Personne.fetch_rql(user),
   216             self.assertEqual(Personne.fetch_rql(user),
   215                               'Any X,AA,AB,AC,AD ORDERBY AA ASC WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD')
   217                               'Any X,AA,AB,AC,AD ORDERBY AA WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD')
   216             # testing relation with cardinality > 1
   218             # testing relation with cardinality > 1
   217             peschema.subjrels['travaille'].rdef(peschema, seschema).cardinality = '**'
   219             peschema.subjrels['travaille'].rdef(peschema, seschema).cardinality = '**'
   218             self.assertEqual(Personne.fetch_rql(user),
   220             self.assertEqual(Personne.fetch_rql(user),
   219                               'Any X,AA,AB ORDERBY AA ASC WHERE X is Personne, X nom AA, X prenom AB')
   221                               'Any X,AA,AB ORDERBY AA WHERE X is Personne, X nom AA, X prenom AB')
   220             # XXX test unauthorized attribute
   222             # XXX test unauthorized attribute
   221         finally:
   223         finally:
   222             # fetch_attrs restored by generic tearDown
   224             # fetch_attrs restored by generic tearDown
   223             for cm in torestore:
   225             for cm in torestore:
   224                 cm.__exit__(None, None, None)
   226                 cm.__exit__(None, None, None)
   225 
   227 
   226     def test_related_rql_base(self):
   228     def test_related_rql_base(self):
   227         Personne = self.vreg['etypes'].etype_class('Personne')
   229         Personne = self.vreg['etypes'].etype_class('Personne')
   228         Note = self.vreg['etypes'].etype_class('Note')
   230         Note = self.vreg['etypes'].etype_class('Note')
   229         SubNote = self.vreg['etypes'].etype_class('SubNote')
   231         SubNote = self.vreg['etypes'].etype_class('SubNote')
   230         self.failUnless(issubclass(self.vreg['etypes'].etype_class('SubNote'), Note))
   232         self.assertTrue(issubclass(self.vreg['etypes'].etype_class('SubNote'), Note))
   231         Personne.fetch_attrs, Personne.fetch_order = fetch_config(('nom', 'type'))
   233         Personne.fetch_attrs, Personne.cw_fetch_order = fetch_config(('nom', 'type'))
   232         Note.fetch_attrs, Note.fetch_order = fetch_config(('type',))
   234         Note.fetch_attrs, Note.cw_fetch_order = fetch_config(('type',))
   233         SubNote.fetch_attrs, SubNote.fetch_order = fetch_config(('type',))
   235         SubNote.fetch_attrs, SubNote.cw_fetch_order = fetch_config(('type',))
   234         p = self.request().create_entity('Personne', nom=u'pouet')
   236         p = self.request().create_entity('Personne', nom=u'pouet')
   235         self.assertEqual(p.cw_related_rql('evaluee'),
   237         self.assertEqual(p.cw_related_rql('evaluee'),
   236                           'Any X,AA,AB ORDERBY AA ASC WHERE E eid %(x)s, E evaluee X, '
   238                          'Any X,AA,AB ORDERBY AA WHERE E eid %(x)s, E evaluee X, '
   237                           'X type AA, X modification_date AB')
   239                          'X type AA, X modification_date AB')
   238         Personne.fetch_attrs, Personne.fetch_order = fetch_config(('nom', ))
   240         n = self.request().create_entity('Note')
       
   241         self.assertEqual(n.cw_related_rql('evaluee', role='object',
       
   242                                           targettypes=('Societe', 'Personne')),
       
   243                          "Any X,AA ORDERBY AB DESC WHERE E eid %(x)s, X evaluee E, "
       
   244                          "X is IN(Personne, Societe), X nom AA, "
       
   245                          "X modification_date AB")
       
   246         Personne.fetch_attrs, Personne.cw_fetch_order = fetch_config(('nom', ))
   239         # XXX
   247         # XXX
   240         self.assertEqual(p.cw_related_rql('evaluee'),
   248         self.assertEqual(p.cw_related_rql('evaluee'),
   241                           'Any X,AA ORDERBY AA DESC '
   249                           'Any X,AA ORDERBY AA DESC '
   242                           'WHERE E eid %(x)s, E evaluee X, X modification_date AA')
   250                           'WHERE E eid %(x)s, E evaluee X, X modification_date AA')
   243 
   251 
   244         tag = self.vreg['etypes'].etype_class('Tag')(self.request())
   252         tag = self.vreg['etypes'].etype_class('Tag')(self.request())
   245         self.assertEqual(tag.cw_related_rql('tags', 'subject'),
   253         self.assertEqual(tag.cw_related_rql('tags', 'subject'),
   246                           'Any X,AA ORDERBY AA DESC '
   254                           'Any X,AA ORDERBY AA DESC '
   247                           'WHERE E eid %(x)s, E tags X, X modification_date AA')
   255                           'WHERE E eid %(x)s, E tags X, X modification_date AA')
   248         self.assertEqual(tag.cw_related_rql('tags', 'subject', ('Personne',)),
   256         self.assertEqual(tag.cw_related_rql('tags', 'subject', ('Personne',)),
   249                           'Any X,AA,AB ORDERBY AA ASC '
   257                           'Any X,AA,AB ORDERBY AA '
   250                           'WHERE E eid %(x)s, E tags X, X is IN (Personne), X nom AA, '
   258                           'WHERE E eid %(x)s, E tags X, X is Personne, X nom AA, '
   251                           'X modification_date AB')
   259                           'X modification_date AB')
   252 
   260 
   253     def test_related_rql_ambiguous_cant_use_fetch_order(self):
   261     def test_related_rql_ambiguous_cant_use_fetch_order(self):
   254         tag = self.vreg['etypes'].etype_class('Tag')(self.request())
   262         tag = self.vreg['etypes'].etype_class('Tag')(self.request())
   255         for ttype in self.schema['tags'].objects():
   263         for ttype in self.schema['tags'].objects():
   256             self.vreg['etypes'].etype_class(ttype).fetch_attrs = ('modification_date',)
   264             self.vreg['etypes'].etype_class(ttype).fetch_attrs = ('modification_date',)
   257         self.assertEqual(tag.cw_related_rql('tags', 'subject'),
   265         self.assertEqual(tag.cw_related_rql('tags', 'subject'),
   258                           'Any X,AA ORDERBY AA DESC '
   266                           'Any X,AA ORDERBY AA DESC '
   259                           'WHERE E eid %(x)s, E tags X, X modification_date AA')
   267                           'WHERE E eid %(x)s, E tags X, X modification_date AA')
   260 
   268 
   261     def test_related_rql_cant_fetch_ambiguous_rtype(self):
   269     def test_related_rql_fetch_ambiguous_rtype(self):
   262         soc_etype = self.vreg['etypes'].etype_class('Societe')
   270         soc_etype = self.vreg['etypes'].etype_class('Societe')
   263         soc = soc_etype(self.request())
   271         soc = soc_etype(self.request())
   264         soc_etype.fetch_attrs = ('fournit',)
   272         soc_etype.fetch_attrs = ('fournit',)
   265         self.vreg['etypes'].etype_class('Service').fetch_attrs = ('fabrique_par',)
   273         self.vreg['etypes'].etype_class('Service').fetch_attrs = ('fabrique_par',)
   266         self.vreg['etypes'].etype_class('Produit').fetch_attrs = ('fabrique_par',)
   274         self.vreg['etypes'].etype_class('Produit').fetch_attrs = ('fabrique_par',)
   267         self.vreg['etypes'].etype_class('Usine').fetch_attrs = ('lieu',)
   275         self.vreg['etypes'].etype_class('Usine').fetch_attrs = ('lieu',)
   268         self.vreg['etypes'].etype_class('Personne').fetch_attrs = ('nom',)
   276         self.vreg['etypes'].etype_class('Personne').fetch_attrs = ('nom',)
   269         # XXX should be improved: we could fetch fabrique_par object too
       
   270         self.assertEqual(soc.cw_related_rql('fournit', 'subject'),
   277         self.assertEqual(soc.cw_related_rql('fournit', 'subject'),
   271                          'Any X WHERE E eid %(x)s, E fournit X')
   278                          'Any X,A WHERE E eid %(x)s, E fournit X, X fabrique_par A')
   272 
   279 
   273     def test_unrelated_rql_security_1_manager(self):
   280     def test_unrelated_rql_security_1_manager(self):
   274         user = self.request().user
   281         user = self.request().user
   275         rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
   282         rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
   276         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
   283         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
   277                          'WHERE NOT EXISTS(ZZ use_email O), S eid %(x)s, '
   284                          'WHERE NOT A use_email O, S eid %(x)s, '
   278                          'O is EmailAddress, O address AA, O alias AB, O modification_date AC')
   285                          'O is EmailAddress, O address AA, O alias AB, O modification_date AC')
   279 
   286 
   280     def test_unrelated_rql_security_1_user(self):
   287     def test_unrelated_rql_security_1_user(self):
   281         req = self.request()
   288         req = self.request()
   282         self.create_user(req, 'toto')
   289         self.create_user(req, 'toto')
   283         self.login('toto')
   290         self.login('toto')
   284         user = req.user
   291         user = req.user
   285         rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
   292         rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
   286         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
   293         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
   287                          'WHERE NOT EXISTS(ZZ use_email O), S eid %(x)s, '
   294                          'WHERE NOT A use_email O, S eid %(x)s, '
   288                          'O is EmailAddress, O address AA, O alias AB, O modification_date AC')
   295                          'O is EmailAddress, O address AA, O alias AB, O modification_date AC')
   289         user = self.execute('Any X WHERE X login "admin"').get_entity(0, 0)
   296         user = self.execute('Any X WHERE X login "admin"').get_entity(0, 0)
   290         rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
   297         rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
   291         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
   298         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
   292                          'WHERE NOT EXISTS(ZZ use_email O, ZZ is CWUser), S eid %(x)s, '
   299                          'WHERE NOT A use_email O, S eid %(x)s, '
   293                          'O is EmailAddress, O address AA, O alias AB, O modification_date AC, A eid %(B)s, '
   300                          'O is EmailAddress, O address AA, O alias AB, O modification_date AC, AD eid %(AE)s, '
   294                          'EXISTS(S identity A, NOT A in_group C, C name "guests", C is CWGroup)')
   301                          'EXISTS(S identity AD, NOT AD in_group AF, AF name "guests", AF is CWGroup), A is CWUser')
   295 
   302 
   296     def test_unrelated_rql_security_1_anon(self):
   303     def test_unrelated_rql_security_1_anon(self):
   297         self.login('anon')
   304         self.login('anon')
   298         user = self.request().user
   305         user = self.request().user
   299         rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
   306         rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
   300         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
   307         self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
   301                          'WHERE NOT EXISTS(ZZ use_email O, ZZ is CWUser), S eid %(x)s, '
   308                          'WHERE NOT A use_email O, S eid %(x)s, '
   302                          'O is EmailAddress, O address AA, O alias AB, O modification_date AC, A eid %(B)s, '
   309                          'O is EmailAddress, O address AA, O alias AB, O modification_date AC, AD eid %(AE)s, '
   303                          'EXISTS(S identity A, NOT A in_group C, C name "guests", C is CWGroup)')
   310                          'EXISTS(S identity AD, NOT AD in_group AF, AF name "guests", AF is CWGroup), A is CWUser')
   304 
   311 
   305     def test_unrelated_rql_security_2(self):
   312     def test_unrelated_rql_security_2(self):
   306         email = self.execute('INSERT EmailAddress X: X address "hop"').get_entity(0, 0)
   313         email = self.execute('INSERT EmailAddress X: X address "hop"').get_entity(0, 0)
   307         rql = email.cw_unrelated_rql('use_email', 'CWUser', 'object')[0]
   314         rql = email.cw_unrelated_rql('use_email', 'CWUser', 'object')[0]
   308         self.assertEqual(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
   315         self.assertEqual(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
   309                          'WHERE NOT EXISTS(S use_email O), O eid %(x)s, S is CWUser, '
   316                          'WHERE NOT S use_email O, O eid %(x)s, S is CWUser, '
   310                          'S login AA, S firstname AB, S surname AC, S modification_date AD')
   317                          'S login AA, S firstname AB, S surname AC, S modification_date AD')
   311         self.login('anon')
   318         self.login('anon')
   312         email = self.execute('Any X WHERE X eid %(x)s', {'x': email.eid}).get_entity(0, 0)
   319         email = self.execute('Any X WHERE X eid %(x)s', {'x': email.eid}).get_entity(0, 0)
   313         rql = email.cw_unrelated_rql('use_email', 'CWUser', 'object')[0]
   320         rql = email.cw_unrelated_rql('use_email', 'CWUser', 'object')[0]
   314         self.assertEqual(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
   321         self.assertEqual(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
   315                          'WHERE NOT EXISTS(S use_email O), O eid %(x)s, S is CWUser, '
   322                          'WHERE NOT S use_email O, O eid %(x)s, S is CWUser, '
   316                          'S login AA, S firstname AB, S surname AC, S modification_date AD, '
   323                          'S login AA, S firstname AB, S surname AC, S modification_date AD, '
   317                          'A eid %(B)s, EXISTS(S identity A, NOT A in_group C, C name "guests", C is CWGroup)')
   324                          'AE eid %(AF)s, EXISTS(S identity AE, NOT AE in_group AG, AG name "guests", AG is CWGroup)')
   318 
   325 
   319     def test_unrelated_rql_security_nonexistant(self):
   326     def test_unrelated_rql_security_nonexistant(self):
   320         self.login('anon')
   327         self.login('anon')
   321         email = self.vreg['etypes'].etype_class('EmailAddress')(self.request())
   328         email = self.vreg['etypes'].etype_class('EmailAddress')(self.request())
   322         rql = email.cw_unrelated_rql('use_email', 'CWUser', 'object')[0]
   329         rql = email.cw_unrelated_rql('use_email', 'CWUser', 'object')[0]
   323         self.assertEqual(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
   330         self.assertEqual(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
   324                          'WHERE S is CWUser, '
   331                          'WHERE S is CWUser, '
   325                          'S login AA, S firstname AB, S surname AC, S modification_date AD, '
   332                          'S login AA, S firstname AB, S surname AC, S modification_date AD, '
   326                          'A eid %(B)s, EXISTS(S identity A, NOT A in_group C, C name "guests", C is CWGroup)')
   333                          'AE eid %(AF)s, EXISTS(S identity AE, NOT AE in_group AG, AG name "guests", AG is CWGroup)')
   327 
   334 
   328     def test_unrelated_rql_constraints_creation_subject(self):
   335     def test_unrelated_rql_constraints_creation_subject(self):
   329         person = self.vreg['etypes'].etype_class('Personne')(self.request())
   336         person = self.vreg['etypes'].etype_class('Personne')(self.request())
   330         rql = person.cw_unrelated_rql('connait', 'Personne', 'subject')[0]
   337         rql = person.cw_unrelated_rql('connait', 'Personne', 'subject')[0]
   331         self.assertEqual(
   338         self.assertEqual(
   336         person = self.vreg['etypes'].etype_class('Personne')(self.request())
   343         person = self.vreg['etypes'].etype_class('Personne')(self.request())
   337         rql = person.cw_unrelated_rql('connait', 'Personne', 'object')[0]
   344         rql = person.cw_unrelated_rql('connait', 'Personne', 'object')[0]
   338         self.assertEqual(
   345         self.assertEqual(
   339             rql, 'Any S,AA,AB,AC ORDERBY AC DESC WHERE '
   346             rql, 'Any S,AA,AB,AC ORDERBY AC DESC WHERE '
   340             'S is Personne, S nom AA, S prenom AB, S modification_date AC, '
   347             'S is Personne, S nom AA, S prenom AB, S modification_date AC, '
   341             'NOT (S connait A, A nom "toto"), A is Personne, EXISTS(S travaille B, B nom "tutu")')
   348             'NOT (S connait AD, AD nom "toto"), AD is Personne, '
       
   349             'EXISTS(S travaille AE, AE nom "tutu")')
   342 
   350 
   343     def test_unrelated_rql_constraints_edition_subject(self):
   351     def test_unrelated_rql_constraints_edition_subject(self):
   344         person = self.request().create_entity('Personne', nom=u'sylvain')
   352         person = self.request().create_entity('Personne', nom=u'sylvain')
   345         rql = person.cw_unrelated_rql('connait', 'Personne', 'subject')[0]
   353         rql = person.cw_unrelated_rql('connait', 'Personne', 'subject')[0]
   346         self.assertEqual(
   354         self.assertEqual(
   347             rql, 'Any O,AA,AB,AC ORDERBY AC DESC WHERE '
   355             rql, 'Any O,AA,AB,AC ORDERBY AC DESC WHERE '
   348             'NOT EXISTS(S connait O), S eid %(x)s, O is Personne, '
   356             'NOT S connait O, S eid %(x)s, O is Personne, '
   349             'O nom AA, O prenom AB, O modification_date AC, '
   357             'O nom AA, O prenom AB, O modification_date AC, '
   350             'NOT S identity O')
   358             'NOT S identity O')
   351 
   359 
   352     def test_unrelated_rql_constraints_edition_object(self):
   360     def test_unrelated_rql_constraints_edition_object(self):
   353         person = self.request().create_entity('Personne', nom=u'sylvain')
   361         person = self.request().create_entity('Personne', nom=u'sylvain')
   354         rql = person.cw_unrelated_rql('connait', 'Personne', 'object')[0]
   362         rql = person.cw_unrelated_rql('connait', 'Personne', 'object')[0]
   355         self.assertEqual(
   363         self.assertEqual(
   356             rql, 'Any S,AA,AB,AC ORDERBY AC DESC WHERE '
   364             rql, 'Any S,AA,AB,AC ORDERBY AC DESC WHERE '
   357             'NOT EXISTS(S connait O), O eid %(x)s, S is Personne, '
   365             'NOT S connait O, O eid %(x)s, S is Personne, '
   358             'S nom AA, S prenom AB, S modification_date AC, '
   366             'S nom AA, S prenom AB, S modification_date AC, '
   359             'NOT S identity O, NOT (S connait A, A nom "toto"), '
   367             'NOT S identity O, NOT (S connait AD, AD nom "toto"), '
   360             'EXISTS(S travaille B, B nom "tutu")')
   368             'EXISTS(S travaille AE, AE nom "tutu")')
       
   369 
       
   370     def test_unrelated_rql_s_linkto_s(self):
       
   371         req = self.request()
       
   372         person = self.vreg['etypes'].etype_class('Personne')(req)
       
   373         self.vreg['etypes'].etype_class('Personne').fetch_attrs = ()
       
   374         soc = req.create_entity('Societe', nom=u'logilab')
       
   375         lt_infos = {('actionnaire', 'subject'): [soc.eid]}
       
   376         rql, args = person.cw_unrelated_rql('associe', 'Personne', 'subject',
       
   377                                             lt_infos=lt_infos)
       
   378         self.assertEqual(u'Any O ORDERBY O WHERE O is Personne, '
       
   379                          u'EXISTS(AA eid %(SOC)s, O actionnaire AA)', rql)
       
   380         self.assertEqual({'SOC': soc.eid}, args)
       
   381 
       
   382     def test_unrelated_rql_s_linkto_o(self):
       
   383         req = self.request()
       
   384         person = self.vreg['etypes'].etype_class('Personne')(req)
       
   385         self.vreg['etypes'].etype_class('Societe').fetch_attrs = ()
       
   386         soc = req.create_entity('Societe', nom=u'logilab')
       
   387         lt_infos = {('contrat_exclusif', 'object'): [soc.eid]}
       
   388         rql, args = person.cw_unrelated_rql('actionnaire', 'Societe', 'subject',
       
   389                                             lt_infos=lt_infos)
       
   390         self.assertEqual(u'Any O ORDERBY O WHERE NOT A actionnaire O, '
       
   391                          u'O is Societe, NOT EXISTS(O eid %(O)s), '
       
   392                          u'A is Personne', rql)
       
   393         self.assertEqual({'O': soc.eid}, args)
       
   394 
       
   395     def test_unrelated_rql_o_linkto_s(self):
       
   396         req = self.request()
       
   397         soc = self.vreg['etypes'].etype_class('Societe')(req)
       
   398         self.vreg['etypes'].etype_class('Personne').fetch_attrs = ()
       
   399         person = req.create_entity('Personne', nom=u'florent')
       
   400         lt_infos = {('contrat_exclusif', 'subject'): [person.eid]}
       
   401         rql, args = soc.cw_unrelated_rql('actionnaire', 'Personne', 'object',
       
   402                                          lt_infos=lt_infos)
       
   403         self.assertEqual(u'Any S ORDERBY S WHERE NOT S actionnaire A, '
       
   404                          u'S is Personne, NOT EXISTS(S eid %(S)s), '
       
   405                          u'A is Societe', rql)
       
   406         self.assertEqual({'S': person.eid}, args)
       
   407 
       
   408     def test_unrelated_rql_o_linkto_o(self):
       
   409         req = self.request()
       
   410         soc = self.vreg['etypes'].etype_class('Societe')(req)
       
   411         self.vreg['etypes'].etype_class('Personne').fetch_attrs = ()
       
   412         person = req.create_entity('Personne', nom=u'florent')
       
   413         lt_infos = {('actionnaire', 'object'): [person.eid]}
       
   414         rql, args = soc.cw_unrelated_rql('dirige', 'Personne', 'object',
       
   415                                          lt_infos=lt_infos)
       
   416         self.assertEqual(u'Any S ORDERBY S WHERE NOT S dirige A, '
       
   417                          u'S is Personne, EXISTS(S eid %(S)s), '
       
   418                          u'A is Societe', rql)
       
   419         self.assertEqual({'S': person.eid}, args)
       
   420 
       
   421     def test_unrelated_rql_s_linkto_s_no_info(self):
       
   422         req = self.request()
       
   423         person = self.vreg['etypes'].etype_class('Personne')(req)
       
   424         self.vreg['etypes'].etype_class('Personne').fetch_attrs = ()
       
   425         soc = req.create_entity('Societe', nom=u'logilab')
       
   426         rql, args = person.cw_unrelated_rql('associe', 'Personne', 'subject')
       
   427         self.assertEqual(u'Any O ORDERBY O WHERE O is Personne', rql)
       
   428         self.assertEqual({}, args)
       
   429 
       
   430     def test_unrelated_rql_s_linkto_s_unused_info(self):
       
   431         req = self.request()
       
   432         person = self.vreg['etypes'].etype_class('Personne')(req)
       
   433         self.vreg['etypes'].etype_class('Personne').fetch_attrs = ()
       
   434         other_p = req.create_entity('Personne', nom=u'titi')
       
   435         lt_infos = {('dirige', 'subject'): [other_p.eid]}
       
   436         rql, args = person.cw_unrelated_rql('associe', 'Personne', 'subject',
       
   437                                             lt_infos=lt_infos)
       
   438         self.assertEqual(u'Any O ORDERBY O WHERE O is Personne', rql)
   361 
   439 
   362     def test_unrelated_base(self):
   440     def test_unrelated_base(self):
   363         req = self.request()
   441         req = self.request()
   364         p = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
   442         p = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
   365         e = req.create_entity('Tag', name=u'x')
   443         e = req.create_entity('Tag', name=u'x')
   366         related = [r.eid for r in e.tags]
   444         related = [r.eid for r in e.tags]
   367         self.failUnlessEqual(related, [])
   445         self.assertEqual(related, [])
   368         unrelated = [r[0] for r in e.unrelated('tags', 'Personne', 'subject')]
   446         unrelated = [r[0] for r in e.unrelated('tags', 'Personne', 'subject')]
   369         self.failUnless(p.eid in unrelated)
   447         self.assertTrue(p.eid in unrelated)
   370         self.execute('SET X tags Y WHERE X is Tag, Y is Personne')
   448         self.execute('SET X tags Y WHERE X is Tag, Y is Personne')
   371         e = self.execute('Any X WHERE X is Tag').get_entity(0, 0)
   449         e = self.execute('Any X WHERE X is Tag').get_entity(0, 0)
   372         unrelated = [r[0] for r in e.unrelated('tags', 'Personne', 'subject')]
   450         unrelated = [r[0] for r in e.unrelated('tags', 'Personne', 'subject')]
   373         self.failIf(p.eid in unrelated)
   451         self.assertFalse(p.eid in unrelated)
   374 
   452 
   375     def test_unrelated_limit(self):
   453     def test_unrelated_limit(self):
   376         req = self.request()
   454         req = self.request()
   377         e = req.create_entity('Tag', name=u'x')
   455         e = req.create_entity('Tag', name=u'x')
   378         req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
   456         req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
   536         req = self.request()
   614         req = self.request()
   537         p1 = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
   615         p1 = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
   538         p2 = req.create_entity('Personne', nom=u'toto')
   616         p2 = req.create_entity('Personne', nom=u'toto')
   539         self.execute('SET X evaluee Y WHERE X nom "di mascio", Y nom "toto"')
   617         self.execute('SET X evaluee Y WHERE X nom "di mascio", Y nom "toto"')
   540         self.assertEqual(p1.evaluee[0].nom, "toto")
   618         self.assertEqual(p1.evaluee[0].nom, "toto")
   541         self.failUnless(not p1.reverse_evaluee)
   619         self.assertTrue(not p1.reverse_evaluee)
   542 
   620 
   543     def test_complete_relation(self):
   621     def test_complete_relation(self):
   544         session = self.session
   622         session = self.session
   545         eid = session.execute(
   623         eid = session.execute(
   546             'INSERT TrInfo X: X comment "zou", X wf_info_for U, X from_state S1, X to_state S2 '
   624             'INSERT TrInfo X: X comment "zou", X wf_info_for U, X from_state S1, X to_state S2 '
   547             'WHERE U login "admin", S1 name "activated", S2 name "deactivated"')[0][0]
   625             'WHERE U login "admin", S1 name "activated", S2 name "deactivated"')[0][0]
   548         trinfo = self.execute('Any X WHERE X eid %(x)s', {'x': eid}).get_entity(0, 0)
   626         trinfo = self.execute('Any X WHERE X eid %(x)s', {'x': eid}).get_entity(0, 0)
   549         trinfo.complete()
   627         trinfo.complete()
   550         self.failUnless(isinstance(trinfo.cw_attr_cache['creation_date'], datetime))
   628         self.assertTrue(isinstance(trinfo.cw_attr_cache['creation_date'], datetime))
   551         self.failUnless(trinfo.cw_relation_cached('from_state', 'subject'))
   629         self.assertTrue(trinfo.cw_relation_cached('from_state', 'subject'))
   552         self.failUnless(trinfo.cw_relation_cached('to_state', 'subject'))
   630         self.assertTrue(trinfo.cw_relation_cached('to_state', 'subject'))
   553         self.failUnless(trinfo.cw_relation_cached('wf_info_for', 'subject'))
   631         self.assertTrue(trinfo.cw_relation_cached('wf_info_for', 'subject'))
   554         self.assertEqual(trinfo.by_transition, ())
   632         self.assertEqual(trinfo.by_transition, ())
   555 
   633 
   556     def test_request_cache(self):
   634     def test_request_cache(self):
   557         req = self.request()
   635         req = self.request()
   558         user = self.execute('CWUser X WHERE X login "admin"', req=req).get_entity(0, 0)
   636         user = self.execute('CWUser X WHERE X login "admin"', req=req).get_entity(0, 0)
   559         state = user.in_state[0]
   637         state = user.in_state[0]
   560         samestate = self.execute('State X WHERE X name "activated"', req=req).get_entity(0, 0)
   638         samestate = self.execute('State X WHERE X name "activated"', req=req).get_entity(0, 0)
   561         self.failUnless(state is samestate)
   639         self.assertTrue(state is samestate)
   562 
   640 
   563     def test_rest_path(self):
   641     def test_rest_path(self):
   564         req = self.request()
   642         req = self.request()
   565         note = req.create_entity('Note', type=u'z')
   643         note = req.create_entity('Note', type=u'z')
   566         self.assertEqual(note.rest_path(), 'note/%s' % note.eid)
   644         self.assertEqual(note.rest_path(), 'note/%s' % note.eid)
   571         person = req.create_entity('Personne', prenom=u'john', nom=u'doe')
   649         person = req.create_entity('Personne', prenom=u'john', nom=u'doe')
   572         self.assertEqual(person.rest_path(), 'personne/doe')
   650         self.assertEqual(person.rest_path(), 'personne/doe')
   573         # ambiguity test
   651         # ambiguity test
   574         person2 = req.create_entity('Personne', prenom=u'remi', nom=u'doe')
   652         person2 = req.create_entity('Personne', prenom=u'remi', nom=u'doe')
   575         person.cw_clear_all_caches()
   653         person.cw_clear_all_caches()
   576         self.assertEqual(person.rest_path(), 'personne/eid/%s' % person.eid)
   654         self.assertEqual(person.rest_path(), unicode(person.eid))
   577         self.assertEqual(person2.rest_path(), 'personne/eid/%s' % person2.eid)
   655         self.assertEqual(person2.rest_path(), unicode(person2.eid))
   578         # unique attr with None value (wikiid in this case)
   656         # unique attr with None value (wikiid in this case)
   579         card1 = req.create_entity('Card', title=u'hop')
   657         card1 = req.create_entity('Card', title=u'hop')
   580         self.assertEqual(card1.rest_path(), 'card/eid/%s' % card1.eid)
   658         self.assertEqual(card1.rest_path(), unicode(card1.eid))
   581         # don't use rest if we have /, ? or & in the path (breaks mod_proxy)
   659         # don't use rest if we have /, ? or & in the path (breaks mod_proxy)
   582         card2 = req.create_entity('Card', title=u'pod', wikiid=u'zo/bi')
   660         card2 = req.create_entity('Card', title=u'pod', wikiid=u'zo/bi')
   583         self.assertEqual(card2.rest_path(), 'card/eid/%d' % card2.eid)
   661         self.assertEqual(card2.rest_path(), unicode(card2.eid))
   584         card3 = req.create_entity('Card', title=u'pod', wikiid=u'zo&bi')
   662         card3 = req.create_entity('Card', title=u'pod', wikiid=u'zo&bi')
   585         self.assertEqual(card3.rest_path(), 'card/eid/%d' % card3.eid)
   663         self.assertEqual(card3.rest_path(), unicode(card3.eid))
   586         card4 = req.create_entity('Card', title=u'pod', wikiid=u'zo?bi')
   664         card4 = req.create_entity('Card', title=u'pod', wikiid=u'zo?bi')
   587         self.assertEqual(card4.rest_path(), 'card/eid/%d' % card4.eid)
   665         self.assertEqual(card4.rest_path(), unicode(card4.eid))
   588 
   666 
   589 
   667 
   590     def test_set_attributes(self):
   668     def test_set_attributes(self):
   591         req = self.request()
   669         req = self.request()
   592         person = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
   670         person = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
   621 
   699 
   622     def test_absolute_url_empty_field(self):
   700     def test_absolute_url_empty_field(self):
   623         req = self.request()
   701         req = self.request()
   624         card = req.create_entity('Card', wikiid=u'', title=u'test')
   702         card = req.create_entity('Card', wikiid=u'', title=u'test')
   625         self.assertEqual(card.absolute_url(),
   703         self.assertEqual(card.absolute_url(),
   626                           'http://testing.fr/cubicweb/card/eid/%s' % card.eid)
   704                           'http://testing.fr/cubicweb/%s' % card.eid)
   627 
   705 
   628     def test_create_entity(self):
   706     def test_create_entity(self):
   629         req = self.request()
   707         req = self.request()
   630         p1 = req.create_entity('Personne', nom=u'fayolle', prenom=u'alexandre')
   708         p1 = req.create_entity('Personne', nom=u'fayolle', prenom=u'alexandre')
   631         p2 = req.create_entity('Personne', nom=u'campeas', prenom=u'aurelien')
   709         p2 = req.create_entity('Personne', nom=u'campeas', prenom=u'aurelien')