Ticket #1762: webtest_blended.patch
| File webtest_blended.patch, 141.7 kB (added by kskuhlman, 4 months ago) |
|---|
-
setup.py
old new 46 46 47 47 testtools = [ 48 48 "nose >= 0.9.3, <= 0.10.0a1", 49 "WebTest", 49 50 ] 50 51 51 52 tgtesttools = [ 52 53 "nose >= 0.9.3, <= 0.10.0a1", 54 "WebTest", 53 55 ] 54 56 55 57 # python 2.5 compatible list -
turbogears/identity/tests/test_identity.py
old new 55 55 56 56 @expose() 57 57 def index(self): 58 pass58 return dict() 59 59 60 60 @expose() 61 61 def identity_failed(self, **kw): … … 69 69 @expose() 70 70 @identity.require(in_group('peon')) 71 71 def in_peon_group(self): 72 user = TG_User.by_user_name("samIam") 73 group_ids = set((TG_Group.by_group_name("peon").id, 74 TG_Group.by_group_name("other").id)) 75 assert identity.current.user == user 76 assert identity.current.user_name == user.user_name 77 assert identity.current.user_id == user.id 78 assert identity.current.groups == set(('peon', 'other')) 79 assert identity.current.group_ids == group_ids 80 assert "samIam" == cherrypy.serving.request.identity.user_name 81 72 82 return 'in_peon_group' 73 83 74 84 @expose() … … 136 146 return 'wrong params: %s\nexpected unicode objects' \ 137 147 ' for all strings' % cherrypy.request.params 138 148 149 @expose() 150 def is_anonymous(self): 151 assert cherrypy.serving.request.identity.user_name == None 152 assert cherrypy.serving.request.identity.anonymous 153 assert identity.current.anonymous 154 return 'is_anonymous' 139 155 140 class TestIdentity(unittest.TestCase):141 156 157 158 class TestIdentity(testutil.TGWebTest): 159 142 160 def setUp(self): 143 161 # identity requires visit and a failure_url 144 162 test_config = {'global': { … … 151 169 self._original_config = original_config 152 170 config.configure_loggers(test_config) 153 171 config.update(test_config['global']) 154 cherrypy.root = IdentityRoot()155 startup.startTurboGears()172 testutil.mount(IdentityRoot()) 173 testutil.TGWebTest.setUp(self) 156 174 self.init_model() 157 175 158 176 def tearDown(self): 159 startup.stopTurboGears() 177 testutil.unmount() 178 testutil.TGWebTest.tearDown(self) 160 179 config.update(self._original_config) 161 180 162 181 def init_model(self): … … 181 200 182 201 def test_user_password_parameters(self): 183 202 """Controller can receive user_name and password parameters.""" 184 testutil.create_request('/new_user_setup?user_name=test&password=pw') 185 firstline = cherrypy.response.body[0] 186 assert 'test pw' in firstline, firstline 203 response = self.app.get('/new_user_setup?user_name=test&password=pw') 204 assert 'test pw' in response 187 205 188 206 def test_user_exists(self): 189 207 u = TG_User.by_user_name('samIam') … … 205 223 config.update({'identity.soprovider.encryption_algorithm': None}) 206 224 # force new config values to load 207 225 startup.startTurboGears() 208 testutil.create_request('/')226 self.app.get('/') 209 227 hub.begin() 210 228 u = TG_User.by_user_name('samIam') 211 229 u.password = u'garçon' … … 219 237 config.update({'identity.soprovider.encryption_algorithm': 'sha1'}) 220 238 # force new config values to load 221 239 startup.startTurboGears() 222 testutil.create_request('/')240 self.app.get('/') 223 241 hub.begin() 224 242 u = TG_User.by_user_name('samIam') 225 243 u.password = 'password' … … 234 252 config.update({'identity.soprovider.encryption_algorithm': 'sha1'}) 235 253 # force new config values to load 236 254 startup.startTurboGears() 237 testutil.create_request('/')255 self.app.get('/') 238 256 hub.begin() 239 257 u = TG_User.by_user_name('samIam') 240 258 u.password = u'garçon' … … 248 266 config.update({'identity.soprovider.encryption_algorithm': 'md5'}) 249 267 # force new config values to load 250 268 startup.startTurboGears() 251 testutil.create_request('/')269 self.app.get('/') 252 270 hub.begin() 253 271 u = TG_User.by_user_name('samIam') 254 272 u.password = 'password' … … 263 281 config.update({'identity.soprovider.encryption_algorithm': 'md5'}) 264 282 # force new config values to load 265 283 startup.startTurboGears() 266 testutil.create_request('/')284 self.app.get('/') 267 285 hub.begin() 268 286 u = TG_User.by_user_name('samIam') 269 287 u.password = u'garçon' … … 280 298 config.update({'identity.soprovider.encryption_algorithm': 'md5'}) 281 299 # force new config values to load 282 300 startup.startTurboGears() 283 testutil.create_request('/')301 self.app.get('/') 284 302 hub.begin() 285 303 u = TG_User.by_user_name('samIam') 286 304 u.password = u'garçon'.encode('UTF-8') … … 295 313 config.update({'identity.soprovider.encryption_algorithm':'sha1'}) 296 314 # force new config values to load 297 315 startup.startTurboGears() 298 testutil.create_request('/')316 self.app.get('/') 299 317 hub.begin() 300 318 u = TG_User.by_user_name('samIam') 301 319 u.set_password_raw('password') … … 308 326 config.update({'identity.soprovider.encryption_algorithm':'sha1'}) 309 327 # force new config values to load 310 328 startup.startTurboGears() 311 testutil.create_request('/')329 self.app.get('/') 312 330 hub.begin() 313 331 u = TG_User.by_user_name('samIam') 314 332 u.set_password_raw(u'garçon') … … 324 342 'identity.tests.test_identity.mycustomencrypt'}) 325 343 # force new config values to load 326 344 startup.startTurboGears() 327 testutil.create_request('/')345 self.app.get('/') 328 346 hub.begin() 329 347 u = TG_User.by_user_name('samIam') 330 348 u.password = 'password' … … 335 353 336 354 def test_anonymous_browsing(self): 337 355 """Test if we can show up anonymously.""" 338 testutil.create_request('/')339 assert identity.current.anonymous356 response = self.app.get('/is_anonymous') 357 assert 'is_anonymous' in response 340 358 341 359 def test_deny_anonymous(self): 342 360 """Test that we have secured an url from anonymous users.""" 343 testutil.create_request('/logged_in_only') 344 firstline = cherrypy.response.body[0] 345 assert 'identity_failed_answer' in firstline, firstline 361 response = self.app.get('/logged_in_only') 362 assert 'identity_failed_answer' in response 346 363 347 364 def test_deny_anonymous_viewable(self): 348 365 """Test that a logged in user can see an resource blocked 349 366 from anonymous users.""" 350 testutil.create_request('/logged_in_only?'367 response = self.app.get('/logged_in_only?' 351 368 'user_name=samIam&password=secret&login=Login') 352 firstline = cherrypy.response.body[0] 353 assert 'logged_in_only' in firstline, firstline 369 assert 'logged_in_only' in response 354 370 355 371 def test_logout(self): 356 372 """Test that logout works and session is gets invalid afterwards.""" 357 testutil.create_request('/in_peon_group?'373 response = self.app.get('/in_peon_group?' 358 374 'user_name=samIam&password=secret&login=Login') 359 self.assertEquals("samIam", cherrypy.serving.request.identity.user_name) 360 session_id = re.match("Set-Cookie: (.*?); Path.*", 361 str(cherrypy.response.simple_cookie)).group(1) 362 testutil.create_request('/logout', headers={'Cookie': session_id }) 363 self.assertEquals(None, cherrypy.serving.request.identity.user_name) 364 assert cherrypy.serving.request.identity.anonymous 375 session_id = response.headers['Set-Cookie'] 376 response = self.app.get('/logout', headers={'Cookie': session_id }) 377 response = self.app.get('/is_anonymous', headers={'Cookie': session_id}) 378 assert response.body == 'is_anonymous' 365 379 366 def test_logout_with_set_identity(self):367 """Test that logout works even when there is no visit_key368 (e.g. when testutils.set_identity_user is used)."""369 request = testutil.DummyRequest()370 old_user = testutil.test_user371 user = TG_User.by_user_name("samIam")372 testutil.set_identity_user(user)373 testutil.attach_identity(request)374 testutil.set_identity_user(old_user)375 testutil.call_with_request(cherrypy.root.logout, request)376 assert request.identity.anonymous377 378 380 def test_require_group(self): 379 381 """Test that a anonymous user""" 380 testutil.create_request('/in_peon_group') 381 firstline = cherrypy.response.body[0] 382 assert 'identity_failed_answer' in firstline, firstline 382 response = self.app.get('/in_peon_group') 383 assert 'identity_failed_answer' in response, response 383 384 384 385 def test_require_expose_required_permission(self): 385 386 """Test that the decorator exposes the correct permissions via _require 386 387 attribute on the actual method.""" 387 testutil.create_request('/test_exposed_require') 388 firstline= cherrypy.response.body[0] 389 assert 'require is exposed' in firstline, firstline 388 response = self.app.get('/test_exposed_require') 389 assert 'require is exposed' in response, response 390 390 391 391 def test_require_group_viewable(self): 392 392 """Test that a user with proper group membership can see a restricted url.""" 393 testutil.create_request('/in_peon_group?'393 response = self.app.get('/in_peon_group?' 394 394 'user_name=samIam&password=secret&login=Login') 395 firstline = cherrypy.response.body[0] 396 assert 'in_peon_group' in firstline, firstline 395 assert 'in_peon_group' in response, response 397 396 user = TG_User.by_user_name("samIam") 398 397 399 398 def test_require_group_viewable(self): 400 399 """Test that the current user and group properties are set correctly.""" 401 testutil.create_request('/in_peon_group?'400 response = self.app.get('/in_peon_group?' 402 401 'user_name=samIam&password=secret&login=Login') 403 402 user = TG_User.by_user_name("samIam") 404 403 group_ids = set((TG_Group.by_group_name("peon").id, 405 404 TG_Group.by_group_name("other").id)) 406 assert identity.current.user == user407 assert identity.current.user_name == user.user_name408 assert identity.current.user_id == user.id409 assert identity.current.groups == set(('peon', 'other'))410 assert identity.current.group_ids == group_ids411 405 412 406 def test_user_not_in_right_group(self): 413 """Test that a user is denied access if they aren't in the right group.""" 414 testutil.create_request('/in_admin_group?' 407 """Test that a user is denied access if they aren't in the right group. 408 """ 409 response = self.app.get('/in_admin_group?' 415 410 'user_name=samIam&password=secret&login=Login') 416 firstline = cherrypy.response.body[0] 417 assert 'identity_failed_answer' in firstline, firstline 411 assert 'identity_failed_answer' in response, response 418 412 419 413 def test_require_permission(self): 420 """Test that an anonymous user is denied access to a permission restricted url.""" 421 testutil.create_request('/has_chopper_permission') 422 firstline = cherrypy.response.body[0] 423 assert 'identity_failed_answer' in firstline, firstline 414 """Test that an anonymous user is denied access to a permission 415 restricted url. 416 """ 417 response = self.app.get('/has_chopper_permission') 418 assert 'identity_failed_answer' in response, response 424 419 425 420 def test_require_permission_viewable(self): 426 421 """Test that a user with proper permissions can see a restricted url.""" 427 testutil.create_request('/has_chopper_permission?'422 response = self.app.get('/has_chopper_permission?' 428 423 'user_name=samIam&password=secret&login=Login') 429 firstline = cherrypy.response.body[0] 430 assert 'has_chopper_permission' in firstline, firstline 424 assert 'has_chopper_permission' in response 431 425 432 426 def test_user_lacks_permission(self): 433 """Test that a user is denied acces if they don't have the proper permission.""" 434 testutil.create_request('/has_boss_permission?' 427 """Test that a user is denied acces if they don't have the proper 428 permission. 429 """ 430 response = self.app.get('/has_boss_permission?' 435 431 'user_name=samIam&password=secret&login=Login') 436 firstline = cherrypy.response.body[0] 437 assert 'identity_failed_answer' in firstline, firstline 432 assert 'identity_failed_answer' in response, response 438 433 439 434 def test_user_info_available(self): 440 435 """Test that we can see user information inside our controller.""" 441 testutil.create_request('/user_email?'436 response = self.app.get('/user_email?' 442 437 'user_name=samIam&password=secret&login=Login') 443 firstline = cherrypy.response.body[0] 444 assert 'samiam@example.com' in firstline, firstline 438 assert 'samiam@example.com' in response, response 445 439 446 440 def test_bad_login(self): 447 441 """Test that we are denied access if we provide a bad login.""" 448 testutil.create_request('/logged_in_only?'442 response = self.app.get('/logged_in_only?' 449 443 'user_name=samIam&password=wrong&login=Login') 450 firstline = cherrypy.response.body[0] 451 assert 'identity_failed_answer' in firstline, firstline 444 assert 'identity_failed_answer' in response, response 452 445 453 446 def test_restricted_subdirectory(self): 454 447 """Test that we can restrict access to a whole subdirectory.""" 455 testutil.create_request('/peon_area/index') 456 firstline = cherrypy.response.body[0] 457 assert 'identity_failed_answer' in firstline, firstline 448 response = self.app.get('/peon_area/index') 449 assert 'identity_failed_answer' in response, response 458 450 459 451 def test_restricted_subdirectory_viewable(self): 460 452 """Test that we can access a restricted subdirectory 461 453 if we have proper credentials.""" 462 testutil.create_request('/peon_area/index?'454 response = self.app.get('/peon_area/index?' 463 455 'user_name=samIam&password=secret&login=Login') 464 firstline = cherrypy.response.body[0] 465 assert 'restricted_index' in firstline, firstline 456 assert 'restricted_index' in response, response 466 457 467 458 def test_decoratator_in_restricted_subdirectory(self): 468 459 """Test that we can require a different permission 469 460 in a protected subdirectory.""" 470 testutil.create_request('/peon_area/in_other_group?'461 response = self.app.get('/peon_area/in_other_group?' 471 462 'user_name=samIam&password=secret&login=Login') 472 firstline = cherrypy.response.body[0] 473 assert 'in_other_group' in firstline, firstline 463 assert 'in_other_group' in response, response 474 464 475 465 def test_decoratator_failure_in_restricted_subdirectory(self): 476 466 """Test that we can get an identity failure from a decorator 477 467 in a restricted subdirectory""" 478 testutil.create_request('/peon_area/in_admin_group?'468 response = self.app.get('/peon_area/in_admin_group?' 479 469 'user_name=samIam&password=secret&login=Login') 480 firstline = cherrypy.response.body[0] 481 assert 'identity_failed_answer' in firstline, firstline 470 assert 'identity_failed_answer' in response, response 482 471 483 472 def test_explicit_checks_in_restricted_subdirectory(self): 484 473 """Test that explicit permission checks in a protected 485 474 directory is handled as expected""" 486 testutil.create_request('/peon_area/in_other_group_explicit_check?'475 response = self.app.get('/peon_area/in_other_group_explicit_check?' 487 476 'user_name=samIam&password=secret&login=Login') 488 firstline = cherrypy.response.body[0] 489 assert 'in_other_group' in firstline, firstline 477 assert 'in_other_group' in response, response 490 478 491 479 def test_throwing_identity_exception_in_restricted_subdirectory(self): 492 480 """Test that throwing an IdentityException in a protected 493 481 directory is handled as expected""" 494 testutil.create_request('/peon_area/in_admin_group_explicit_check?'482 response = self.app.get('/peon_area/in_admin_group_explicit_check?' 495 483 'user_name=samIam&password=secret&login=Login') 496 firstline = cherrypy.response.body[0] 497 assert 'identity_failed' in firstline, firstline 484 assert 'identity_failed' in response, response 498 485 499 486 def test_decode_filter_whenidfails(self): 500 487 """Test that the decode filter doesn't break with nested 501 488 variables and Identity""" 502 489 params = urllib.quote(IdentityRoot._test_encoded_params.decode( 503 490 'utf-8').encode('latin-1'), '=&') 504 testutil.create_request('/test_params?' + params) 505 firstline = cherrypy.response.body[0] 506 assert 'identity_failed_answer' in firstline, firstline 491 response = self.app.get('/test_params?' + params) 492 assert 'identity_failed_answer' in response, response 507 493 508 494 def test_decode_filter_whenidworks(self): 509 495 """Test that the decode filter doesn't break with nested … … 511 497 params = urllib.quote(IdentityRoot._test_encoded_params.decode( 512 498 'utf-8').encode('latin-1'), '=&') 513 499 params += '&user_name=samIam&password=secret&login=Login' 514 testutil.create_request('/test_params?' + params) 515 firstline = cherrypy.response.body[0] 516 assert 'params ok' in firstline, firstline 500 response = self.app.get('/test_params?' + params) 501 assert 'params ok' in response, response 517 502 518 503 519 504 class TestTGUser(testutil.DBTest): … … 522 507 def setUp(self): 523 508 self._identity_on = config.get('identity.on', False) 524 509 config.update({'identity.on': False}) 525 try:526 self._provider = cherrypy.request.identityProvider527 except AttributeError:528 self._provider= None529 cherrypy.request.identityProvider = None530 510 startup.startTurboGears() 531 511 testutil.DBTest.setUp(self) 532 512 533 513 def tearDown(self): 534 514 testutil.DBTest.tearDown(self) 535 515 startup.stopTurboGears() 536 cherrypy.request.identityProvider = self._provider537 516 config.update({'identity.on': self._identity_on}) 538 517 539 518 def test_create_user(self): -
turbogears/identity/tests/test_visit.py
old new 2 2 from unittest import TestCase 3 3 import cherrypy 4 4 from turbogears import config, controllers, expose, startup, testutil, visit 5 from Cookie import SimpleCookie 5 6 6 7 7 def cookie_header( morsel):8 def cookie_header(response): 8 9 """Returns a dict containing cookie information to pass to a server.""" 9 return {'Cookie': morsel.output(header="")[1:]}10 return dict(Cookie=response.headers['Set-Cookie']) 10 11 11 12 12 13 class VisitRoot(controllers.RootController): 13 14 14 15 @expose() 15 16 def index(self): 16 return dict() 17 new = None 18 if visit.current(): 19 new = visit.current().is_new 20 visit_on = config.get('visit.on') 21 return dict(new=new, visit_on=visit_on) 17 22 18 23 19 24 class TestVisit(TestCase): 20 25 21 26 def setUp(self): 27 testutil.stop_server(tg_only = True) 22 28 self._visit_on = config.get('visit.on', False) 23 29 config.update({'visit.on': True}) 24 30 self._visit_timeout = config.get('visit.timeout', 20) 25 31 config.update({'visit.timeout': 50}) 26 32 self.cookie_name = config.get("visit.cookie.name", 'tg-visit') 27 cherrypy.root = VisitRoot() 33 self.app = testutil.make_app(VisitRoot) 34 testutil.start_server() 28 35 29 36 def tearDown(self): 30 startup.stopTurboGears()37 testutil.stop_server(tg_only = True) 31 38 config.update({'visit.timeout': self._visit_timeout}) 32 39 config.update({'visit.on': self._visit_on}) 33 40 34 41 def test_visit_response(self): 35 42 """Test if the visit cookie is set in cherrypy.response.""" 36 testutil.create_request("/")37 assert cherrypy.response.simple_cookie.has_key(self.cookie_name)43 response = self.app.get("/") 44 assert response.cookies_set.has_key(self.cookie_name) 38 45 39 46 def test_new_visit(self): 40 47 """Test that we can see a new visit on the server.""" 41 testutil.create_request("/")42 assert visit.current().is_new48 response = self.app.get("/") 49 assert response.raw['new'] 43 50 44 51 def test_old_visit(self): 45 52 """Test if we can track a visitor over time.""" 46 testutil.create_request("/")53 response = self.app.get("/") 47 54 # first visit's cookie 48 morsel = cherrypy.response.simple_cookie[self.cookie_name] 49 testutil.create_request("/", headers=cookie_header(morsel)) 50 assert not visit.current().is_new 55 print "Headers", response.headers 56 print "Config", config.get('visit.on') 57 morsel = response.cookies_set[self.cookie_name] 58 response = self.app.get("/", headers=cookie_header(response)) 59 assert not response.raw['new'] 51 60 52 61 def test_cookie_expires(self): 53 62 """Test if the visit timeout mechanism works.""" 54 63 timeout = config.get('visit.timeout', 50) 64 _app = self.app 55 65 try: 56 66 # set expiration to one second for this test only 67 testutil.stop_server(tg_only = True) 57 68 config.update({'visit.timeout': 1.0/60}) 58 testutil.create_request("/") 59 morsel = cherrypy.response.simple_cookie[self.cookie_name] 69 self.app = testutil.make_app(VisitRoot) 70 testutil.start_server() 71 response = self.app.get("/") 72 morsel = response.cookies_set[self.cookie_name] 60 73 time.sleep(2) # 2 seconds 61 testutil.create_request("/", headers=cookie_header(morsel))74 response = self.app.get("/", headers=cookie_header(response)) 62 75 finally: 63 76 config.update({'visit.timeout': timeout}) 64 assert cherrypy.response.simple_cookie[ 65 self.cookie_name].value != morsel.value, \ 77 self.app = _app 78 assert response.cookies_set[ 79 self.cookie_name] != morsel, \ 66 80 'cookie values should not match' 67 assert visit.current().is_new, \81 assert response.raw['new'], \ 68 82 'this should be a new visit, as the cookie has expired' 69 83 70 84 def test_cookie_not_permanent(self): 71 85 """Check that by default the visit cookie is not permanent.""" 72 testutil.create_request('/') 73 morsel = cherrypy.response.simple_cookie[self.cookie_name] 86 response = self.app.get('/') 87 cookies = SimpleCookie(response.headers['Set-Cookie']) 88 morsel = cookies[self.cookie_name] 74 89 assert not morsel['expires'] and not morsel['max-age'] 75 90 76 91 def test_cookie_permanent(self): … … 78 93 permanent = config.get('visit.cookie.permanent', False) 79 94 try: 80 95 # set cookie permanent for this test only (needs restart) 81 startup.stopTurboGears()96 testutil.stop_server(tg_only = True) 82 97 config.update({'visit.cookie.permanent': True}) 83 startup.startTurboGears() 84 testutil.create_request('/') 85 morsel = cherrypy.response.simple_cookie[self.cookie_name] 98 app = testutil.make_app(VisitRoot) 99 testutil.start_server() 100 response = app.get('/') 101 cookies = SimpleCookie(response.headers['Set-Cookie']) 102 morsel = cookies[self.cookie_name] 86 103 finally: 87 104 config.update({'visit.cookie.permanent': permanent}) 88 assert morsel['max-age'] == 3000105 assert morsel['max-age'] == '3000' 89 106 expires = time.mktime(time.strptime(morsel['expires'], 90 107 '%a, %d-%b-%Y %H:%M:%S GMT')[:8] + (0,)) 91 should_expire = time.mktime(time.gmtime()) + morsel['max-age'] 92 assert abs(should_expire - expires) < 3 108 should_expire = time.mktime(time.gmtime()) + int(morsel['max-age']) 109 assert abs(should_expire - expires) < 3, (should_expire, expires, should_expire - expires) 110 -
turbogears/visit/api.py
old new 251 251 max_age = self.cookie_max_age 252 252 if max_age: 253 253 # use 'expires' because MSIE ignores 'max-age' 254 cookies[self.cookie_name]['expires'] = time.strftime(254 cookies[self.cookie_name]['expires'] = '"%s"' % time.strftime( 255 255 "%a, %d-%b-%Y %H:%M:%S GMT", 256 256 time.gmtime(time.time() + max_age)) 257 257 # 'max-age' takes precedence on standard conformant browsers -
turbogears/tests/test_form_controllers.py
old new 1 from unittest import TestCase2 1 from datetime import datetime 2 from unittest import TestCase 3 3 import cherrypy 4 4 from turbogears import widgets, config, controllers, expose, mochikit, \ 5 5 validate, validators, testutil 6 from turbogears.testutil import mount, unmount, make_app 6 7 7 8 9 def setup_module(): 10 global app 11 app = make_app(MyRoot) 12 testutil.start_server() 13 14 def teardown_module(): 15 testutil.stop_server() 16 17 8 18 class MyFormFields(widgets.WidgetsList): 9 19 #XXX: Since allow_extra_fields should be removed from validators.Schema, 10 20 # we need a validator for every input-expecting widget … … 16 26 myform = widgets.TableForm(fields=MyFormFields()) 17 27 18 28 29 class State(object): 30 counter = 0 31 32 class AddingValidator(validators.FancyValidator): 33 def _to_python(self, value, state=None): 34 state.counter += 1 35 return value 36 37 class AddingSchema(validators.Schema): 38 a = AddingValidator() 39 b = AddingValidator() 40 41 class AddingNestedSchema(AddingSchema): 42 c = AddingSchema() 43 44 19 45 class MyRoot(controllers.RootController): 20 46 21 47 @expose(html="turbogears.tests.form") … … 31 57 def testform(self, name, date, age, tg_errors=None): 32 58 if tg_errors: 33 59 self.has_errors = True 34 self.name = name 35 self.age = age 36 self.date = date 60 return dict(name=name, user_age=age, birthdate=date) 37 61 38 62 @expose() 39 63 @validate(form=myform) 40 64 def testform_new_style(self, name, date, age): 41 65 if cherrypy.request.validation_errors: 42 66 self.has_errors = True 43 self.name = name 44 self.age = age 45 self.date = date 67 return dict(name=name, age=age, date=date) 46 68 69 @expose() 70 @validate(validators=AddingNestedSchema(), state_factory=State) 71 def validation(self, a, b, c): 72 return 'counter: %d' % cherrypy.request.validation_state.counter 73 47 74 def test_form_translation(): 48 75 """Form input is translated into properly converted parameters""" 49 root = MyRoot() 50 cherrypy.root = root 51 testutil.create_request("/testform?name=ed&date=11/05/2005&age=5") 52 assert root.name == "ed" 53 assert root.age == 5 76 response = app.get("/testform?name=ed&date=11/05/2005&age=5") 77 assert response.raw['name'] == "ed" 78 assert response.raw['user_age'] == 5 54 79 55 80 def test_form_translation_new_style(): 56 81 """Form input is translated into properly converted parameters""" 57 root = MyRoot() 58 cherrypy.root = root 59 testutil.create_request("/testform_new_style?name=ed&date=11/05/2005&age=5&") 60 assert root.name == "ed" 61 assert root.age == 5 82 response = app.get("/testform_new_style?name=ed&date=11/05/2005&age=5&") 83 assert response.raw['name'] == "ed" 84 assert response.raw['age'] == 5 62 85 63 86 def test_invalid_form_with_error_handling(): 64 87 """Invalid forms can be handled by the method""" 65 root = cherrypy.root 66 testutil.create_request("/testform?name=ed&age=edalso&date=11/05/2005") 67 assert root.has_errors 88 response = app.get("/testform?name=ed&age=edalso&date=11/05/2005") 68 89 69 90 def test_css_should_appear(): 70 91 """CSS should appear when asked for""" 71 testutil.create_request("/")72 assert "calendar-system.css" in cherrypy.response.body[0]92 response = app.get("/") 93 assert "calendar-system.css" in response 73 94 74 95 def test_javascript_should_appear(): 75 96 """JavaScript should appear when asked for""" 76 testutil.create_request("/")77 assert "calendar.js" in cherrypy.response.body[0]97 response = app.get("/") 98 assert "calendar.js" in response 78 99 79 100 def test_include_mochikit(): 80 101 """JSLinks (and MochiKit especially) can be included easily""" 81 testutil.create_request("/usemochi")82 assert "MochiKit.js" in cherrypy.response.body[0]102 response = app.get("/usemochi") 103 assert "MochiKit.js" in response 83 104 84 105 def test_suppress_mochikit(): 85 106 """MochiKit inclusion can be suppressed""" 86 config.update({"global": {"tg.mochikit_suppress": True}}) 87 testutil.create_request("/usemochi") 88 suppressed_body = cherrypy.response.body[0] 107 config.update({"global":{"tg.mochikit_suppress" : True}}) 108 suppressed = app.get("/usemochi") 89 109 # repair the fixture 90 config.update({"global": {"tg.mochikit_suppress": False}}) 91 testutil.create_request("/usemochi") 92 included_body = cherrypy.response.body[0] 93 assert "MochiKit.js" not in suppressed_body 94 assert "MochiKit.js" in included_body 110 config.update({"global":{"tg.mochikit_suppress" : False}}) 95 111 112 included = app.get("/usemochi") 113 assert "MochiKit.js" not in suppressed.body 114 assert "MochiKit.js" in included.body 115 96 116 def test_mochikit_everywhere(): 97 117 """MochiKit can be included everywhere by setting tg.mochikit_all""" 98 config.update({"global": {"tg.mochikit_all": True}})99 testutil.create_request("/")100 config.update({"global": {"tg.mochikit_all": False}})101 assert "MochiKit.js" in cherrypy.response.body[0]118 config.update({"global":{"tg.mochikit_all" : True}}) 119 response = app.get("/") 120 config.update({"global":{"tg.mochikit_all" : False}}) 121 assert "MochiKit.js" in response 102 122 103 123 def test_mochikit_nowhere(): 104 124 """Setting tg.mochikit_suppress will prevent including it everywhere""" 105 125 config.update({"global": {"tg.mochikit_all": True}}) 106 126 config.update({"global": {"tg.mochikit_suppress": True}}) 107 testutil.create_request("/")127 response = app.get("/") 108 128 config.update({"global": {"tg.mochikit_all": False}}) 109 129 config.update({"global": {"tg.mochikit_suppress": False}}) 110 assert "MochiKit.js" not in cherrypy.response.body[0]130 assert "MochiKit.js" not in response 111 131 112 132 def test_include_widgets(): 113 133 """Any widget can be included everywhere by setting tg.include_widgets""" 114 134 config.update({"global": {"tg.include_widgets": ["mochikit"]}}) 115 testutil.create_request("/")135 response = app.get("/") 116 136 config.update({"global": {"tg.include_widgets": []}}) 117 assert "MochiKit.js" in cherrypy.response.body[0]137 assert "MochiKit.js" in response 118 138 139 def test_counter_is_incremented(): 140 # parameter values are irrelevant 141 url = '/validation?a=1&b=2&c.a=3&c.b=4' 142 response = app.get(url) 143 msg = "Validation state is not handled properly" 144 # 4 == 1 (a) + 1(b) + 1(c.a) + 1(c.b) 145 assert 'counter: 4' in response.body, msg 119 146 120 class State(object):121 counter = 0122 123 class AddingValidator(validators.FancyValidator):124 def _to_python(self, value, state=None):125 state.counter += 1126 return value127 128 class AddingSchema(validators.Schema):129 a = AddingValidator()130 b = AddingValidator()131 132 class AddingNestedSchema(AddingSchema):133 c = AddingSchema()134 135 136 class TestValidationState(TestCase):137 138 class Controller(controllers.RootController):139 140 @expose()141 @validate(validators=AddingNestedSchema(), state_factory=State)142 def validation(self, a, b, c):143 return 'counter: %d' % cherrypy.request.validation_state.counter144 145 def __init__(self, *args, **kw):146 super(TestValidationState, self).__init__(*args, **kw)147 148 def test_counter_is_incremented(self):149 cherrypy.root = self.Controller()150 # parameter values are irrelevant151 url = '/validation?a=1&b=2&c.a=3&c.b=4'152 testutil.create_request(url)153 body = cherrypy.response.body[0]154 msg = "Validation state is not handled properly"155 # 4 == 1 (a) + 1(b) + 1(c.a) + 1(c.b)156 self.failUnless('counter: 4' in body, msg) -
turbogears/tests/test_errorhandling.py
old new 1 1 import unittest 2 3 import cherrypy4 5 2 from turbogears.controllers import error_handler, exception_handler, \ 6 3 expose, validate, RootController, Controller 7 4 from turbogears.errorhandling import FailsafeSchema … … 16 13 else: 17 14 return str(errors) 18 15 16 def setup_module(): 17 testutil.unmount() 18 testutil.mount(MyRoot()) 19 testutil.mount(NestedController(), "/nestedcontroller") 20 testutil.start_server() 19 21 22 def teardown_module(): 23 testutil.unmount() 24 testutil.stop_server() 25 20 26 class MyRoot(RootController): 21 27 22 28 def defaulterrorhandler(self, tg_source, tg_errors, tg_exceptions, … … 94 100 "second": validators.Int(not_empty=True)}) 95 101 @error_handler(defaulterrorhandler) 96 102 def positionalargs(self, first, second, *args, **kw): 97 self.first = first98 self.second = second99 self.third = args[0]100 103 return dict(title="Positional arguments", first=first, second=second, 101 args=args, bar=kw["bar"])104 third=args[0], args=args, bar=kw["bar"]) 102 105 103 106 @expose() 104 107 @validate(validators={"bar": validators.Int(not_empty=True)}) … … 141 144 return self.notexposed(bar) 142 145 143 146 def continuation(self, tg_source): 144 self.continuation = True 145 return tg_source(self) 147 response = tg_source(self) 148 response['continuation'] = True 149 return response 146 150 147 151 @expose() 148 152 @validate(validators={"bar": validators.Int(not_empty=True)}) … … 208 212 return dict(title="Nested") 209 213 210 214 215 app = testutil.make_app() 216 211 217 class TestErrorHandler(unittest.TestCase): 212 218 213 def setUp(self):214 cherrypy.root = MyRoot()215 cherrypy.root.nestedcontroller = NestedController()216 217 219 def test_defaultErrorHandler(self): 218 220 """Default error handler.""" 219 testutil.create_request("/defaulterror?bar=abc")220 self.failUnless("Default error handler" in cherrypy.response.body[0])221 testutil.create_request("/defaulterror?bar=true")222 self.failUnless("Default error provider" in cherrypy.response.body[0])221 response = app.get("/defaulterror?bar=abc") 222 self.failUnless("Default error handler" in response) 223 response = app.get("/defaulterror?bar=true") 224 self.failUnless("Default error provider" in response) 223 225 224 226 def test_specialisedErrorHandler(self): 225 227 """Error handler specialisation.""" 226 testutil.create_request("/specialisederror?bar=abc&baz=a@b.com") 227 self.failUnless("Default error handler" in cherrypy.response.body[0]) 228 testutil.create_request("/specialisederror?baz=abc&bar=1") 229 self.failUnless("Specialised error handler" in 230 cherrypy.response.body[0]) 231 testutil.create_request("/specialisederror?bar=1&baz=a@b.com") 232 self.failUnless("Specialised error provider" in 233 cherrypy.response.body[0]) 228 response = app.get("/specialisederror?bar=abc&baz=a@b.com") 229 self.failUnless("Default error handler" in response) 230 response = app.get("/specialisederror?baz=abc&bar=1") 231 self.failUnless("Specialised error handler" in response) 232 response = app.get("/specialisederror?bar=1&baz=a@b.com") 233 self.failUnless("Specialised error provider" in response) 234 234 235 235 def test_exceptionErrorHandler(self): 236 236 """Error handler for exceptions.""" 237 testutil.create_request("/exceptionerror")238 self.failUnless("Default error handler" in cherrypy.response.body[0])237 response = app.get("/exceptionerror") 238 self.failUnless("Default error handler" in response) 239 239 240 240 def test_recursiveErrorHandler(self): 241 241 """Recursive error handler.""" 242 testutil.create_request("/recursiveerror?bar=abc") 243 self.failUnless("Recursive error handler" in cherrypy.response.body[0]) 244 testutil.create_request("/recursiveerror?bar=1") 245 self.failUnless("Recursive error provider" in 246 cherrypy.response.body[0]) 242 response = app.get("/recursiveerror?bar=abc") 243 self.failUnless("Recursive error handler" in response) 244 response = app.get("/recursiveerror?bar=1") 245 self.failUnless("Recursive error provider" in response) 247 246 248 247 def test_implicitErrorHandler(self): 249 248 """Implicit error handling.""" 250 testutil.create_request("/impliciterror?bar=abc") 251 self.failUnless("Implicit error handler" in 252 cherrypy.response.body[0]) 253 testutil.create_request("/impliciterror?bar=1") 254 self.failUnless("Implicit error provider" in 255 cherrypy.response.body[0]) 249 response = app.get("/impliciterror?bar=abc") 250 self.failUnless("Implicit error handler" in response) 251 response = app.get("/impliciterror?bar=1") 252 self.failUnless("Implicit error provider" in response) 256 253 257 254 def test_normalMethodErrorHandler(self): 258 255 """Normal method as an error handler.""" 259 testutil.create_request("/normalmethodcaller?bar=abc")260 self.failUnless("Normal method" in cherrypy.response.body[0])261 testutil.create_request("/normalmethodcaller?bar=true")262 self.failUnless("Normal method caller" in cherrypy.response.body[0])256 response = app.get("/normalmethodcaller?bar=abc") 257 self.failUnless("Normal method" in response) 258 response = app.get("/normalmethodcaller?bar=true") 259 self.failUnless("Normal method caller" in response) 263 260 264 261 def test_infiniteRecursionPrevention(self): 265 262 """Infinite recursion prevention.""" 266 testutil.create_request("/infiniteloop")267 self.failUnless("Exception 2" in cherrypy.response.body[0])263 response = app.get("/infiniteloop") 264 self.failUnless("Exception 2" in response) 268 265 269 266 def test_positionalArgs(self): 270 267 """Positional argument validation.""" 271 testutil.create_request("/positionalargs/first/23/third?bar=abc")272 self.failUnless("Default error handler" in cherrypy.response.body[0])273 testutil.create_request("/positionalargs/first/abc/third?bar=false")274 self.failUnless("Default error handler" in cherrypy.response.body[0])275