summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Bokov <razum2um@mail.ru>2011-11-22 05:34:52 +0700
committerVlad Bokov <razum2um@mail.ru>2011-11-22 05:34:52 +0700
commit2f56f6ee6cb9e7a78230b7fb3b4a6e5dd096ec70 (patch)
tree143b3ef733dbb30ae61d2afdacc51b1471e4a28b
parentf35aab2070aa5884ac7b82666af81d4375211fe7 (diff)
downloadaskbot-2f56f6ee6cb9e7a78230b7fb3b4a6e5dd096ec70.tar.gz
askbot-2f56f6ee6cb9e7a78230b7fb3b4a6e5dd096ec70.tar.bz2
askbot-2f56f6ee6cb9e7a78230b7fb3b4a6e5dd096ec70.zip
Feature #111: improvements in CLOSED MODE
- drop from django.conf.settings - make a separate group - make all views except askbot-related work - tests
-rw-r--r--askbot/conf/__init__.py1
-rw-r--r--askbot/conf/access_control.py23
-rw-r--r--askbot/conf/login_providers.py21
-rw-r--r--askbot/middleware/forum_mode.py25
-rw-r--r--askbot/setup_templates/settings.py1
-rw-r--r--askbot/tests/page_load_tests.py166
-rw-r--r--askbot/tests/permission_assertion_tests.py25
-rw-r--r--askbot/tests/utils.py44
8 files changed, 244 insertions, 62 deletions
diff --git a/askbot/conf/__init__.py b/askbot/conf/__init__.py
index 64fe41fb..4f228ea7 100644
--- a/askbot/conf/__init__.py
+++ b/askbot/conf/__init__.py
@@ -19,6 +19,7 @@ import askbot.conf.markup
import askbot.conf.social_sharing
import askbot.conf.badges
import askbot.conf.login_providers
+import askbot.conf.access_control
import askbot.conf.site_modes
#import main settings object
diff --git a/askbot/conf/access_control.py b/askbot/conf/access_control.py
new file mode 100644
index 00000000..88bedfed
--- /dev/null
+++ b/askbot/conf/access_control.py
@@ -0,0 +1,23 @@
+from askbot.conf.settings_wrapper import settings
+from askbot.conf.super_groups import LOGIN_USERS_COMMUNICATION
+from askbot.deps import livesettings
+from django.utils.translation import ugettext as _
+
+ACCESS_CONTROL = livesettings.ConfigurationGroup(
+ 'ACCESS_CONTROL',
+ _('Access control settings'),
+ super_group = LOGIN_USERS_COMMUNICATION
+ )
+
+settings.register(
+ livesettings.BooleanValue(
+ ACCESS_CONTROL,
+ 'ASKBOT_CLOSED_FORUM_MODE',
+ default = False,
+ description=_('Support mode where only registered users can access the forum'),
+ help_text=_('to activate this permanently use ASKBOT_CLOSED_FORUM_MODE '
+ 'in your settings.py')
+ )
+)
+
+
diff --git a/askbot/conf/login_providers.py b/askbot/conf/login_providers.py
index da832a1d..b6073eea 100644
--- a/askbot/conf/login_providers.py
+++ b/askbot/conf/login_providers.py
@@ -56,22 +56,11 @@ settings.register(
livesettings.ImageValue(
LOGIN_PROVIDERS,
'WORDPRESS_SITE_ICON',
- upload_directory = django_settings.ASKBOT_FILE_UPLOAD_DIR,
- upload_url = '/' + django_settings.ASKBOT_UPLOADED_FILES_URL,
- default = '/images/logo.gif',
- description = _('Upload your icon'),
- url_resolver = skin_utils.get_media_url
- )
-)
-
-settings.register(
- livesettings.BooleanValue(
- LOGIN_PROVIDERS,
- 'ASKBOT_CLOSED_FORUM_MODE',
- default = django_settings.ASKBOT_CLOSED_FORUM_MODE,
- description=_('Support mode where only registered users can access the forum'),
- help_text=_('to activate this permanently use ASKBOT_CLOSED_FORUM_MODE '
- 'in your settings.py')
+ upload_directory=django_settings.ASKBOT_FILE_UPLOAD_DIR,
+ upload_url='/' + django_settings.ASKBOT_UPLOADED_FILES_URL,
+ default='/images/logo.gif',
+ description=_('Upload your icon'),
+ url_resolver=skin_utils.get_media_url
)
)
diff --git a/askbot/middleware/forum_mode.py b/askbot/middleware/forum_mode.py
index ff99be49..874b5559 100644
--- a/askbot/middleware/forum_mode.py
+++ b/askbot/middleware/forum_mode.py
@@ -5,14 +5,31 @@ from django.core.urlresolvers import resolve
from askbot.conf import settings as askbot_settings
+PROTECTED_URLS = [
+ 'about',
+ 'feeds',
+ 'privacy',
+ 'tags',
+ 'badges',
+ 'questions',
+ 'question',
+ 'question_revisions',
+ 'users',
+ 'edit_user',
+ 'faq',
+ 'user_profile',
+ 'answer_revisions',
+ 'user_subscriptions']
+
+
class ForumModeMiddleware(object):
-
+
def process_request(self, request):
if (askbot_settings.ASKBOT_CLOSED_FORUM_MODE
and request.user.is_anonymous()
- and not (request.path == settings.LOGIN_URL or
- resolve(request.path).url_name in ['custom_css', 'custom_js', 'askbot_jsi18n', 'askbot_media', 'sitemap'])):
- request.user.message_set.create(_('Please log in to use %s') % askbot_settings.APP_SHORT_NAME)
+ and resolve(request.path).url_name in PROTECTED_URLS):
+ request.user.message_set.create(_('Please log in to use %s') % \
+ askbot_settings.APP_SHORT_NAME)
return HttpResponseRedirect(settings.LOGIN_URL)
else:
return None
diff --git a/askbot/setup_templates/settings.py b/askbot/setup_templates/settings.py
index e8adc2ce..2f6a0f9b 100644
--- a/askbot/setup_templates/settings.py
+++ b/askbot/setup_templates/settings.py
@@ -209,7 +209,6 @@ LOGIN_URL = '/%s%s%s' % (ASKBOT_URL,_('account/'),_('signin/'))
ASKBOT_UPLOADED_FILES_URL = '%s%s' % (ASKBOT_URL, 'upfiles/')
ALLOW_UNICODE_SLUGS = False
ASKBOT_USE_STACKEXCHANGE_URLS = False #mimic url scheme of stackexchange
-ASKBOT_CLOSED_FORUM_MODE = False
#Celery Settings
BROKER_TRANSPORT = "djkombu.transport.DatabaseTransport"
diff --git a/askbot/tests/page_load_tests.py b/askbot/tests/page_load_tests.py
index 442b1bd7..285d8bc7 100644
--- a/askbot/tests/page_load_tests.py
+++ b/askbot/tests/page_load_tests.py
@@ -1,6 +1,7 @@
from django.test import TestCase
from django.test import signals
from django.template import defaultfilters
+from django.conf import settings
from django.core.urlresolvers import reverse
import coffin
import coffin.template
@@ -8,11 +9,15 @@ from askbot import models
from askbot.utils.slug import slugify
from askbot.deployment import package_utils
from askbot.tests.utils import AskbotTestCase
+from askbot.conf import settings as askbot_settings
+from askbot.tests.utils import skipIf
import sys
+
def patch_jinja2():
from jinja2 import Template
ORIG_JINJA2_RENDERER = Template.render
+
def instrumented_render(template_object, *args, **kwargs):
context = dict(*args, **kwargs)
signals.template_rendered.send(
@@ -28,26 +33,35 @@ if CMAJOR == 0 and CMINOR == 3 and CMICRO < 4:
import ipdb; ipdb.set_trace()
patch_jinja2()
+
class PageLoadTestCase(AskbotTestCase):
def try_url(
self,
- url_name, status_code=200, template=None,
+ url_name, status_code=200, template=None,
kwargs={}, redirect_url=None, follow=False,
- data = {},
- ):
- url = reverse(url_name, kwargs = kwargs)
- url_info = 'getting url %s' % url
+ data={}):
+ url = reverse(url_name, kwargs=kwargs)
+ if status_code == 302:
+ url_info = 'redirecting to LOGIN_URL in closed_mode: %s' % url
+ else:
+ url_info = 'getting url %s' % url
if data:
url_info += '?' + '&'.join(['%s=%s' % (k, v) for k, v in data.iteritems()])
print url_info
+ # if redirect expected, but we wont' follow
+ if status_code == 302 and follow:
+ response = self.client.get(url, data=data)
+ self.assertTrue(settings.LOGIN_URL in response['Location'])
+ return
+
r = self.client.get(url, data=data, follow=follow)
if hasattr(self.client, 'redirect_chain'):
print 'redirect chain: %s' % ','.join(self.client.redirect_chain)
self.assertEqual(r.status_code, status_code)
- if template:
+ if template and status_code != 302:
if isinstance(r.template, coffin.template.Template):
self.assertEqual(r.template.name, template)
elif isinstance(r.template, list):
@@ -99,168 +113,220 @@ class PageLoadTestCase(AskbotTestCase):
self.failUnless(response.redirect_chain[0][0].endswith('/questions/'))
self.assertEquals(response.template.name, 'main_page.html')
- def proto_test_non_user_urls(self):
+ def proto_test_non_user_urls(self, status_code):
"""test all reader views thoroughly
on non-crashiness (no correcteness tests here)
"""
self.try_url('sitemap')
- self.try_url('feeds', kwargs={'url':'rss'})
- self.try_url('about', template='about.html')
- self.try_url('privacy', template='privacy.html')
+ self.try_url(
+ 'feeds',
+ status_code=status_code,
+ kwargs={'url':'rss'})
+ self.try_url(
+ 'about',
+ status_code=status_code,
+ template='about.html')
+ self.try_url(
+ 'privacy',
+ status_code=status_code,
+ template='privacy.html')
self.try_url('logout', template='authopenid/logout.html')
#todo: test different tabs
- self.try_url('tags', template='tags.html')
- self.try_url('tags', data={'sort':'name'}, template='tags.html')
- self.try_url('tags', data={'sort':'used'}, template='tags.html')
- self.try_url('badges', template='badges.html')
self.try_url(
- 'answer_revisions',
+ 'tags',
+ status_code=status_code,
+ template='tags.html')
+ self.try_url(
+ 'tags',
+ status_code=status_code,
+ data={'sort':'name'}, template='tags.html')
+ self.try_url(
+ 'tags',
+ status_code=status_code,
+ data={'sort':'used'}, template='tags.html')
+ self.try_url(
+ 'badges',
+ status_code=status_code,
+ template='badges.html')
+ self.try_url(
+ 'answer_revisions',
+ status_code=status_code,
template='revisions.html',
kwargs={'id':38}
)
#todo: test different sort methods and scopes
self.try_url(
'questions',
+ status_code=status_code,
template='main_page.html'
)
self.try_url(
'questions',
+ status_code=status_code,
data={'start_over':'true'},
template='main_page.html'
)
self.try_url(
'questions',
+ status_code=status_code,
data={'scope':'unanswered'},
template='main_page.html'
)
self.try_url(
'questions',
+ status_code=status_code,
data={'scope':'favorite'},
template='main_page.html'
)
self.try_url(
'questions',
+ status_code=status_code,
data={'scope':'unanswered', 'sort':'age-desc'},
template='main_page.html'
)
self.try_url(
'questions',
+ status_code=status_code,
data={'scope':'unanswered', 'sort':'age-asc'},
template='main_page.html'
)
self.try_url(
'questions',
+ status_code=status_code,
data={'scope':'unanswered', 'sort':'activity-desc'},
template='main_page.html'
)
self.try_url(
'questions',
+ status_code=status_code,
data={'scope':'unanswered', 'sort':'activity-asc'},
template='main_page.html'
)
self.try_url(
'questions',
+ status_code=status_code,
data={'sort':'answers-desc'},
template='main_page.html'
)
self.try_url(
'questions',
+ status_code=status_code,
data={'sort':'answers-asc'},
template='main_page.html'
)
self.try_url(
'questions',
+ status_code=status_code,
data={'sort':'votes-desc'},
template='main_page.html'
)
self.try_url(
'questions',
+ status_code=status_code,
data={'sort':'votes-asc'},
template='main_page.html'
)
self.try_url(
'question',
+ status_code=status_code,
kwargs={'id':1},
follow=True,
template='question.html'
)
self.try_url(
'question',
+ status_code=status_code,
kwargs={'id':2},
follow=True,
template='question.html'
)
self.try_url(
'question',
+ status_code=status_code,
kwargs={'id':3},
follow=True,
template='question.html'
)
self.try_url(
'question_revisions',
+ status_code=status_code,
kwargs={'id':17},
template='revisions.html'
)
- self.try_url('users', template='users.html')
+ self.try_url('users',
+ status_code=status_code,
+ template='users.html')
#todo: really odd naming conventions for sort methods
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'reputation'},
)
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'newest'},
)
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'last'},
)
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'user'},
)
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'reputation', 'page':2},
)
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'newest', 'page':2},
)
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'last', 'page':2},
)
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'user', 'page':2},
)
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'reputation', 'page':1},
)
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'newest', 'page':1},
)
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'last', 'page':1},
)
self.try_url(
'users',
+ status_code=status_code,
template='users.html',
data={'sort':'user', 'page':1},
)
@@ -268,72 +334,99 @@ class PageLoadTestCase(AskbotTestCase):
'edit_user',
template='authopenid/signin.html',
kwargs={'id':4},
- status_code=200,
+ status_code=status_code,
follow=True,
)
self.try_url(
'faq',
template='faq_static.html',
- status_code=200,
+ status_code=status_code,
)
def test_non_user_urls(self):
- self.proto_test_non_user_urls()
+ self.proto_test_non_user_urls(status_code=200)
+
+ @skipIf('askbot.middleware.forum_mode.ForumModeMiddleware' \
+ not in settings.MIDDLEWARE_CLASSES,
+ 'no ForumModeMiddleware set')
+ def test_non_user_urls_in_closed_forum_mode(self):
+ askbot_settings.ASKBOT_CLOSED_FORUM_MODE = True
+ self.proto_test_non_user_urls(status_code=302)
+ askbot_settings.ASKBOT_CLOSED_FORUM_MODE = False
#def test_non_user_urls_logged_in(self):
#user = User.objects.get(id=1)
#somehow login this user
#self.proto_test_non_user_urls()
- def test_user_urls(self):
+ def proto_test_user_urls(self, status_code):
user = models.User.objects.get(id=2)
name_slug = slugify(user.username)
self.try_url(
- 'user_profile',
+ 'user_profile',
kwargs={'id': 2, 'slug': name_slug},
- data={'sort':'stats'},
+ status_code=status_code,
+ data={'sort':'stats'},
template='user_profile/user_stats.html'
)
self.try_url(
- 'user_profile',
+ 'user_profile',
kwargs={'id': 2, 'slug': name_slug},
- data={'sort':'recent'},
+ status_code=status_code,
+ data={'sort':'recent'},
template='user_profile/user_recent.html'
)
self.try_url(
- 'user_profile',
+ 'user_profile',
kwargs={'id': 2, 'slug': name_slug},
- data={'sort':'inbox'},
+ status_code=status_code,
+ data={'sort':'inbox'},
template='authopenid/signin.html',
follow=True
)
self.try_url(
- 'user_profile',
+ 'user_profile',
kwargs={'id': 2, 'slug': name_slug},
- data={'sort':'reputation'},
+ status_code=status_code,
+ data={'sort':'reputation'},
template='user_profile/user_reputation.html'
)
self.try_url(
- 'user_profile',
+ 'user_profile',
kwargs={'id': 2, 'slug': name_slug},
- data={'sort':'votes'},
+ status_code=status_code,
+ data={'sort':'votes'},
template='authopenid/signin.html',
follow = True
)
self.try_url(
- 'user_profile',
+ 'user_profile',
kwargs={'id': 2, 'slug': name_slug},
- data={'sort':'favorites'},
+ status_code=status_code,
+ data={'sort':'favorites'},
template='user_profile/user_favorites.html'
)
self.try_url(
- 'user_profile',
+ 'user_profile',
kwargs={'id': 2, 'slug': name_slug},
- data={'sort':'email_subscriptions'},
+ status_code=status_code,
+ data={'sort':'email_subscriptions'},
template='authopenid/signin.html',
follow = True
)
+ def test_user_urls(self):
+ self.proto_test_user_urls(status_code=200)
+
+ @skipIf('askbot.middleware.forum_mode.ForumModeMiddleware' \
+ not in settings.MIDDLEWARE_CLASSES,
+ 'no ForumModeMiddleware set')
+ def test_user_urls_in_closed_forum_mode(self):
+ askbot_settings.ASKBOT_CLOSED_FORUM_MODE = True
+ self.proto_test_user_urls(status_code=302)
+ askbot_settings.ASKBOT_CLOSED_FORUM_MODE = False
+
+
def test_user_urls_logged_in(self):
user = models.User.objects.get(id=2)
name_slug = slugify(user.username)
@@ -360,12 +453,13 @@ class PageLoadTestCase(AskbotTestCase):
)
self.client.login(method = 'force', user_id = asker.id)
self.try_url(
- 'user_profile',
+ 'user_profile',
kwargs={'id': asker.id, 'slug': slugify(asker.username)},
- data={'sort':'inbox'},
+ data={'sort':'inbox'},
template='user_profile/user_inbox.html',
)
+
class AvatarTests(AskbotTestCase):
def test_avatar_for_two_word_user_works(self):
diff --git a/askbot/tests/permission_assertion_tests.py b/askbot/tests/permission_assertion_tests.py
index 56b85f9b..14680999 100644
--- a/askbot/tests/permission_assertion_tests.py
+++ b/askbot/tests/permission_assertion_tests.py
@@ -8,6 +8,8 @@ from askbot.tests import utils
from askbot.conf import settings as askbot_settings
from askbot import models
from askbot.templatetags import extra_filters as template_filters
+from askbot.tests.utils import skipIf
+
class PermissionAssertionTestCase(TestCase):
"""base TestCase class for permission
@@ -1587,18 +1589,31 @@ class ClosedForumTests(utils.AskbotTestCase):
self.question = self.post_question()
self.test_url = reverse('question', kwargs={'id':self.question.id})
self.redirect_to = settings.LOGIN_URL
+ self.client = Client()
askbot_settings.ASKBOT_CLOSED_FORUM_MODE = True
+ @skipIf('askbot.middleware.forum_mode.ForumModeMiddleware' \
+ not in settings.MIDDLEWARE_CLASSES,
+ 'no ForumModeMiddleware set')
+ def test_login_page_accessable(self):
+ # futher see in page_load_tests.py
+ response = self.client.get(reverse('user_signin'))
+ self.assertEquals(response.status_code, 200)
+
+ @skipIf('askbot.middleware.forum_mode.ForumModeMiddleware' \
+ not in settings.MIDDLEWARE_CLASSES,
+ 'no ForumModeMiddleware set')
def test_anonymous_access(self):
- client = Client()
- response = client.get(self.test_url)
+ response = self.client.get(self.test_url)
self.assertEquals(response.status_code, 302)
self.assertTrue(self.redirect_to in response['Location'])
+ @skipIf('askbot.middleware.forum_mode.ForumModeMiddleware' \
+ not in settings.MIDDLEWARE_CLASSES,
+ 'no ForumModeMiddleware set')
def test_authentificated_access(self):
- client = Client()
- client.login(username=self.other_user.username, password=self.password)
- response = client.get(self.test_url)
+ self.client.login(username=self.other_user.username, password=self.password)
+ response = self.client.get(self.test_url)
self.assertEquals(response.status_code, 302)
self.assertTrue(self.redirect_to not in response['Location'])
self.assertTrue(self.test_url in response['Location'])
diff --git a/askbot/tests/utils.py b/askbot/tests/utils.py
index 03478419..54a2a0ec 100644
--- a/askbot/tests/utils.py
+++ b/askbot/tests/utils.py
@@ -1,6 +1,7 @@
"""utility functions used by Askbot test cases
"""
from django.test import TestCase
+from django.utils.unittest.compatibility import wraps
from askbot import models
def create_user(
@@ -176,3 +177,46 @@ class AskbotTestCase(TestCase):
)
return comment
+
+"""
+Some test decorators, taken from Django-1.3
+"""
+
+
+class SkipTest(Exception):
+ """
+ Raise this exception in a test to skip it.
+
+ Usually you can use TestResult.skip() or one of the skipping decorators
+ instead of raising this directly.
+ """
+
+
+def _id(obj):
+ return obj
+
+
+def skip(reason):
+ """
+ Unconditionally skip a test.
+ """
+ def decorator(test_item):
+ if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
+ @wraps(test_item)
+ def skip_wrapper(*args, **kwargs):
+ raise SkipTest(reason)
+ test_item = skip_wrapper
+
+ test_item.__unittest_skip__ = True
+ test_item.__unittest_skip_why__ = reason
+ return test_item
+ return decorator
+
+
+def skipIf(condition, reason):
+ """
+ Skip a test if the condition is true.
+ """
+ if condition:
+ return skip(reason)
+ return _id