diff options
author | Vlad Bokov <razum2um@mail.ru> | 2011-11-22 05:34:52 +0700 |
---|---|---|
committer | Vlad Bokov <razum2um@mail.ru> | 2011-11-22 05:34:52 +0700 |
commit | 2f56f6ee6cb9e7a78230b7fb3b4a6e5dd096ec70 (patch) | |
tree | 143b3ef733dbb30ae61d2afdacc51b1471e4a28b | |
parent | f35aab2070aa5884ac7b82666af81d4375211fe7 (diff) | |
download | askbot-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__.py | 1 | ||||
-rw-r--r-- | askbot/conf/access_control.py | 23 | ||||
-rw-r--r-- | askbot/conf/login_providers.py | 21 | ||||
-rw-r--r-- | askbot/middleware/forum_mode.py | 25 | ||||
-rw-r--r-- | askbot/setup_templates/settings.py | 1 | ||||
-rw-r--r-- | askbot/tests/page_load_tests.py | 166 | ||||
-rw-r--r-- | askbot/tests/permission_assertion_tests.py | 25 | ||||
-rw-r--r-- | askbot/tests/utils.py | 44 |
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 |