Author: Gustavo
Date: Wed Mar  4 13:57:28 2009
New Revision: 6475
URL: http://trac.turbogears.org/changeset/6475

Log:
Added the long awaited auth* tests. Fixes #2198.

Added:
   
projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/tests/functional/test_authentication.py_tmpl
   (contents, props changed)
Modified:
   
projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/tests/__init__.py_tmpl
   
projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/tests/functional/test_root.py_tmpl
   projects/tg.devtools/trunk/devtools/templates/turbogears/test.ini_tmpl

Modified: 
projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/tests/__init__.py_tmpl
==============================================================================
--- 
projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/tests/__init__.py_tmpl
   (original)
+++ 
projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/tests/__init__.py_tmpl
   Wed Mar  4 13:57:28 2009
@@ -17,12 +17,29 @@
 
 
 class TestController(object):
-    """Base functional test case for the controllers."""
-
+    """
+    Base functional test case for the controllers.
+    
+    The {{project}} application instance (``self.app``) set up in this test 
+    case (and descendants) has authentication disabled, so that developers can
+    test the protected areas independently of the :mod:`repoze.who` plugins
+    used initially. This way, authentication can be tested once and separately.
+    
+    Check {{package}}.tests.functional.test_authentication for the repoze.who
+    integration tests.
+    
+    This is the officially supported way to test protected areas with
+    repoze.who-testutil (http://code.gustavonarea.net/repoze.who-testutil/).
+    
+    """
+    
+    application_under_test = 'main_without_authn'
+    
     def setUp(self):
         # Loading the application:
         conf_dir = config.here
-        wsgiapp = loadapp('config:test.ini', relative_to=conf_dir)
+        wsgiapp = loadapp('config:test.ini#%s' % self.application_under_test,
+                          relative_to=conf_dir)
         self.app = TestApp(wsgiapp)
         # Setting it up:
         test_file = path.join(conf_dir, 'test.ini')

Added: 
projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/tests/functional/test_authentication.py_tmpl
==============================================================================
--- (empty file)
+++ 
projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/tests/functional/test_authentication.py_tmpl
     Wed Mar  4 13:57:28 2009
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+{{if auth == "sqlalchemy"}}
+"""
+Integration tests for the :mod:`repoze.who`-powered authentication sub-system.
+
+As {{project}} grows and the authentication method changes, only these tests
+should be updated.
+
+"""
+
+from {{package}}.tests import TestController
+
+
+class TestAuthentication(TestController):
+    """
+    Tests for the default authentication setup.
+    
+    By default in TurboGears 2, :mod:`repoze.who` is configured with the same
+    plugins specified by repoze.what-quickstart (which are listed in
+    
http://code.gustavonarea.net/repoze.what-quickstart/#repoze.what.plugins.quickstart.setup_sql_auth).
+    
+    As the settings for those plugins change, or the plugins are replaced,
+    these tests should be updated.
+    
+    """
+    
+    application_under_test = 'main'
+    
+    def test_forced_login(self):
+        """
+        Anonymous users must be redirected to the login form when authorization
+        is denied.
+        
+        Next, upon successful login they should be redirected to the initially
+        requested page.
+        
+        """
+        # Requesting a protected area
+        resp = self.app.get('/secc/', status=302)
+        assert resp.location.startswith('http://localhost/login')
+        # Getting the login form:
+        resp = resp.follow(status=200)
+        form = resp.form
+        # Submitting the login form:
+        form['login'] = u'manager'
+        form['password'] = 'managepass'
+        post_login = form.submit(status=302)
+        # Being redirected to the initially requested page:
+        assert post_login.location.startswith('http://localhost/post_login')
+        initial_page = post_login.follow(status=302)
+        assert 'authtkt' in initial_page.request.cookies, \
+               "Session cookie wasn't defined: %s" % 
initial_page.request.cookies
+        assert initial_page.location.startswith('http://localhost/secc/'), \
+               initial_page.location
+
+    def test_voluntary_login(self):
+        """Voluntary logins must work correctly"""
+        # Going to the login form voluntarily:
+        resp = self.app.get('/login', status=200)
+        form = resp.form
+        # Submitting the login form:
+        form['login'] = u'manager'
+        form['password'] = 'managepass'
+        post_login = form.submit(status=302)
+        # Being redirected to the home page:
+        assert post_login.location.startswith('http://localhost/post_login')
+        home_page = post_login.follow(status=302)
+        assert 'authtkt' in home_page.request.cookies, \
+               'Session cookie was not defined: %s' % home_page.request.cookies
+        assert home_page.location == 'http://localhost/'
+
+    def test_logout(self):
+        """Logouts must work correctly"""
+        # Logging in voluntarily the quick way:
+        resp = self.app.get('/login_handler?login=manager&password=managepass',
+                            status=302)
+        resp = resp.follow(status=302)
+        assert 'authtkt' in resp.request.cookies, \
+               'Session cookie was not defined: %s' % resp.request.cookies
+        # Logging out:
+        resp = self.app.get('/logout_handler', status=302)
+        assert resp.location.startswith('http://localhost/post_logout')
+        # Finally, redirected to the home page:
+        home_page = resp.follow(status=302)
+        assert home_page.request.cookies.get('authtkt') == '', \
+               'Session cookie was not deleted: %s' % home_page.request.cookies
+        assert home_page.location == 'http://localhost/', home_page.location
+
+{{endif}}

Modified: 
projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/tests/functional/test_root.py_tmpl
==============================================================================
--- 
projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/tests/functional/test_root.py_tmpl
       (original)
+++ 
projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/tests/functional/test_root.py_tmpl
       Wed Mar  4 13:57:28 2009
@@ -28,7 +28,21 @@
         assert_true(links, "Mummy, there are no links here!")
 
 {{if auth == 'sqlalchemy'}}
-    def test_secc(self):
-        response = self.app.get('/secc')
-        assert 'login' in response.location
+    def test_secc_with_manager(self):
+        """Only the manager can access the secure controller"""
+        # Note how authentication is forged:
+        environ = {'REMOTE_USER': 'manager'}
+        resp = self.app.get('/secc', extra_environ=environ, status=200)
+        assert 'Secure Controller here' in resp.body, resp.body
+    
+    def test_secc_with_editor(self):
+        """The editor shouldn't access the secure controller"""
+        environ = {'REMOTE_USER': 'editor'}
+        self.app.get('/secc', extra_environ=environ, status=403)
+        # It's enough to know that authorization was denied with a 403 status
+    
+    def test_secc_with_anonymous(self):
+        """Anonymous users must not access the secure controller"""
+        self.app.get('/secc', status=401)
+        # It's enough to know that authorization was denied with a 401 status
 {{endif}}

Modified: projects/tg.devtools/trunk/devtools/templates/turbogears/test.ini_tmpl
==============================================================================
--- projects/tg.devtools/trunk/devtools/templates/turbogears/test.ini_tmpl      
(original)
+++ projects/tg.devtools/trunk/devtools/templates/turbogears/test.ini_tmpl      
Wed Mar  4 13:57:28 2009
@@ -21,4 +21,8 @@
 {{endif}}
 use = config:development.ini
 
+[app:main_without_authn]
+use = main
+skip_authentication = True
+
 # Add additional test specific configuration options as necessary.

Reply via email to