Ticket #1762: webtest_blended.patch

File webtest_blended.patch, 141.7 kB (added by kskuhlman, 4 months ago)

Patch including a blending of Luke & Ken's approaches.

  • setup.py

    old new  
    4646 
    4747testtools =  [ 
    4848    "nose >= 0.9.3, <= 0.10.0a1", 
     49    "WebTest", 
    4950] 
    5051 
    5152tgtesttools =  [ 
    5253    "nose >= 0.9.3, <= 0.10.0a1", 
     54    "WebTest", 
    5355] 
    5456 
    5557# python 2.5 compatible list 
  • turbogears/identity/tests/test_identity.py

    old new  
    5555 
    5656    @expose() 
    5757    def index(self): 
    58         pass 
     58        return dict() 
    5959 
    6060    @expose() 
    6161    def identity_failed(self, **kw): 
     
    6969    @expose() 
    7070    @identity.require(in_group('peon')) 
    7171    def in_peon_group(self): 
     72        user = TG_User.by_user_name("samIam") 
     73        group_ids = set((TG_Group.by_group_name("peon").id, 
     74            TG_Group.by_group_name("other").id)) 
     75        assert identity.current.user == user 
     76        assert identity.current.user_name == user.user_name 
     77        assert identity.current.user_id == user.id 
     78        assert identity.current.groups == set(('peon', 'other')) 
     79        assert identity.current.group_ids == group_ids 
     80        assert "samIam" == cherrypy.serving.request.identity.user_name 
     81 
    7282        return 'in_peon_group' 
    7383 
    7484    @expose() 
     
    136146            return 'wrong params: %s\nexpected unicode objects' \ 
    137147                ' for all strings' % cherrypy.request.params 
    138148 
     149    @expose() 
     150    def is_anonymous(self): 
     151        assert cherrypy.serving.request.identity.user_name == None 
     152        assert cherrypy.serving.request.identity.anonymous 
     153        assert identity.current.anonymous 
     154        return 'is_anonymous' 
    139155 
    140 class TestIdentity(unittest.TestCase): 
    141156 
     157 
     158class TestIdentity(testutil.TGWebTest): 
     159 
    142160    def setUp(self): 
    143161        # identity requires visit and a failure_url 
    144162        test_config = {'global': { 
     
    151169        self._original_config = original_config 
    152170        config.configure_loggers(test_config) 
    153171        config.update(test_config['global']) 
    154         cherrypy.root = IdentityRoot(
    155         startup.startTurboGears(
     172        testutil.mount(IdentityRoot()
     173        testutil.TGWebTest.setUp(self
    156174        self.init_model() 
    157175 
    158176    def tearDown(self): 
    159         startup.stopTurboGears() 
     177        testutil.unmount() 
     178        testutil.TGWebTest.tearDown(self) 
    160179        config.update(self._original_config) 
    161180 
    162181    def init_model(self): 
     
    181200 
    182201    def test_user_password_parameters(self): 
    183202        """Controller can receive user_name and password parameters.""" 
    184         testutil.create_request('/new_user_setup?user_name=test&password=pw') 
    185         firstline = cherrypy.response.body[0] 
    186         assert 'test pw' in firstline, firstline 
     203        response = self.app.get('/new_user_setup?user_name=test&password=pw') 
     204        assert 'test pw' in response 
    187205 
    188206    def test_user_exists(self): 
    189207        u = TG_User.by_user_name('samIam') 
     
    205223        config.update({'identity.soprovider.encryption_algorithm': None}) 
    206224        # force new config values to load 
    207225        startup.startTurboGears() 
    208         testutil.create_request('/') 
     226        self.app.get('/') 
    209227        hub.begin() 
    210228        u = TG_User.by_user_name('samIam') 
    211229        u.password = u'garçon' 
     
    219237        config.update({'identity.soprovider.encryption_algorithm': 'sha1'}) 
    220238        # force new config values to load 
    221239        startup.startTurboGears() 
    222         testutil.create_request('/') 
     240        self.app.get('/') 
    223241        hub.begin() 
    224242        u = TG_User.by_user_name('samIam') 
    225243        u.password = 'password' 
     
    234252        config.update({'identity.soprovider.encryption_algorithm': 'sha1'}) 
    235253        # force new config values to load 
    236254        startup.startTurboGears() 
    237         testutil.create_request('/') 
     255        self.app.get('/') 
    238256        hub.begin() 
    239257        u = TG_User.by_user_name('samIam') 
    240258        u.password = u'garçon' 
     
    248266        config.update({'identity.soprovider.encryption_algorithm': 'md5'}) 
    249267        # force new config values to load 
    250268        startup.startTurboGears() 
    251         testutil.create_request('/') 
     269        self.app.get('/') 
    252270        hub.begin() 
    253271        u = TG_User.by_user_name('samIam') 
    254272        u.password = 'password' 
     
    263281        config.update({'identity.soprovider.encryption_algorithm': 'md5'}) 
    264282        # force new config values to load 
    265283        startup.startTurboGears() 
    266         testutil.create_request('/') 
     284        self.app.get('/') 
    267285        hub.begin() 
    268286        u = TG_User.by_user_name('samIam') 
    269287        u.password = u'garçon' 
     
    280298        config.update({'identity.soprovider.encryption_algorithm': 'md5'}) 
    281299        # force new config values to load 
    282300        startup.startTurboGears() 
    283         testutil.create_request('/') 
     301        self.app.get('/') 
    284302        hub.begin() 
    285303        u = TG_User.by_user_name('samIam') 
    286304        u.password = u'garçon'.encode('UTF-8') 
     
    295313        config.update({'identity.soprovider.encryption_algorithm':'sha1'}) 
    296314        # force new config values to load 
    297315        startup.startTurboGears() 
    298         testutil.create_request('/') 
     316        self.app.get('/') 
    299317        hub.begin() 
    300318        u = TG_User.by_user_name('samIam') 
    301319        u.set_password_raw('password') 
     
    308326        config.update({'identity.soprovider.encryption_algorithm':'sha1'}) 
    309327        # force new config values to load 
    310328        startup.startTurboGears() 
    311         testutil.create_request('/') 
     329        self.app.get('/') 
    312330        hub.begin() 
    313331        u = TG_User.by_user_name('samIam') 
    314332        u.set_password_raw(u'garçon') 
     
    324342                'identity.tests.test_identity.mycustomencrypt'}) 
    325343        # force new config values to load 
    326344        startup.startTurboGears() 
    327         testutil.create_request('/') 
     345        self.app.get('/') 
    328346        hub.begin() 
    329347        u = TG_User.by_user_name('samIam') 
    330348        u.password = 'password' 
     
    335353 
    336354    def test_anonymous_browsing(self): 
    337355        """Test if we can show up anonymously.""" 
    338         testutil.create_request('/') 
    339         assert identity.current.anonymous 
     356        response = self.app.get('/is_anonymous') 
     357        assert 'is_anonymous' in response 
    340358 
    341359    def test_deny_anonymous(self): 
    342360        """Test that we have secured an url from anonymous users.""" 
    343         testutil.create_request('/logged_in_only') 
    344         firstline = cherrypy.response.body[0] 
    345         assert 'identity_failed_answer' in firstline, firstline 
     361        response = self.app.get('/logged_in_only') 
     362        assert 'identity_failed_answer' in response 
    346363 
    347364    def test_deny_anonymous_viewable(self): 
    348365        """Test that a logged in user can see an resource blocked 
    349366        from anonymous users.""" 
    350         testutil.create_request('/logged_in_only?' 
     367        response = self.app.get('/logged_in_only?' 
    351368            'user_name=samIam&password=secret&login=Login') 
    352         firstline = cherrypy.response.body[0] 
    353         assert 'logged_in_only' in firstline, firstline 
     369        assert 'logged_in_only' in response 
    354370 
    355371    def test_logout(self): 
    356372        """Test that logout works and session is gets invalid afterwards.""" 
    357         testutil.create_request('/in_peon_group?' 
     373        response = self.app.get('/in_peon_group?' 
    358374            'user_name=samIam&password=secret&login=Login') 
    359         self.assertEquals("samIam", cherrypy.serving.request.identity.user_name) 
    360         session_id = re.match("Set-Cookie: (.*?); Path.*", 
    361             str(cherrypy.response.simple_cookie)).group(1) 
    362         testutil.create_request('/logout', headers={'Cookie': session_id }) 
    363         self.assertEquals(None, cherrypy.serving.request.identity.user_name) 
    364         assert cherrypy.serving.request.identity.anonymous 
     375        session_id = response.headers['Set-Cookie'] 
     376        response = self.app.get('/logout', headers={'Cookie': session_id }) 
     377        response = self.app.get('/is_anonymous', headers={'Cookie': session_id}) 
     378        assert response.body == 'is_anonymous' 
    365379 
    366     def test_logout_with_set_identity(self): 
    367         """Test that logout works even when there is no visit_key 
    368         (e.g. when testutils.set_identity_user is used).""" 
    369         request = testutil.DummyRequest() 
    370         old_user = testutil.test_user 
    371         user = TG_User.by_user_name("samIam") 
    372         testutil.set_identity_user(user) 
    373         testutil.attach_identity(request) 
    374         testutil.set_identity_user(old_user) 
    375         testutil.call_with_request(cherrypy.root.logout, request) 
    376         assert request.identity.anonymous 
    377  
    378380    def test_require_group(self): 
    379381        """Test that a anonymous user""" 
    380         testutil.create_request('/in_peon_group') 
    381         firstline = cherrypy.response.body[0] 
    382         assert 'identity_failed_answer' in firstline, firstline 
     382        response = self.app.get('/in_peon_group') 
     383        assert 'identity_failed_answer' in response, response 
    383384 
    384385    def test_require_expose_required_permission(self): 
    385386        """Test that the decorator exposes the correct permissions via _require 
    386387        attribute on the actual method.""" 
    387         testutil.create_request('/test_exposed_require') 
    388         firstline= cherrypy.response.body[0] 
    389         assert 'require is exposed' in firstline, firstline 
     388        response = self.app.get('/test_exposed_require') 
     389        assert 'require is exposed' in response, response 
    390390 
    391391    def test_require_group_viewable(self): 
    392392        """Test that a user with proper group membership can see a restricted url.""" 
    393         testutil.create_request('/in_peon_group?' 
     393        response = self.app.get('/in_peon_group?' 
    394394            'user_name=samIam&password=secret&login=Login') 
    395         firstline = cherrypy.response.body[0] 
    396         assert 'in_peon_group' in firstline, firstline 
     395        assert 'in_peon_group' in response, response 
    397396        user = TG_User.by_user_name("samIam") 
    398397 
    399398    def test_require_group_viewable(self): 
    400399        """Test that the current user and group properties are set correctly.""" 
    401         testutil.create_request('/in_peon_group?' 
     400        response = self.app.get('/in_peon_group?' 
    402401            'user_name=samIam&password=secret&login=Login') 
    403402        user = TG_User.by_user_name("samIam") 
    404403        group_ids = set((TG_Group.by_group_name("peon").id, 
    405404            TG_Group.by_group_name("other").id)) 
    406         assert identity.current.user == user 
    407         assert identity.current.user_name == user.user_name 
    408         assert identity.current.user_id == user.id 
    409         assert identity.current.groups == set(('peon', 'other')) 
    410         assert identity.current.group_ids == group_ids 
    411405 
    412406    def test_user_not_in_right_group(self): 
    413         """Test that a user is denied access if they aren't in the right group.""" 
    414         testutil.create_request('/in_admin_group?' 
     407        """Test that a user is denied access if they aren't in the right group. 
     408        """ 
     409        response = self.app.get('/in_admin_group?' 
    415410            'user_name=samIam&password=secret&login=Login') 
    416         firstline = cherrypy.response.body[0] 
    417         assert 'identity_failed_answer' in firstline, firstline 
     411        assert 'identity_failed_answer' in response, response 
    418412 
    419413    def test_require_permission(self): 
    420         """Test that an anonymous user is denied access to a permission restricted url.""" 
    421         testutil.create_request('/has_chopper_permission') 
    422         firstline = cherrypy.response.body[0] 
    423         assert 'identity_failed_answer' in firstline, firstline 
     414        """Test that an anonymous user is denied access to a permission  
     415        restricted url. 
     416        """ 
     417        response = self.app.get('/has_chopper_permission') 
     418        assert 'identity_failed_answer' in response, response 
    424419 
    425420    def test_require_permission_viewable(self): 
    426421        """Test that a user with proper permissions can see a restricted url.""" 
    427         testutil.create_request('/has_chopper_permission?' 
     422        response = self.app.get('/has_chopper_permission?' 
    428423            'user_name=samIam&password=secret&login=Login') 
    429         firstline = cherrypy.response.body[0] 
    430         assert 'has_chopper_permission' in firstline, firstline 
     424        assert 'has_chopper_permission' in response 
    431425 
    432426    def test_user_lacks_permission(self): 
    433         """Test that a user is denied acces if they don't have the proper permission.""" 
    434         testutil.create_request('/has_boss_permission?' 
     427        """Test that a user is denied acces if they don't have the proper  
     428        permission. 
     429        """ 
     430        response = self.app.get('/has_boss_permission?' 
    435431            'user_name=samIam&password=secret&login=Login') 
    436         firstline = cherrypy.response.body[0] 
    437         assert 'identity_failed_answer' in firstline, firstline 
     432        assert 'identity_failed_answer' in response, response 
    438433 
    439434    def test_user_info_available(self): 
    440435        """Test that we can see user information inside our controller.""" 
    441         testutil.create_request('/user_email?' 
     436        response = self.app.get('/user_email?' 
    442437            'user_name=samIam&password=secret&login=Login') 
    443         firstline = cherrypy.response.body[0] 
    444         assert 'samiam@example.com' in firstline, firstline 
     438        assert 'samiam@example.com' in response, response 
    445439 
    446440    def test_bad_login(self): 
    447441        """Test that we are denied access if we provide a bad login.""" 
    448         testutil.create_request('/logged_in_only?' 
     442        response = self.app.get('/logged_in_only?' 
    449443            'user_name=samIam&password=wrong&login=Login') 
    450         firstline = cherrypy.response.body[0] 
    451         assert 'identity_failed_answer' in firstline, firstline 
     444        assert 'identity_failed_answer' in response, response 
    452445 
    453446    def test_restricted_subdirectory(self): 
    454447        """Test that we can restrict access to a whole subdirectory.""" 
    455         testutil.create_request('/peon_area/index') 
    456         firstline = cherrypy.response.body[0] 
    457         assert 'identity_failed_answer' in firstline, firstline 
     448        response = self.app.get('/peon_area/index') 
     449        assert 'identity_failed_answer' in response, response 
    458450 
    459451    def test_restricted_subdirectory_viewable(self): 
    460452        """Test that we can access a restricted subdirectory 
    461453        if we have proper credentials.""" 
    462         testutil.create_request('/peon_area/index?' 
     454        response = self.app.get('/peon_area/index?' 
    463455            'user_name=samIam&password=secret&login=Login') 
    464         firstline = cherrypy.response.body[0] 
    465         assert 'restricted_index' in firstline, firstline 
     456        assert 'restricted_index' in response, response 
    466457 
    467458    def test_decoratator_in_restricted_subdirectory(self): 
    468459        """Test that we can require a different permission 
    469460        in a protected subdirectory.""" 
    470         testutil.create_request('/peon_area/in_other_group?' 
     461        response = self.app.get('/peon_area/in_other_group?' 
    471462            'user_name=samIam&password=secret&login=Login') 
    472         firstline = cherrypy.response.body[0] 
    473         assert 'in_other_group' in firstline, firstline 
     463        assert 'in_other_group' in response, response 
    474464 
    475465    def test_decoratator_failure_in_restricted_subdirectory(self): 
    476466        """Test that we can get an identity failure from a decorator 
    477467        in a restricted subdirectory""" 
    478         testutil.create_request('/peon_area/in_admin_group?' 
     468        response = self.app.get('/peon_area/in_admin_group?' 
    479469            'user_name=samIam&password=secret&login=Login') 
    480         firstline = cherrypy.response.body[0] 
    481         assert 'identity_failed_answer' in firstline, firstline 
     470        assert 'identity_failed_answer' in response, response 
    482471 
    483472    def test_explicit_checks_in_restricted_subdirectory(self): 
    484473        """Test that explicit permission checks in a protected 
    485474        directory is handled as expected""" 
    486         testutil.create_request('/peon_area/in_other_group_explicit_check?' 
     475        response = self.app.get('/peon_area/in_other_group_explicit_check?' 
    487476            'user_name=samIam&password=secret&login=Login') 
    488         firstline = cherrypy.response.body[0] 
    489         assert 'in_other_group' in firstline, firstline 
     477        assert 'in_other_group' in response, response 
    490478 
    491479    def test_throwing_identity_exception_in_restricted_subdirectory(self): 
    492480        """Test that throwing an IdentityException in a protected 
    493481        directory is handled as expected""" 
    494         testutil.create_request('/peon_area/in_admin_group_explicit_check?' 
     482        response = self.app.get('/peon_area/in_admin_group_explicit_check?' 
    495483            'user_name=samIam&password=secret&login=Login') 
    496         firstline = cherrypy.response.body[0] 
    497         assert 'identity_failed' in firstline, firstline 
     484        assert 'identity_failed' in response, response 
    498485 
    499486    def test_decode_filter_whenidfails(self): 
    500487        """Test that the decode filter doesn't break with nested 
    501488        variables and Identity""" 
    502489        params = urllib.quote(IdentityRoot._test_encoded_params.decode( 
    503490            'utf-8').encode('latin-1'), '=&') 
    504         testutil.create_request('/test_params?' + params) 
    505         firstline = cherrypy.response.body[0] 
    506         assert 'identity_failed_answer' in firstline, firstline 
     491        response = self.app.get('/test_params?' + params) 
     492        assert 'identity_failed_answer' in response, response 
    507493 
    508494    def test_decode_filter_whenidworks(self): 
    509495        """Test that the decode filter doesn't break with nested 
     
    511497        params = urllib.quote(IdentityRoot._test_encoded_params.decode( 
    512498            'utf-8').encode('latin-1'), '=&') 
    513499        params += '&user_name=samIam&password=secret&login=Login' 
    514         testutil.create_request('/test_params?' + params) 
    515         firstline = cherrypy.response.body[0] 
    516         assert 'params ok' in firstline, firstline 
     500        response = self.app.get('/test_params?' + params) 
     501        assert 'params ok' in response, response 
    517502 
    518503 
    519504class TestTGUser(testutil.DBTest): 
     
    522507    def setUp(self): 
    523508        self._identity_on = config.get('identity.on', False) 
    524509        config.update({'identity.on': False}) 
    525         try: 
    526             self._provider = cherrypy.request.identityProvider 
    527         except AttributeError: 
    528             self._provider= None 
    529         cherrypy.request.identityProvider = None 
    530510        startup.startTurboGears() 
    531511        testutil.DBTest.setUp(self) 
    532512 
    533513    def tearDown(self): 
    534514        testutil.DBTest.tearDown(self) 
    535515        startup.stopTurboGears() 
    536         cherrypy.request.identityProvider = self._provider 
    537516        config.update({'identity.on': self._identity_on}) 
    538517 
    539518    def test_create_user(self): 
  • turbogears/identity/tests/test_visit.py

    old new  
    22from unittest import TestCase 
    33import cherrypy 
    44from turbogears import config, controllers, expose, startup, testutil, visit 
     5from Cookie import SimpleCookie 
    56 
    67 
    7 def cookie_header(morsel): 
     8def cookie_header(response): 
    89    """Returns a dict containing cookie information to pass to a server.""" 
    9     return {'Cookie': morsel.output(header="")[1:]} 
     10    return dict(Cookie=response.headers['Set-Cookie']) 
    1011 
    1112 
    1213class VisitRoot(controllers.RootController): 
    1314 
    1415    @expose() 
    1516    def index(self): 
    16         return dict() 
     17        new = None 
     18        if visit.current(): 
     19            new = visit.current().is_new 
     20        visit_on = config.get('visit.on') 
     21        return dict(new=new, visit_on=visit_on) 
    1722 
    1823 
    1924class TestVisit(TestCase): 
    2025 
    2126    def setUp(self): 
     27        testutil.stop_server(tg_only = True) 
    2228        self._visit_on = config.get('visit.on', False) 
    2329        config.update({'visit.on': True}) 
    2430        self._visit_timeout = config.get('visit.timeout', 20) 
    2531        config.update({'visit.timeout': 50}) 
    2632        self.cookie_name = config.get("visit.cookie.name", 'tg-visit') 
    27         cherrypy.root = VisitRoot() 
     33        self.app = testutil.make_app(VisitRoot) 
     34        testutil.start_server() 
    2835 
    2936    def tearDown(self): 
    30         startup.stopTurboGears(
     37        testutil.stop_server(tg_only = True
    3138        config.update({'visit.timeout': self._visit_timeout}) 
    3239        config.update({'visit.on': self._visit_on}) 
    3340 
    3441    def test_visit_response(self): 
    3542        """Test if the visit cookie is set in cherrypy.response.""" 
    36         testutil.create_request("/") 
    37         assert cherrypy.response.simple_cookie.has_key(self.cookie_name) 
     43        response = self.app.get("/") 
     44        assert response.cookies_set.has_key(self.cookie_name) 
    3845 
    3946    def test_new_visit(self): 
    4047        """Test that we can see a new visit on the server.""" 
    41         testutil.create_request("/") 
    42         assert visit.current().is_new 
     48        response = self.app.get("/") 
     49        assert response.raw['new'] 
    4350 
    4451    def test_old_visit(self): 
    4552        """Test if we can track a visitor over time.""" 
    46         testutil.create_request("/") 
     53        response = self.app.get("/") 
    4754        # first visit's cookie 
    48         morsel = cherrypy.response.simple_cookie[self.cookie_name] 
    49         testutil.create_request("/", headers=cookie_header(morsel)) 
    50         assert not visit.current().is_new 
     55        print "Headers", response.headers 
     56        print "Config", config.get('visit.on') 
     57        morsel = response.cookies_set[self.cookie_name] 
     58        response = self.app.get("/", headers=cookie_header(response)) 
     59        assert not response.raw['new'] 
    5160 
    5261    def test_cookie_expires(self): 
    5362        """Test if the visit timeout mechanism works.""" 
    5463        timeout = config.get('visit.timeout', 50) 
     64        _app = self.app 
    5565        try: 
    5666            # set expiration to one second for this test only 
     67            testutil.stop_server(tg_only = True) 
    5768            config.update({'visit.timeout': 1.0/60}) 
    58             testutil.create_request("/") 
    59             morsel = cherrypy.response.simple_cookie[self.cookie_name] 
     69            self.app = testutil.make_app(VisitRoot) 
     70            testutil.start_server() 
     71            response = self.app.get("/") 
     72            morsel = response.cookies_set[self.cookie_name] 
    6073            time.sleep(2) # 2 seconds 
    61             testutil.create_request("/", headers=cookie_header(morsel)) 
     74            response = self.app.get("/", headers=cookie_header(response)) 
    6275        finally: 
    6376            config.update({'visit.timeout': timeout}) 
    64         assert cherrypy.response.simple_cookie[ 
    65                 self.cookie_name].value != morsel.value, \ 
     77            self.app = _app 
     78        assert response.cookies_set[ 
     79                self.cookie_name] != morsel, \ 
    6680            'cookie values should not match' 
    67         assert visit.current().is_new, \ 
     81        assert response.raw['new'], \ 
    6882            'this should be a new visit, as the cookie has expired' 
    6983 
    7084    def test_cookie_not_permanent(self): 
    7185        """Check that by default the visit cookie is not permanent.""" 
    72         testutil.create_request('/') 
    73         morsel = cherrypy.response.simple_cookie[self.cookie_name] 
     86        response = self.app.get('/') 
     87        cookies = SimpleCookie(response.headers['Set-Cookie']) 
     88        morsel = cookies[self.cookie_name] 
    7489        assert not morsel['expires'] and not morsel['max-age'] 
    7590 
    7691    def test_cookie_permanent(self): 
     
    7893        permanent = config.get('visit.cookie.permanent', False) 
    7994        try: 
    8095            # set cookie permanent for this test only (needs restart) 
    81             startup.stopTurboGears(
     96            testutil.stop_server(tg_only = True
    8297            config.update({'visit.cookie.permanent': True}) 
    83             startup.startTurboGears() 
    84             testutil.create_request('/') 
    85             morsel = cherrypy.response.simple_cookie[self.cookie_name] 
     98            app = testutil.make_app(VisitRoot) 
     99            testutil.start_server() 
     100            response = app.get('/') 
     101            cookies = SimpleCookie(response.headers['Set-Cookie']) 
     102            morsel = cookies[self.cookie_name] 
    86103        finally: 
    87104            config.update({'visit.cookie.permanent': permanent}) 
    88         assert morsel['max-age'] == 3000 
     105        assert morsel['max-age'] == '3000' 
    89106        expires = time.mktime(time.strptime(morsel['expires'], 
    90107            '%a, %d-%b-%Y %H:%M:%S GMT')[:8] + (0,)) 
    91         should_expire = time.mktime(time.gmtime()) + morsel['max-age'] 
    92         assert abs(should_expire - expires) < 3 
     108        should_expire = time.mktime(time.gmtime()) + int(morsel['max-age']) 
     109        assert abs(should_expire - expires) < 3, (should_expire, expires, should_expire - expires) 
     110 
  • turbogears/visit/api.py

    old new  
    251251        max_age = self.cookie_max_age 
    252252        if max_age: 
    253253            # use 'expires' because MSIE ignores 'max-age' 
    254             cookies[self.cookie_name]['expires'] = time.strftime( 
     254            cookies[self.cookie_name]['expires'] = '"%s"' % time.strftime( 
    255255                "%a, %d-%b-%Y %H:%M:%S GMT", 
    256256                time.gmtime(time.time() + max_age)) 
    257257            # 'max-age' takes precedence on standard conformant browsers 
  • turbogears/tests/test_form_controllers.py

    old new  
    1 from unittest import TestCase 
    21from datetime import datetime 
     2from unittest import TestCase 
    33import cherrypy 
    44from turbogears import widgets, config, controllers, expose, mochikit, \ 
    55    validate, validators, testutil 
     6from turbogears.testutil import mount, unmount, make_app 
    67 
    78 
     9def setup_module(): 
     10    global app 
     11    app = make_app(MyRoot) 
     12    testutil.start_server() 
     13 
     14def teardown_module(): 
     15    testutil.stop_server() 
     16 
     17 
    818class MyFormFields(widgets.WidgetsList): 
    919    #XXX: Since allow_extra_fields should be removed from validators.Schema, 
    1020    #     we need a validator for every input-expecting widget 
     
    1626myform = widgets.TableForm(fields=MyFormFields()) 
    1727 
    1828 
     29class State(object): 
     30    counter = 0 
     31 
     32class AddingValidator(validators.FancyValidator): 
     33    def _to_python(self, value, state=None): 
     34        state.counter += 1 
     35        return value 
     36 
     37class AddingSchema(validators.Schema): 
     38    a = AddingValidator() 
     39    b = AddingValidator() 
     40 
     41class AddingNestedSchema(AddingSchema): 
     42    c = AddingSchema() 
     43 
     44 
    1945class MyRoot(controllers.RootController): 
    2046 
    2147    @expose(html="turbogears.tests.form") 
     
    3157    def testform(self, name, date, age, tg_errors=None): 
    3258        if tg_errors: 
    3359            self.has_errors = True 
    34         self.name = name 
    35         self.age = age 
    36         self.date = date 
     60        return dict(name=name, user_age=age, birthdate=date) 
    3761 
    3862    @expose() 
    3963    @validate(form=myform) 
    4064    def testform_new_style(self, name, date, age): 
    4165        if cherrypy.request.validation_errors: 
    4266            self.has_errors = True 
    43         self.name = name 
    44         self.age = age 
    45         self.date = date 
     67        return dict(name=name, age=age, date=date) 
    4668 
     69    @expose() 
     70    @validate(validators=AddingNestedSchema(), state_factory=State) 
     71    def validation(self, a, b, c): 
     72        return 'counter: %d' % cherrypy.request.validation_state.counter 
     73 
    4774def test_form_translation(): 
    4875    """Form input is translated into properly converted parameters""" 
    49     root = MyRoot() 
    50     cherrypy.root = root 
    51     testutil.create_request("/testform?name=ed&date=11/05/2005&age=5") 
    52     assert root.name == "ed" 
    53     assert root.age == 5 
     76    response = app.get("/testform?name=ed&date=11/05/2005&age=5") 
     77    assert response.raw['name'] == "ed" 
     78    assert response.raw['user_age'] == 5 
    5479 
    5580def test_form_translation_new_style(): 
    5681    """Form input is translated into properly converted parameters""" 
    57     root = MyRoot() 
    58     cherrypy.root = root 
    59     testutil.create_request("/testform_new_style?name=ed&date=11/05/2005&age=5&") 
    60     assert root.name == "ed" 
    61     assert root.age == 5 
     82    response = app.get("/testform_new_style?name=ed&date=11/05/2005&age=5&") 
     83    assert response.raw['name'] == "ed" 
     84    assert response.raw['age'] == 5 
    6285 
    6386def test_invalid_form_with_error_handling(): 
    6487    """Invalid forms can be handled by the method""" 
    65     root = cherrypy.root 
    66     testutil.create_request("/testform?name=ed&age=edalso&date=11/05/2005") 
    67     assert root.has_errors 
     88    response = app.get("/testform?name=ed&age=edalso&date=11/05/2005") 
    6889 
    6990def test_css_should_appear(): 
    7091    """CSS should appear when asked for""" 
    71     testutil.create_request("/") 
    72     assert "calendar-system.css" in cherrypy.response.body[0] 
     92    response = app.get("/") 
     93    assert "calendar-system.css" in response 
    7394 
    7495def test_javascript_should_appear(): 
    7596    """JavaScript should appear when asked for""" 
    76     testutil.create_request("/") 
    77     assert "calendar.js" in cherrypy.response.body[0] 
     97    response = app.get("/") 
     98    assert "calendar.js" in response 
    7899 
    79100def test_include_mochikit(): 
    80101    """JSLinks (and MochiKit especially) can be included easily""" 
    81     testutil.create_request("/usemochi") 
    82     assert "MochiKit.js" in cherrypy.response.body[0] 
     102    response = app.get("/usemochi") 
     103    assert "MochiKit.js" in response 
    83104 
    84105def test_suppress_mochikit(): 
    85106    """MochiKit inclusion can be suppressed""" 
    86     config.update({"global": {"tg.mochikit_suppress": True}}) 
    87     testutil.create_request("/usemochi") 
    88     suppressed_body = cherrypy.response.body[0] 
     107    config.update({"global":{"tg.mochikit_suppress" : True}}) 
     108    suppressed = app.get("/usemochi") 
    89109    # repair the fixture 
    90     config.update({"global": {"tg.mochikit_suppress": False}}) 
    91     testutil.create_request("/usemochi") 
    92     included_body = cherrypy.response.body[0] 
    93     assert "MochiKit.js" not in suppressed_body 
    94     assert "MochiKit.js" in included_body 
     110    config.update({"global":{"tg.mochikit_suppress" : False}}) 
    95111 
     112    included = app.get("/usemochi") 
     113    assert "MochiKit.js" not in suppressed.body 
     114    assert "MochiKit.js" in included.body 
     115 
    96116def test_mochikit_everywhere(): 
    97117    """MochiKit can be included everywhere by setting tg.mochikit_all""" 
    98     config.update({"global": {"tg.mochikit_all": True}}) 
    99     testutil.create_request("/") 
    100     config.update({"global": {"tg.mochikit_all": False}}) 
    101     assert "MochiKit.js" in cherrypy.response.body[0] 
     118    config.update({"global":{"tg.mochikit_all" : True}}) 
     119    response = app.get("/") 
     120    config.update({"global":{"tg.mochikit_all" : False}}) 
     121    assert "MochiKit.js" in response 
    102122 
    103123def test_mochikit_nowhere(): 
    104124    """Setting tg.mochikit_suppress will prevent including it everywhere""" 
    105125    config.update({"global": {"tg.mochikit_all": True}}) 
    106126    config.update({"global": {"tg.mochikit_suppress": True}}) 
    107     testutil.create_request("/") 
     127    response = app.get("/") 
    108128    config.update({"global": {"tg.mochikit_all": False}}) 
    109129    config.update({"global": {"tg.mochikit_suppress": False}}) 
    110     assert "MochiKit.js" not in cherrypy.response.body[0] 
     130    assert "MochiKit.js" not in response 
    111131 
    112132def test_include_widgets(): 
    113133    """Any widget can be included everywhere by setting tg.include_widgets""" 
    114134    config.update({"global": {"tg.include_widgets": ["mochikit"]}}) 
    115     testutil.create_request("/") 
     135    response = app.get("/") 
    116136    config.update({"global": {"tg.include_widgets": []}}) 
    117     assert "MochiKit.js" in cherrypy.response.body[0] 
     137    assert "MochiKit.js" in response 
    118138 
     139def test_counter_is_incremented(): 
     140    # parameter values are irrelevant 
     141    url = '/validation?a=1&b=2&c.a=3&c.b=4' 
     142    response = app.get(url) 
     143    msg = "Validation state is not handled properly" 
     144    # 4 == 1 (a) + 1(b) + 1(c.a) + 1(c.b) 
     145    assert 'counter: 4' in response.body, msg 
    119146 
    120 class State(object): 
    121     counter = 0 
    122  
    123 class AddingValidator(validators.FancyValidator): 
    124     def _to_python(self, value, state=None): 
    125         state.counter += 1 
    126         return value 
    127  
    128 class AddingSchema(validators.Schema): 
    129     a = AddingValidator() 
    130     b = AddingValidator() 
    131  
    132 class AddingNestedSchema(AddingSchema): 
    133     c = AddingSchema() 
    134  
    135  
    136 class TestValidationState(TestCase): 
    137  
    138     class Controller(controllers.RootController): 
    139  
    140         @expose() 
    141         @validate(validators=AddingNestedSchema(), state_factory=State) 
    142         def validation(self, a, b, c): 
    143             return 'counter: %d' % cherrypy.request.validation_state.counter 
    144  
    145     def __init__(self, *args, **kw): 
    146         super(TestValidationState, self).__init__(*args, **kw) 
    147  
    148     def test_counter_is_incremented(self): 
    149         cherrypy.root = self.Controller() 
    150         # parameter values are irrelevant 
    151         url = '/validation?a=1&b=2&c.a=3&c.b=4' 
    152         testutil.create_request(url) 
    153         body = cherrypy.response.body[0] 
    154         msg = "Validation state is not handled properly" 
    155         # 4 == 1 (a) + 1(b) + 1(c.a) + 1(c.b) 
    156         self.failUnless('counter: 4' in body, msg) 
  • turbogears/tests/test_errorhandling.py

    old new  
    11import unittest 
    2  
    3 import cherrypy 
    4  
    52from turbogears.controllers import error_handler, exception_handler, \ 
    63                                   expose, validate, RootController, Controller 
    74from turbogears.errorhandling import FailsafeSchema 
     
    1613    else: 
    1714        return str(errors) 
    1815 
     16def setup_module(): 
     17    testutil.unmount() 
     18    testutil.mount(MyRoot()) 
     19    testutil.mount(NestedController(), "/nestedcontroller") 
     20    testutil.start_server() 
    1921 
     22def teardown_module(): 
     23    testutil.unmount() 
     24    testutil.stop_server() 
     25 
    2026class MyRoot(RootController): 
    2127 
    2228    def defaulterrorhandler(self, tg_source, tg_errors, tg_exceptions, 
     
    94100        "second": validators.Int(not_empty=True)}) 
    95101    @error_handler(defaulterrorhandler) 
    96102    def positionalargs(self, first, second, *args, **kw): 
    97         self.first = first 
    98         self.second = second 
    99         self.third = args[0] 
    100103        return dict(title="Positional arguments", first=first, second=second, 
    101                     args=args, bar=kw["bar"]) 
     104                    third=args[0], args=args, bar=kw["bar"]) 
    102105 
    103106    @expose() 
    104107    @validate(validators={"bar": validators.Int(not_empty=True)}) 
     
    141144        return self.notexposed(bar) 
    142145 
    143146    def continuation(self, tg_source): 
    144         self.continuation = True 
    145         return tg_source(self) 
     147        response = tg_source(self) 
     148        response['continuation'] = True 
     149        return response 
    146150 
    147151    @expose() 
    148152    @validate(validators={"bar": validators.Int(not_empty=True)}) 
     
    208212        return dict(title="Nested") 
    209213 
    210214 
     215app = testutil.make_app() 
     216 
    211217class TestErrorHandler(unittest.TestCase): 
    212218 
    213     def setUp(self): 
    214         cherrypy.root = MyRoot() 
    215         cherrypy.root.nestedcontroller = NestedController() 
    216  
    217219    def test_defaultErrorHandler(self): 
    218220        """Default error handler.""" 
    219         testutil.create_request("/defaulterror?bar=abc") 
    220         self.failUnless("Default error handler" in cherrypy.response.body[0]
    221         testutil.create_request("/defaulterror?bar=true") 
    222         self.failUnless("Default error provider" in cherrypy.response.body[0]
     221        response = app.get("/defaulterror?bar=abc") 
     222        self.failUnless("Default error handler" in response
     223        response = app.get("/defaulterror?bar=true") 
     224        self.failUnless("Default error provider" in response
    223225 
    224226    def test_specialisedErrorHandler(self): 
    225227        """Error handler specialisation.""" 
    226         testutil.create_request("/specialisederror?bar=abc&baz=a@b.com") 
    227         self.failUnless("Default error handler" in cherrypy.response.body[0]) 
    228         testutil.create_request("/specialisederror?baz=abc&bar=1") 
    229         self.failUnless("Specialised error handler" in 
    230                         cherrypy.response.body[0]) 
    231         testutil.create_request("/specialisederror?bar=1&baz=a@b.com") 
    232         self.failUnless("Specialised error provider" in 
    233                         cherrypy.response.body[0]) 
     228        response = app.get("/specialisederror?bar=abc&baz=a@b.com") 
     229        self.failUnless("Default error handler" in response) 
     230        response = app.get("/specialisederror?baz=abc&bar=1") 
     231        self.failUnless("Specialised error handler" in response) 
     232        response = app.get("/specialisederror?bar=1&baz=a@b.com") 
     233        self.failUnless("Specialised error provider" in response) 
    234234 
    235235    def test_exceptionErrorHandler(self): 
    236236        """Error handler for exceptions.""" 
    237         testutil.create_request("/exceptionerror") 
    238         self.failUnless("Default error handler" in cherrypy.response.body[0]
     237        response = app.get("/exceptionerror") 
     238        self.failUnless("Default error handler" in response
    239239 
    240240    def test_recursiveErrorHandler(self): 
    241241        """Recursive error handler.""" 
    242         testutil.create_request("/recursiveerror?bar=abc") 
    243         self.failUnless("Recursive error handler" in cherrypy.response.body[0]) 
    244         testutil.create_request("/recursiveerror?bar=1") 
    245         self.failUnless("Recursive error provider" in 
    246                         cherrypy.response.body[0]) 
     242        response = app.get("/recursiveerror?bar=abc") 
     243        self.failUnless("Recursive error handler" in response) 
     244        response = app.get("/recursiveerror?bar=1") 
     245        self.failUnless("Recursive error provider" in response) 
    247246 
    248247    def test_implicitErrorHandler(self): 
    249248        """Implicit error handling.""" 
    250         testutil.create_request("/impliciterror?bar=abc") 
    251         self.failUnless("Implicit error handler" in 
    252                         cherrypy.response.body[0]) 
    253         testutil.create_request("/impliciterror?bar=1") 
    254         self.failUnless("Implicit error provider" in 
    255                         cherrypy.response.body[0]) 
     249        response = app.get("/impliciterror?bar=abc") 
     250        self.failUnless("Implicit error handler" in response) 
     251        response = app.get("/impliciterror?bar=1") 
     252        self.failUnless("Implicit error provider" in response) 
    256253 
    257254    def test_normalMethodErrorHandler(self): 
    258255        """Normal method as an error handler.""" 
    259         testutil.create_request("/normalmethodcaller?bar=abc") 
    260         self.failUnless("Normal method" in cherrypy.response.body[0]
    261         testutil.create_request("/normalmethodcaller?bar=true") 
    262         self.failUnless("Normal method caller" in cherrypy.response.body[0]
     256        response = app.get("/normalmethodcaller?bar=abc") 
     257        self.failUnless("Normal method" in response
     258        response = app.get("/normalmethodcaller?bar=true") 
     259        self.failUnless("Normal method caller" in response
    263260 
    264261    def test_infiniteRecursionPrevention(self): 
    265262        """Infinite recursion prevention.""" 
    266         testutil.create_request("/infiniteloop") 
    267         self.failUnless("Exception 2" in cherrypy.response.body[0]
     263        response = app.get("/infiniteloop") 
     264        self.failUnless("Exception 2" in response
    268265 
    269266    def test_positionalArgs(self): 
    270267        """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