Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

improved details view coverage, fixed issue 678 (language fallback on…

… root), improved docs on cmsplugin subclasses (663)
  • Loading branch information...
commit 269d97be1e0342847df5f4dc64dd6e75001e9784 1 parent 431a61b
Jonas Obrist ojii authored
24 cms/test/testcases.py
View
@@ -136,14 +136,16 @@ def assertObjectDoesNotExist(self, qs, **filter):
raise self.failureException, "ObjectDoesNotExist not raised"
def create_page(self, parent_page=None, user=None, position="last-child",
- title=None, site=1, published=False, in_navigation=False, moderate=False, **extra):
+ title=None, site=1, published=False, in_navigation=False,
+ moderate=False, language=None, title_extra=None, **extra):
"""
Common way for page creation with some checks
"""
_thread_locals.user = user
- language = settings.LANGUAGES[0][0]
- if settings.CMS_SITE_LANGUAGES.get(site, False):
- language = settings.CMS_SITE_LANGUAGES[site][0]
+ if not language:
+ language = settings.LANGUAGES[0][0]
+ if settings.CMS_SITE_LANGUAGES.get(site, False):
+ language = settings.CMS_SITE_LANGUAGES[site][0]
site = Site.objects.get(pk=site)
page_data = {
@@ -173,7 +175,15 @@ def create_page(self, parent_page=None, user=None, position="last-child",
else:
slug = slugify(title)
self.counter = self.counter + 1
- self.create_title(title=title, slug=slug, language=language, page=page)
+ if not title_extra:
+ title_extra = {}
+ self.create_title(
+ title=title,
+ slug=slug,
+ language=language,
+ page=page,
+ **title_extra
+ )
del _thread_locals.user
return page
@@ -234,7 +244,7 @@ def get_context(self, path=None):
return Context(context)
- def get_request(self, path=None):
+ def get_request(self, path=None, language=settings.LANGUAGES[0][0]):
if not path:
path = self.get_pages_root()
@@ -264,7 +274,7 @@ def get_request(self, path=None):
request = WSGIRequest(environ)
request.session = self.client.session
request.user = getattr(self, 'user', AnonymousUser())
- request.LANGUAGE_CODE = settings.LANGUAGES[0][0]
+ request.LANGUAGE_CODE = language
return request
def create_page_user(self, username, password=None,
1  cms/tests/__init__.py
View
@@ -21,6 +21,7 @@
from cms.tests.forms import FormsTestCase
from cms.tests.toolbar import ToolbarTests
from cms.tests.middleware import MiddlewareTestCase
+from cms.tests.views import ViewTests
try:
from cms.tests.javascript import JavascriptTestCase
except ImportError:
120 cms/tests/views.py
View
@@ -0,0 +1,120 @@
+from cms.apphook_pool import apphook_pool
+from cms.test.testcases import SettingsOverrideTestCase
+from cms.test.util.context_managers import SettingsOverride
+from cms.views import _handle_no_page, details
+from django.conf import settings
+from django.core.urlresolvers import clear_url_caches
+from django.http import Http404
+import sys
+
+
+APP_NAME = 'SampleApp'
+APP_MODULE = "testapp.sampleapp.cms_app"
+
+
+class ViewTests(SettingsOverrideTestCase):
+ urls = 'testapp.urls_for_apphook_tests'
+ settings_overrides = {'CMS_MODERATOR': False}
+
+ def setUp(self):
+ clear_url_caches()
+
+ def test_01_handle_no_page(self):
+ """
+ Test handle nopage correctly works with DEBUG=True
+ """
+ request = self.get_request('/')
+ slug = ''
+ self.assertRaises(Http404, _handle_no_page, request, slug)
+ with SettingsOverride(DEBUG=True):
+ request = self.get_request('/')
+ slug = ''
+ response = _handle_no_page(request, slug)
+ self.assertEqual(response.status_code, 200)
+
+ def test_02_language_fallback(self):
+ """
+ Test language fallbacks in details view
+ """
+ self.create_page(published=True, language='en')
+ request = self.get_request('/', 'de')
+ response = details(request, '')
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(response['Location'], '/en/')
+ with SettingsOverride(CMS_LANGUAGE_FALLBACK=False):
+ self.assertRaises(Http404, details, request, '')
+
+ def test_03_apphook_not_hooked(self):
+ """
+ Test details view when apphook pool has apphooks, but they're not
+ actually hooked
+ """
+ if APP_MODULE in sys.modules:
+ del sys.modules[APP_MODULE]
+ apphooks = (
+ '%s.%s' % (APP_MODULE, APP_NAME),
+ )
+ self.create_page(published=True, language='en')
+ with SettingsOverride(CMS_APPHOOKS=apphooks):
+ apphook_pool.clear()
+ response = self.client.get('/')
+ self.assertEqual(response.status_code, 200)
+ apphook_pool.clear()
+
+ def test_04_redirect(self):
+ redirect_one = 'https://www.django-cms.org/'
+ redirect_two = '/'
+ redirect_three = '/en/'
+ # test external redirect
+ one = self.create_page(
+ published=True,
+ language='en',
+ title_extra={'redirect': redirect_one}
+ )
+ url = one.get_absolute_url()
+ request = self.get_request(url)
+ response = details(request, url.strip('/'))
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(response['Location'], redirect_one)
+
+ # test internal language neutral redirect
+ two = self.create_page(
+ parent_page=one,
+ published=True,
+ language='en',
+ title_extra={'redirect': redirect_two}
+ )
+ url = two.get_absolute_url()
+ request = self.get_request(url)
+ response = details(request, url.strip('/'))
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(response['Location'], '/en/')
+
+ # test internal forced language redirect
+ three = self.create_page(
+ parent_page=one,
+ published=True,
+ language='en',
+ title_extra={'redirect': redirect_three}
+ )
+ url = three.get_absolute_url()
+ request = self.get_request(url)
+ response = details(request, url.strip('/'))
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(response['Location'], redirect_three)
+
+ def test_05_login_required(self):
+ self.create_page(
+ published=True,
+ language='en',
+ login_required=True,
+ )
+ request = self.get_request('/')
+ response = details(request, '')
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(response['Location'], '%s?next=/en/' % settings.LOGIN_URL)
+ with SettingsOverride(i18n_installed=False):
+ request = self.get_request('/')
+ response = details(request, '')
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(response['Location'], '%s?next=/' % settings.LOGIN_URL)
9 cms/views.py
View
@@ -4,7 +4,7 @@
from cms.utils import get_template_from_request, get_language_from_request
from cms.utils.i18n import get_fallback_languages
from cms.utils.page_resolver import get_page_from_request
-from django.conf import settings, settings as django_settings
+from django.conf import settings
from django.conf.urls.defaults import patterns
from django.core.urlresolvers import resolve, Resolver404
from django.http import Http404, HttpResponseRedirect
@@ -39,7 +39,7 @@ def details(request, slug):
# We resolve an alternate language for the page if it's not available.
# Since the "old" details view had an exception for the root page, it is
# ported here. So no resolution if the slug is ''.
- if (current_language not in available_languages) and (slug != ''):
+ if (current_language not in available_languages):
if settings.CMS_LANGUAGE_FALLBACK:
# If we didn't find the required page in the requested (current)
# language, let's try to find a suitable fallback in the list of
@@ -78,7 +78,8 @@ def details(request, slug):
# Check if the page has a redirect url defined for this language.
redirect_url = page.get_redirect(language=current_language)
if redirect_url:
- if settings.i18n_installed and redirect_url[0] == "/":
+ if (settings.i18n_installed and redirect_url[0] == "/"
+ and not redirect_url.startswith('/%s/' % current_language)):
redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/"))
# add language prefix to url
return HttpResponseRedirect(redirect_url)
@@ -89,7 +90,7 @@ def details(request, slug):
path = urlquote("/%s%s" % (request.LANGUAGE_CODE, request.get_full_path()))
else:
path = urlquote(request.get_full_path())
- tup = django_settings.LOGIN_URL , "next", path
+ tup = settings.LOGIN_URL , "next", path
return HttpResponseRedirect('%s?%s=%s' % tup)
template_name = get_template_from_request(request, page, no_current_page=True)
10 docs/extending_cms/custom_plugins.rst
View
@@ -74,9 +74,13 @@ Now models.py looks like the following::
.. warning::
- Two limitations apply when subclassing the `CMSPlugin` class to use with
- your custom plugins: the resulting subclass cannot be further subclassed,
- and subclasses of `CMSPlugin` cannot have a field called "text".
+ ``CMSPlugin`` subclasses cannot be further subclassed, if you want to make
+ a reusable plugin model, make an abstract base model which does not extend
+ ``CMSPlugin`` and subclass this abstract model as well as ``CMSPlugin`` in
+ your real plugin model.
+ Further note that you cannot name your model fields the same as any plugin's
+ lowercased model name you use is called, due to the implicit one to one
+ relation Django uses for subclassed models.
1  tests/testapp/sampleapp/urls.py
View
@@ -10,4 +10,5 @@
url(r'^account/$', 'sample_view', {'message': 'sample account page'}, name='sample-account'),
url(r'^account/my_profile/$', 'sample_view', {'message': 'sample my profile page'}, name='sample-profile'),
url(r'(?P<id>[0-9]+)/$', 'category_view', name='category_view'),
+ url(r'notfound/$', 'notfound', name='notfound'),
)
6 tests/testapp/sampleapp/views.py
View
@@ -1,4 +1,5 @@
# Create your views here.
+from django.http import Http404
from django.shortcuts import render_to_response
from django.template.context import RequestContext
from testapp.sampleapp.models import Category
@@ -8,4 +9,7 @@ def sample_view(request, **kw):
return render_to_response("sampleapp/home.html", context)
def category_view(request, id):
- return render_to_response('sampleapp/category_view.html', RequestContext(request, {'category':Category.objects.get(pk=id)}))
+ return render_to_response('sampleapp/category_view.html', RequestContext(request, {'category':Category.objects.get(pk=id)}))
+
+def notfound(request):
+ raise Http404
Please sign in to comment.
Something went wrong with that request. Please try again.