web/test/unittest_views_basecontrollers.py
changeset 0 b97547f5f1fa
child 1398 5fe84a5f7035
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     1 """cubicweb.web.views.basecontrollers unit tests"""
       
     2 import simplejson
       
     3 
       
     4 from logilab.common.testlib import unittest_main
       
     5 
       
     6 from cubicweb import Binary, Unauthorized
       
     7 from cubicweb.devtools._apptest import TestEnvironment
       
     8 from cubicweb.devtools.apptest import EnvBasedTC, ControllerTC
       
     9 
       
    10 from cubicweb.common import ValidationError
       
    11 from cubicweb.common.uilib import rql_for_eid
       
    12 
       
    13 from cubicweb.web import INTERNAL_FIELD_VALUE, Redirect, RequestError
       
    14 from cubicweb.web.views.basecontrollers import xmlize
       
    15 
       
    16 from cubicweb.entities.authobjs import EUser
       
    17 
       
    18 
       
    19 class EditControllerTC(ControllerTC):
       
    20     def setUp(self):
       
    21         ControllerTC.setUp(self)
       
    22         self.failUnless('users' in self.schema.eschema('EGroup').get_groups('read'))
       
    23         
       
    24     def tearDown(self):
       
    25         ControllerTC.tearDown(self)
       
    26         self.failUnless('users' in self.schema.eschema('EGroup').get_groups('read'))
       
    27         
       
    28     def test_noparam_edit(self):
       
    29         """check behaviour of this controller without any form parameter
       
    30         """
       
    31         
       
    32         self.req.form = {}
       
    33         self.assertRaises(ValidationError, self.publish, self.req)
       
    34         
       
    35     def test_validation_unique(self):
       
    36         """test creation of two linked entities
       
    37         """        
       
    38         user = self.user()
       
    39         self.req.form = {'eid': 'X', '__type:X': 'EUser',
       
    40                          'login:X': u'admin', 'edits-login:X': u'', 
       
    41                          'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'', 
       
    42                          }
       
    43         self.assertRaises(ValidationError, self.publish, self.req)
       
    44 
       
    45 
       
    46     def test_user_editing_itself(self):
       
    47         """checking that a manager user can edit itself
       
    48         """
       
    49         user = self.user()
       
    50         basegroups = [str(eid) for eid, in self.execute('EGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
       
    51         groupeids = [eid for eid, in self.execute('EGroup G WHERE G name in ("managers", "users")')]
       
    52         groups = [str(eid) for eid in groupeids]
       
    53         stateeid = [eid for eid, in self.execute('State S WHERE S name "activated"')][0]
       
    54         self.req.form = {
       
    55             'eid':       `user.eid`,
       
    56             '__type:'+`user.eid`:    'EUser',
       
    57             'login:'+`user.eid`:     unicode(user.login),
       
    58             'firstname:'+`user.eid`: u'Th\xe9nault',
       
    59             'surname:'+`user.eid`:   u'Sylvain',
       
    60             'in_group:'+`user.eid`:  groups,
       
    61             'in_state:'+`user.eid`:  `stateeid`,
       
    62             #
       
    63             'edits-login:'+`user.eid`:     unicode(user.login),
       
    64             'edits-firstname:'+`user.eid`: u'',
       
    65             'edits-surname:'+`user.eid`:   u'',
       
    66             'edits-in_group:'+`user.eid`:  basegroups,
       
    67             'edits-in_state:'+`user.eid`:  `stateeid`,
       
    68             }
       
    69         path, params = self.expect_redirect_publish()
       
    70         e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}, 'x').get_entity(0, 0)
       
    71         self.assertEquals(e.firstname, u'Th\xe9nault')
       
    72         self.assertEquals(e.surname, u'Sylvain')
       
    73         self.assertEquals(e.login, user.login)
       
    74         self.assertEquals([g.eid for g in e.in_group], groupeids)
       
    75         self.assertEquals(e.in_state[0].eid, stateeid)
       
    76 
       
    77     def test_user_can_change_its_password(self):
       
    78         user = self.create_user('user')
       
    79         cnx = self.login('user')
       
    80         req = self.request()
       
    81         #self.assertEquals(self.ctrl.schema['EUser']._groups['read'],
       
    82         #                  ('managers', 'users'))
       
    83         req.form = {
       
    84             'eid': `user.eid`, '__type:'+`user.eid`: 'EUser',
       
    85             '__maineid' : str(user.eid),
       
    86             'upassword:'+`user.eid`: 'tournicoton',
       
    87             'upassword-confirm:'+`user.eid`: 'tournicoton',
       
    88             'edits-upassword:'+`user.eid`:  '',
       
    89             }
       
    90         path, params = self.expect_redirect_publish(req)
       
    91         cnx.commit() # commit to check we don't get late validation error for instance
       
    92         self.assertEquals(path, 'euser/user')
       
    93         self.failIf('vid' in params)
       
    94 
       
    95     def testr_user_editing_itself_no_relation(self):
       
    96         """checking we can edit an entity without specifying some required
       
    97         relations (meaning no changes)
       
    98         """
       
    99         user = self.user()
       
   100         groupeids = [eid for eid, in self.execute('EGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
       
   101         self.req.form = {
       
   102             'eid':       `user.eid`,
       
   103             '__type:'+`user.eid`:    'EUser',
       
   104             'login:'+`user.eid`:     unicode(user.login),
       
   105             'firstname:'+`user.eid`: u'Th\xe9nault',
       
   106             'surname:'+`user.eid`:   u'Sylvain',
       
   107             #
       
   108             'edits-login:'+`user.eid`:     unicode(user.login),
       
   109             'edits-firstname:'+`user.eid`: u'',
       
   110             'edits-surname:'+`user.eid`:   u'',
       
   111             }
       
   112         path, params = self.expect_redirect_publish()
       
   113         e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}, 'x').get_entity(0, 0)
       
   114         self.assertEquals(e.login, user.login)
       
   115         self.assertEquals(e.firstname, u'Th\xe9nault')
       
   116         self.assertEquals(e.surname, u'Sylvain')
       
   117         self.assertEquals([g.eid for g in e.in_group], groupeids)
       
   118         stateeids = [eid for eid, in self.execute('State S WHERE S name "activated"')]
       
   119         self.assertEquals([s.eid for s in e.in_state], stateeids)
       
   120         
       
   121         
       
   122     def test_create_multiple_linked(self):
       
   123         gueid = self.execute('EGroup G WHERE G name "users"')[0][0]
       
   124         self.req.form = {'eid': ['X', 'Y'],
       
   125                          
       
   126                          '__type:X': 'EUser',
       
   127                          '__maineid' : 'X',
       
   128                          'login:X': u'adim', 'edits-login:X': u'', 
       
   129                          'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'', 
       
   130                          'surname:X': u'Di Mascio', 'edits-surname:X': '',
       
   131 
       
   132                          'in_group:X': `gueid`, 'edits-in_group:X': INTERNAL_FIELD_VALUE, 
       
   133                          
       
   134                          '__type:Y': 'EmailAddress',
       
   135                          'address:Y': u'dima@logilab.fr', 'edits-address:Y': '',
       
   136                          'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE, 
       
   137                          }
       
   138         path, params = self.expect_redirect_publish()
       
   139         # should be redirected on the created person
       
   140         self.assertEquals(path, 'euser/adim')
       
   141         e = self.execute('Any P WHERE P surname "Di Mascio"').get_entity(0, 0)
       
   142         self.assertEquals(e.surname, 'Di Mascio')
       
   143         email = e.use_email[0]
       
   144         self.assertEquals(email.address, 'dima@logilab.fr')
       
   145         
       
   146     def test_edit_multiple_linked(self):
       
   147         peid = self.create_user('adim').eid
       
   148         self.req.form = {'eid': [`peid`, 'Y'],
       
   149                          '__type:%s'%peid: 'EUser',
       
   150                          'surname:%s'%peid: u'Di Masci', 'edits-surname:%s'%peid: '',
       
   151                          
       
   152                          '__type:Y': 'EmailAddress',
       
   153                          'address:Y': u'dima@logilab.fr', 'edits-address:Y': '',
       
   154                          'use_email:%s'%peid: 'Y', 'edits-use_email:%s'%peid: INTERNAL_FIELD_VALUE,
       
   155                          
       
   156                          '__redirectrql': 'Any X WHERE X eid %s'%peid,
       
   157                          }
       
   158         path, params = self.expect_redirect_publish()
       
   159         # should be redirected on the created person
       
   160         eid = params['rql'].split()[-1]
       
   161         e = self.execute('Any X WHERE X eid %(x)s', {'x': eid}, 'x').get_entity(0, 0)
       
   162         self.assertEquals(e.surname, 'Di Masci')
       
   163         email = e.use_email[0]
       
   164         self.assertEquals(email.address, 'dima@logilab.fr')
       
   165         
       
   166         emaileid = email.eid
       
   167         self.req.form = {'eid': [`peid`, `emaileid`],
       
   168                          '__type:%s'%peid: 'EUser',
       
   169                          'surname:%s'%peid: u'Di Masci', 'edits-surname:%s'%peid: 'Di Masci',
       
   170                          '__type:%s'%emaileid: 'EmailAddress',
       
   171                          'address:%s'%emaileid: u'adim@logilab.fr', 'edits-address:%s'%emaileid: 'dima@logilab.fr',
       
   172                          'use_email:%s'%peid: `emaileid`, 'edits-use_email:%s'%peid: `emaileid`, 
       
   173                          '__redirectrql': 'Any X WHERE X eid %s'%peid,
       
   174                          }
       
   175         path, params = self.expect_redirect_publish()
       
   176         # should be redirected on the created person
       
   177         eid = params['rql'].split()[-1]
       
   178         e = self.execute('Any X WHERE X eid %(x)s', {'x': eid}, 'x').get_entity(0, 0)
       
   179         self.assertEquals(e.surname, 'Di Masci')
       
   180         email = e.use_email[0]
       
   181         self.assertEquals(email.address, 'adim@logilab.fr')
       
   182 
       
   183         
       
   184     def test_password_confirm(self):
       
   185         """test creation of two linked entities
       
   186         """        
       
   187         user = self.user()
       
   188         self.req.form = {'__cloned_eid:X': user.eid,
       
   189                          'eid': 'X', '__type:X': 'EUser',
       
   190                          'login:X': u'toto', 'edits-login:X': u'', 
       
   191                          'upassword:X': u'toto', 'edits-upassword:X': u'', 
       
   192                          }
       
   193         self.assertRaises(ValidationError, self.publish, self.req)
       
   194         self.req.form = {'__cloned_eid:X': user.eid,
       
   195                          'eid': 'X', '__type:X': 'EUser',
       
   196                          'login:X': u'toto', 'edits-login:X': u'', 
       
   197                          'upassword:X': u'toto', 'upassword-confirm:X': u'tutu', 'edits-upassword:X': u'', 
       
   198                          }
       
   199         self.assertRaises(ValidationError, self.publish, self.req)
       
   200 
       
   201 
       
   202     def test_interval_bound_constraint_success(self):
       
   203         feid = self.execute('INSERT File X: X name "toto.txt", X data %(data)s',
       
   204                             {'data': Binary('yo')})[0][0]
       
   205         self.req.form = {'eid': ['X'],
       
   206                          '__type:X': 'Salesterm',
       
   207                          'amount:X': u'-10', 'edits-amount:X': '',
       
   208                          'described_by_test:X': str(feid), 'edits-described_by_test:X': INTERNAL_FIELD_VALUE,
       
   209                          }
       
   210         self.assertRaises(ValidationError, self.publish, self.req)
       
   211         self.req.form = {'eid': ['X'],
       
   212                          '__type:X': 'Salesterm',
       
   213                          'amount:X': u'110', 'edits-amount:X': '',
       
   214                          'described_by_test:X': str(feid), 'edits-described_by_test:X': INTERNAL_FIELD_VALUE,
       
   215                          }
       
   216         self.assertRaises(ValidationError, self.publish, self.req)
       
   217         self.req.form = {'eid': ['X'],
       
   218                          '__type:X': 'Salesterm',
       
   219                          'amount:X': u'10', 'edits-amount:X': '',
       
   220                          'described_by_test:X': str(feid), 'edits-described_by_test:X': INTERNAL_FIELD_VALUE,
       
   221                          }
       
   222         self.expect_redirect_publish()
       
   223         # should be redirected on the created 
       
   224         #eid = params['rql'].split()[-1]
       
   225         e = self.execute('Salesterm X').get_entity(0, 0)
       
   226         self.assertEquals(e.amount, 10)
       
   227 
       
   228     def test_req_pending_insert(self):
       
   229         """make sure req's pending insertions are taken into account"""
       
   230         tmpgroup = self.add_entity('EGroup', name=u"test")
       
   231         user = self.user()
       
   232         self.req.set_session_data('pending_insert', set([(user.eid, 'in_group', tmpgroup.eid)]))
       
   233         path, params = self.expect_redirect_publish()
       
   234         usergroups = [gname for gname, in
       
   235                       self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
       
   236         self.assertUnorderedIterableEquals(usergroups, ['managers', 'test'])
       
   237         self.assertEquals(self.req.get_pending_inserts(), [])
       
   238 
       
   239 
       
   240     def test_req_pending_delete(self):
       
   241         """make sure req's pending deletions are taken into account"""
       
   242         user = self.user()
       
   243         groupeid = self.execute('INSERT EGroup G: G name "test", U in_group G WHERE U eid %(x)s',
       
   244                                 {'x': user.eid})[0][0]
       
   245         usergroups = [gname for gname, in
       
   246                       self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
       
   247         # just make sure everything was set correctly
       
   248         self.assertUnorderedIterableEquals(usergroups, ['managers', 'test'])
       
   249         # now try to delete the relation
       
   250         self.req.set_session_data('pending_delete', set([(user.eid, 'in_group', groupeid)]))
       
   251         path, params = self.expect_redirect_publish()
       
   252         usergroups = [gname for gname, in
       
   253                       self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
       
   254         self.assertUnorderedIterableEquals(usergroups, ['managers'])
       
   255         self.assertEquals(self.req.get_pending_deletes(), [])
       
   256 
       
   257     def test_custom_attribute_handler(self):
       
   258         def custom_login_edit(self, formparams, value, relations):
       
   259             formparams['login'] = value.upper()
       
   260             relations.append('X login %(login)s')
       
   261         EUser.custom_login_edit = custom_login_edit
       
   262         try:
       
   263             user = self.user()
       
   264             eid = repr(user.eid)
       
   265             self.req.form = {
       
   266                 'eid': eid,
       
   267                 '__type:'+eid:  'EUser',
       
   268                 'login:'+eid: u'foo',
       
   269                 'edits-login:'+eid:  unicode(user.login),
       
   270                 }
       
   271             path, params = self.expect_redirect_publish()
       
   272             rset = self.execute('Any L WHERE X eid %(x)s, X login L', {'x': user.eid}, 'x')
       
   273             self.assertEquals(rset[0][0], 'FOO')
       
   274         finally:
       
   275             del EUser.custom_login_edit
       
   276         
       
   277     def test_redirect_apply_button(self):
       
   278         redirectrql = rql_for_eid(4012) # whatever
       
   279         self.req.form = {
       
   280                          'eid': 'A', '__type:A': 'BlogEntry',
       
   281                          '__maineid' : 'A',
       
   282                          'content:A': u'"13:03:43"', 'edits-content:A': '',
       
   283                          'title:A': u'huuu', 'edits-title:A': '',
       
   284                          '__redirectrql': redirectrql,
       
   285                          '__redirectvid': 'primary',
       
   286                          '__redirectparams': 'toto=tutu&tata=titi',
       
   287                          '__form_id': 'edition',
       
   288                          '__action_apply': '',
       
   289                          }
       
   290         path, params = self.expect_redirect_publish()
       
   291         self.failUnless(path.startswith('blogentry/'))
       
   292         eid = path.split('/')[1]
       
   293         self.assertEquals(params['vid'], 'edition')
       
   294         self.assertNotEquals(int(eid), 4012)
       
   295         self.assertEquals(params['__redirectrql'], redirectrql)
       
   296         self.assertEquals(params['__redirectvid'], 'primary')
       
   297         self.assertEquals(params['__redirectparams'], 'toto=tutu&tata=titi')
       
   298 
       
   299     def test_redirect_ok_button(self):
       
   300         redirectrql = rql_for_eid(4012) # whatever
       
   301         self.req.form = {
       
   302                          'eid': 'A', '__type:A': 'BlogEntry',
       
   303                          '__maineid' : 'A',
       
   304                          'content:A': u'"13:03:43"', 'edits-content:A': '',
       
   305                          'title:A': u'huuu', 'edits-title:A': '',
       
   306                          '__redirectrql': redirectrql,
       
   307                          '__redirectvid': 'primary',
       
   308                          '__redirectparams': 'toto=tutu&tata=titi',
       
   309                          '__form_id': 'edition',
       
   310                          }
       
   311         path, params = self.expect_redirect_publish()
       
   312         self.assertEquals(path, 'view')
       
   313         self.assertEquals(params['rql'], redirectrql)
       
   314         self.assertEquals(params['vid'], 'primary')
       
   315         self.assertEquals(params['tata'], 'titi')
       
   316         self.assertEquals(params['toto'], 'tutu')
       
   317 
       
   318     def test_redirect_delete_button(self):
       
   319         eid = self.add_entity('BlogEntry', title=u'hop', content=u'hop').eid
       
   320         self.req.form = {'eid': str(eid), '__type:%s'%eid: 'BlogEntry',
       
   321                          '__action_delete': ''}
       
   322         path, params = self.expect_redirect_publish()
       
   323         self.assertEquals(path, 'blogentry')
       
   324         self.assertEquals(params, {u'__message': u'entity deleted'})
       
   325         eid = self.add_entity('EmailAddress', address=u'hop@logilab.fr').eid
       
   326         self.execute('SET X use_email E WHERE E eid %(e)s, X eid %(x)s',
       
   327                      {'x': self.session().user.eid, 'e': eid}, 'x')
       
   328         self.commit()
       
   329         self.req.form = {'eid': str(eid), '__type:%s'%eid: 'EmailAddress',
       
   330                          '__action_delete': ''}
       
   331         path, params = self.expect_redirect_publish()
       
   332         self.assertEquals(path, 'euser/admin')
       
   333         self.assertEquals(params, {u'__message': u'entity deleted'})
       
   334         eid1 = self.add_entity('BlogEntry', title=u'hop', content=u'hop').eid
       
   335         eid2 = self.add_entity('EmailAddress', address=u'hop@logilab.fr').eid
       
   336         self.req.form = {'eid': [str(eid1), str(eid2)],
       
   337                          '__type:%s'%eid1: 'BlogEntry',
       
   338                          '__type:%s'%eid2: 'EmailAddress',
       
   339                          '__action_delete': ''}
       
   340         path, params = self.expect_redirect_publish()
       
   341         self.assertEquals(path, 'view')
       
   342         self.assertEquals(params, {u'__message': u'entities deleted'})
       
   343 
       
   344     def test_nonregr_egroup_etype_editing(self):
       
   345         """non-regression test checking that a manager user can edit a EEType entity (EGroup)
       
   346         """
       
   347         groupeids = [eid for eid, in self.execute('EGroup G WHERE G name "managers"')]
       
   348         groups = [str(eid) for eid in groupeids]
       
   349         eeetypeeid = self.execute('EEType X WHERE X name "EGroup"')[0][0]
       
   350         basegroups = [str(eid) for eid, in self.execute('EGroup G WHERE X read_permission G, X eid %(x)s', {'x': eeetypeeid})]
       
   351         self.req.form = {
       
   352                 'eid':      `eeetypeeid`,
       
   353                 '__type:'+`eeetypeeid`:   'EEType',
       
   354                 'name:'+`eeetypeeid`:     u'EGroup',
       
   355                 'final:'+`eeetypeeid`:    False,
       
   356                 'meta:'+`eeetypeeid`:     True,
       
   357                 'description:'+`eeetypeeid`:     u'users group', 
       
   358                 'read_permission:'+`eeetypeeid`:  groups,
       
   359                 #
       
   360                 'edits-name:'+`eeetypeeid`:     u'EGroup',
       
   361                 'edits-final:'+`eeetypeeid`:    False,
       
   362                 'edits-meta:'+`eeetypeeid`:     True,
       
   363                 'edits-description:'+`eeetypeeid`:     u'users group', 
       
   364                 'edits-read_permission:'+`eeetypeeid`:  basegroups,
       
   365                 }
       
   366         try:
       
   367             path, params = self.expect_redirect_publish()
       
   368             e = self.execute('Any X WHERE X eid %(x)s', {'x': eeetypeeid}, 'x').get_entity(0, 0)
       
   369             self.assertEquals(e.name, 'EGroup')
       
   370             self.assertEquals([g.eid for g in e.read_permission], groupeids)
       
   371         finally:
       
   372             # restore
       
   373             self.execute('SET X read_permission Y WHERE X name "EGroup", Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
       
   374             self.commit()
       
   375             
       
   376     def test_nonregr_eetype_etype_editing(self):
       
   377         """non-regression test checking that a manager user can edit a EEType entity (EEType)
       
   378         """
       
   379         groupeids = sorted(eid for eid, in self.execute('EGroup G WHERE G name in ("managers", "users")'))
       
   380         groups = [str(eid) for eid in groupeids]
       
   381         eeetypeeid = self.execute('EEType X WHERE X name "EEType"')[0][0]
       
   382         basegroups = [str(eid) for eid, in self.execute('EGroup G WHERE X read_permission G, X eid %(x)s', {'x': eeetypeeid})]
       
   383         self.req.form = {
       
   384                 'eid':      `eeetypeeid`,
       
   385                 '__type:'+`eeetypeeid`:  'EEType',
       
   386                 'name:'+`eeetypeeid`:     u'EEType',
       
   387                 'final:'+`eeetypeeid`:    False,
       
   388                 'meta:'+`eeetypeeid`:     True,
       
   389                 'description:'+`eeetypeeid`:     u'users group', 
       
   390                 'read_permission:'+`eeetypeeid`:  groups,
       
   391 
       
   392                 'edits-name:'+`eeetypeeid`:     u'EEType',
       
   393                 'edits-final:'+`eeetypeeid`:    False,
       
   394                 'edits-meta:'+`eeetypeeid`:     True,
       
   395                 'edits-description:'+`eeetypeeid`:     u'users group', 
       
   396                 'edits-read_permission:'+`eeetypeeid`:  basegroups,
       
   397                 }
       
   398         try:
       
   399             path, params = self.expect_redirect_publish()
       
   400             e = self.execute('Any X WHERE X eid %(x)s', {'x': eeetypeeid}, 'x').get_entity(0, 0)
       
   401             self.assertEquals(e.name, 'EEType')
       
   402             self.assertEquals(sorted(g.eid for g in e.read_permission), groupeids)
       
   403         finally:
       
   404             # restore
       
   405             self.execute('SET X read_permission Y WHERE X name "EEType", Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
       
   406             self.commit()
       
   407         
       
   408     def test_nonregr_strange_text_input(self):
       
   409         """non-regression test checking text input containing "13:03:43"
       
   410 
       
   411         this seems to be postgres (tsearch?) specific
       
   412         """        
       
   413         self.req.form = {
       
   414                          'eid': 'A', '__type:A': 'BlogEntry',
       
   415                          '__maineid' : 'A',
       
   416                          'title:A': u'"13:03:40"', 'edits-title:A': '',
       
   417                          'content:A': u'"13:03:43"', 'edits-content:A': ''}
       
   418         path, params = self.expect_redirect_publish()
       
   419         self.failUnless(path.startswith('blogentry/'))
       
   420         eid = path.split('/')[1]
       
   421         e = self.execute('Any C, T WHERE C eid %(x)s, C content T', {'x': eid}, 'x').get_entity(0, 0)
       
   422         self.assertEquals(e.title, '"13:03:40"')
       
   423         self.assertEquals(e.content, '"13:03:43"')
       
   424 
       
   425 
       
   426     def test_nonregr_multiple_empty_email_addr(self):
       
   427         gueid = self.execute('EGroup G WHERE G name "users"')[0][0]
       
   428         self.req.form = {'eid': ['X', 'Y'],
       
   429                          
       
   430                          '__type:X': 'EUser',
       
   431                          'login:X': u'adim', 'edits-login:X': u'', 
       
   432                          'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'', 
       
   433                          'in_group:X': `gueid`, 'edits-in_group:X': INTERNAL_FIELD_VALUE, 
       
   434                          
       
   435                          '__type:Y': 'EmailAddress',
       
   436                          'address:Y': u'', 'edits-address:Y': '',
       
   437                          'alias:Y': u'', 'edits-alias:Y': '',
       
   438                          'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE, 
       
   439                          }
       
   440         self.assertRaises(ValidationError, self.publish, self.req)
       
   441 
       
   442     def test_nonregr_copy(self):
       
   443         user = self.user()
       
   444         self.req.form = {'__cloned_eid:X': user.eid,
       
   445                          'eid': 'X', '__type:X': 'EUser',
       
   446                          '__maineid' : 'X',
       
   447                          'login:X': u'toto', 'edits-login:X': u'', 
       
   448                          'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'', 
       
   449                          }
       
   450         path, params = self.expect_redirect_publish()
       
   451         self.assertEquals(path, 'euser/toto')
       
   452         e = self.execute('Any X WHERE X is EUser, X login "toto"').get_entity(0, 0)
       
   453         self.assertEquals(e.login, 'toto')
       
   454         self.assertEquals(e.in_group[0].name, 'managers')
       
   455 
       
   456 
       
   457     def test_nonregr_rollback_on_validation_error(self):
       
   458         p = self.create_user("doe")
       
   459         # do not try to skip 'primary_email' for this test
       
   460         old_skips = p.__class__.skip_copy_for
       
   461         p.__class__.skip_copy_for = ()
       
   462         try:
       
   463             e = self.add_entity('EmailAddress', address=u'doe@doe.com')
       
   464             self.execute('SET P use_email E, P primary_email E WHERE P eid %(p)s, E eid %(e)s',
       
   465                          {'p' : p.eid, 'e' : e.eid})
       
   466             self.req.form = {'__cloned_eid:X': p.eid,
       
   467                              'eid': 'X', '__type:X': 'EUser',
       
   468                              'login': u'dodo', 'edits-login': u'dodo', 
       
   469                              'surname:X': u'Boom', 'edits-surname:X': u'',
       
   470                              '__errorurl' : "whatever but required",
       
   471                              }
       
   472             # try to emulate what really happens in the web application
       
   473             # 1/ validate form => EditController.publish raises a ValidationError
       
   474             #    which fires a Redirect
       
   475             # 2/ When re-publishing the copy form, the publisher implicitly commits
       
   476             try:
       
   477                 self.env.app.publish('edit', self.req)
       
   478             except Redirect:
       
   479                 self.req.form['rql'] = 'Any X WHERE X eid %s' % p.eid
       
   480                 self.req.form['vid'] = 'copy'
       
   481                 self.env.app.publish('view', self.req)
       
   482             rset = self.execute('EUser P WHERE P surname "Boom"')
       
   483             self.assertEquals(len(rset), 0)
       
   484         finally:
       
   485             p.__class__.skip_copy_for = old_skips
       
   486 
       
   487 
       
   488 class EmbedControllerTC(EnvBasedTC):
       
   489 
       
   490     def test_nonregr_embed_publish(self):
       
   491         # This test looks a bit stupid but at least it will probably
       
   492         # fail if the controller API changes and if EmbedController is not
       
   493         # updated (which is what happened before this test)
       
   494         req = self.request()
       
   495         req.form['url'] = 'http://intranet.logilab.fr/'
       
   496         controller = self.env.app.select_controller('embed', req)
       
   497         result = controller.publish(rset=None)
       
   498 
       
   499 
       
   500 class ReportBugControllerTC(EnvBasedTC):
       
   501 
       
   502     def test_usable_by_guets(self):
       
   503         req = self.request()
       
   504         self.env.app.select_controller('reportbug', req)
       
   505 
       
   506 
       
   507 class SendMailControllerTC(EnvBasedTC):
       
   508 
       
   509     def test_not_usable_by_guets(self):
       
   510         self.login('anon')
       
   511         req = self.request()
       
   512         self.assertRaises(Unauthorized, self.env.app.select_controller, 'sendmail', req)
       
   513    
       
   514 
       
   515 
       
   516 class JSONControllerTC(EnvBasedTC):
       
   517 
       
   518     def ctrl(self, req=None):
       
   519         req = req or self.request(url='http://whatever.fr/')
       
   520         return self.env.app.select_controller('json', req)
       
   521 
       
   522     def setup_database(self):
       
   523         self.pytag = self.add_entity('Tag', name=u'python')
       
   524         self.cubicwebtag = self.add_entity('Tag', name=u'cubicweb')
       
   525         self.john = self.create_user(u'John')
       
   526 
       
   527 
       
   528     ## tests ##################################################################
       
   529     def test_simple_exec(self):
       
   530         ctrl = self.ctrl(self.request(rql='EUser P WHERE P login "John"',
       
   531                                       pageid='123'))
       
   532         self.assertTextEquals(ctrl.publish(),
       
   533                               xmlize(self.john.view('primary')))
       
   534 
       
   535     def test_json_exec(self):
       
   536         rql = 'Any T,N WHERE T is Tag, T name N'
       
   537         ctrl = self.ctrl(self.request(mode='json', rql=rql, pageid='123'))
       
   538         self.assertEquals(ctrl.publish(),
       
   539                           simplejson.dumps(self.execute(rql).rows))
       
   540 
       
   541     def test_remote_add_existing_tag(self):
       
   542         self.remote_call('tag_entity', self.john.eid, ['python'])
       
   543         self.assertUnorderedIterableEquals([tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
       
   544                              ['python', 'cubicweb'])
       
   545         self.assertEquals(self.execute('Any N WHERE T tags P, P is EUser, T name N').rows,
       
   546                           [['python']])
       
   547     
       
   548     def test_remote_add_new_tag(self):
       
   549         self.remote_call('tag_entity', self.john.eid, ['javascript'])
       
   550         self.assertUnorderedIterableEquals([tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
       
   551                              ['python', 'cubicweb', 'javascript'])
       
   552         self.assertEquals(self.execute('Any N WHERE T tags P, P is EUser, T name N').rows,
       
   553                           [['javascript']])
       
   554 
       
   555     def test_edit_field(self):
       
   556         nbusers = len(self.execute('EUser P'))
       
   557         eid = self.john.eid
       
   558         self.remote_call('edit_field', 'apply',
       
   559                          ('eid', 'firstname:%s' % eid, '__maineid', '__type:%s'% eid, 'edits-firstname:%s' % eid ),
       
   560                          (str(eid), u'Remi', str(eid), 'EUser', self.john.firstname),
       
   561                          'firstname',
       
   562                          eid)
       
   563         self.commit()
       
   564         rset = self.execute('EUser P')
       
   565         # make sure we did not insert a new euser here
       
   566         self.assertEquals(len(rset), nbusers)
       
   567         john = self.execute('Any X WHERE X eid %(x)s', {'x': self.john.eid}, 'x').get_entity(0, 0)
       
   568         self.assertEquals(john.eid, self.john.eid)
       
   569         self.assertEquals(john.firstname, 'Remi')
       
   570 
       
   571 
       
   572     def test_pending_insertion(self):
       
   573         res, req = self.remote_call('add_pending_insert', ['12', 'tags', '13'])
       
   574         deletes = req.get_pending_deletes()
       
   575         self.assertEquals(deletes, [])
       
   576         inserts = req.get_pending_inserts()
       
   577         self.assertEquals(inserts, ['12:tags:13'])
       
   578         res, req = self.remote_call('add_pending_insert', ['12', 'tags', '14'])
       
   579         deletes = req.get_pending_deletes()
       
   580         self.assertEquals(deletes, [])
       
   581         inserts = req.get_pending_inserts()
       
   582         self.assertEquals(inserts, ['12:tags:13', '12:tags:14'])
       
   583         inserts = req.get_pending_inserts(12)
       
   584         self.assertEquals(inserts, ['12:tags:13', '12:tags:14'])
       
   585         inserts = req.get_pending_inserts(13)
       
   586         self.assertEquals(inserts, ['12:tags:13'])
       
   587         inserts = req.get_pending_inserts(14)
       
   588         self.assertEquals(inserts, ['12:tags:14'])
       
   589         req.remove_pending_operations()
       
   590 
       
   591     def test_pending_deletion(self):
       
   592         res, req = self.remote_call('add_pending_delete', ['12', 'tags', '13'])
       
   593         inserts = req.get_pending_inserts()
       
   594         self.assertEquals(inserts, [])
       
   595         deletes = req.get_pending_deletes()
       
   596         self.assertEquals(deletes, ['12:tags:13'])
       
   597         res, req = self.remote_call('add_pending_delete', ['12', 'tags', '14'])
       
   598         inserts = req.get_pending_inserts()
       
   599         self.assertEquals(inserts, [])
       
   600         deletes = req.get_pending_deletes()
       
   601         self.assertEquals(deletes, ['12:tags:13', '12:tags:14'])
       
   602         deletes = req.get_pending_deletes(12)
       
   603         self.assertEquals(deletes, ['12:tags:13', '12:tags:14'])
       
   604         deletes = req.get_pending_deletes(13)
       
   605         self.assertEquals(deletes, ['12:tags:13'])
       
   606         deletes = req.get_pending_deletes(14)
       
   607         self.assertEquals(deletes, ['12:tags:14'])
       
   608         req.remove_pending_operations()
       
   609 
       
   610     def test_remove_pending_operations(self):
       
   611         self.remote_call('add_pending_delete', ['12', 'tags', '13'])
       
   612         _, req = self.remote_call('add_pending_insert', ['12', 'tags', '14'])
       
   613         inserts = req.get_pending_inserts()
       
   614         self.assertEquals(inserts, ['12:tags:14'])
       
   615         deletes = req.get_pending_deletes()
       
   616         self.assertEquals(deletes, ['12:tags:13'])
       
   617         req.remove_pending_operations()
       
   618         self.assertEquals(req.get_pending_deletes(), [])
       
   619         self.assertEquals(req.get_pending_inserts(), [])
       
   620         
       
   621 
       
   622     def test_add_inserts(self):
       
   623         res, req = self.remote_call('add_pending_inserts',
       
   624                                     [('12', 'tags', '13'), ('12', 'tags', '14')])
       
   625         inserts = req.get_pending_inserts()
       
   626         self.assertEquals(inserts, ['12:tags:13', '12:tags:14'])
       
   627         req.remove_pending_operations()
       
   628         
       
   629 
       
   630     # silly tests
       
   631     def test_external_resource(self):
       
   632         self.assertEquals(self.remote_call('external_resource', 'RSS_LOGO')[0],
       
   633                           simplejson.dumps(self.request().external_resource('RSS_LOGO')))
       
   634     def test_i18n(self):
       
   635         self.assertEquals(self.remote_call('i18n', ['bimboom'])[0],
       
   636                           simplejson.dumps(['bimboom']))
       
   637 
       
   638     def test_format_date(self):
       
   639         self.assertEquals(self.remote_call('format_date', '"2007-01-01 12:00:00"')[0],
       
   640                           simplejson.dumps('2007/01/01'))
       
   641 
       
   642         
       
   643 
       
   644         
       
   645 if __name__ == '__main__':
       
   646     unittest_main()