web/test/unittest_application.py
changeset 9641 4147cc32371d
parent 9478 2d7521881d3d
child 9642 9a42eaeea263
equal deleted inserted replaced
9640:26ea1c4387bf 9641:4147cc32371d
   165             config = super(ApplicationTC, cls).config
   165             config = super(ApplicationTC, cls).config
   166             config.global_set_option('allow-email-login', True)
   166             config.global_set_option('allow-email-login', True)
   167             return config
   167             return config
   168 
   168 
   169     def test_cnx_user_groups_sync(self):
   169     def test_cnx_user_groups_sync(self):
   170         user = self.user()
   170         with self.admin_access.client_cnx() as cnx:
   171         self.assertEqual(user.groups, set(('managers',)))
   171             user = cnx.user
   172         self.execute('SET X in_group G WHERE X eid %s, G name "guests"' % user.eid)
   172             self.assertEqual(user.groups, set(('managers',)))
   173         user = self.user()
   173             cnx.execute('SET X in_group G WHERE X eid %s, G name "guests"' % user.eid)
   174         self.assertEqual(user.groups, set(('managers',)))
   174             user = cnx.user
   175         self.commit()
   175             self.assertEqual(user.groups, set(('managers',)))
   176         user = self.user()
   176             cnx.commit()
   177         self.assertEqual(user.groups, set(('managers', 'guests')))
   177             user = cnx.user
   178         # cleanup
   178             self.assertEqual(user.groups, set(('managers', 'guests')))
   179         self.execute('DELETE X in_group G WHERE X eid %s, G name "guests"' % user.eid)
   179             # cleanup
   180         self.commit()
   180             cnx.execute('DELETE X in_group G WHERE X eid %s, G name "guests"' % user.eid)
       
   181             cnx.commit()
   181 
   182 
   182     def test_publish_validation_error(self):
   183     def test_publish_validation_error(self):
   183         req = self.request()
   184         with self.admin_access.web_request() as req:
   184         user = self.user()
   185             user = self.user()
   185         eid = unicode(user.eid)
   186             eid = unicode(user.eid)
   186         req.form = {
   187             req.form = {
   187             'eid':       eid,
   188                 'eid':       eid,
   188             '__type:'+eid:    'CWUser', '_cw_entity_fields:'+eid: 'login-subject',
   189                 '__type:'+eid:    'CWUser', '_cw_entity_fields:'+eid: 'login-subject',
   189             'login-subject:'+eid:     '', # ERROR: no login specified
   190                 'login-subject:'+eid:     '', # ERROR: no login specified
   190              # just a sample, missing some necessary information for real life
   191                  # just a sample, missing some necessary information for real life
   191             '__errorurl': 'view?vid=edition...'
   192                 '__errorurl': 'view?vid=edition...'
   192             }
   193                 }
   193         path, params = self.expect_redirect_handle_request(req, 'edit')
   194             path, params = self.expect_redirect_handle_request(req, 'edit')
   194         forminfo = req.session.data['view?vid=edition...']
   195             forminfo = req.session.data['view?vid=edition...']
   195         eidmap = forminfo['eidmap']
   196             eidmap = forminfo['eidmap']
   196         self.assertEqual(eidmap, {})
   197             self.assertEqual(eidmap, {})
   197         values = forminfo['values']
   198             values = forminfo['values']
   198         self.assertEqual(values['login-subject:'+eid], '')
   199             self.assertEqual(values['login-subject:'+eid], '')
   199         self.assertEqual(values['eid'], eid)
   200             self.assertEqual(values['eid'], eid)
   200         error = forminfo['error']
   201             error = forminfo['error']
   201         self.assertEqual(error.entity, user.eid)
   202             self.assertEqual(error.entity, user.eid)
   202         self.assertEqual(error.errors['login-subject'], 'required field')
   203             self.assertEqual(error.errors['login-subject'], 'required field')
   203 
   204 
   204 
   205 
   205     def test_validation_error_dont_loose_subentity_data_ctrl(self):
   206     def test_validation_error_dont_loose_subentity_data_ctrl(self):
   206         """test creation of two linked entities
   207         """test creation of two linked entities
   207 
   208 
   208         error occurs on the web controller
   209         error occurs on the web controller
   209         """
   210         """
   210         req = self.request()
   211         with self.admin_access.web_request() as req:
   211         # set Y before X to ensure both entities are edited, not only X
   212             # set Y before X to ensure both entities are edited, not only X
   212         req.form = {'eid': ['Y', 'X'], '__maineid': 'X',
   213             req.form = {'eid': ['Y', 'X'], '__maineid': 'X',
   213                     '__type:X': 'CWUser', '_cw_entity_fields:X': 'login-subject',
   214                         '__type:X': 'CWUser', '_cw_entity_fields:X': 'login-subject',
   214                     # missing required field
   215                         # missing required field
   215                     'login-subject:X': u'',
   216                         'login-subject:X': u'',
   216                     # but email address is set
   217                         # but email address is set
   217                     '__type:Y': 'EmailAddress', '_cw_entity_fields:Y': 'address-subject',
   218                         '__type:Y': 'EmailAddress', '_cw_entity_fields:Y': 'address-subject',
   218                     'address-subject:Y': u'bougloup@logilab.fr',
   219                         'address-subject:Y': u'bougloup@logilab.fr',
   219                     'use_email-object:Y': 'X',
   220                         'use_email-object:Y': 'X',
   220                     # necessary to get validation error handling
   221                         # necessary to get validation error handling
   221                     '__errorurl': 'view?vid=edition...',
   222                         '__errorurl': 'view?vid=edition...',
   222                     }
   223                         }
   223         path, params = self.expect_redirect_handle_request(req, 'edit')
   224             path, params = self.expect_redirect_handle_request(req, 'edit')
   224         forminfo = req.session.data['view?vid=edition...']
   225             forminfo = req.session.data['view?vid=edition...']
   225         self.assertEqual(set(forminfo['eidmap']), set('XY'))
   226             self.assertEqual(set(forminfo['eidmap']), set('XY'))
   226         self.assertEqual(forminfo['eidmap']['X'], None)
   227             self.assertEqual(forminfo['eidmap']['X'], None)
   227         self.assertIsInstance(forminfo['eidmap']['Y'], int)
   228             self.assertIsInstance(forminfo['eidmap']['Y'], int)
   228         self.assertEqual(forminfo['error'].entity, 'X')
   229             self.assertEqual(forminfo['error'].entity, 'X')
   229         self.assertEqual(forminfo['error'].errors,
   230             self.assertEqual(forminfo['error'].errors,
   230                           {'login-subject': 'required field'})
   231                               {'login-subject': 'required field'})
   231         self.assertEqual(forminfo['values'], req.form)
   232             self.assertEqual(forminfo['values'], req.form)
   232 
   233 
   233 
   234 
   234     def test_validation_error_dont_loose_subentity_data_repo(self):
   235     def test_validation_error_dont_loose_subentity_data_repo(self):
   235         """test creation of two linked entities
   236         """test creation of two linked entities
   236 
   237 
   237         error occurs on the repository
   238         error occurs on the repository
   238         """
   239         """
   239         req = self.request()
   240         with self.admin_access.web_request() as req:
   240         # set Y before X to ensure both entities are edited, not only X
   241             # set Y before X to ensure both entities are edited, not only X
   241         req.form = {'eid': ['Y', 'X'], '__maineid': 'X',
   242             req.form = {'eid': ['Y', 'X'], '__maineid': 'X',
   242                     '__type:X': 'CWUser', '_cw_entity_fields:X': 'login-subject,upassword-subject',
   243                         '__type:X': 'CWUser', '_cw_entity_fields:X': 'login-subject,upassword-subject',
   243                     # already existent user
   244                         # already existent user
   244                     'login-subject:X': u'admin',
   245                         'login-subject:X': u'admin',
   245                     'upassword-subject:X': u'admin', 'upassword-subject-confirm:X': u'admin',
   246                         'upassword-subject:X': u'admin', 'upassword-subject-confirm:X': u'admin',
   246                     '__type:Y': 'EmailAddress', '_cw_entity_fields:Y': 'address-subject',
   247                         '__type:Y': 'EmailAddress', '_cw_entity_fields:Y': 'address-subject',
   247                     'address-subject:Y': u'bougloup@logilab.fr',
   248                         'address-subject:Y': u'bougloup@logilab.fr',
   248                     'use_email-object:Y': 'X',
   249                         'use_email-object:Y': 'X',
   249                     # necessary to get validation error handling
   250                         # necessary to get validation error handling
   250                     '__errorurl': 'view?vid=edition...',
   251                         '__errorurl': 'view?vid=edition...',
   251                     }
   252                         }
   252         path, params = self.expect_redirect_handle_request(req, 'edit')
   253             path, params = self.expect_redirect_handle_request(req, 'edit')
   253         forminfo = req.session.data['view?vid=edition...']
   254             forminfo = req.session.data['view?vid=edition...']
   254         self.assertEqual(set(forminfo['eidmap']), set('XY'))
   255             self.assertEqual(set(forminfo['eidmap']), set('XY'))
   255         self.assertIsInstance(forminfo['eidmap']['X'], int)
   256             self.assertIsInstance(forminfo['eidmap']['X'], int)
   256         self.assertIsInstance(forminfo['eidmap']['Y'], int)
   257             self.assertIsInstance(forminfo['eidmap']['Y'], int)
   257         self.assertEqual(forminfo['error'].entity, forminfo['eidmap']['X'])
   258             self.assertEqual(forminfo['error'].entity, forminfo['eidmap']['X'])
   258         self.assertEqual(forminfo['error'].errors,
   259             self.assertEqual(forminfo['error'].errors,
   259                           {'login-subject': u'the value "admin" is already used, use another one'})
   260                               {'login-subject': u'the value "admin" is already used, use another one'})
   260         self.assertEqual(forminfo['values'], req.form)
   261             self.assertEqual(forminfo['values'], req.form)
   261 
   262 
   262     def test_ajax_view_raise_arbitrary_error(self):
   263     def test_ajax_view_raise_arbitrary_error(self):
   263         class ErrorAjaxView(view.View):
   264         class ErrorAjaxView(view.View):
   264             __regid__ = 'test.ajax.error'
   265             __regid__ = 'test.ajax.error'
   265             def call(self):
   266             def call(self):
   266                 raise Exception('whatever')
   267                 raise Exception('whatever')
   267         with self.temporary_appobjects(ErrorAjaxView):
   268         with self.temporary_appobjects(ErrorAjaxView):
   268             with real_error_handling(self.app) as app:
   269             with real_error_handling(self.app) as app:
   269                 req = self.request(vid='test.ajax.error')
   270                 with self.admin_access.web_request(vid='test.ajax.error') as req:
   270                 req.ajax_request = True
   271                     req.ajax_request = True
   271                 page = app.handle_request(req, '')
   272                     page = app.handle_request(req, '')
   272         self.assertEqual(httplib.INTERNAL_SERVER_ERROR,
   273         self.assertEqual(httplib.INTERNAL_SERVER_ERROR,
   273                          req.status_out)
   274                          req.status_out)
   274 
   275 
   275     def _test_cleaned(self, kwargs, injected, cleaned):
   276     def _test_cleaned(self, kwargs, injected, cleaned):
   276         req = self.request(**kwargs)
   277         with self.admin_access.web_request(**kwargs) as req:
   277         page = self.app_handle_request(req, 'view')
   278             page = self.app_handle_request(req, 'view')
   278         self.assertNotIn(injected, page)
   279             self.assertNotIn(injected, page)
   279         self.assertIn(cleaned, page)
   280             self.assertIn(cleaned, page)
   280 
   281 
   281     def test_nonregr_script_kiddies(self):
   282     def test_nonregr_script_kiddies(self):
   282         """test against current script injection"""
   283         """test against current script injection"""
   283         injected = '<i>toto</i>'
   284         injected = '<i>toto</i>'
   284         cleaned = 'toto'
   285         cleaned = 'toto'
   293         # in which case we need a kindof repo -> http server notification
   294         # in which case we need a kindof repo -> http server notification
   294         # protocol
   295         # protocol
   295         vreg = self.app.vreg
   296         vreg = self.app.vreg
   296         # default value
   297         # default value
   297         self.assertEqual(vreg.property_value('ui.language'), 'en')
   298         self.assertEqual(vreg.property_value('ui.language'), 'en')
   298         self.execute('INSERT CWProperty X: X value "fr", X pkey "ui.language"')
   299         with self.admin_access.client_cnx() as cnx:
   299         self.assertEqual(vreg.property_value('ui.language'), 'en')
   300             cnx.execute('INSERT CWProperty X: X value "fr", X pkey "ui.language"')
   300         self.commit()
   301             self.assertEqual(vreg.property_value('ui.language'), 'en')
   301         self.assertEqual(vreg.property_value('ui.language'), 'fr')
   302             cnx.commit()
   302         self.execute('SET X value "de" WHERE X pkey "ui.language"')
   303             self.assertEqual(vreg.property_value('ui.language'), 'fr')
   303         self.assertEqual(vreg.property_value('ui.language'), 'fr')
   304             cnx.execute('SET X value "de" WHERE X pkey "ui.language"')
   304         self.commit()
   305             self.assertEqual(vreg.property_value('ui.language'), 'fr')
   305         self.assertEqual(vreg.property_value('ui.language'), 'de')
   306             cnx.commit()
   306         self.execute('DELETE CWProperty X WHERE X pkey "ui.language"')
   307             self.assertEqual(vreg.property_value('ui.language'), 'de')
   307         self.assertEqual(vreg.property_value('ui.language'), 'de')
   308             cnx.execute('DELETE CWProperty X WHERE X pkey "ui.language"')
   308         self.commit()
   309             self.assertEqual(vreg.property_value('ui.language'), 'de')
   309         self.assertEqual(vreg.property_value('ui.language'), 'en')
   310             cnx.commit()
       
   311             self.assertEqual(vreg.property_value('ui.language'), 'en')
   310 
   312 
   311     # authentication tests ####################################################
   313     # authentication tests ####################################################
   312 
   314 
   313     def test_http_auth_no_anon(self):
   315     def test_http_auth_no_anon(self):
   314         req, origsession = self.init_authentication('http')
   316         req, origsession = self.init_authentication('http')
   338         self.assertAuthSuccess(req, origsession)
   340         self.assertAuthSuccess(req, origsession)
   339         self.assertRaises(LogOut, self.app_handle_request, req, 'logout')
   341         self.assertRaises(LogOut, self.app_handle_request, req, 'logout')
   340         self.assertEqual(len(self.open_sessions), 0)
   342         self.assertEqual(len(self.open_sessions), 0)
   341 
   343 
   342     def test_login_by_email(self):
   344     def test_login_by_email(self):
   343         login = self.request().user.login
   345         with self.admin_access.client_cnx() as cnx:
   344         address = login + u'@localhost'
   346             login = cnx.user.login
   345         self.execute('INSERT EmailAddress X: X address %(address)s, U primary_email X '
   347             address = login + u'@localhost'
   346                      'WHERE U login %(login)s', {'address': address, 'login': login})
   348             cnx.execute('INSERT EmailAddress X: X address %(address)s, U primary_email X '
   347         self.commit()
   349                         'WHERE U login %(login)s', {'address': address, 'login': login})
       
   350             cnx.commit()
   348         # # option allow-email-login not set
   351         # # option allow-email-login not set
   349         req, origsession = self.init_authentication('cookie')
   352         req, origsession = self.init_authentication('cookie')
   350         # req.form['__login'] = address
   353         # req.form['__login'] = address
   351         # req.form['__password'] = self.admpassword
   354         # req.form['__password'] = self.admpassword
   352         # self.assertAuthFailure(req)
   355         # self.assertAuthFailure(req)
   415         self.assertAuthSuccess(req, origsession)
   418         self.assertAuthSuccess(req, origsession)
   416         self.assertRaises(LogOut, self.app_handle_request, req, 'logout')
   419         self.assertRaises(LogOut, self.app_handle_request, req, 'logout')
   417         self.assertEqual(0, len(self.open_sessions))
   420         self.assertEqual(0, len(self.open_sessions))
   418 
   421 
   419     def test_anonymized_request(self):
   422     def test_anonymized_request(self):
   420         req = self.request()
   423         with self.admin_access.web_request() as req:
   421         self.assertEqual(self.admlogin, req.session.user.login)
   424             self.assertEqual(self.admlogin, req.session.user.login)
   422         # admin should see anon + admin
   425             # admin should see anon + admin
   423         self.assertEqual(2, len(list(req.find_entities('CWUser'))))
   426             self.assertEqual(2, len(list(req.find_entities('CWUser'))))
   424         with anonymized_request(req):
   427             with anonymized_request(req):
   425             self.assertEqual('anon', req.session.login, 'anon')
   428                 self.assertEqual('anon', req.session.login, 'anon')
   426             # anon should only see anon user
   429                 # anon should only see anon user
   427             self.assertEqual(1, len(list(req.find_entities('CWUser'))))
   430                 self.assertEqual(1, len(list(req.find_entities('CWUser'))))
   428         self.assertEqual(self.admlogin, req.session.login)
   431             self.assertEqual(self.admlogin, req.session.login)
   429         self.assertEqual(2, len(list(req.find_entities('CWUser'))))
   432             self.assertEqual(2, len(list(req.find_entities('CWUser'))))
   430 
   433 
   431     def test_non_regr_optional_first_var(self):
   434     def test_non_regr_optional_first_var(self):
   432         req = self.request()
   435         with self.admin_access.web_request() as req:
   433         # expect a rset with None in [0][0]
   436             # expect a rset with None in [0][0]
   434         req.form['rql'] = 'rql:Any OV1, X WHERE X custom_workflow OV1?'
   437             req.form['rql'] = 'rql:Any OV1, X WHERE X custom_workflow OV1?'
   435         self.app_handle_request(req)
   438             self.app_handle_request(req)
   436 
   439 
   437 
   440 
   438 if __name__ == '__main__':
   441 if __name__ == '__main__':
   439     unittest_main()
   442     unittest_main()