web/test/unittest_views_basecontrollers.py
brancholdstable
changeset 6665 90f2f20367bc
parent 6412 370357e68837
child 6796 e70ca9abfc51
equal deleted inserted replaced
6018:f4d1d5d9ccbb 6665:90f2f20367bc
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
    14 # details.
    14 # details.
    15 #
    15 #
    16 # You should have received a copy of the GNU Lesser General Public License along
    16 # You should have received a copy of the GNU Lesser General Public License along
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    18 """cubicweb.web.views.basecontrollers unit tests
    18 """cubicweb.web.views.basecontrollers unit tests"""
    19 
       
    20 """
       
    21 
    19 
    22 from logilab.common.testlib import unittest_main, mock_object
    20 from logilab.common.testlib import unittest_main, mock_object
    23 
    21 
    24 from cubicweb import Binary, NoSelectableObject, ValidationError
    22 from cubicweb import Binary, NoSelectableObject, ValidationError
    25 from cubicweb.view import STRICT_DOCTYPE
    23 from cubicweb.view import STRICT_DOCTYPE
    26 from cubicweb.devtools.testlib import CubicWebTC
    24 from cubicweb.devtools.testlib import CubicWebTC
       
    25 from cubicweb.utils import json_dumps
    27 from cubicweb.uilib import rql_for_eid
    26 from cubicweb.uilib import rql_for_eid
    28 from cubicweb.web import INTERNAL_FIELD_VALUE, Redirect, RequestError, json
    27 from cubicweb.web import INTERNAL_FIELD_VALUE, Redirect, RequestError
    29 from cubicweb.entities.authobjs import CWUser
    28 from cubicweb.entities.authobjs import CWUser
    30 from cubicweb.web.views.autoform import get_pending_inserts, get_pending_deletes
    29 from cubicweb.web.views.autoform import get_pending_inserts, get_pending_deletes
    31 u = unicode
    30 u = unicode
    32 
    31 
    33 def req_form(user):
    32 def req_form(user):
    47 
    46 
    48     def test_noparam_edit(self):
    47     def test_noparam_edit(self):
    49         """check behaviour of this controller without any form parameter
    48         """check behaviour of this controller without any form parameter
    50         """
    49         """
    51         ex = self.assertRaises(ValidationError, self.ctrl_publish, self.request())
    50         ex = self.assertRaises(ValidationError, self.ctrl_publish, self.request())
    52         self.assertEquals(ex.errors, {None: u'no selected entities'})
    51         self.assertEqual(ex.errors, {None: u'no selected entities'})
    53 
    52 
    54     def test_validation_unique(self):
    53     def test_validation_unique(self):
    55         """test creation of two linked entities
    54         """test creation of two linked entities
    56         """
    55         """
    57         user = self.user()
    56         user = self.user()
    61                     'login-subject:X': u'admin',
    60                     'login-subject:X': u'admin',
    62                     'upassword-subject:X': u'toto',
    61                     'upassword-subject:X': u'toto',
    63                     'upassword-subject-confirm:X': u'toto',
    62                     'upassword-subject-confirm:X': u'toto',
    64                     }
    63                     }
    65         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
    64         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
    66         self.assertEquals(ex.errors, {'login-subject': 'the value "admin" is already used, use another one'})
    65         self.assertEqual(ex.errors, {'login-subject': 'the value "admin" is already used, use another one'})
    67 
    66 
    68     def test_user_editing_itself(self):
    67     def test_user_editing_itself(self):
    69         """checking that a manager user can edit itself
    68         """checking that a manager user can edit itself
    70         """
    69         """
    71         user = self.user()
    70         user = self.user()
    82             'firstname-subject:'+eid:   u'Sylvain',
    81             'firstname-subject:'+eid:   u'Sylvain',
    83             'in_group-subject:'+eid:  groups,
    82             'in_group-subject:'+eid:  groups,
    84             }
    83             }
    85         path, params = self.expect_redirect_publish(req, 'edit')
    84         path, params = self.expect_redirect_publish(req, 'edit')
    86         e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
    85         e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
    87         self.assertEquals(e.firstname, u'Sylvain')
    86         self.assertEqual(e.firstname, u'Sylvain')
    88         self.assertEquals(e.surname, u'Th\xe9nault')
    87         self.assertEqual(e.surname, u'Th\xe9nault')
    89         self.assertEquals(e.login, user.login)
    88         self.assertEqual(e.login, user.login)
    90         self.assertEquals([g.eid for g in e.in_group], groupeids)
    89         self.assertEqual([g.eid for g in e.in_group], groupeids)
    91 
    90 
    92     def test_user_can_change_its_password(self):
    91     def test_user_can_change_its_password(self):
    93         user = self.create_user('user')
    92         user = self.create_user('user')
    94         cnx = self.login('user')
    93         cnx = self.login('user')
    95         req = self.request()
    94         req = self.request()
   101             'upassword-subject:'+eid: 'tournicoton',
   100             'upassword-subject:'+eid: 'tournicoton',
   102             'upassword-subject-confirm:'+eid: 'tournicoton',
   101             'upassword-subject-confirm:'+eid: 'tournicoton',
   103             }
   102             }
   104         path, params = self.expect_redirect_publish(req, 'edit')
   103         path, params = self.expect_redirect_publish(req, 'edit')
   105         cnx.commit() # commit to check we don't get late validation error for instance
   104         cnx.commit() # commit to check we don't get late validation error for instance
   106         self.assertEquals(path, 'cwuser/user')
   105         self.assertEqual(path, 'cwuser/user')
   107         self.failIf('vid' in params)
   106         self.failIf('vid' in params)
   108 
   107 
   109     def test_user_editing_itself_no_relation(self):
   108     def test_user_editing_itself_no_relation(self):
   110         """checking we can edit an entity without specifying some required
   109         """checking we can edit an entity without specifying some required
   111         relations (meaning no changes)
   110         relations (meaning no changes)
   122             'firstname-subject:'+eid: u'Th\xe9nault',
   121             'firstname-subject:'+eid: u'Th\xe9nault',
   123             'surname-subject:'+eid:   u'Sylvain',
   122             'surname-subject:'+eid:   u'Sylvain',
   124             }
   123             }
   125         path, params = self.expect_redirect_publish(req, 'edit')
   124         path, params = self.expect_redirect_publish(req, 'edit')
   126         e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
   125         e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
   127         self.assertEquals(e.login, user.login)
   126         self.assertEqual(e.login, user.login)
   128         self.assertEquals(e.firstname, u'Th\xe9nault')
   127         self.assertEqual(e.firstname, u'Th\xe9nault')
   129         self.assertEquals(e.surname, u'Sylvain')
   128         self.assertEqual(e.surname, u'Sylvain')
   130         self.assertEquals([g.eid for g in e.in_group], groupeids)
   129         self.assertEqual([g.eid for g in e.in_group], groupeids)
   131         self.assertEquals(e.state, 'activated')
   130         self.assertEqual(e.cw_adapt_to('IWorkflowable').state, 'activated')
   132 
   131 
   133 
   132 
   134     def test_create_multiple_linked(self):
   133     def test_create_multiple_linked(self):
   135         gueid = self.execute('CWGroup G WHERE G name "users"')[0][0]
   134         gueid = self.execute('CWGroup G WHERE G name "users"')[0][0]
   136         req = self.request()
   135         req = self.request()
   148                     'address-subject:Y': u'dima@logilab.fr',
   147                     'address-subject:Y': u'dima@logilab.fr',
   149                     'use_email-object:Y': 'X',
   148                     'use_email-object:Y': 'X',
   150                     }
   149                     }
   151         path, params = self.expect_redirect_publish(req, 'edit')
   150         path, params = self.expect_redirect_publish(req, 'edit')
   152         # should be redirected on the created person
   151         # should be redirected on the created person
   153         self.assertEquals(path, 'cwuser/adim')
   152         self.assertEqual(path, 'cwuser/adim')
   154         e = self.execute('Any P WHERE P surname "Di Mascio"').get_entity(0, 0)
   153         e = self.execute('Any P WHERE P surname "Di Mascio"').get_entity(0, 0)
   155         self.assertEquals(e.surname, 'Di Mascio')
   154         self.assertEqual(e.surname, 'Di Mascio')
   156         email = e.use_email[0]
   155         email = e.use_email[0]
   157         self.assertEquals(email.address, 'dima@logilab.fr')
   156         self.assertEqual(email.address, 'dima@logilab.fr')
   158 
   157 
   159     def test_edit_multiple_linked(self):
   158     def test_edit_multiple_linked(self):
   160         peid = u(self.create_user('adim').eid)
   159         peid = u(self.create_user('adim').eid)
   161         req = self.request()
   160         req = self.request()
   162         req.form = {'eid': [peid, 'Y'], '__maineid': peid,
   161         req.form = {'eid': [peid, 'Y'], '__maineid': peid,
   170                     'address-subject:Y': u'dima@logilab.fr',
   169                     'address-subject:Y': u'dima@logilab.fr',
   171                     'use_email-object:Y': peid,
   170                     'use_email-object:Y': peid,
   172                     }
   171                     }
   173         path, params = self.expect_redirect_publish(req, 'edit')
   172         path, params = self.expect_redirect_publish(req, 'edit')
   174         # should be redirected on the created person
   173         # should be redirected on the created person
   175         self.assertEquals(path, 'cwuser/adim')
   174         self.assertEqual(path, 'cwuser/adim')
   176         e = self.execute('Any P WHERE P surname "Di Masci"').get_entity(0, 0)
   175         e = self.execute('Any P WHERE P surname "Di Masci"').get_entity(0, 0)
   177         email = e.use_email[0]
   176         email = e.use_email[0]
   178         self.assertEquals(email.address, 'dima@logilab.fr')
   177         self.assertEqual(email.address, 'dima@logilab.fr')
   179 
   178 
   180         emaileid = u(email.eid)
   179         emaileid = u(email.eid)
   181         req = self.request()
   180         req = self.request()
   182         req.form = {'eid': [peid, emaileid],
   181         req.form = {'eid': [peid, emaileid],
   183 
   182 
   190                     'address-subject:'+emaileid: u'adim@logilab.fr',
   189                     'address-subject:'+emaileid: u'adim@logilab.fr',
   191                     'use_email-object:'+emaileid: peid,
   190                     'use_email-object:'+emaileid: peid,
   192                     }
   191                     }
   193         path, params = self.expect_redirect_publish(req, 'edit')
   192         path, params = self.expect_redirect_publish(req, 'edit')
   194         email.clear_all_caches()
   193         email.clear_all_caches()
   195         self.assertEquals(email.address, 'adim@logilab.fr')
   194         self.assertEqual(email.address, 'adim@logilab.fr')
   196 
   195 
   197 
   196 
   198     def test_password_confirm(self):
   197     def test_password_confirm(self):
   199         """test creation of two linked entities
   198         """test creation of two linked entities
   200         """
   199         """
   205                     '_cw_edited_fields:X': 'login-subject,upassword-subject',
   204                     '_cw_edited_fields:X': 'login-subject,upassword-subject',
   206                     'login-subject:X': u'toto',
   205                     'login-subject:X': u'toto',
   207                     'upassword-subject:X': u'toto',
   206                     'upassword-subject:X': u'toto',
   208                     }
   207                     }
   209         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
   208         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
   210         self.assertEquals(ex.errors, {'upassword-subject': u'password and confirmation don\'t match'})
   209         self.assertEqual(ex.errors, {'upassword-subject': u'password and confirmation don\'t match'})
   211         req = self.request()
   210         req = self.request()
   212         req.form = {'__cloned_eid:X': u(user.eid),
   211         req.form = {'__cloned_eid:X': u(user.eid),
   213                     'eid': 'X', '__type:X': 'CWUser',
   212                     'eid': 'X', '__type:X': 'CWUser',
   214                     '_cw_edited_fields:X': 'login-subject,upassword-subject',
   213                     '_cw_edited_fields:X': 'login-subject,upassword-subject',
   215                     'login-subject:X': u'toto',
   214                     'login-subject:X': u'toto',
   216                     'upassword-subject:X': u'toto',
   215                     'upassword-subject:X': u'toto',
   217                     'upassword-subject-confirm:X': u'tutu',
   216                     'upassword-subject-confirm:X': u'tutu',
   218                     }
   217                     }
   219         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
   218         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
   220         self.assertEquals(ex.errors, {'upassword-subject': u'password and confirmation don\'t match'})
   219         self.assertEqual(ex.errors, {'upassword-subject': u'password and confirmation don\'t match'})
   221 
   220 
   222 
   221 
   223     def test_interval_bound_constraint_success(self):
   222     def test_interval_bound_constraint_success(self):
   224         feid = self.execute('INSERT File X: X data_name "toto.txt", X data %(data)s',
   223         feid = self.execute('INSERT File X: X data_name "toto.txt", X data %(data)s',
   225                             {'data': Binary('yo')})[0][0]
   224                             {'data': Binary('yo')})[0][0]
   226         req = self.request()
   225         self.commit()
       
   226         req = self.request(rollbackfirst=True)
   227         req.form = {'eid': ['X'],
   227         req.form = {'eid': ['X'],
   228                     '__type:X': 'Salesterm',
   228                     '__type:X': 'Salesterm',
   229                     '_cw_edited_fields:X': 'amount-subject,described_by_test-subject',
   229                     '_cw_edited_fields:X': 'amount-subject,described_by_test-subject',
   230                     'amount-subject:X': u'-10',
   230                     'amount-subject:X': u'-10',
   231                     'described_by_test-subject:X': u(feid),
   231                     'described_by_test-subject:X': u(feid),
   232                 }
   232                 }
   233         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
   233         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
   234         self.assertEquals(ex.errors, {'amount-subject': 'value must be >= 0'})
   234         self.assertEqual(ex.errors, {'amount-subject': 'value must be >= 0'})
   235         req = self.request()
   235         req = self.request(rollbackfirst=True)
   236         req.form = {'eid': ['X'],
   236         req.form = {'eid': ['X'],
   237                     '__type:X': 'Salesterm',
   237                     '__type:X': 'Salesterm',
   238                     '_cw_edited_fields:X': 'amount-subject,described_by_test-subject',
   238                     '_cw_edited_fields:X': 'amount-subject,described_by_test-subject',
   239                     'amount-subject:X': u'110',
   239                     'amount-subject:X': u'110',
   240                     'described_by_test-subject:X': u(feid),
   240                     'described_by_test-subject:X': u(feid),
   241                     }
   241                     }
   242         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
   242         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
   243         self.assertEquals(ex.errors, {'amount-subject': 'value must be <= 100'})
   243         self.assertEqual(ex.errors, {'amount-subject': 'value must be <= 100'})
   244         req = self.request()
   244         req = self.request(rollbackfirst=True)
   245         req.form = {'eid': ['X'],
   245         req.form = {'eid': ['X'],
   246                     '__type:X': 'Salesterm',
   246                     '__type:X': 'Salesterm',
   247                     '_cw_edited_fields:X': 'amount-subject,described_by_test-subject',
   247                     '_cw_edited_fields:X': 'amount-subject,described_by_test-subject',
   248                     'amount-subject:X': u'10',
   248                     'amount-subject:X': u'10',
   249                     'described_by_test-subject:X': u(feid),
   249                     'described_by_test-subject:X': u(feid),
   250                     }
   250                     }
   251         self.expect_redirect_publish(req, 'edit')
   251         self.expect_redirect_publish(req, 'edit')
   252         # should be redirected on the created
   252         # should be redirected on the created
   253         #eid = params['rql'].split()[-1]
   253         #eid = params['rql'].split()[-1]
   254         e = self.execute('Salesterm X').get_entity(0, 0)
   254         e = self.execute('Salesterm X').get_entity(0, 0)
   255         self.assertEquals(e.amount, 10)
   255         self.assertEqual(e.amount, 10)
   256 
   256 
   257     def test_req_pending_insert(self):
   257     def test_req_pending_insert(self):
   258         """make sure req's pending insertions are taken into account"""
   258         """make sure req's pending insertions are taken into account"""
   259         tmpgroup = self.request().create_entity('CWGroup', name=u"test")
   259         tmpgroup = self.request().create_entity('CWGroup', name=u"test")
   260         user = self.user()
   260         user = self.user()
   261         req = self.request(**req_form(user))
   261         req = self.request(**req_form(user))
   262         req.session.data['pending_insert'] = set([(user.eid, 'in_group', tmpgroup.eid)])
   262         req.session.data['pending_insert'] = set([(user.eid, 'in_group', tmpgroup.eid)])
   263         path, params = self.expect_redirect_publish(req, 'edit')
   263         path, params = self.expect_redirect_publish(req, 'edit')
   264         usergroups = [gname for gname, in
   264         usergroups = [gname for gname, in
   265                       self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
   265                       self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
   266         self.assertUnorderedIterableEquals(usergroups, ['managers', 'test'])
   266         self.assertItemsEqual(usergroups, ['managers', 'test'])
   267         self.assertEquals(get_pending_inserts(req), [])
   267         self.assertEqual(get_pending_inserts(req), [])
   268 
   268 
   269 
   269 
   270     def test_req_pending_delete(self):
   270     def test_req_pending_delete(self):
   271         """make sure req's pending deletions are taken into account"""
   271         """make sure req's pending deletions are taken into account"""
   272         user = self.user()
   272         user = self.user()
   273         groupeid = self.execute('INSERT CWGroup G: G name "test", U in_group G WHERE U eid %(x)s',
   273         groupeid = self.execute('INSERT CWGroup G: G name "test", U in_group G WHERE U eid %(x)s',
   274                                 {'x': user.eid})[0][0]
   274                                 {'x': user.eid})[0][0]
   275         usergroups = [gname for gname, in
   275         usergroups = [gname for gname, in
   276                       self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
   276                       self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
   277         # just make sure everything was set correctly
   277         # just make sure everything was set correctly
   278         self.assertUnorderedIterableEquals(usergroups, ['managers', 'test'])
   278         self.assertItemsEqual(usergroups, ['managers', 'test'])
   279         # now try to delete the relation
   279         # now try to delete the relation
   280         req = self.request(**req_form(user))
   280         req = self.request(**req_form(user))
   281         req.session.data['pending_delete'] = set([(user.eid, 'in_group', groupeid)])
   281         req.session.data['pending_delete'] = set([(user.eid, 'in_group', groupeid)])
   282         path, params = self.expect_redirect_publish(req, 'edit')
   282         path, params = self.expect_redirect_publish(req, 'edit')
   283         usergroups = [gname for gname, in
   283         usergroups = [gname for gname, in
   284                       self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
   284                       self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
   285         self.assertUnorderedIterableEquals(usergroups, ['managers'])
   285         self.assertItemsEqual(usergroups, ['managers'])
   286         self.assertEquals(get_pending_deletes(req), [])
   286         self.assertEqual(get_pending_deletes(req), [])
   287 
       
   288     # def test_custom_attribute_handler(self):
       
   289     #     def custom_login_edit(self, formparams, value, relations):
       
   290     #         formparams['login'] = value.upper()
       
   291     #         relations.append('X login %(login)s')
       
   292     #     CWUser.custom_login_edit = custom_login_edit
       
   293     #     try:
       
   294     #         user = self.user()
       
   295     #         eid = repr(user.eid)
       
   296     #         req = self.request()
       
   297     #         req.form = {
       
   298     #             'eid': eid,
       
   299     #             '__type:'+eid:  'CWUser',
       
   300     #             'login:'+eid: u'foo',
       
   301     #             }
       
   302     #         path, params = self.expect_redirect_publish(req, 'edit')
       
   303     #         rset = self.execute('Any L WHERE X eid %(x)s, X login L', {'x': user.eid}, 'x')
       
   304     #         self.assertEquals(rset[0][0], 'FOO')
       
   305     #     finally:
       
   306     #         del CWUser.custom_login_edit
       
   307 
   287 
   308     def test_redirect_apply_button(self):
   288     def test_redirect_apply_button(self):
   309         redirectrql = rql_for_eid(4012) # whatever
   289         redirectrql = rql_for_eid(4012) # whatever
   310         req = self.request()
   290         req = self.request()
   311         req.form = {
   291         req.form = {
   320             '__action_apply': '',
   300             '__action_apply': '',
   321             }
   301             }
   322         path, params = self.expect_redirect_publish(req, 'edit')
   302         path, params = self.expect_redirect_publish(req, 'edit')
   323         self.failUnless(path.startswith('blogentry/'))
   303         self.failUnless(path.startswith('blogentry/'))
   324         eid = path.split('/')[1]
   304         eid = path.split('/')[1]
   325         self.assertEquals(params['vid'], 'edition')
   305         self.assertEqual(params['vid'], 'edition')
   326         self.assertNotEquals(int(eid), 4012)
   306         self.assertNotEqual(int(eid), 4012)
   327         self.assertEquals(params['__redirectrql'], redirectrql)
   307         self.assertEqual(params['__redirectrql'], redirectrql)
   328         self.assertEquals(params['__redirectvid'], 'primary')
   308         self.assertEqual(params['__redirectvid'], 'primary')
   329         self.assertEquals(params['__redirectparams'], 'toto=tutu&tata=titi')
   309         self.assertEqual(params['__redirectparams'], 'toto=tutu&tata=titi')
   330 
   310 
   331     def test_redirect_ok_button(self):
   311     def test_redirect_ok_button(self):
   332         redirectrql = rql_for_eid(4012) # whatever
   312         redirectrql = rql_for_eid(4012) # whatever
   333         req = self.request()
   313         req = self.request()
   334         req.form = {
   314         req.form = {
   340             '__redirectvid': 'primary',
   320             '__redirectvid': 'primary',
   341             '__redirectparams': 'toto=tutu&tata=titi',
   321             '__redirectparams': 'toto=tutu&tata=titi',
   342             '__form_id': 'edition',
   322             '__form_id': 'edition',
   343             }
   323             }
   344         path, params = self.expect_redirect_publish(req, 'edit')
   324         path, params = self.expect_redirect_publish(req, 'edit')
   345         self.assertEquals(path, 'view')
   325         self.assertEqual(path, 'view')
   346         self.assertEquals(params['rql'], redirectrql)
   326         self.assertEqual(params['rql'], redirectrql)
   347         self.assertEquals(params['vid'], 'primary')
   327         self.assertEqual(params['vid'], 'primary')
   348         self.assertEquals(params['tata'], 'titi')
   328         self.assertEqual(params['tata'], 'titi')
   349         self.assertEquals(params['toto'], 'tutu')
   329         self.assertEqual(params['toto'], 'tutu')
   350 
   330 
   351     def test_redirect_delete_button(self):
   331     def test_redirect_delete_button(self):
   352         req = self.request()
   332         req = self.request()
   353         eid = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
   333         eid = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
   354         req.form = {'eid': u(eid), '__type:%s'%eid: 'BlogEntry',
   334         req.form = {'eid': u(eid), '__type:%s'%eid: 'BlogEntry',
   355                     '__action_delete': ''}
   335                     '__action_delete': ''}
   356         path, params = self.expect_redirect_publish(req, 'edit')
   336         path, params = self.expect_redirect_publish(req, 'edit')
   357         self.assertEquals(path, 'blogentry')
   337         self.assertEqual(path, 'blogentry')
   358         self.assertIn('_cwmsgid', params)
   338         self.assertIn('_cwmsgid', params)
   359         eid = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
   339         eid = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
   360         self.execute('SET X use_email E WHERE E eid %(e)s, X eid %(x)s',
   340         self.execute('SET X use_email E WHERE E eid %(e)s, X eid %(x)s',
   361                      {'x': self.session.user.eid, 'e': eid})
   341                      {'x': self.session.user.eid, 'e': eid})
   362         self.commit()
   342         self.commit()
   363         req = req
   343         req = req
   364         req.form = {'eid': u(eid), '__type:%s'%eid: 'EmailAddress',
   344         req.form = {'eid': u(eid), '__type:%s'%eid: 'EmailAddress',
   365                     '__action_delete': ''}
   345                     '__action_delete': ''}
   366         path, params = self.expect_redirect_publish(req, 'edit')
   346         path, params = self.expect_redirect_publish(req, 'edit')
   367         self.assertEquals(path, 'cwuser/admin')
   347         self.assertEqual(path, 'cwuser/admin')
   368         self.assertIn('_cwmsgid', params)
   348         self.assertIn('_cwmsgid', params)
   369         eid1 = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
   349         eid1 = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
   370         eid2 = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
   350         eid2 = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
   371         req = self.request()
   351         req = self.request()
   372         req.form = {'eid': [u(eid1), u(eid2)],
   352         req.form = {'eid': [u(eid1), u(eid2)],
   373                     '__type:%s'%eid1: 'BlogEntry',
   353                     '__type:%s'%eid1: 'BlogEntry',
   374                     '__type:%s'%eid2: 'EmailAddress',
   354                     '__type:%s'%eid2: 'EmailAddress',
   375                     '__action_delete': ''}
   355                     '__action_delete': ''}
   376         path, params = self.expect_redirect_publish(req, 'edit')
   356         path, params = self.expect_redirect_publish(req, 'edit')
   377         self.assertEquals(path, 'view')
   357         self.assertEqual(path, 'view')
   378         self.assertIn('_cwmsgid', params)
   358         self.assertIn('_cwmsgid', params)
   379 
   359 
   380     def test_nonregr_eetype_etype_editing(self):
   360     def test_nonregr_eetype_etype_editing(self):
   381         """non-regression test checking that a manager user can edit a CWEType entity
   361         """non-regression test checking that a manager user can edit a CWEType entity
   382         """
   362         """
   396             'read_permission-subject:'+cwetypeeid:  groups,
   376             'read_permission-subject:'+cwetypeeid:  groups,
   397             }
   377             }
   398         try:
   378         try:
   399             path, params = self.expect_redirect_publish(req, 'edit')
   379             path, params = self.expect_redirect_publish(req, 'edit')
   400             e = self.execute('Any X WHERE X eid %(x)s', {'x': cwetypeeid}).get_entity(0, 0)
   380             e = self.execute('Any X WHERE X eid %(x)s', {'x': cwetypeeid}).get_entity(0, 0)
   401             self.assertEquals(e.name, 'CWEType')
   381             self.assertEqual(e.name, 'CWEType')
   402             self.assertEquals(sorted(g.eid for g in e.read_permission), groupeids)
   382             self.assertEqual(sorted(g.eid for g in e.read_permission), groupeids)
   403         finally:
   383         finally:
   404             # restore
   384             # restore
   405             self.execute('SET X read_permission Y WHERE X name "CWEType", Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
   385             self.execute('SET X read_permission Y WHERE X name "CWEType", Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
   406             self.commit()
   386             self.commit()
   407 
   387 
   418             'content-subject:A': u'"13:03:43"',}
   398             'content-subject:A': u'"13:03:43"',}
   419         path, params = self.expect_redirect_publish(req, 'edit')
   399         path, params = self.expect_redirect_publish(req, 'edit')
   420         self.failUnless(path.startswith('blogentry/'))
   400         self.failUnless(path.startswith('blogentry/'))
   421         eid = path.split('/')[1]
   401         eid = path.split('/')[1]
   422         e = self.execute('Any C, T WHERE C eid %(x)s, C content T', {'x': eid}).get_entity(0, 0)
   402         e = self.execute('Any C, T WHERE C eid %(x)s, C content T', {'x': eid}).get_entity(0, 0)
   423         self.assertEquals(e.title, '"13:03:40"')
   403         self.assertEqual(e.title, '"13:03:40"')
   424         self.assertEquals(e.content, '"13:03:43"')
   404         self.assertEqual(e.content, '"13:03:43"')
   425 
   405 
   426 
   406 
   427     def test_nonregr_multiple_empty_email_addr(self):
   407     def test_nonregr_multiple_empty_email_addr(self):
   428         gueid = self.execute('CWGroup G WHERE G name "users"')[0][0]
   408         gueid = self.execute('CWGroup G WHERE G name "users"')[0][0]
   429         req = self.request()
   409         req = self.request()
   440                     'address-subject:Y': u'',
   420                     'address-subject:Y': u'',
   441                     'alias-subject:Y': u'',
   421                     'alias-subject:Y': u'',
   442                     'use_email-object:Y': 'X',
   422                     'use_email-object:Y': 'X',
   443                     }
   423                     }
   444         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
   424         ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
   445         self.assertEquals(ex.errors, {'address-subject': u'required field'})
   425         self.assertEqual(ex.errors, {'address-subject': u'required field'})
   446 
   426 
   447     def test_nonregr_copy(self):
   427     def test_nonregr_copy(self):
   448         user = self.user()
   428         user = self.user()
   449         req = self.request()
   429         req = self.request()
   450         req.form = {'__maineid' : 'X', 'eid': 'X',
   430         req.form = {'__maineid' : 'X', 'eid': 'X',
   452                     '_cw_edited_fields:X': 'login-subject,upassword-subject',
   432                     '_cw_edited_fields:X': 'login-subject,upassword-subject',
   453                     'login-subject:X': u'toto',
   433                     'login-subject:X': u'toto',
   454                     'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
   434                     'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
   455                     }
   435                     }
   456         path, params = self.expect_redirect_publish(req, 'edit')
   436         path, params = self.expect_redirect_publish(req, 'edit')
   457         self.assertEquals(path, 'cwuser/toto')
   437         self.assertEqual(path, 'cwuser/toto')
   458         e = self.execute('Any X WHERE X is CWUser, X login "toto"').get_entity(0, 0)
   438         e = self.execute('Any X WHERE X is CWUser, X login "toto"').get_entity(0, 0)
   459         self.assertEquals(e.login, 'toto')
   439         self.assertEqual(e.login, 'toto')
   460         self.assertEquals(e.in_group[0].name, 'managers')
   440         self.assertEqual(e.in_group[0].name, 'managers')
   461 
   441 
   462 
   442 
   463     def test_nonregr_rollback_on_validation_error(self):
   443     def test_nonregr_rollback_on_validation_error(self):
   464         p = self.create_user("doe")
   444         p = self.create_user("doe")
   465         # do not try to skip 'primary_email' for this test
   445         # do not try to skip 'primary_email' for this test
   487                 req = self.request()
   467                 req = self.request()
   488                 req.form['rql'] = 'Any X WHERE X eid %s' % p.eid
   468                 req.form['rql'] = 'Any X WHERE X eid %s' % p.eid
   489                 req.form['vid'] = 'copy'
   469                 req.form['vid'] = 'copy'
   490                 self.app_publish(req, 'view')
   470                 self.app_publish(req, 'view')
   491             rset = self.execute('CWUser P WHERE P surname "Boom"')
   471             rset = self.execute('CWUser P WHERE P surname "Boom"')
   492             self.assertEquals(len(rset), 0)
   472             self.assertEqual(len(rset), 0)
   493         finally:
   473         finally:
   494             p.__class__.skip_copy_for = old_skips
   474             p.__class__.skip_copy_for = old_skips
   495 
   475 
   496 
   476 
   497 class EmbedControllerTC(CubicWebTC):
   477 class EmbedControllerTC(CubicWebTC):
   559         self.failUnless(source.startswith('<div>'))
   539         self.failUnless(source.startswith('<div>'))
   560 
   540 
   561 #     def test_json_exec(self):
   541 #     def test_json_exec(self):
   562 #         rql = 'Any T,N WHERE T is Tag, T name N'
   542 #         rql = 'Any T,N WHERE T is Tag, T name N'
   563 #         ctrl = self.ctrl(self.request(mode='json', rql=rql, pageid='123'))
   543 #         ctrl = self.ctrl(self.request(mode='json', rql=rql, pageid='123'))
   564 #         self.assertEquals(ctrl.publish(),
   544 #         self.assertEqual(ctrl.publish(),
   565 #                           json.dumps(self.execute(rql).rows))
   545 #                           json_dumps(self.execute(rql).rows))
   566 
   546 
   567     def test_remote_add_existing_tag(self):
   547     def test_remote_add_existing_tag(self):
   568         self.remote_call('tag_entity', self.john.eid, ['python'])
   548         self.remote_call('tag_entity', self.john.eid, ['python'])
   569         self.assertUnorderedIterableEquals(
   549         self.assertItemsEqual(
   570             [tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
   550             [tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
   571             ['python', 'cubicweb'])
   551             ['python', 'cubicweb'])
   572         self.assertEquals(
   552         self.assertEqual(
   573             self.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
   553             self.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
   574             [['python']])
   554             [['python']])
   575 
   555 
   576     def test_remote_add_new_tag(self):
   556     def test_remote_add_new_tag(self):
   577         self.remote_call('tag_entity', self.john.eid, ['javascript'])
   557         self.remote_call('tag_entity', self.john.eid, ['javascript'])
   578         self.assertUnorderedIterableEquals(
   558         self.assertItemsEqual(
   579             [tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
   559             [tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
   580             ['python', 'cubicweb', 'javascript'])
   560             ['python', 'cubicweb', 'javascript'])
   581         self.assertEquals(
   561         self.assertEqual(
   582             self.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
   562             self.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
   583             [['javascript']])
   563             [['javascript']])
   584 
   564 
   585     def test_pending_insertion(self):
   565     def test_pending_insertion(self):
   586         res, req = self.remote_call('add_pending_inserts', [['12', 'tags', '13']])
   566         res, req = self.remote_call('add_pending_inserts', [['12', 'tags', '13']])
   587         deletes = get_pending_deletes(req)
   567         deletes = get_pending_deletes(req)
   588         self.assertEquals(deletes, [])
   568         self.assertEqual(deletes, [])
   589         inserts = get_pending_inserts(req)
   569         inserts = get_pending_inserts(req)
   590         self.assertEquals(inserts, ['12:tags:13'])
   570         self.assertEqual(inserts, ['12:tags:13'])
   591         res, req = self.remote_call('add_pending_inserts', [['12', 'tags', '14']])
   571         res, req = self.remote_call('add_pending_inserts', [['12', 'tags', '14']])
   592         deletes = get_pending_deletes(req)
   572         deletes = get_pending_deletes(req)
   593         self.assertEquals(deletes, [])
   573         self.assertEqual(deletes, [])
   594         inserts = get_pending_inserts(req)
   574         inserts = get_pending_inserts(req)
   595         self.assertEquals(inserts, ['12:tags:13', '12:tags:14'])
   575         self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
   596         inserts = get_pending_inserts(req, 12)
   576         inserts = get_pending_inserts(req, 12)
   597         self.assertEquals(inserts, ['12:tags:13', '12:tags:14'])
   577         self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
   598         inserts = get_pending_inserts(req, 13)
   578         inserts = get_pending_inserts(req, 13)
   599         self.assertEquals(inserts, ['12:tags:13'])
   579         self.assertEqual(inserts, ['12:tags:13'])
   600         inserts = get_pending_inserts(req, 14)
   580         inserts = get_pending_inserts(req, 14)
   601         self.assertEquals(inserts, ['12:tags:14'])
   581         self.assertEqual(inserts, ['12:tags:14'])
   602         req.remove_pending_operations()
   582         req.remove_pending_operations()
   603 
   583 
   604     def test_pending_deletion(self):
   584     def test_pending_deletion(self):
   605         res, req = self.remote_call('add_pending_delete', ['12', 'tags', '13'])
   585         res, req = self.remote_call('add_pending_delete', ['12', 'tags', '13'])
   606         inserts = get_pending_inserts(req)
   586         inserts = get_pending_inserts(req)
   607         self.assertEquals(inserts, [])
   587         self.assertEqual(inserts, [])
   608         deletes = get_pending_deletes(req)
   588         deletes = get_pending_deletes(req)
   609         self.assertEquals(deletes, ['12:tags:13'])
   589         self.assertEqual(deletes, ['12:tags:13'])
   610         res, req = self.remote_call('add_pending_delete', ['12', 'tags', '14'])
   590         res, req = self.remote_call('add_pending_delete', ['12', 'tags', '14'])
   611         inserts = get_pending_inserts(req)
   591         inserts = get_pending_inserts(req)
   612         self.assertEquals(inserts, [])
   592         self.assertEqual(inserts, [])
   613         deletes = get_pending_deletes(req)
   593         deletes = get_pending_deletes(req)
   614         self.assertEquals(deletes, ['12:tags:13', '12:tags:14'])
   594         self.assertEqual(deletes, ['12:tags:13', '12:tags:14'])
   615         deletes = get_pending_deletes(req, 12)
   595         deletes = get_pending_deletes(req, 12)
   616         self.assertEquals(deletes, ['12:tags:13', '12:tags:14'])
   596         self.assertEqual(deletes, ['12:tags:13', '12:tags:14'])
   617         deletes = get_pending_deletes(req, 13)
   597         deletes = get_pending_deletes(req, 13)
   618         self.assertEquals(deletes, ['12:tags:13'])
   598         self.assertEqual(deletes, ['12:tags:13'])
   619         deletes = get_pending_deletes(req, 14)
   599         deletes = get_pending_deletes(req, 14)
   620         self.assertEquals(deletes, ['12:tags:14'])
   600         self.assertEqual(deletes, ['12:tags:14'])
   621         req.remove_pending_operations()
   601         req.remove_pending_operations()
   622 
   602 
   623     def test_remove_pending_operations(self):
   603     def test_remove_pending_operations(self):
   624         self.remote_call('add_pending_delete', ['12', 'tags', '13'])
   604         self.remote_call('add_pending_delete', ['12', 'tags', '13'])
   625         _, req = self.remote_call('add_pending_inserts', [['12', 'tags', '14']])
   605         _, req = self.remote_call('add_pending_inserts', [['12', 'tags', '14']])
   626         inserts = get_pending_inserts(req)
   606         inserts = get_pending_inserts(req)
   627         self.assertEquals(inserts, ['12:tags:14'])
   607         self.assertEqual(inserts, ['12:tags:14'])
   628         deletes = get_pending_deletes(req)
   608         deletes = get_pending_deletes(req)
   629         self.assertEquals(deletes, ['12:tags:13'])
   609         self.assertEqual(deletes, ['12:tags:13'])
   630         req.remove_pending_operations()
   610         req.remove_pending_operations()
   631         self.assertEquals(get_pending_deletes(req), [])
   611         self.assertEqual(get_pending_deletes(req), [])
   632         self.assertEquals(get_pending_inserts(req), [])
   612         self.assertEqual(get_pending_inserts(req), [])
   633 
   613 
   634 
   614 
   635     def test_add_inserts(self):
   615     def test_add_inserts(self):
   636         res, req = self.remote_call('add_pending_inserts',
   616         res, req = self.remote_call('add_pending_inserts',
   637                                     [('12', 'tags', '13'), ('12', 'tags', '14')])
   617                                     [('12', 'tags', '13'), ('12', 'tags', '14')])
   638         inserts = get_pending_inserts(req)
   618         inserts = get_pending_inserts(req)
   639         self.assertEquals(inserts, ['12:tags:13', '12:tags:14'])
   619         self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
   640         req.remove_pending_operations()
   620         req.remove_pending_operations()
   641 
   621 
   642 
   622 
   643     # silly tests
   623     # silly tests
   644     def test_external_resource(self):
   624     def test_external_resource(self):
   645         self.assertEquals(self.remote_call('external_resource', 'RSS_LOGO')[0],
   625         self.assertEqual(self.remote_call('external_resource', 'RSS_LOGO')[0],
   646                           json.dumps(self.request().external_resource('RSS_LOGO')))
   626                           json_dumps(self.config.uiprops['RSS_LOGO']))
   647     def test_i18n(self):
   627     def test_i18n(self):
   648         self.assertEquals(self.remote_call('i18n', ['bimboom'])[0],
   628         self.assertEqual(self.remote_call('i18n', ['bimboom'])[0],
   649                           json.dumps(['bimboom']))
   629                           json_dumps(['bimboom']))
   650 
   630 
   651     def test_format_date(self):
   631     def test_format_date(self):
   652         self.assertEquals(self.remote_call('format_date', '2007-01-01 12:00:00')[0],
   632         self.assertEqual(self.remote_call('format_date', '2007-01-01 12:00:00')[0],
   653                           json.dumps('2007/01/01'))
   633                           json_dumps('2007/01/01'))
   654 
   634 
   655 
   635 
   656 
   636 
   657 
   637 
   658 if __name__ == '__main__':
   638 if __name__ == '__main__':