Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #1762: TurboGears-1.1-WebTest.patch

File TurboGears-1.1-WebTest.patch, 83.8 KB (added by lmacken, 4 years ago)

Updated again with some minor cleanups

  • setup.py

     
    2424    "TurboCheetah >= 1.0", 
    2525    "TurboJson >= 1.1.2", 
    2626    "tgMochiKit >= 0.1alpha", 
     27    "WebTest", 
    2728] 
    2829 
    2930# for when we get rid of Kid & SQLObject dependency 
  • turbogears/identity/tests/test_identity.py

     
    5555 
    5656    @expose() 
    5757    def index(self): 
    58         pass 
     58        return dict() 
    5959 
    6060    @expose() 
    6161    def identity_failed(self, **kw): 
     
    137137                ' for all strings' % cherrypy.request.params 
    138138 
    139139 
    140 class TestIdentity(unittest.TestCase): 
     140class TestIdentity(testutil.TGWebTest): 
    141141 
    142142    def setUp(self): 
    143143        # identity requires visit and a failure_url 
     
    152152        config.configure_loggers(test_config) 
    153153        config.update(test_config['global']) 
    154154        cherrypy.root = IdentityRoot() 
    155         startup.startTurboGears() 
     155        testutil.TGWebTest.setUp(self) 
    156156        self.init_model() 
    157157 
    158158    def tearDown(self): 
    159         startup.stopTurboGears() 
     159        testutil.TGWebTest.tearDown(self) 
    160160        config.update(self._original_config) 
    161161 
    162162    def init_model(self): 
     
    181181 
    182182    def test_user_password_parameters(self): 
    183183        """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 
     184        response = self.app.get('/new_user_setup?user_name=test&password=pw') 
     185        assert 'test pw' in response 
    187186 
    188187    def test_user_exists(self): 
    189188        u = TG_User.by_user_name('samIam') 
     
    205204        config.update({'identity.soprovider.encryption_algorithm': None}) 
    206205        # force new config values to load 
    207206        startup.startTurboGears() 
    208         testutil.create_request('/') 
     207        self.app.get('/') 
    209208        hub.begin() 
    210209        u = TG_User.by_user_name('samIam') 
    211210        u.password = u'garçon' 
     
    219218        config.update({'identity.soprovider.encryption_algorithm': 'sha1'}) 
    220219        # force new config values to load 
    221220        startup.startTurboGears() 
    222         testutil.create_request('/') 
     221        self.app.get('/') 
    223222        hub.begin() 
    224223        u = TG_User.by_user_name('samIam') 
    225224        u.password = 'password' 
     
    234233        config.update({'identity.soprovider.encryption_algorithm': 'sha1'}) 
    235234        # force new config values to load 
    236235        startup.startTurboGears() 
    237         testutil.create_request('/') 
     236        self.app.get('/') 
    238237        hub.begin() 
    239238        u = TG_User.by_user_name('samIam') 
    240239        u.password = u'garçon' 
     
    248247        config.update({'identity.soprovider.encryption_algorithm': 'md5'}) 
    249248        # force new config values to load 
    250249        startup.startTurboGears() 
    251         testutil.create_request('/') 
     250        self.app.get('/') 
    252251        hub.begin() 
    253252        u = TG_User.by_user_name('samIam') 
    254253        u.password = 'password' 
     
    263262        config.update({'identity.soprovider.encryption_algorithm': 'md5'}) 
    264263        # force new config values to load 
    265264        startup.startTurboGears() 
    266         testutil.create_request('/') 
     265        self.app.get('/') 
    267266        hub.begin() 
    268267        u = TG_User.by_user_name('samIam') 
    269268        u.password = u'garçon' 
     
    280279        config.update({'identity.soprovider.encryption_algorithm': 'md5'}) 
    281280        # force new config values to load 
    282281        startup.startTurboGears() 
    283         testutil.create_request('/') 
     282        self.app.get('/') 
    284283        hub.begin() 
    285284        u = TG_User.by_user_name('samIam') 
    286285        u.password = u'garçon'.encode('UTF-8') 
     
    295294        config.update({'identity.soprovider.encryption_algorithm':'sha1'}) 
    296295        # force new config values to load 
    297296        startup.startTurboGears() 
    298         testutil.create_request('/') 
     297        self.app.get('/') 
    299298        hub.begin() 
    300299        u = TG_User.by_user_name('samIam') 
    301300        u.set_password_raw('password') 
     
    308307        config.update({'identity.soprovider.encryption_algorithm':'sha1'}) 
    309308        # force new config values to load 
    310309        startup.startTurboGears() 
    311         testutil.create_request('/') 
     310        self.app.get('/') 
    312311        hub.begin() 
    313312        u = TG_User.by_user_name('samIam') 
    314313        u.set_password_raw(u'garçon') 
     
    324323                'identity.tests.test_identity.mycustomencrypt'}) 
    325324        # force new config values to load 
    326325        startup.startTurboGears() 
    327         testutil.create_request('/') 
     326        self.app.get('/') 
    328327        hub.begin() 
    329328        u = TG_User.by_user_name('samIam') 
    330329        u.password = 'password' 
     
    335334 
    336335    def test_anonymous_browsing(self): 
    337336        """Test if we can show up anonymously.""" 
    338         testutil.create_request('/') 
     337        self.app.get('/') 
    339338        assert identity.current.anonymous 
    340339 
    341340    def test_deny_anonymous(self): 
    342341        """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 
     342        response = self.app.get('/logged_in_only') 
     343        assert 'identity_failed_answer' in response 
    346344 
    347345    def test_deny_anonymous_viewable(self): 
    348346        """Test that a logged in user can see an resource blocked 
    349347        from anonymous users.""" 
    350         testutil.create_request('/logged_in_only?' 
     348        response = self.app.get('/logged_in_only?' 
    351349            'user_name=samIam&password=secret&login=Login') 
    352         firstline = cherrypy.response.body[0] 
    353         assert 'logged_in_only' in firstline, firstline 
     350        assert 'logged_in_only' in response 
    354351 
    355352    def test_logout(self): 
    356353        """Test that logout works and session is gets invalid afterwards.""" 
    357         testutil.create_request('/in_peon_group?' 
     354        response = self.app.get('/in_peon_group?' 
    358355            'user_name=samIam&password=secret&login=Login') 
     356        assert False 
    359357        self.assertEquals("samIam", cherrypy.serving.request.identity.user_name) 
    360358        session_id = re.match("Set-Cookie: (.*?); Path.*", 
    361359            str(cherrypy.response.simple_cookie)).group(1) 
  • turbogears/tests/test_form_controllers.py

     
    3434        self.name = name 
    3535        self.age = age 
    3636        self.date = date 
     37        return dict() 
    3738 
    3839    @expose() 
    3940    @validate(form=myform) 
     
    4344        self.name = name 
    4445        self.age = age 
    4546        self.date = date 
     47        return dict() 
    4648 
    47 def test_form_translation(): 
    48     """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 
    5449 
    55 def test_form_translation_new_style(): 
    56     """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 
     50class TestFormControllers(testutil.TGWebTest): 
    6251 
    63 def test_invalid_form_with_error_handling(): 
    64     """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 
     52    def test_form_translation(self): 
     53        """Form input is translated into properly converted parameters""" 
     54        root = MyRoot() 
     55        cherrypy.root = root 
     56        self.app.get("/testform?name=ed&date=11/05/2005&age=5") 
     57        assert root.name == "ed" 
     58        assert root.age == 5 
    6859 
    69 def test_css_should_appear(): 
    70     """CSS should appear when asked for""" 
    71     testutil.create_request("/") 
    72     assert "calendar-system.css" in cherrypy.response.body[0] 
     60    def test_form_translation_new_style(self): 
     61        """Form input is translated into properly converted parameters""" 
     62        root = MyRoot() 
     63        cherrypy.root = root 
     64        self.app.get("/testform_new_style?name=ed&date=11/05/2005&age=5&") 
     65        assert root.name == "ed" 
     66        assert root.age == 5 
    7367 
    74 def test_javascript_should_appear(): 
    75     """JavaScript should appear when asked for""" 
    76     testutil.create_request("/") 
    77     assert "calendar.js" in cherrypy.response.body[0] 
     68    def test_invalid_form_with_error_handling(self): 
     69        """Invalid forms can be handled by the method""" 
     70        root = cherrypy.root 
     71        self.app.get("/testform?name=ed&age=edalso&date=11/05/2005") 
     72        assert root.has_errors 
    7873 
    79 def test_include_mochikit(): 
    80     """JSLinks (and MochiKit especially) can be included easily""" 
    81     testutil.create_request("/usemochi") 
    82     assert "MochiKit.js" in cherrypy.response.body[0] 
     74    def test_css_should_appear(self): 
     75        """CSS should appear when asked for""" 
     76        cherrypy.root = MyRoot() 
     77        response = self.app.get("/") 
     78        assert "calendar-system.css" in response 
    8379 
    84 def test_suppress_mochikit(): 
    85     """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] 
    89     # 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 
     80    def test_javascript_should_appear(self): 
     81        """JavaScript should appear when asked for""" 
     82        cherrypy.root = MyRoot() 
     83        response = self.app.get("/") 
     84        assert "calendar.js" in response 
    9585 
    96 def test_mochikit_everywhere(): 
    97     """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] 
     86    def test_include_mochikit(self): 
     87        """JSLinks (and MochiKit especially) can be included easily""" 
     88        cherrypy.root = MyRoot() 
     89        response = self.app.get("/usemochi") 
     90        assert "MochiKit.js" in response 
    10291 
    103 def test_mochikit_nowhere(): 
    104     """Setting tg.mochikit_suppress will prevent including it everywhere""" 
    105     config.update({"global": {"tg.mochikit_all": True}}) 
    106     config.update({"global": {"tg.mochikit_suppress": True}}) 
    107     testutil.create_request("/") 
    108     config.update({"global": {"tg.mochikit_all": False}}) 
    109     config.update({"global": {"tg.mochikit_suppress": False}}) 
    110     assert "MochiKit.js" not in cherrypy.response.body[0] 
     92    def test_suppress_mochikit(self): 
     93        """MochiKit inclusion can be suppressed""" 
     94        cherrypy.root = MyRoot() 
     95        config.update({"global": {"tg.mochikit_suppress": True}}) 
     96        response = self.app.get("/usemochi") 
     97        suppressed_body = response.body 
     98        # repair the fixture 
     99        config.update({"global": {"tg.mochikit_suppress": False}}) 
     100        response = self.app.get("/usemochi") 
     101        included_body = response.body 
     102        assert "MochiKit.js" not in suppressed_body 
     103        assert "MochiKit.js" in included_body 
    111104 
    112 def test_include_widgets(): 
    113     """Any widget can be included everywhere by setting tg.include_widgets""" 
    114     config.update({"global": {"tg.include_widgets": ["mochikit"]}}) 
    115     testutil.create_request("/") 
    116     config.update({"global": {"tg.include_widgets": []}}) 
    117     assert "MochiKit.js" in cherrypy.response.body[0] 
     105    def test_mochikit_everywhere(self): 
     106        """MochiKit can be included everywhere by setting tg.mochikit_all""" 
     107        cherrypy.root = MyRoot() 
     108        config.update({"global": {"tg.mochikit_all": True}}) 
     109        response = self.app.get("/") 
     110        config.update({"global": {"tg.mochikit_all": False}}) 
     111        assert "MochiKit.js" in response 
    118112 
     113    def test_mochikit_nowhere(self): 
     114        """Setting tg.mochikit_suppress will prevent including it everywhere""" 
     115        cherrypy.root = MyRoot() 
     116        config.update({"global": {"tg.mochikit_all": True}}) 
     117        config.update({"global": {"tg.mochikit_suppress": True}}) 
     118        response = self.app.get("/") 
     119        config.update({"global": {"tg.mochikit_all": False}}) 
     120        config.update({"global": {"tg.mochikit_suppress": False}}) 
     121        assert "MochiKit.js" not in response 
    119122 
     123    def test_include_widgets(self): 
     124        """Any widget can be included everywhere by setting tg.include_widgets""" 
     125        cherrypy.root = MyRoot() 
     126        config.update({"global": {"tg.include_widgets": ["mochikit"]}}) 
     127        response = self.app.get("/") 
     128        config.update({"global": {"tg.include_widgets": []}}) 
     129        assert "MochiKit.js" in response 
     130 
     131 
    120132class State(object): 
    121133    counter = 0 
    122134 
  • turbogears/tests/test_errorhandling.py

     
    208208        return dict(title="Nested") 
    209209 
    210210 
    211 class TestErrorHandler(unittest.TestCase): 
     211class TestErrorHandler(testutil.TGWebTest): 
    212212 
    213213    def setUp(self): 
     214        testutil.TGWebTest.setUp(self) 
    214215        cherrypy.root = MyRoot() 
    215216        cherrypy.root.nestedcontroller = NestedController() 
    216217 
    217218    def test_defaultErrorHandler(self): 
    218219        """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]) 
     220        response = self.app.get("/defaulterror?bar=abc") 
     221        self.failUnless("Default error handler" in response) 
     222        response = self.app.get("/defaulterror?bar=true") 
     223        self.failUnless("Default error provider" in response) 
    223224 
    224225    def test_specialisedErrorHandler(self): 
    225226        """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") 
     227        response = self.app.get("/specialisederror?bar=abc&baz=a@b.com") 
     228        self.failUnless("Default error handler" in response) 
     229        response = self.app.get("/specialisederror?baz=abc&bar=1") 
    229230        self.failUnless("Specialised error handler" in 
    230                         cherrypy.response.body[0]) 
    231         testutil.create_request("/specialisederror?bar=1&baz=a@b.com") 
     231                        response) 
     232        response = self.app.get("/specialisederror?bar=1&baz=a@b.com") 
    232233        self.failUnless("Specialised error provider" in 
    233                         cherrypy.response.body[0]) 
     234                        response) 
    234235 
    235236    def test_exceptionErrorHandler(self): 
    236237        """Error handler for exceptions.""" 
    237         testutil.create_request("/exceptionerror") 
    238         self.failUnless("Default error handler" in cherrypy.response.body[0]) 
     238        response = self.app.get("/exceptionerror") 
     239        self.failUnless("Default error handler" in response) 
    239240 
    240241    def test_recursiveErrorHandler(self): 
    241242        """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") 
     243        response = self.app.get("/recursiveerror?bar=abc") 
     244        self.failUnless("Recursive error handler" in response) 
     245        response = self.app.get("/recursiveerror?bar=1") 
    245246        self.failUnless("Recursive error provider" in 
    246                         cherrypy.response.body[0]) 
     247                        response) 
    247248 
    248249    def test_implicitErrorHandler(self): 
    249250        """Implicit error handling.""" 
    250         testutil.create_request("/impliciterror?bar=abc") 
     251        response = self.app.get("/impliciterror?bar=abc") 
    251252        self.failUnless("Implicit error handler" in 
    252                         cherrypy.response.body[0]) 
    253         testutil.create_request("/impliciterror?bar=1") 
     253                        response) 
     254        response = self.app.get("/impliciterror?bar=1") 
    254255        self.failUnless("Implicit error provider" in 
    255                         cherrypy.response.body[0]) 
     256                        response) 
    256257 
    257258    def test_normalMethodErrorHandler(self): 
    258259        """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]) 
     260        response = self.app.get("/normalmethodcaller?bar=abc") 
     261        self.failUnless("Normal method" in response) 
     262        response = self.app.get("/normalmethodcaller?bar=true") 
     263        self.failUnless("Normal method caller" in response) 
    263264 
    264265    def test_infiniteRecursionPrevention(self): 
    265266        """Infinite recursion prevention.""" 
    266         testutil.create_request("/infiniteloop") 
    267         self.failUnless("Exception 2" in cherrypy.response.body[0]) 
     267        response = self.app.get("/infiniteloop") 
     268        self.failUnless("Exception 2" in response) 
    268269 
    269270    def test_positionalArgs(self): 
    270271        """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         testutil.create_request("/positionalargs/first/abc/third?bar=abc") 
    276         self.failUnless("Default error handler" in cherrypy.response.body[0]) 
    277         testutil.create_request("/positionalargs/first/23/third?bar=true") 
    278         self.failUnless("Positional arguments" in cherrypy.response.body[0]) 
     272        response = self.app.get("/positionalargs/first/23/third?bar=abc") 
     273        self.failUnless("Default error handler" in response) 
     274        response = self.app.get("/positionalargs/first/abc/third?bar=false") 
     275        self.failUnless("Default error handler" in response) 
     276        response = self.app.get("/positionalargs/first/abc/third?bar=abc") 
     277        self.failUnless("Default error handler" in response) 
     278        response = self.app.get("/positionalargs/first/23/third?bar=true") 
     279        self.failUnless("Positional arguments" in response) 
    279280        self.failUnless(cherrypy.root.first == "first") 
    280281        self.failUnless(cherrypy.root.second == 23) 
    281282        self.failUnless(cherrypy.root.third == "third") 
    282283 
    283284    def test_missingArgs(self): 
    284285        """Arguments required in validation missing.""" 
    285         testutil.create_request("/missingargs") 
    286         self.failUnless("Default error handler" in cherrypy.response.body[0]) 
    287         testutil.create_request("/missingargs?bar=12") 
    288         self.failUnless("Missing args provider" in cherrypy.response.body[0]) 
     286        response = self.app.get("/missingargs") 
     287        self.failUnless("Default error handler" in response) 
     288        response = self.app.get("/missingargs?bar=12") 
     289        self.failUnless("Missing args provider" in response) 
    289290 
    290291    def test_nohandler(self): 
    291292        """No error hanlder declared.""" 
    292         testutil.create_request("/nohandler") 
    293         self.failUnless("Exception raised" in cherrypy.response.body[0]) 
     293        response = self.app.get("/nohandler") 
     294        self.failUnless("Exception raised" in response) 
    294295 
    295296    def test_bindArgs(self): 
    296297        """Arguments can be bond to an error handler.""" 
    297         testutil.create_request("/bindargs") 
    298         self.failUnless("123" in cherrypy.response.body[0]) 
     298        response = self.app.get("/bindargs") 
     299        self.failUnless("123" in response) 
    299300 
    300301    def test_notExposed(self): 
    301302        """Validation error handling is decoupled from expose.""" 
    302         testutil.create_request("/notexposedcaller?foo=a&bar=rab&baz=c") 
    303         self.failUnless("Not exposed error" in cherrypy.response.body[0]) 
    304         self.failUnless("rab" in cherrypy.response.body[0]) 
     303        response = self.app.get("/notexposedcaller?foo=a&bar=rab&baz=c") 
     304        self.failUnless("Not exposed error" in response) 
     305        self.failUnless("rab" in response) 
    305306 
    306307    def test_continuations(self): 
    307308        """Continuations via error handling mechanism.""" 
    308         testutil.create_request("/continuationcaller?bar=a") 
    309         self.failUnless("Continuation caller" in cherrypy.response.body[0]) 
     309        response = self.app.get("/continuationcaller?bar=a") 
     310        self.failUnless("Continuation caller" in response) 
    310311        self.failUnless(cherrypy.root.continuation == True) 
    311312 
    312313    def test_nested(self): 
    313314        """Potentially ambiguous cases.""" 
    314         testutil.create_request("/nest?bar=a") 
    315         self.failUnless("Default error handler" in cherrypy.response.body[0]) 
    316         testutil.create_request("/nestedcontroller/nest?bar=a") 
    317         self.failUnless("Nested" in cherrypy.response.body[0]) 
     315        response = self.app.get("/nest?bar=a") 
     316        self.failUnless("Default error handler" in response) 
     317        response = self.app.get("/nestedcontroller/nest?bar=a") 
     318        self.failUnless("Nested" in response) 
    318319 
    319320    def test_failsafe(self): 
    320321        """Failsafe values for erroneous input.""" 
    321         testutil.create_request("/failsafenone?bar=a&baz=b") 
    322         self.failUnless('"bar": "a"' in cherrypy.response.body[0]) 
    323         self.failUnless('"baz": "b"' in cherrypy.response.body[0]) 
    324         testutil.create_request("/failsafevaluesdict?bar=a&baz=b") 
    325         self.failUnless('"bar": 1' in cherrypy.response.body[0]) 
    326         self.failUnless('"baz": 2' in cherrypy.response.body[0]) 
    327         testutil.create_request("/failsafevaluesatom?bar=a&baz=b") 
    328         self.failUnless('"bar": 13' in cherrypy.response.body[0]) 
    329         self.failUnless('"baz": 13' in cherrypy.response.body[0]) 
    330         testutil.create_request("/failsafemaperrors?bar=a&baz=b") 
     322        response = self.app.get("/failsafenone?bar=a&baz=b") 
     323        self.failUnless('"bar": "a"' in response) 
     324        self.failUnless('"baz": "b"' in response) 
     325        response = self.app.get("/failsafevaluesdict?bar=a&baz=b") 
     326        self.failUnless('"bar": 1' in response) 
     327        self.failUnless('"baz": 2' in response) 
     328        response = self.app.get("/failsafevaluesatom?bar=a&baz=b") 
     329        self.failUnless('"bar": 13' in response) 
     330        self.failUnless('"baz": 13' in response) 
     331        response = self.app.get("/failsafemaperrors?bar=a&baz=b") 
    331332        self.failUnless('"bar": "Please enter an integer value"' in 
    332                         cherrypy.response.body[0]) 
     333                        response) 
    333334        self.failUnless('"baz": "Please enter an integer value"' in 
    334                         cherrypy.response.body[0]) 
    335         testutil.create_request("/failsafeformencode?bar=a&baz=b") 
    336         self.failUnless('"bar": 1' in cherrypy.response.body[0]) 
    337         self.failUnless('"baz": 2' in cherrypy.response.body[0]) 
    338         testutil.create_request("/failsafedefaults?bar=a&baz=b") 
    339         self.failUnless('"bar": 1' in cherrypy.response.body[0]) 
    340         self.failUnless('"baz": 2' in cherrypy.response.body[0]) 
     335                        response) 
     336        response = self.app.get("/failsafeformencode?bar=a&baz=b") 
     337        self.failUnless('"bar": 1' in response) 
     338        self.failUnless('"baz": 2' in response) 
     339        response = self.app.get("/failsafedefaults?bar=a&baz=b") 
     340        self.failUnless('"bar": 1' in response,response) 
     341        self.failUnless('"baz": 2' in response) 
  • turbogears/tests/test_sqlalchemy.py

     
    99from turbogears.database import metadata, session, mapper, \ 
    1010    bind_metadata, get_metadata 
    1111from turbogears.controllers import RootController 
    12 from turbogears.testutil import create_request, sqlalchemy_cleanup, \ 
     12from turbogears.testutil import sqlalchemy_cleanup, TGWebTest, \ 
    1313    capture_log, print_log 
    1414 
    1515 
     
    162162        return "No exceptions occurred" 
    163163 
    164164 
    165 def test_implicit_trans_no_error(): 
    166     """If a controller runs sucessfully, the transaction is commited.""" 
    167     capture_log("turbogears.database") 
    168     cherrypy.root = MyRoot() 
    169     create_request("/no_error?name=A.%20Dent") 
    170     output = cherrypy.response.body[0] 
    171     print output 
    172     print_log() 
    173     q = session.query(Person) 
    174     arthur = q.filter_by(name="A. Dent").first() 
    175     assert 'someconfirmhandler' in output, \ 
    176         'The no error should have redirected to someconfirmhandler' 
    177     assert arthur is not None, 'Person arthur should have been saved!' 
    178     assert arthur.name == "A. Dent", 'Person arthur should be named "A. Dent"' 
     165class TestSQLAlchemy(TGWebTest): 
    179166 
    180 def test_raise_sa_exception(): 
    181     """If a controller causes an SA exception, it is raised properly.""" 
    182     capture_log("turbogears.database") 
    183     cherrypy.root = MyRoot() 
    184     create_request("/create_person?id=20") 
    185     output = cherrypy.response.body[0] 
    186     print_log() 
    187     print output 
    188     assert 'No exceptions occurred' in output 
    189     assert cherrypy.response.status.startswith("200") 
    190     create_request("/create_person?id=20") 
    191     output = cherrypy.response.body[0] 
    192     assert cherrypy.response.status.startswith("500") 
    193     print output 
    194     assert 'KARL25' not in output, \ 
    195         'Exception should NOT have been handled by our handler' 
    196     assert 'DBAPIError' in output, \ 
    197         'The page should have displayed an SQLAlchemy exception' 
     167    def test_implicit_trans_no_error(self): 
     168        """If a controller runs sucessfully, the transaction is commited.""" 
     169        #capture_log("turbogears.database") 
     170        cherrypy.root = MyRoot() 
     171        response = self.app.get("/no_error?name=A.%20Dent") 
     172        output = response.body 
     173        #print output 
     174        #print_log() 
     175        q = session.query(Person) 
     176        arthur = q.filter_by(name="A. Dent").first() 
     177        assert 'someconfirmhandler' in output, \ 
     178            'The no error should have redirected to someconfirmhandler' 
     179        assert arthur is not None, 'Person arthur should have been saved!' 
     180        assert arthur.name == "A. Dent", 'Person arthur should be named "A. Dent"' 
    198181 
    199 def test_user_exception(): 
    200     """If a controller raises an exception, transactions are rolled back.""" 
    201     capture_log("turbogears.database") 
    202     cherrypy.root = MyRoot() 
    203     create_request("/create_person?id=19&docom=0&doerr=1&name=Martin%20GAL") 
    204     output = cherrypy.response.body[0] 
    205     print_log() 
    206     print output 
    207     assert 'KARL25' in output, \ 
    208         'The exception handler should have answered us' 
    209     p = session.query(Person).get(19) 
    210     assert p is None, \ 
    211         'This Person should have been rolled back: %s' % p 
     182    def test_raise_sa_exception(self): 
     183        """If a controller causes an SA exception, it is raised properly.""" 
     184        #capture_log("turbogears.database") 
     185        cherrypy.root = MyRoot() 
     186        response = self.app.get("/create_person?id=20", status=200) 
     187        output = response.body 
     188        #print_log() 
     189        print output 
     190        assert 'No exceptions occurred' in output 
     191        response = self.app.get("/create_person?id=20", status=500) 
     192        output = response.body 
     193        print output 
     194        assert 'KARL25' not in output, \ 
     195            'Exception should NOT have been handled by our handler' 
     196        assert 'DBAPIError' in output, \ 
     197            'The page should have displayed an SQLAlchemy exception' 
    212198 
    213 def test_user_redirect(): 
    214     """If a controller redirects, transactions are committed.""" 
    215     cherrypy.root = MyRoot() 
    216     create_request("/create_person?id=22&doerr=2") 
    217     assert session.query(Person).get(22) is not None, \ 
    218         'The controller only redirected, the Person should have been saved' 
     199    def test_user_exception(self): 
     200        """If a controller raises an exception, transactions are rolled back.""" 
     201        #capture_log("turbogears.database") 
     202        cherrypy.root = MyRoot() 
     203        response = self.app.get("/create_person?id=19&docom=0&doerr=1&name=Martin%20GAL") 
     204        output = response.body 
     205        #print_log() 
     206        print output 
     207        assert 'KARL25' in output, \ 
     208            'The exception handler should have answered us' 
     209        p = session.query(Person).get(19) 
     210        assert p is None, \ 
     211            'This Person should have been rolled back: %s' % p 
    219212 
    220 def test_cntrl_commit(): 
    221     """It's safe to commit a transaction in the controller.""" 
    222     cherrypy.root = MyRoot() 
    223     create_request("/create_person?id=23&docom=1") 
    224     assert 'InvalidRequestError' not in cherrypy.response.body[0] 
    225     assert session.query(Person).get(23) is not None, \ 
    226         'The Person 23 should have been saved during commit inside controller' 
     213    def test_user_redirect(self): 
     214        """If a controller redirects, transactions are committed.""" 
     215        cherrypy.root = MyRoot() 
     216        self.app.get("/create_person?id=22&doerr=2") 
     217        assert session.query(Person).get(22) is not None, \ 
     218            'The controller only redirected, the Person should have been saved' 
    227219 
    228 def test_cntrl_commit2(): 
    229     """A commit inside the controller is not rolled back by the exception.""" 
    230     cherrypy.root = MyRoot() 
    231     create_request("/create_person?id=24&docom=1&doerr=1") 
    232     assert 'InvalidRequestError' not in cherrypy.response.body[0] 
    233     assert session.query(Person).get(24) is not None, \ 
    234         'The Person 24 should have been saved during commit' \ 
    235         ' inside controller and not rolled back' 
     220    def test_cntrl_commit(self): 
     221        """It's safe to commit a transaction in the controller.""" 
     222        cherrypy.root = MyRoot() 
     223        response = self.app.get("/create_person?id=23&docom=1") 
     224        assert 'InvalidRequestError' not in response 
     225        assert session.query(Person).get(23) is not None, \ 
     226            'The Person 23 should have been saved during commit inside controller' 
    236227 
    237 def test_cntrl_flush(): 
    238     """It's safe to flush in the controller.""" 
    239     cherrypy.root = MyRoot() 
    240     create_request("/create_person?id=25&doflush=1") 
    241     print cherrypy.response.body[0] 
    242     assert 'No exceptions occurred' in cherrypy.response.body[0] 
    243     create_request("/create_person?id=25&doflush=0") 
    244     assert cherrypy.response.status.startswith("500") 
    245     assert 'IntegrityError' in cherrypy.response.body[0] 
    246     create_request("/create_person?id=25&doflush=1") 
    247     assert cherrypy.response.status.startswith("200") 
    248     assert 'IntegrityError' in cherrypy.response.body[0] 
    249     create_request("/create_person?id=25&doflush=2") 
    250     assert cherrypy.response.status.startswith("200") 
    251     assert 'No exceptions occurred' in cherrypy.response.body[0] 
     228    def test_cntrl_commit2(self): 
     229        """A commit inside the controller is not rolled back by the exception.""" 
     230        cherrypy.root = MyRoot() 
     231        response = self.app.get("/create_person?id=24&docom=1&doerr=1") 
     232        assert 'InvalidRequestError' not in response 
     233        assert session.query(Person).get(24) is not None, \ 
     234            'The Person 24 should have been saved during commit' \ 
     235            ' inside controller and not rolled back' 
    252236 
     237    def test_cntrl_flush(self): 
     238        """It's safe to flush in the controller.""" 
     239        cherrypy.root = MyRoot() 
     240        response = self.app.get("/create_person?id=25&doflush=1") 
     241        assert 'No exceptions occurred' in response 
     242        response = self.app.get("/create_person?id=25&doflush=0", status=500) 
     243        assert 'IntegrityError' in response 
     244        response = self.app.get("/create_person?id=25&doflush=1") 
     245        assert 'IntegrityError' in response 
     246        response = self.app.get("/create_person?id=25&doflush=2") 
     247        assert 'No exceptions occurred' in response 
    253248 
     249 
    254250# Exception handling with rollback 
    255251 
    256252class RbRoot(RootController): 
     
    292288            session.rollback() 
    293289        raise Exception('test') 
    294290 
     291class TestExceptionRollback(TGWebTest): 
    295292 
    296 def test_exc_rollback(): 
    297     """An exception within a controller method causes a rollback. 
     293    def test_exc_rollback(self): 
     294        """An exception within a controller method causes a rollback. 
    298295 
    299     Try to create a user that should rollback because of an exception 
    300     so user 25 should not exist, but user 26 should be present since it 
    301     is created by the exception handler. 
     296        Try to create a user that should rollback because of an exception 
     297        so user 25 should not exist, but user 26 should be present since it 
     298        is created by the exception handler. 
    302299 
    303     """ 
    304     cherrypy.root = RbRoot() 
    305     create_request('/doerr?id=26') 
    306     output = cherrypy.response.body[0] 
    307     print output 
    308     assert 'KARL27' in output, 'Exception handler should have answered' 
    309     assert session.query(User).get(26) is None 
    310     assert session.query(User).get(27) is not None 
     300        """ 
     301        cherrypy.root = RbRoot() 
     302        response = self.app.get('/doerr?id=26') 
     303        assert 'KARL27' in response, 'Exception handler should have answered' 
     304        assert session.query(User).get(26) is None 
     305        assert session.query(User).get(27) is not None 
    311306 
    312 def test_exc_rollback2(): 
    313     """An exception within a controller method causes a rollback. 
     307    def test_exc_rollback2(self): 
     308        """An exception within a controller method causes a rollback. 
    314309 
    315     Try to create a user that should rollback because of an exception 
    316     so user XX should not exist. 
     310        Try to create a user that should rollback because of an exception 
     311        so user XX should not exist. 
    317312 
    318     """ 
    319     cherrypy.root = RbRoot() 
    320     create_request('/doerr?id=XX') 
    321     output = cherrypy.response.body[0] 
    322     assert 'KARL27' in output, 'Exception handler should have answered' 
    323     assert session.query(User).get('XX') is None 
     313        """ 
     314        cherrypy.root = RbRoot() 
     315        response = self.app.get('/doerr?id=XX') 
     316        assert 'KARL27' in response, 'Exception handler should have answered' 
     317        assert session.query(User).get('XX') is None 
    324318 
    325 def test_exc_done_rollback(): 
    326     """No problems with error handler if controller manually rollbacks.""" 
    327     cherrypy.root = RbRoot() 
    328     create_request('/doerr?id=28&dorb=1') 
    329     output = cherrypy.response.body[0] 
    330     assert 'KARL27' in output, 'Exception handler should have answered' 
    331     assert session.query(User).get(28) is None 
    332     assert session.query(User).get(29) is not None 
     319    def test_exc_done_rollback(self): 
     320        """No problems with error handler if controller manually rollbacks.""" 
     321        cherrypy.root = RbRoot() 
     322        response = self.app.get('/doerr?id=28&dorb=1') 
     323        assert 'KARL27' in response, 'Exception handler should have answered' 
     324        assert session.query(User).get(28) is None 
     325        assert session.query(User).get(29) is not None 
    333326 
    334327 
    335328# Session freshness tests 
     
    352345        assert session.query(Test).get(1).val == 'b' 
    353346        return dict() 
    354347 
     348class TestSessionFreshness(TGWebTest): 
    355349 
    356 def test_session_freshness(): 
    357     """Check for session freshness. 
     350    def test_session_freshness(self): 
     351        """Check for session freshness. 
    358352 
    359     Changes made to the data in thread B should be reflected in thread A. 
     353        Changes made to the data in thread B should be reflected in thread A. 
    360354 
    361     """ 
    362     test_table.insert().execute(dict(id=1, val='a')) 
    363     cherrypy.root = FreshRoot() 
    364     create_request("/test1") 
    365     assert cherrypy.response.status.startswith("200") 
    366     assert 'AssertionError' not in cherrypy.response.body[0] 
    367     # Call test2 in a different thread 
    368     class ThreadB(threading.Thread): 
    369         def run(self): 
    370             create_request("/test2") 
    371             assert cherrypy.response.status.startswith("200") 
    372             assert 'AssertionError' not in cherrypy.response.body[0] 
    373     thrdb = ThreadB() 
    374     thrdb.start() 
    375     thrdb.join() 
    376     create_request("/test3") 
    377     assert cherrypy.response.status.startswith("200") 
    378     assert 'AssertionError' not in cherrypy.response.body[0] 
     355        """ 
     356        test_table.insert().execute(dict(id=1, val='a')) 
     357        cherrypy.root = FreshRoot() 
     358        response = self.app.get("/test1") 
     359        assert 'AssertionError' not in response 
     360        # Call test2 in a different thread 
     361        class ThreadB(threading.Thread): 
     362            def __init__(self, app): 
     363                threading.Thread.__init__(self) 
     364                self.app = app 
     365            def run(self): 
     366                response = self.app.get("/test2") 
     367                assert 'AssertionError' not in response 
     368        thrdb = ThreadB(app=self.app) 
     369        thrdb.start() 
     370        thrdb.join() 
     371        response = self.app.get("/test3") 
     372        assert 'AssertionError' not in response 
  • turbogears/tests/test_expose.py

     
    11import cherrypy 
    22import simplejson 
    33 
    4 from turbogears import controllers, expose 
    5 from turbogears.testutil import create_request 
     4from turbogears import controllers, expose, testutil 
    65 
    76 
    87class ExposeRoot(controllers.RootController): 
     
    1918        return dict(title="Foobar", mybool=False, someval="foo") 
    2019 
    2120 
    22 def test_gettinghtml(): 
    23     cherrypy.root = ExposeRoot() 
    24     create_request("/with_json") 
    25     body = cherrypy.response.body[0] 
    26     assert "Paging all foo" in body 
     21class TestExposeRoot(testutil.TGWebTest): 
    2722 
    28 def test_gettingjson(): 
    29     cherrypy.root = ExposeRoot() 
    30     create_request("/with_json?tg_format=json") 
    31     body = cherrypy.response.body[0] 
    32     assert '"title": "Foobar"' in body 
     23    def test_gettinghtml(self): 
     24        cherrypy.root = ExposeRoot() 
     25        response = self.app.get("/with_json") 
     26        assert "Paging all foo" in response 
    3327 
    34 def test_gettingjsonviaaccept(): 
    35     cherrypy.root = ExposeRoot() 
    36     create_request("/with_json_via_accept", 
    37             headers=dict(Accept="text/javascript")) 
    38     body = cherrypy.response.body[0] 
    39     assert '"title": "Foobar"' in body 
     28    def test_gettingjson(self): 
     29        cherrypy.root = ExposeRoot() 
     30        response = self.app.get("/with_json?tg_format=json") 
     31        assert '"title": "Foobar"' in response 
    4032 
    41 def test_getting_json_with_accept_but_using_tg_format(): 
    42     cherrypy.root = ExposeRoot() 
    43     create_request("/with_json_via_accept?tg_format=json") 
    44     body = cherrypy.response.body[0] 
    45     assert '"title": "Foobar"' in body 
     33    def test_gettingjsonviaaccept(self): 
     34        cherrypy.root = ExposeRoot() 
     35        response = self.app.get("/with_json_via_accept", 
     36                headers=dict(Accept="text/javascript")) 
     37        assert '"title": "Foobar"' in response 
    4638 
    47 def test_getting_plaintext(): 
    48     cherrypy.root = ExposeRoot() 
    49     create_request("/with_json_via_accept", 
    50         headers=dict(Accept="text/plain")) 
    51     print cherrypy.response.body[0] 
    52     assert cherrypy.response.body[0] == "This is a plain text for foo." 
     39    def test_getting_json_with_accept_but_using_tg_format(self): 
     40        cherrypy.root = ExposeRoot() 
     41        response = self.app.get("/with_json_via_accept?tg_format=json") 
     42        assert '"title": "Foobar"' in response 
    5343 
    54 def test_allow_json(): 
     44    def test_getting_plaintext(self): 
     45        cherrypy.root = ExposeRoot() 
     46        response = self.app.get("/with_json_via_accept", 
     47                headers=dict(Accept="text/plain")) 
     48        assert response.body == "This is a plain text for foo." 
    5549 
    56     class NewRoot(controllers.RootController): 
    57         @expose(template="turbogears.tests.doesnotexist", allow_json=True) 
    58         def test(self): 
    59             return dict(title="Foobar", mybool=False, someval="niggles") 
     50    def test_allow_json(self): 
    6051 
    61     cherrypy.root = NewRoot() 
    62     create_request("/test", headers= dict(accept="text/javascript")) 
    63     body = cherrypy.response.body[0] 
    64     values = simplejson.loads(body) 
    65     assert values == dict(title="Foobar", mybool=False, someval="niggles", 
    66         tg_flash=None) 
    67     assert cherrypy.response.headers["Content-Type"] == "text/javascript" 
    68     create_request("/test?tg_format=json") 
    69     body = cherrypy.response.body[0] 
    70     values = simplejson.loads(body) 
    71     assert values == dict(title="Foobar", mybool=False, someval="niggles", 
    72         tg_flash=None) 
    73     assert cherrypy.response.headers["Content-Type"] == "text/javascript" 
     52        class NewRoot(controllers.RootController): 
     53            @expose(template="turbogears.tests.doesnotexist", allow_json=True) 
     54            def test(self): 
     55                return dict(title="Foobar", mybool=False, someval="niggles") 
     56 
     57        cherrypy.root = NewRoot() 
     58        response = self.app.get("/test", headers= dict(accept="text/javascript")) 
     59        values = simplejson.loads(response.body) 
     60        assert values == dict(title="Foobar", mybool=False, someval="niggles", 
     61            tg_flash=None) 
     62        assert response.content_type == "text/javascript" 
     63        response = self.app.get("/test?tg_format=json") 
     64        values = simplejson.loads(response.body) 
     65        assert values == dict(title="Foobar", mybool=False, someval="niggles", 
     66            tg_flash=None) 
     67        assert response.content_type == "text/javascript" 
  • turbogears/tests/test_controllers.py

     
    11import unittest 
     2import simplejson 
    23import formencode 
    34import cherrypy 
    45import pkg_resources 
     
    1819 
    1920    @expose() 
    2021    def index(self): 
    21         pass 
     22        return dict() 
    2223 
    2324    def validation_error_handler(self, tg_source, tg_errors, *args, **kw): 
    2425        self.functionname = tg_source.__name__ 
     
    4849                "turbogears.tests", "test_controllers.py")) 
    4950 
    5051    @expose() 
    51     def unicode(self): 
    52         cherrypy.response.headers["Content-Type"] = "text/html" 
     52    def unicode(self, response=None): 
     53        # TODO: fix me?  make response a strict parameter? or can we use cp safely 
     54        if response is None: 
     55            response = cherrypy.response 
     56        response.headers["Content-Type"] = "text/html" 
    5357        return u'\u00bfHabla espa\u00f1ol?' 
    5458 
    5559    @expose() 
     
    162166    def flash_redirected(self): 
    163167        return dict(title="Foobar", mybool=False, someval="niggles") 
    164168 
     169    @expose() 
     170    def redirect(self): 
     171        redirect("/foo") 
     172 
     173    @expose() 
     174    def raise_redirect(self): 
     175        raise redirect("/foo") 
     176 
    165177    @expose(html="turbogears.tests.simple", allow_json=True) 
    166178    def flash_redirect_with_trouble_chars(self): 
    167179        flash(u"$foo, k\xe4se;\tbar!") 
     
    211223        return "redirected OK" 
    212224 
    213225 
    214 class TestRoot(unittest.TestCase): 
     226class TestRoot(testutil.TGWebTest): 
    215227 
    216228    def setUp(self): 
     229        testutil.TGWebTest.setUp(self) 
    217230        cherrypy.root = None 
    218231        cherrypy.tree.mount_points = {} 
    219232        cherrypy.tree.mount(MyRoot(), "/") 
    220233        cherrypy.tree.mount(SubApp(), "/subthing") 
    221234 
    222235    def tearDown(self): 
     236        testutil.TGWebTest.tearDown(self) 
    223237        cherrypy.root = None 
    224238        cherrypy.tree.mount_points = {} 
    225239 
    226240    def test_js_files(self): 
    227241        """Can access the JavaScript files""" 
    228         testutil.create_request("/tg_js/MochiKit.js") 
    229         assert cherrypy.response.headers[ 
    230             "Content-Type"] == "application/x-javascript" 
    231         assert cherrypy.response.status == "200 OK" 
     242        response = self.app.get("/tg_js/MochiKit.js", status=200) 
     243        assert response.headers["Content-Type"] == "application/x-javascript" 
    232244 
    233245    def test_json_output(self): 
    234         testutil.create_request("/test?tg_format=json") 
    235         import simplejson 
    236         values = simplejson.loads(cherrypy.response.body[0]) 
     246        response = self.app.get("/test?tg_format=json") 
     247        values = simplejson.loads(response.body) 
    237248        assert values == dict(title="Foobar", mybool=False, 
    238249            someval="niggles", tg_flash=None) 
    239         assert cherrypy.response.headers["Content-Type"] == "text/javascript" 
     250        assert response.headers["Content-Type"] == "text/javascript" 
    240251 
    241252    def test_implied_json(self): 
    242         testutil.create_request("/impliedjson?tg_format=json") 
    243         assert '"title": "Blah"' in cherrypy.response.body[0] 
     253        response = self.app.get("/impliedjson?tg_format=json") 
     254        assert '"title": "Blah"' in response 
    244255 
    245256    def test_allow_json(self): 
    246         testutil.create_request("/allowjson?tg_format=json") 
    247         assert cherrypy.response.status.startswith("500") 
    248         assert cherrypy.response.headers["Content-Type"] == "text/html" 
     257        response = self.app.get("/allowjson?tg_format=json", status=500) 
     258        assert response.headers["Content-Type"] == "text/html" 
    249259 
    250260    def test_allow_json_config(self): 
    251261        """JSON output can be enabled via config.""" 
     
    256266                return dict(title="Foobar", mybool=False, someval="foo", 
    257267                     tg_html="turbogears.tests.simple") 
    258268        cherrypy.root = JSONRoot() 
    259         testutil.create_request('/allowjsonconfig?tg_format=json') 
    260         assert cherrypy.response.headers["Content-Type"] == "text/javascript" 
     269        response = self.app.get('/allowjsonconfig?tg_format=json') 
     270        assert response.headers["Content-Type"] == "text/javascript" 
    261271        config.update({'tg.allow_json': False}) 
    262272 
    263273    def test_allow_json_config_false(self): 
     
    269279                return dict(title="Foobar", mybool=False, someval="foo", 
    270280                     tg_html="turbogears.tests.simple") 
    271281        cherrypy.root = JSONRoot() 
    272         testutil.create_request('/allowjson?tg_format=json') 
    273         assert cherrypy.response.status.startswith("404") 
    274         assert cherrypy.response.headers["Content-Type"] == "text/html" 
     282        response = self.app.get('/allowjson?tg_format=json', status=404) 
     283        assert response.headers["Content-Type"] == "text/html" 
    275284        config.update({'tg.allow_json': False}) 
    276285 
    277286    def test_invalid_return(self): 
    278         testutil.create_request("/invalid") 
    279         assert cherrypy.response.status.startswith("500") 
     287        response = self.app.get("/invalid", status=500) 
    280288 
    281289    def test_strict_parameters(self): 
    282290        config.update({"tg.strict_parameters": True}) 
    283         testutil.create_request( 
    284             "/save?submit=save&firstname=Foo&lastname=Bar&badparam=1") 
    285         assert cherrypy.response.status.startswith("500") 
     291        response = self.app.get( 
     292            "/save?submit=save&firstname=Foo&lastname=Bar&badparam=1", 
     293            status=500) 
    286294        assert not hasattr(cherrypy.root, "errors") 
    287295 
    288296    def test_throw_out_random(self): 
    289297        """Can append random value to the URL to avoid caching problems.""" 
    290         testutil.create_request("/test?tg_random=1") 
    291         assert "Paging all niggles" in cherrypy.response.body[0] 
     298        response = self.app.get("/test?tg_random=1") 
     299        assert "Paging all niggles" in response 
    292300        config.update({"tg.strict_parameters": True}) 
    293         testutil.create_request("/test?tg_random=1") 
    294         assert cherrypy.response.status.startswith("200") 
    295         assert "Paging all niggles" in cherrypy.response.body[0] 
    296         testutil.create_request("/test?tg_not_random=1") 
    297         assert cherrypy.response.status.startswith("500") 
     301        response = self.app.get("/test?tg_random=1", status=200) 
     302        assert "Paging all niggles" in response 
     303        response = self.app.get("/test?tg_not_random=1", status=500) 
    298304        assert not hasattr(cherrypy.root, "errors") 
    299305 
    300306    def test_ignore_parameters(self): 
    301307        config.update({"tg.strict_parameters": True}) 
    302         testutil.create_request("/test?ignore_me=1") 
    303         assert cherrypy.response.status.startswith("500") 
     308        response = self.app.get("/test?ignore_me=1", status=500) 
    304309        assert not hasattr(cherrypy.root, "errors") 
    305310        config.update({"tg.ignore_parameters": ['ignore_me', 'me_too']}) 
    306         testutil.create_request("/test?ignore_me=1") 
    307         assert "Paging all niggles" in cherrypy.response.body[0] 
    308         testutil.create_request("/test?me_too=1") 
    309         assert cherrypy.response.status.startswith("200") 
    310         assert "Paging all niggles" in cherrypy.response.body[0] 
    311         testutil.create_request("/test?me_not=1") 
    312         assert cherrypy.response.status.startswith("500") 
     311        response = self.app.get("/test?ignore_me=1") 
     312        assert "Paging all niggles" in response 
     313        response = self.app.get("/test?me_too=1", status=200) 
     314        assert "Paging all niggles" in response 
     315        response = self.app.get("/test?me_not=1", status=500) 
    313316        assert not hasattr(cherrypy.root, "errors") 
    314317 
    315318    def test_retrieve_dict_directly(self): 
    316         d = testutil.call(cherrypy.root.returnjson) 
    317         assert d["title"] == "Foobar" 
     319        response = self.app.get('/returnjson') 
     320        assert response.namespace["title"] == "Foobar" 
    318321 
    319322    def test_templateOutput(self): 
    320         testutil.create_request("/test") 
    321         assert "Paging all niggles" in cherrypy.response.body[0] 
     323        response = self.app.get("/test") 
     324        assert "Paging all niggles" in response 
    322325 
    323326    def test_safari_unicode_fix(self): 
    324         testutil.create_request("/unicode", headers={'User-Agent': 
     327        response = self.app.get("/unicode", headers={'User-Agent': 
    325328            "Apple WebKit Safari/412.2"}) 
    326         firstline = cherrypy.response.body[0].split('\n')[0] 
     329        firstline = response.body.split('\n')[0] 
    327330        assert firstline == "¿Habla español?" 
    328331        assert isinstance(firstline, str) 
    329332 
    330333    def test_default_format(self): 
    331334        """The default format can be set via expose""" 
    332         testutil.create_request("/returnjson") 
    333         firstline = cherrypy.response.body[0] 
    334         assert '"title": "Foobar"' in firstline 
    335         testutil.create_request("/returnjson?tg_format=html") 
    336         assert cherrypy.response.status.startswith("500") 
    337         firstline = cherrypy.response.body[0] 
    338         assert '"title": "Foobar"' not in firstline 
     335        response = self.app.get("/returnjson") 
     336        assert '"title": "Foobar"' in response 
     337        response = self.app.get("/returnjson?tg_format=html", status=500) 
    339338 
    340339    def test_content_type(self): 
    341340        """The content-type can be set via expose""" 
    342         testutil.create_request("/contenttype") 
    343         assert cherrypy.response.headers["Content-Type"] == "xml/atom" 
     341        response = self.app.get("/contenttype") 
     342        assert response.headers["Content-Type"] == "xml/atom" 
    344343 
    345344    def test_returned_template_name(self): 
    346         testutil.create_request("/returnedtemplate") 
    347         data = cherrypy.response.body[0].lower() 
     345        response = self.app.get("/returnedtemplate") 
     346        data = response.body.lower() 
    348347        assert "<body>" in data 
    349348        assert 'groovy test template' in data 
    350349 
    351350    def test_returned_template_short(self): 
    352         testutil.create_request("/returnedtemplate_short") 
    353         assert "Paging all foo" in cherrypy.response.body[0] 
     351        response = self.app.get("/returnedtemplate_short") 
     352        assert "Paging all foo" in response 
    354353 
    355354    def test_expose_template_short(self): 
    356         testutil.create_request("/exposetemplate_short") 
    357         assert "Paging all foo" in cherrypy.response.body[0] 
     355        response = self.app.get("/exposetemplate_short") 
     356        assert "Paging all foo" in response 
    358357 
    359358    def test_validation(self): 
    360359        """Data can be converted and validated""" 
    361         testutil.create_request("/istrue?value=true") 
     360        response = self.app.get("/istrue?value=true") 
    362361        assert cherrypy.root.value is True 
    363         testutil.create_request("/istrue?value=false") 
     362        response = self.app.get("/istrue?value=false") 
    364363        assert cherrypy.root.value is False 
    365364        cherrypy.root = MyRoot() 
    366         testutil.create_request("/istrue?value=foo") 
     365        response = self.app.get("/istrue?value=foo") 
    367366        assert not hasattr(cherrypy.root, "value") 
    368367        assert cherrypy.root.functionname == "istrue" 
    369         testutil.create_request("/save?submit=send&firstname=John&lastname=Doe") 
     368        response = self.app.get("/save?submit=send&firstname=John&lastname=Doe") 
    370369        assert cherrypy.root.fullname == "John Doe" 
    371370        assert cherrypy.root.submit == "send" 
    372         testutil.create_request("/save?submit=send&firstname=Arthur") 
     371        response = self.app.get("/save?submit=send&firstname=Arthur") 
    373372        assert cherrypy.root.fullname == "Arthur Miller" 
    374         testutil.create_request("/save?submit=send&firstname=Arthur&lastname=") 
     373        response = self.app.get("/save?submit=send&firstname=Arthur&lastname=") 
    375374        assert cherrypy.root.fullname == "Arthur " 
    376         testutil.create_request("/save?submit=send&firstname=D&lastname=") 
     375        response = self.app.get("/save?submit=send&firstname=D&lastname=") 
    377376        assert len(cherrypy.root.errors) == 1 
    378377        assert cherrypy.root.errors.has_key("firstname") 
    379378        assert "characters" in cherrypy.root.errors["firstname"].msg.lower() 
    380         testutil.create_request("/save?submit=send&firstname=&lastname=") 
     379        response = self.app.get("/save?submit=send&firstname=&lastname=") 
    381380        assert len(cherrypy.root.errors) == 1 
    382381        assert cherrypy.root.errors.has_key("firstname") 
    383382 
    384383    def test_validation_chained(self): 
    385384        """Validation is not repeated if it already happened""" 
    386385        cherrypy.root.value = None 
    387         testutil.create_request("/errorchain?value=true") 
     386        self.app.get("/errorchain?value=true") 
    388387        assert cherrypy.root.value is None 
    389         testutil.create_request("/errorchain?value=notbool") 
     388        self.app.get("/errorchain?value=notbool") 
    390389        assert cherrypy.root.value == 'notbool' 
    391390 
    392391    def test_validation_nested(self): 
    393392        """Validation is not repeated in nested method call""" 
    394393        cherrypy.root.value = None 
    395         testutil.create_request("/nestedcall?value=true") 
     394        response = self.app.get("/nestedcall?value=true") 
    396395        assert cherrypy.root.value == 'True' 
    397         testutil.create_request("/nestedcall?value=false") 
     396        self.app.get("/nestedcall?value=false") 
    398397        assert cherrypy.root.value == 'False' 
    399398 
    400399    def test_validation_with_schema(self): 
    401400        """Data can be converted/validated with formencode.Schema instance""" 
    402         testutil.create_request("/save2?submit=send&firstname=Joe&lastname=Doe") 
     401        response = self.app.get("/save2?submit=send&firstname=Joe&lastname=Doe") 
    403402        assert cherrypy.root.fullname == "Joe Doe" 
    404403        assert cherrypy.root.submit == "send" 
    405         testutil.create_request("/save2?submit=send&firstname=Arthur&lastname=") 
     404        response = self.app.get("/save2?submit=send&firstname=Arthur&lastname=") 
    406405        assert cherrypy.root.fullname == "Arthur " 
    407         testutil.create_request("/save2?submit=send&firstname=&lastname=") 
     406        response = self.app.get("/save2?submit=send&firstname=&lastname=") 
    408407        assert len(cherrypy.root.errors) == 1 
    409408        assert cherrypy.root.errors.has_key("firstname") 
    410         testutil.create_request("/save2?submit=send&firstname=D&lastname=") 
     409        response = self.app.get("/save2?submit=send&firstname=D&lastname=") 
    411410        assert len(cherrypy.root.errors) == 1 
    412411        assert cherrypy.root.errors.has_key("firstname") 
    413412 
    414413    def test_other_template(self): 
    415414        """'tg_html' in a returned dict will use the template specified there""" 
    416         testutil.create_request("/useother") 
    417         assert "This is the other template" in cherrypy.response.body[0] 
     415        response = self.app.get("/useother") 
     416        assert "This is the other template" in response 
    418417 
    419418    def test_cheetah_template(self): 
    420419        """Cheetah templates can be used as well""" 
    421         testutil.create_request("/usecheetah") 
    422         body = cherrypy.response.body[0] 
    423         assert "This is the Cheetah test template." in body 
    424         assert "Paging all chimps." in body 
     420        response = self.app.get("/usecheetah") 
     421        assert "This is the Cheetah test template." in response 
     422        assert "Paging all chimps." in response 
    425423 
    426424    def test_run_with_trans(self): 
    427425        """run_with_transaction is called only on topmost exposed method""" 
    428426        oldrwt = database.run_with_transaction 
    429427        database.run_with_transaction = cherrypy.root.rwt 
    430         testutil.create_request("/nestedcall?value=true") 
     428        self.app.get("/nestedcall?value=true") 
    431429        database.run_with_transaction = oldrwt 
    432430        assert cherrypy.root.value 
    433431        assert cherrypy.root.rwt_called == 1 
    434432 
    435433    def test_positional(self): 
    436434        """Positional parameters should work""" 
    437         testutil.create_request("/pos/foo") 
     435        response = self.app.get("/pos/foo") 
    438436        assert cherrypy.root.posvalue == "foo" 
    439437 
    440438    def test_flash_plain(self): 
    441439        """flash with strings should work""" 
    442         testutil.create_request("/flash_plain?tg_format=json") 
    443         import simplejson 
    444         values = simplejson.loads(cherrypy.response.body[0]) 
     440        response = self.app.get("/flash_plain?tg_format=json") 
     441        values = simplejson.loads(response.body) 
    445442        assert values["tg_flash"] == "plain" 
    446         assert not cherrypy.response.simple_cookie.has_key("tg_flash") 
     443        assert not response.headers.has_key("tg_flash") 
    447444 
    448445    def test_flash_unicode(self): 
    449446        """flash with unicode objects should work""" 
    450         testutil.create_request("/flash_unicode?tg_format=json") 
    451         import simplejson 
    452         values = simplejson.loads(cherrypy.response.body[0]) 
     447        response = self.app.get("/flash_unicode?tg_format=json") 
     448        values = simplejson.loads(response.body) 
    453449        assert values["tg_flash"] == u"\xfcnicode" 
    454         assert not cherrypy.response.simple_cookie.has_key("tg_flash") 
     450        assert not response.headers.has_key("tg_flash") 
    455451 
    456452    def test_flash_on_redirect(self): 
    457453        """flash must survive a redirect""" 
    458         testutil.create_request("/flash_redirect?tg_format=json") 
    459         assert cherrypy.response.status.startswith("302") 
    460         testutil.create_request(cherrypy.response.headers["Location"], 
    461             headers=dict(Cookie=cherrypy.response.simple_cookie.output( 
    462                 header="").strip())) 
    463         import simplejson 
    464         values = simplejson.loads(cherrypy.response.body[0]) 
     454        response = self.app.get("/flash_redirect?tg_format=json", status=302) 
     455        response = self.app.get(response.location, 
     456            headers=dict(Cookie=response.headers['Set-Cookie'])) 
     457        values = simplejson.loads(response.body) 
    465458        assert values["tg_flash"] == u"redirect \xfcnicode" 
    466459 
    467460    def test_flash_redirect_with_trouble_chars(self): 
    468461        """flash redirect with chars that can cause troubles in cookies""" 
    469         testutil.create_request("/flash_redirect_with_trouble_chars?tg_format=json") 
    470         assert cherrypy.response.status.startswith("302") 
    471         value = cherrypy.response.simple_cookie["tg_flash"].value 
     462        response = self.app.get("/flash_redirect_with_trouble_chars?tg_format=json", status=302) 
     463 
     464        # FIXME: 
     465        # This now returns: '"%24foo%2C%20k\\303\\244se%3B%09bar!"' 
     466        value = response.cookies_set['tg_flash'] 
     467 
     468        # ...where this normally returns: '%24foo%2C%20k\xc3\xa4se%3B%09bar!' 
     469        #value = cherrypy.response.simple_cookie["tg_flash"].value 
     470 
    472471        assert '$' not in value 
    473472        assert ',' not in value and ';' not in value 
    474473        assert ' ' not in value and '\t' not in value 
    475474        assert 'foo' in value and 'bar' in value 
    476475        assert u'k\xe4se'.encode('utf-8') in value 
    477476        assert '!' in value 
    478         testutil.create_request(cherrypy.response.headers["Location"], 
    479             headers=dict(Cookie=cherrypy.response.simple_cookie.output( 
    480                 header="").strip())) 
    481         import simplejson 
    482         values = simplejson.loads(cherrypy.response.body[0]) 
     477 
     478        response = self.app.get(response.location, 
     479                                headers=dict(Cookie=response.headers['Set-Cookie'])) 
     480        values = simplejson.loads(response.body) 
    483481        assert values["tg_flash"] == u"$foo, k\xe4se;\tbar!" 
    484482 
    485483    def test_double_flash(self): 
     
    487485        # Here we are calling method that sets a flash message. However flash 
    488486        # cookie is still there. Turbogears should discard old flash message 
    489487        # from cookie and use new one, set by flash_plain(). 
    490         testutil.create_request("/flash_plain?tg_format=json", 
     488        response = self.app.get("/flash_plain?tg_format=json", 
    491489            headers=dict(Cookie='tg_flash="old flash"; Path=/;')) 
    492         import simplejson 
    493         values = simplejson.loads(cherrypy.response.body[0]) 
     490        values = simplejson.loads(response.body) 
    494491        assert values["tg_flash"] == "plain" 
    495         assert cherrypy.response.simple_cookie.has_key("tg_flash"), \ 
     492        assert response.cookies_set.has_key("tg_flash"), \ 
    496493                "Cookie clearing request should be present" 
    497         flashcookie = cherrypy.response.simple_cookie['tg_flash'] 
    498         assert flashcookie['expires'] == 0 
    499494 
    500495    def test_set_kid_outputformat_in_config(self): 
    501496        """the outputformat for kid can be set in the config""" 
    502497        config.update({'kid.outputformat': 'xhtml'}) 
    503         testutil.create_request('/test') 
    504         response = cherrypy.response.body[0] 
     498        response = self.app.get('/test') 
    505499        assert '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML ' in response 
    506500        config.update({'kid.outputformat': 'html'}) 
    507         testutil.create_request('/test') 
    508         response = cherrypy.response.body[0] 
     501        response = self.app.get('/test') 
    509502        assert  '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML ' in response 
    510503        assert '    This is the groovy test ' in response 
    511504        config.update({'kid.outputformat': 'html compact'}) 
    512         testutil.create_request('/test') 
    513         response = cherrypy.response.body[0] 
     505        response = self.app.get('/test') 
    514506        assert  '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML ' in response 
    515507        assert 'This is the groovy test ' in response 
    516508        assert '    ' not in response 
     
    518510    def test_fileserving(self): 
    519511        #outputcap = StringIO() 
    520512        #sys.stdout = outputcap 
    521         testutil.create_request("/servefile") 
     513        response = self.app.get("/servefile") 
    522514        assert cherrypy.root.servedit 
    523515        assert not cherrypy.root.serve_exceptions 
    524516        #assert "AssertionError" not in outputcap.getvalue() 
    525517 
    526518    def test_internal_redirect(self): 
    527519        """regression test for #1022, #1407 and #1598""" 
    528         testutil.create_request("/internal_redirect") 
    529         firstline = cherrypy.response.body[0] 
    530         assert "redirected OK" in firstline 
     520        response = self.app.get("/internal_redirect") 
     521        assert "redirected OK" in response 
    531522 
    532523    def test_internal_redirect_nested_variables(self): 
    533524        """regression test for #1022, #1407 and #1598""" 
    534         testutil.create_request( 
     525        response = self.app.get( 
    535526            "/internal_redirect?a=1&a-1.b=2&a-2.c=3&a-2.c-1=4") 
    536         firstline = cherrypy.response.body[0] 
    537         assert "redirected OK" in firstline 
     527        assert "redirected OK" in response 
    538528 
    539529    def test_exc_value(self): 
    540530        """Exception is handled gracefully by the right exception handler.""" 
    541         testutil.create_request("/raise_value_exc") 
    542         assert 'handling_value' in cherrypy.response.body[0] 
     531        response = self.app.get("/raise_value_exc") 
     532        assert 'handling_value' in response 
    543533 
    544534    def test_exc_index(self): 
    545535        """Exception is handled gracefully by the right exception handler.""" 
    546         testutil.create_request("/raise_index_exc") 
    547         assert 'handling_index' in cherrypy.response.body[0] 
     536        response = self.app.get("/raise_index_exc") 
     537        assert 'handling_index' in response 
    548538 
    549539    def test_exc_all(self): 
    550540        """Test a controller that is protected by multiple exception handlers. 
     
    553543        by their respective handlers without problem... 
    554544 
    555545        """ 
    556         testutil.create_request("/raise_all_exc?num=1") 
    557         assert 'handling_value' in cherrypy.response.body[0] 
    558         testutil.create_request("/raise_all_exc?num=2") 
    559         assert 'handling_index' in cherrypy.response.body[0] 
    560         testutil.create_request("/raise_all_exc?num=3") 
    561         assert 'handling_key' in cherrypy.response.body[0] 
     546        response = self.app.get("/raise_all_exc?num=1") 
     547        assert 'handling_value' in response 
     548        response = self.app.get("/raise_all_exc?num=2") 
     549        assert 'handling_index' in response 
     550        response = self.app.get("/raise_all_exc?num=3") 
     551        assert 'handling_key' in response 
    562552 
    563553 
    564 class TestURLs(unittest.TestCase): 
     554class TestURLs(testutil.TGWebTest): 
    565555 
    566556    def setUp(self): 
     557        testutil.TGWebTest.setUp(self) 
    567558        cherrypy.tree.mount_points = {} 
    568559        cherrypy.root = MyRoot() 
    569560        cherrypy.root.subthing = SubApp() 
    570561        cherrypy.root.subthing.subsubthing = SubApp() 
    571562 
    572563    def test_basic_urls(self): 
    573         testutil.create_request("/") 
     564        self.app.get("/") 
    574565        assert "/foo" == url("/foo") 
    575566        assert "foo/bar" == url(["foo", "bar"]) 
    576567        assert url("/foo", bar=1, baz=2) in \ 
     
    584575        assert url("/foo") == "/foo" 
    585576 
    586577    def test_approots(self): 
    587         testutil.create_request("/subthing/") 
     578        config.update({"server.webpath": "/subthing"}) 
     579        self.app.get("/subthing/") 
    588580        assert url("foo") == "foo" 
    589581        assert url("/foo") == "/subthing/foo" 
    590582 
    591583    def test_lower_approots(self): 
    592         testutil.create_request("/subthing/subsubthing/") 
     584        config.update({"server.webpath": "/subthing/subsubthing"}) 
     585        self.app.get("/subthing/subsubthing/") 
    593586        assert url("/foo") == "/subthing/subsubthing/foo" 
    594587 
    595     def test_approots_With_path(self): 
    596         config.update({"server.webpath": "/coolsite/root"}) 
    597         startup.startTurboGears() 
    598         testutil.create_request("/coolsite/root/subthing/") 
     588    def test_approots_with_path(self): 
     589        config.update({"server.webpath": "/coolsite/root/subthing"}) 
     590        self.app.get("/subthing/") 
    599591        assert url("/foo") == "/coolsite/root/subthing/foo" 
    600592 
    601593    def test_redirect(self): 
    602594        config.update({"server.webpath": "/coolsite/root"}) 
    603         startup.startTurboGears() 
    604         testutil.create_request("/coolsite/root/subthing/") 
    605         try: 
    606             redirect("/foo") 
    607             assert False, "redirect exception should have been raised" 
    608         except cherrypy.HTTPRedirect, e: 
    609             assert "http://localhost/coolsite/root/subthing/foo" in e.urls 
    610         try: 
    611             raise redirect("/foo") 
    612             assert False, "redirect exception should have been raised" 
    613         except cherrypy.HTTPRedirect, e: 
    614             assert "http://localhost/coolsite/root/subthing/foo" in e.urls 
     595        response = self.app.get("/redirect") 
     596        assert response.location == 'http://localhost:80/coolsite/root/foo' 
     597        self.app.get("/raise_redirect") 
     598        assert response.location == 'http://localhost:80/coolsite/root/foo' 
    615599 
    616600    def test_multi_values(self): 
    617         testutil.create_request("/") 
     601        self.app.get("/") 
    618602        assert url("/foo", bar=[1, 2]) in \ 
    619603            ["/foo?bar=1&bar=2", "/foo?bar=2&bar=1"] 
    620604        assert url("/foo", bar=("asdf", "qwer")) in \ 
     
    622606 
    623607    def test_unicode(self): 
    624608        """url() can handle unicode parameters""" 
    625         testutil.create_request("/") 
     609        self.app.get("/") 
    626610        assert url('/', x=u'\N{LATIN SMALL LETTER A WITH GRAVE}' 
    627611            u'\N{LATIN SMALL LETTER E WITH GRAVE}' 
    628612            u'\N{LATIN SMALL LETTER I WITH GRAVE}' 
     
    632616 
    633617    def test_list(self): 
    634618        """url() can handle list parameters, with unicode too""" 
    635         testutil.create_request("/") 
     619        self.app.get("/") 
    636620        assert url('/', foo=['bar', u'\N{LATIN SMALL LETTER A WITH GRAVE}'] 
    637621            ) == '/?foo=bar&foo=%C3%A0' 
    638622 
    639623    def tearDown(self): 
     624        testutil.TGWebTest.tearDown(self) 
    640625        config.update({"server.webpath": ""}) 
    641         startup.startTurboGears() 
    642626 
    643627 
    644 def test_index_trailing_slash(): 
    645     """If there is no trailing slash on an index method call, redirect""" 
    646     cherrypy.root = SubApp() 
    647     cherrypy.root.foo = SubApp() 
    648     testutil.create_request("/foo") 
    649     assert cherrypy.response.status.startswith("302") 
     628    def test_index_trailing_slash(self): 
     629        """If there is no trailing slash on an index method call, redirect""" 
     630        cherrypy.root = SubApp() 
     631        cherrypy.root.foo = SubApp() 
     632        self.app.get("/foo", status=302) 
    650633 
    651 def test_can_use_internally_defined_arguments(): 
    652     """Can use argument names that are internally used by TG in controllers""" 
     634    def test_can_use_internally_defined_arguments(self): 
     635        """Can use argument names that are internally used by TG in controllers""" 
    653636 
    654     class App(controllers.RootController): 
     637        class App(controllers.RootController): 
    655638 
    656         @expose() 
    657         def index(self, **kw): 
    658             return "\n".join(["%s:%s" % i for i in kw.iteritems()]) 
     639            @expose() 
     640            def index(self, **kw): 
     641                return "\n".join(["%s:%s" % i for i in kw.iteritems()]) 
    659642 
    660     cherrypy.root = App() 
    661     testutil.create_request("/?format=foo&template=bar&fragment=boo") 
    662     output = cherrypy.response.body[0] 
    663     assert "format:foo" in output 
    664     assert "template:bar" in output 
    665     assert "fragment:boo" in output 
     643        cherrypy.root = App() 
     644        response = self.app.get("/?format=foo&template=bar&fragment=boo") 
     645        assert "format:foo" in response 
     646        assert "template:bar" in response 
     647        assert "fragment:boo" in response 
    666648 
    667 def test_url_kwargs_overwrite_tgparams(): 
    668     """Check keys in tgparams in call to url overwrite kw args""" 
    669     params = {'spamm': 'eggs'} 
    670     assert 'spamm=ham' in url('/foo', params, spamm='ham') 
     649    def test_url_kwargs_overwrite_tgparams(self): 
     650        """Check keys in tgparams in call to url overwrite kw args""" 
     651        params = {'spamm': 'eggs'} 
     652        assert 'spamm=ham' in url('/foo', params, spamm='ham') 
    671653 
    672 def test_url_doesnt_change_tgparams(): 
    673     """Test that url() does not change the dict passed as second arg""" 
    674     params = {'spamm': 'eggs'} 
    675     assert 'foo' in url('/foo', params, spamm='ham') 
    676     assert params['spamm'] == 'eggs' 
     654    def test_url_doesnt_change_tgparams(self): 
     655        """Test that url() does not change the dict passed as second arg""" 
     656        params = {'spamm': 'eggs'} 
     657        assert 'foo' in url('/foo', params, spamm='ham') 
     658        assert params['spamm'] == 'eggs' 
  • turbogears/tests/test_catwalk.py

     
    4040        pass 
    4141    index = turbogears.expose()(index) 
    4242 
    43 class Browse(unittest.TestCase): 
     43class Browse(testutil.TGWebTest): 
    4444    def setUp(self): 
     45        testutil.TGWebTest.setUp(self) 
    4546        browse_data(browse) 
    4647        cherrypy.root = MyRoot() 
    4748 
    4849    def test_wrong_filter_format(self): 
    4950        cherrypy.root.catwalk = CatWalk(browse) 
    50         testutil.create_request("/catwalk/browse/?object_name=Song&filters=Guantanemera&tg_format=json") 
    51         response = cherrypy.response.body[0] 
     51        response = self.app.get("/catwalk/browse/?object_name=Song&filters=Guantanemera&tg_format=json") 
    5252        assert 'filter_format_error' in response 
    5353 
    5454    def test_wrong_filter_column(self): 
    5555        cherrypy.root.catwalk = CatWalk(browse) 
    56         testutil.create_request("/catwalk/browse/?object_name=Song&filters=guacamole:2&tg_format=json") 
    57         response = cherrypy.response.body[0] 
     56        response = self.app.get("/catwalk/browse/?object_name=Song&filters=guacamole:2&tg_format=json") 
    5857        assert 'filter_column_error' in response 
    5958 
    6059    def test_filters(self): 
    6160        cherrypy.root.catwalk = CatWalk(browse) 
    62         testutil.create_request("/catwalk/browse/?object_name=Song&tg_format=json") 
    63         response = cherrypy.response.body[0] 
     61        response = self.app.get("/catwalk/browse/?object_name=Song&tg_format=json") 
    6462        values = simplejson.loads(response) 
    6563        assert values['total'] == 15 * 15 * 15 #without the filters we get all songs (3375) 
    66         testutil.create_request("/catwalk/browse/?object_name=Song&filters=album:1&tg_format=json") 
    67         response = cherrypy.response.body[0] 
     64        response = self.app.get("/catwalk/browse/?object_name=Song&filters=album:1&tg_format=json") 
    6865        values = simplejson.loads(response) 
    6966        assert values['total'] == 15 #filter by album id (only 15 songs) 
    7067 
    7168    def test_response_fields(self): 
    7269        #Check that the response contains the expected keys 
    7370        cherrypy.root.catwalk = CatWalk(browse) 
    74         testutil.create_request("/catwalk/browse/?object_name=Artist&start=3&page_size=20&tg_format=json") 
    75         response = cherrypy.response.body[0] 
     71        response = self.app.get("/catwalk/browse/?object_name=Artist&start=3&page_size=20&tg_format=json") 
    7672        values = simplejson.loads(response) 
    7773        assert values.has_key('headers') 
    7874        assert values.has_key('rows') 
     
    8783        #Control that the count for related and multiple joins match 
    8884        #the number of related instances when accessed as a field 
    8985        cherrypy.root.catwalk = CatWalk(browse) 
    90         testutil.create_request("/catwalk/browse/?object_name=Artist&tg_format=json") 
    91         response = cherrypy.response.body[0] 
     86        response = self.app.get("/catwalk/browse/?object_name=Artist&tg_format=json") 
    9287        values = simplejson.loads(response) 
    9388        artist = browse.Artist.get(1) 
    9489        assert int(values['rows'][0]['genres']) == len(list(artist.genres)) 
     
    9792    def test_rows_column_number(self): 
    9893        #Control that the number of columns match the number of fields in the model 
    9994        cherrypy.root.catwalk = CatWalk(browse) 
    100         testutil.create_request("/catwalk/browse/?object_name=Artist&tg_format=json") 
    101         response = cherrypy.response.body[0] 
     95        response = self.app.get("/catwalk/browse/?object_name=Artist&tg_format=json") 
    10296        values = simplejson.loads(response) 
    10397        assert len(values['rows'][0]) == 4 
    10498 
    10599    def test_rows_limit(self): 
    106100        #Update the limit of rows for the query and control the number of rows returned 
    107101        cherrypy.root.catwalk = CatWalk(browse) 
    108         testutil.create_request("/catwalk/browse/?object_name=Artist&tg_format=json") 
    109         response = cherrypy.response.body[0] 
     102        response = self.app.get("/catwalk/browse/?object_name=Artist&tg_format=json") 
    110103        values = simplejson.loads(response) 
    111104        assert values.has_key('rows') 
    112105        assert len(values['rows']) == 10 
    113         testutil.create_request("/catwalk/browse/?object_name=Artist&page_size=15&tg_format=json") 
    114         response = cherrypy.response.body[0] 
     106        response = self.app.get("/catwalk/browse/?object_name=Artist&page_size=15&tg_format=json") 
    115107        values = simplejson.loads(response) 
    116108        assert values.has_key('rows') 
    117109        assert len(values['rows']) == 15 
     
    119111    def test_header_labels(self): 
    120112        #Check that the returned header labels match the the model 
    121113        cherrypy.root.catwalk = CatWalk(browse) 
    122         testutil.create_request("/catwalk/browse/?object_name=Artist&tg_format=json") 
    123         response = cherrypy.response.body[0] 
     114        response = self.app.get("/catwalk/browse/?object_name=Artist&tg_format=json") 
    124115        values = simplejson.loads(response) 
    125116        assert len(values['headers']) == 5 
    126117        for header in values['headers']: 
    127118            assert header['name'] in ['id','name','albums','genres', 'plays_instruments'] 
    128119 
    129120 
    130 class TestJoinedOperations( testutil.DBTest): 
     121class TestJoinedOperations(testutil.DBWebTest): 
    131122    model = browse 
    132123 
    133124    def setUp(self): 
    134125        cherrypy.root = MyRoot() 
    135126        cherrypy.root.catwalk = CatWalk(browse) 
    136         testutil.DBTest.setUp(self) 
     127        testutil.DBWebTest.setUp(self) 
    137128        browse_data(browse) 
    138129 
    139130    def test_addremove_related_joins(self): 
    140131        # check the update_join function when nondefault add/remove are used 
    141132        artist = self.model.Artist.get(1) 
    142133        assert len(artist.plays_instruments) == 0 
    143         testutil.create_request("/catwalk/updateJoins?objectName=Artist&id=1&join=plays_instruments&joinType=&joinObjectName=Instrument&joins=1%2C2&tg_format=json") 
     134        response = self.app.get("/catwalk/updateJoins?objectName=Artist&id=1&join=plays_instruments&joinType=&joinObjectName=Instrument&joins=1%2C2&tg_format=json") 
    144135        assert len(artist.plays_instruments) == 2 
    145         testutil.create_request("/catwalk/updateJoins?objectName=Artist&id=1&join=plays_instruments&joinType=&joinObjectName=Instrument&joins=1&tg_format=json") 
     136        response = self.app.get("/catwalk/updateJoins?objectName=Artist&id=1&join=plays_instruments&joinType=&joinObjectName=Instrument&joins=1&tg_format=json") 
    146137        assert len(artist.plays_instruments) == 1, str(artist.plays_instruments) 
  • turbogears/tests/test_paginate.py

     
    44from urllib import quote 
    55import warnings 
    66 
    7 from turbogears import config, expose, database 
     7from turbogears import config, expose, database, testutil 
    88from turbogears.controllers import RootController, url 
    99from turbogears.database import get_engine, metadata, session, mapper 
    1010from turbogears.paginate import paginate, sort_ordering, sort_data 
    11 from turbogears.testutil import create_request, sqlalchemy_cleanup 
     11from turbogears.testutil import sqlalchemy_cleanup 
    1212from turbojson.jsonify import jsonify 
    1313 
    1414import cherrypy 
     
    183183    return result 
    184184 
    185185 
    186 class TestSpy(unittest.TestCase): 
     186class TestSpy(testutil.TGWebTest): 
    187187    """Never trust a spy""" 
    188188 
    189189    class MyRoot(RootController): 
     
    218218 
    219219 
    220220    def setUp(self): 
     221        testutil.TGWebTest.setUp(self) 
    221222        cherrypy.root = self.MyRoot() 
    222223 
    223224    def test_spy(self): 
    224         create_request('/spy') 
    225         body = cherrypy.response.body[0] 
    226         Spy.assert_ok(body, 'current_page', 1) 
     225        response = self.app.get('/spy') 
     226        Spy.assert_ok(response.body, 'current_page', 1) 
    227227        try: 
    228             Spy.assert_ok(body, 'current_page', 2) 
     228            Spy.assert_ok(response.body, 'current_page', 2) 
    229229            raise Exception("above test should have failed") 
    230230        except AssertionError: 
    231231            pass 
    232232 
    233233    def test_correct_expectation(self): 
    234         create_request('/spy_correct_expectation') 
    235         body = cherrypy.response.body[0] 
    236         assert "ok: [paginate" in body 
     234        response = self.app.get('/spy_correct_expectation') 
     235        assert "ok: [paginate" in response 
    237236 
    238237    def test_wrong_expectation(self): 
    239         create_request('/spy_wrong_expectation') 
    240         body = cherrypy.response.body[0] 
    241         assert "fail: expected page_count=9, got page_count=10" in body 
     238        response = self.app.get('/spy_wrong_expectation') 
     239        assert "fail: expected page_count=9, got page_count=10" in response 
    242240 
    243241    def test_invalid_expectation(self): 
    244         create_request('/spy_invalid_expectation') 
    245         body = cherrypy.response.body[0] 
    246         assert "fail: paginate does not have 'foobar' attribute" in body 
     242        response = self.app.get('/spy_invalid_expectation') 
     243        assert "fail: paginate does not have 'foobar' attribute" in response 
    247244 
    248245    def test_raw_expectation(self): 
    249         create_request('/spy_correct_expectation') 
    250         Spy.assert_ok(cherrypy.response.body[0], 'var_name', 'data') 
    251         Spy.assert_ok(cherrypy.response.body[0], 'var_name', "'data'", raw=True) 
     246        response = self.app.get('/spy_correct_expectation') 
     247        Spy.assert_ok(response.body, 'var_name', 'data') 
     248        Spy.assert_ok(response.body, 'var_name', "'data'", raw=True) 
    252249 
    253250 
    254 class TestPagination(unittest.TestCase): 
     251class TestPagination(testutil.TGWebTest): 
    255252    """Base class for all Paginate TestCases""" 
    256253 
    257     def request(self, url): 
    258         create_request(url) 
    259         self.body = cherrypy.response.body[0] 
     254    def request(self, url, status=200): 
     255        response = self.app.get(url, status=status) 
     256        self.body = response.body 
    260257        if "fail: " in self.body: 
    261258            print self.body 
    262259            assert False, "Spy alert! Check body output for details..." 
     
    343340 
    344341 
    345342    def setUp(self): 
     343        testutil.TGWebTest.setUp(self) 
    346344        cherrypy.root = self.MyRoot() 
    347345 
    348346    def test_pagination_old_style(self): 
     
    439437        Spy.assert_ok(self.body, 'pages', xrange(4, 8)) 
    440438 
    441439    def test_invalid_dynamic_limit(self): 
    442         self.request("/invalid_dynamic") 
    443         assert cherrypy.response.status.startswith("500") 
     440        self.request("/invalid_dynamic", status=500) 
    444441        assert 'paginate: dynamic_limit (foobar) not found in output dict' in self.body 
    445442 
    446443    def test_dynamic_limit(self): 
     
    754751 
    755752 
    756753    def setUp(self): 
     754        testutil.TGWebTest.setUp(self) 
    757755        cherrypy.root = self.MyRoot() 
    758756 
    759757    def assert_order(self, *args): 
     
    826824 
    827825    def test_invalid_default_reversed(self): 
    828826        for method in "Q", "QA", "SR", "SO", "SL": 
    829             self.request("/wrong_reversed/?method=%s" % method) 
    830             assert cherrypy.response.status.startswith("500") 
     827            self.request("/wrong_reversed/?method=%s" % method, status=500) 
    831828            assert ('paginate: default_reversed (deprecated) only allowed' 
    832829                ' when default_order is a basestring') in self.body 
    833830 
  • turbogears/testutil.py

     
    1818except ImportError: 
    1919    sqlalchemy = None 
    2020 
     21from webtest import TestApp 
     22 
    2123from turbogears import startup, config, update_config, \ 
    2224    controllers, database, validators 
    2325from turbogears.identity import current_provider 
     
    195197                item.dropTable(ifExists=True) 
    196198 
    197199 
     200class TGWebTest(unittest.TestCase): 
     201    """A WebTest enabled unit testing class. 
     202 
     203    This allows testers to subclass us and use self.app to make WebTest calls. 
     204    """ 
     205    def setUp(self): 
     206        from cherrypy._cpwsgi import wsgiApp 
     207        start_cp() 
     208        startup.startTurboGears() 
     209        self.app = TestApp(wsgiApp) 
     210 
     211    def tearDown(self): 
     212        startup.stopTurboGears() 
     213        del self.app 
     214 
     215    def login_user(self, user): 
     216        """ Log a specified user object into the system """ 
     217        self.app.post(config.get('identity.failure_url'), { 
     218                'user_name' : user.user_name, 
     219                'password'  : user.password, 
     220                'login'     : 'Login', 
     221        }) 
     222 
     223 
     224class DBWebTest(TGWebTest, DBTest): 
     225    """A database driven WebTest enabled unit testing class. 
     226 
     227    This class will automatically setup and tear down your database, along 
     228    with TurboGears and WebTest before and after each unit test. 
     229    """ 
     230    def setUp(self): 
     231        DBTest.setUp(self) 
     232        TGWebTest.setUp(self) 
     233 
     234    def tearDown(self): 
     235        TGWebTest.tearDown(self) 
     236        DBTest.tearDown(self) 
     237 
     238 
    198239def reset_cp(): 
    199240    cherrypy.root = None 
    200241 
     
    301342 
    302343__all__ = ["call", "create_request", "DBTest", 
    303344    "attach_identity", "set_identity_user", 
    304     "capture_log", "print_log", "get_log", "sqlalchemy_cleanup"] 
     345    "capture_log", "print_log", "get_log", "sqlalchemy_cleanup", 
     346    "TGWebTest", "DBWebTest"] 
  • turbogears/view/base.py

     
    107107    @type template: string 
    108108 
    109109    """ 
     110    if hasattr(cherrypy.request, 'wsgi_environ'): 
     111        if 'paste.testing' in cherrypy.request.wsgi_environ: 
     112            cherrypy.request.wsgi_environ['paste.testing_variables']['namespace'] = info 
    110113    template = info.pop("tg_template", template) 
    111114    if not info.has_key("tg_flash"): 
    112115        if config.get("tg.empty_flash", True):