cubicweb/entities/test/unittest_base.py
changeset 11057 0b59724cb3f2
parent 11044 00c5ee272a6d
child 11761 78c8a2bb04ff
equal deleted inserted replaced
11052:058bb3dc685f 11057:0b59724cb3f2
       
     1 # -*- coding: utf-8 -*-
       
     2 # copyright 2003-2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     3 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     4 #
       
     5 # This file is part of CubicWeb.
       
     6 #
       
     7 # CubicWeb is free software: you can redistribute it and/or modify it under the
       
     8 # terms of the GNU Lesser General Public License as published by the Free
       
     9 # Software Foundation, either version 2.1 of the License, or (at your option)
       
    10 # any later version.
       
    11 #
       
    12 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT
       
    13 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
       
    14 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
       
    15 # details.
       
    16 #
       
    17 # You should have received a copy of the GNU Lesser General Public License along
       
    18 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
       
    19 """unit tests for cubicweb.entities.base module
       
    20 """
       
    21 
       
    22 from logilab.common.testlib import unittest_main
       
    23 from logilab.common.decorators import clear_cache
       
    24 from logilab.common.registry import yes
       
    25 
       
    26 from cubicweb.devtools.testlib import CubicWebTC
       
    27 
       
    28 from cubicweb.entities import AnyEntity
       
    29 
       
    30 
       
    31 class BaseEntityTC(CubicWebTC):
       
    32 
       
    33     def setup_database(self):
       
    34         with self.admin_access.repo_cnx() as cnx:
       
    35             self.membereid = self.create_user(cnx, 'member').eid
       
    36             cnx.commit()
       
    37 
       
    38 
       
    39 class MetadataTC(BaseEntityTC):
       
    40 
       
    41     def test_creator(self):
       
    42         with self.new_access('member').repo_cnx() as cnx:
       
    43             entity = cnx.create_entity('Bookmark', title=u"hello", path=u'project/cubicweb')
       
    44             cnx.commit()
       
    45             self.assertEqual(entity.creator.eid, self.membereid)
       
    46             self.assertEqual(entity.dc_creator(), u'member')
       
    47 
       
    48     def test_type(self):
       
    49         # dc_type may be translated
       
    50         with self.admin_access.client_cnx() as cnx:
       
    51             member = cnx.entity_from_eid(self.membereid)
       
    52             self.assertEqual(member.dc_type(), 'CWUser')
       
    53 
       
    54     def test_cw_etype(self):
       
    55         # cw_etype is never translated
       
    56         with self.admin_access.client_cnx() as cnx:
       
    57             member = cnx.entity_from_eid(self.membereid)
       
    58             self.assertEqual(member.cw_etype, 'CWUser')
       
    59 
       
    60     def test_entity_meta_attributes(self):
       
    61         # XXX move to yams
       
    62         self.assertEqual(self.schema['CWUser'].meta_attributes(), {})
       
    63         self.assertEqual(dict((str(k), v)
       
    64                               for k, v in self.schema['State'].meta_attributes().items()),
       
    65                          {'description_format': ('format', 'description')})
       
    66 
       
    67     def test_fti_rql_method(self):
       
    68         class EmailAddress(AnyEntity):
       
    69             __regid__ = 'EmailAddress'
       
    70             __select__ = AnyEntity.__select__ & yes(2)
       
    71 
       
    72             @classmethod
       
    73             def cw_fti_index_rql_queries(cls, req):
       
    74                 return ['EmailAddress Y']
       
    75 
       
    76         with self.admin_access.web_request() as req:
       
    77             req.create_entity('EmailAddress', address=u'foo@bar.com')
       
    78             eclass = self.vreg['etypes'].etype_class('EmailAddress')
       
    79             # deprecated
       
    80             self.assertEqual(['Any X, ADDRESS, ALIAS WHERE X is EmailAddress, '
       
    81                               'X address ADDRESS, X alias ALIAS'],
       
    82                              eclass.cw_fti_index_rql_queries(req))
       
    83 
       
    84             self.assertEqual(['Any X, ADDRESS, ALIAS ORDERBY X LIMIT 1000 WHERE X is EmailAddress, '
       
    85                               'X address ADDRESS, X alias ALIAS, X eid > 0'],
       
    86                              [rset.rql for rset in eclass.cw_fti_index_rql_limit(req)])
       
    87 
       
    88             # test backwards compatibility with custom method
       
    89             with self.temporary_appobjects(EmailAddress):
       
    90                 self.vreg['etypes'].clear_caches()
       
    91                 eclass = self.vreg['etypes'].etype_class('EmailAddress')
       
    92                 self.assertEqual(['EmailAddress Y'],
       
    93                                  [rset.rql for rset in eclass.cw_fti_index_rql_limit(req)])
       
    94 
       
    95 
       
    96 class EmailAddressTC(BaseEntityTC):
       
    97 
       
    98     def test_canonical_form(self):
       
    99         with self.admin_access.repo_cnx() as cnx:
       
   100             email1 = cnx.execute('INSERT EmailAddress X: '
       
   101                                  'X address "maarten.ter.huurne@philips.com"').get_entity(0, 0)
       
   102             email2 = cnx.execute('INSERT EmailAddress X: '
       
   103                                  'X address "maarten@philips.com"').get_entity(0, 0)
       
   104             email3 = cnx.execute('INSERT EmailAddress X: '
       
   105                                  'X address "toto@logilab.fr"').get_entity(0, 0)
       
   106             email1.cw_set(prefered_form=email2)
       
   107             self.assertEqual(email1.prefered.eid, email2.eid)
       
   108             self.assertEqual(email2.prefered.eid, email2.eid)
       
   109             self.assertEqual(email3.prefered.eid, email3.eid)
       
   110 
       
   111     def test_mangling(self):
       
   112         query = 'INSERT EmailAddress X: X address "maarten.ter.huurne@philips.com"'
       
   113         with self.admin_access.repo_cnx() as cnx:
       
   114             email = cnx.execute(query).get_entity(0, 0)
       
   115             self.assertEqual(email.display_address(), 'maarten.ter.huurne@philips.com')
       
   116             self.assertEqual(email.printable_value('address'), 'maarten.ter.huurne@philips.com')
       
   117             self.vreg.config.global_set_option('mangle-emails', True)
       
   118             try:
       
   119                 self.assertEqual(email.display_address(), 'maarten.ter.huurne at philips dot com')
       
   120                 self.assertEqual(email.printable_value('address'),
       
   121                                  'maarten.ter.huurne at philips dot com')
       
   122                 email = cnx.execute('INSERT EmailAddress X: X address "syt"').get_entity(0, 0)
       
   123                 self.assertEqual(email.display_address(), 'syt')
       
   124                 self.assertEqual(email.printable_value('address'), 'syt')
       
   125             finally:
       
   126                 self.vreg.config.global_set_option('mangle-emails', False)
       
   127 
       
   128     def test_printable_value_escape(self):
       
   129         with self.admin_access.repo_cnx() as cnx:
       
   130             email = cnx.execute('INSERT EmailAddress X: '
       
   131                                 'X address "maarten&ter@philips.com"').get_entity(0, 0)
       
   132             self.assertEqual(email.printable_value('address'),
       
   133                              'maarten&amp;ter@philips.com')
       
   134             self.assertEqual(email.printable_value('address', format='text/plain'),
       
   135                              'maarten&ter@philips.com')
       
   136 
       
   137 
       
   138 class CWUserTC(BaseEntityTC):
       
   139 
       
   140     def test_complete(self):
       
   141         with self.admin_access.repo_cnx() as cnx:
       
   142             e = cnx.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
       
   143             e.complete()
       
   144 
       
   145     def test_matching_groups(self):
       
   146         with self.admin_access.repo_cnx() as cnx:
       
   147             e = cnx.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
       
   148             self.assertTrue(e.matching_groups('managers'))
       
   149             self.assertFalse(e.matching_groups('xyz'))
       
   150             self.assertTrue(e.matching_groups(('xyz', 'managers')))
       
   151             self.assertFalse(e.matching_groups(('xyz', 'abcd')))
       
   152 
       
   153     def test_dc_title_and_name(self):
       
   154         with self.admin_access.repo_cnx() as cnx:
       
   155             e = cnx.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
       
   156             self.assertEqual(e.dc_title(), 'member')
       
   157             self.assertEqual(e.name(), 'member')
       
   158             e.cw_set(firstname=u'bouah')
       
   159             self.assertEqual(e.dc_title(), 'member')
       
   160             self.assertEqual(e.name(), u'bouah')
       
   161             e.cw_set(surname=u'lôt')
       
   162             self.assertEqual(e.dc_title(), 'member')
       
   163             self.assertEqual(e.name(), u'bouah lôt')
       
   164 
       
   165     def test_falsey_dc_title(self):
       
   166         with self.admin_access.repo_cnx() as cnx:
       
   167             e = cnx.create_entity('Company', order=0, name=u'pythonian')
       
   168             cnx.commit()
       
   169             self.assertEqual(u'0', e.dc_title())
       
   170 
       
   171     def test_allowed_massmail_keys(self):
       
   172         with self.admin_access.repo_cnx() as cnx:
       
   173             e = cnx.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
       
   174             # Bytes/Password attributes should be omitted
       
   175             self.assertEqual(
       
   176                 e.cw_adapt_to('IEmailable').allowed_massmail_keys(),
       
   177                 set(('surname', 'firstname', 'login', 'last_login_time',
       
   178                      'creation_date', 'modification_date', 'cwuri', 'eid'))
       
   179             )
       
   180 
       
   181     def test_cw_instantiate_object_relation(self):
       
   182         """ a weird non regression test """
       
   183         with self.admin_access.repo_cnx() as cnx:
       
   184             e = cnx.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
       
   185             cnx.create_entity('CWGroup', name=u'logilab', reverse_in_group=e)
       
   186 
       
   187 
       
   188 class HTMLtransformTC(BaseEntityTC):
       
   189 
       
   190     def test_sanitized_html(self):
       
   191         with self.admin_access.repo_cnx() as cnx:
       
   192             c = cnx.create_entity('Company', name=u'Babar',
       
   193                                   description=u"""
       
   194 Title
       
   195 =====
       
   196 
       
   197 Elephant management best practices.
       
   198 
       
   199 .. raw:: html
       
   200 
       
   201    <script>alert("coucou")</script>
       
   202 """, description_format=u'text/rest')
       
   203             cnx.commit()
       
   204             c.cw_clear_all_caches()
       
   205             self.assertIn('alert',
       
   206                           c.printable_value('description', format='text/plain'))
       
   207             self.assertNotIn('alert',
       
   208                              c.printable_value('description', format='text/html'))
       
   209 
       
   210 
       
   211 class SpecializedEntityClassesTC(CubicWebTC):
       
   212 
       
   213     def select_eclass(self, etype):
       
   214         # clear selector cache
       
   215         clear_cache(self.vreg['etypes'], 'etype_class')
       
   216         return self.vreg['etypes'].etype_class(etype)
       
   217 
       
   218     def test_etype_class_selection_and_specialization(self):
       
   219         # no specific class for Subdivisions, the default one should be selected
       
   220         eclass = self.select_eclass('SubDivision')
       
   221         self.assertTrue(eclass.__autogenerated__)
       
   222         # self.assertEqual(eclass.__bases__, (AnyEntity,))
       
   223         # build class from most generic to most specific and make
       
   224         # sure the most specific is always selected
       
   225         self.vreg._loadedmods[__name__] = {}
       
   226         for etype in ('Company', 'Division', 'SubDivision'):
       
   227             class Foo(AnyEntity):
       
   228                 __regid__ = etype
       
   229             self.vreg.register(Foo)
       
   230             eclass = self.select_eclass('SubDivision')
       
   231             self.assertTrue(eclass.__autogenerated__)
       
   232             self.assertFalse(eclass is Foo)
       
   233             if etype == 'SubDivision':
       
   234                 self.assertEqual(eclass.__bases__, (Foo,))
       
   235             else:
       
   236                 self.assertEqual(eclass.__bases__[0].__bases__, (Foo,))
       
   237         # check Division eclass is still selected for plain Division entities
       
   238         eclass = self.select_eclass('Division')
       
   239         self.assertEqual(eclass.cw_etype, 'Division')
       
   240 
       
   241 
       
   242 class ISerializableTC(CubicWebTC):
       
   243 
       
   244     def test_serialization(self):
       
   245         with self.admin_access.repo_cnx() as cnx:
       
   246             entity = cnx.create_entity('CWGroup', name=u'tmp')
       
   247             cnx.commit()
       
   248             serializer = entity.cw_adapt_to('ISerializable')
       
   249             expected = {
       
   250                 'cw_etype': u'CWGroup',
       
   251                 'cw_source': 'system',
       
   252                 'eid': entity.eid,
       
   253                 'cwuri': u'http://testing.fr/cubicweb/%s' % entity.eid,
       
   254                 'creation_date': entity.creation_date,
       
   255                 'modification_date': entity.modification_date,
       
   256                 'name': u'tmp',
       
   257             }
       
   258             self.assertEqual(serializer.serialize(), expected)
       
   259 
       
   260 
       
   261 if __name__ == '__main__':
       
   262     unittest_main()