Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix broken unit tests #13

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions cms_redirects/admin.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
from django.contrib import admin
from cms_redirects.models import CMSRedirect


class CMSRedirectAdmin(admin.ModelAdmin):
list_display = ('old_path', 'new_path', 'page', 'page_site', 'site', 'actual_response_code',)
list_filter = ('site',)
search_fields = ('old_path', 'new_path', 'page__title_set__title')
radio_fields = {'site': admin.VERTICAL}
fieldsets = [
('Source', {
"fields": ('site','old_path',)
"fields": ('site', 'old_path',)
}),
('Destination', {
"fields": ('new_path','page', 'response_code',)
"fields": ('new_path', 'page', 'response_code',)
}),
]

Expand Down
38 changes: 18 additions & 20 deletions cms_redirects/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,45 +13,43 @@ def get_redirect(old_path):


def remove_slash(path):
return path[:path.rfind('/')]+path[path.rfind('/')+1:]
return path[:path.rfind('/')] + path[path.rfind('/') + 1:]


def remove_query(path):
return path.split('?', 1)[0]


class RedirectFallbackMiddleware(object):

def process_exception(self, request, exception):
if isinstance(exception, http.Http404):

# First try the whole path.
path = request.get_full_path()
r = get_redirect(path)
redirect = get_redirect(path)

# It could be that we need to try without a trailing slash.
if r is None and settings.APPEND_SLASH:
r = get_redirect(remove_slash(path))
if redirect is None and settings.APPEND_SLASH:
redirect = get_redirect(remove_slash(path))

# It could be that the redirect is defined without a query string.
if r is None and path.count('?'):
r = get_redirect(remove_query(path))
if redirect is None and path.count('?'):
redirect = get_redirect(remove_query(path))

# It could be that we need to try without query string and without a trailing slash.
if r is None and path.count('?') and settings.APPEND_SLASH:
r = get_redirect(remove_slash(remove_query(path)))

if redirect is None and path.count('?') and settings.APPEND_SLASH:
redirect = get_redirect(remove_slash(remove_query(path)))

if r is not None:
if r.page:
if r.response_code == '302':
return http.HttpResponseRedirect(r.page.get_absolute_url())
if redirect is not None:
if redirect.page:
if redirect.response_code == '302':
return http.HttpResponseRedirect(redirect.page.get_absolute_url())
else:
return http.HttpResponsePermanentRedirect(r.page.get_absolute_url())
if r.new_path == '':
return http.HttpResponsePermanentRedirect(redirect.page.get_absolute_url())
if redirect.new_path == '':
return http.HttpResponseGone()
if r.response_code == '302':
return http.HttpResponseRedirect(r.new_path)
if redirect.response_code == '302':
return http.HttpResponseRedirect(redirect.new_path)
else:
return http.HttpResponsePermanentRedirect(r.new_path)


return http.HttpResponsePermanentRedirect(redirect.new_path)
35 changes: 23 additions & 12 deletions cms_redirects/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,44 @@
('302', '302'),
)


class CMSRedirect(models.Model):
page = PageField(verbose_name=_("page"), blank=True, null=True, help_text=_("A link to a page has priority over a text link."))
page = PageField(verbose_name=_("page"),
blank=True,
null=True,
help_text=_("A link to a page has priority over a text link."))
site = models.ForeignKey(Site)
old_path = models.CharField(_('redirect from'), max_length=200, db_index=True,
help_text=_("This should be an absolute path, excluding the domain name. Example: '/events/search/'."))
new_path = models.CharField(_('redirect to'), max_length=200, blank=True,
help_text=_("This can be either an absolute path (as above) or a full URL starting with 'http://'."))
response_code = models.CharField(_('response code'), max_length=3, choices=RESPONSE_CODES, default=RESPONSE_CODES[0][0],
help_text=_("This is the http response code returned if a destination is specified. If no destination is specified the response code will be 410."))

old_path = models.CharField(_('redirect from'),
max_length=200,
db_index=True,
help_text=_("This should be an absolute path, excluding the domain name. Example: '/events/search/'."))
new_path = models.CharField(_('redirect to'),
max_length=200,
blank=True,
help_text=_("This can be either an absolute path (as above) or a full URL starting with 'http://'."))
response_code = models.CharField(_('response code'),
max_length=3,
choices=RESPONSE_CODES,
default=RESPONSE_CODES[0][0],
help_text=_("This is the http response code returned if a destination is specified. If no destination is specified the response code will be 410."))

def page_site(self):
if self.page:
return u'%s' % self.page.site
return u''
page_site.short_description = "Page Site"

def actual_response_code(self):
if self.page or self.new_path:
return self.response_code
return u'410'
actual_response_code.short_description = "Response Code"

class Meta:
verbose_name = _('CMS Redirect')
verbose_name_plural = _('CMS Redirects')
unique_together=(('site', 'old_path'),)
unique_together = (('site', 'old_path'),)
ordering = ('old_path',)

def __unicode__(self):
return "%s ---> %s" % (self.old_path, self.new_path)
100 changes: 56 additions & 44 deletions cms_redirects/tests.py
Original file line number Diff line number Diff line change
@@ -1,82 +1,94 @@
import unittest

from django.test.client import Client
from django.test import TestCase
from django.contrib.sites.models import Site
from django.conf import settings
from django.contrib.auth.models import User
from django.test.utils import override_settings

from cms.models import Page, Title
from cms.api import create_page, publish_page
from cms_redirects.models import CMSRedirect

class TestRedirects(unittest.TestCase):

@override_settings(APPEND_SLASH=False)
class TestRedirects(TestCase):

def setUp(self):
settings.APPEND_SLASH = False

self.site = Site.objects.get_current()

page = Page()
page.site = self.site
page.save()
page.publish()
self.page = page
self.page = create_page(title='Hello world!',
# TODO we're assuming here that at least one template exists
# in the settings file.
template=settings.CMS_TEMPLATES[0][0],
language='en'
)

self.user = User.objects.create_user('test_user', '[email protected]', 'test_user')
self.user.is_superuser = True
self.user.save()

title = Title(title="Hello world!")
title.page = page
title.language = u'en'
title.save()
publish_page(self.page, self.user)

def test_301_page_redirect(self):
r_301_page = CMSRedirect(site=self.site, page=self.page, old_path='/301_page.php')
r_301_page = CMSRedirect(site=self.site,
page=self.page,
old_path='/301_page.php')
r_301_page.save()

c = Client()
r = c.get('/301_page.php')
self.assertEqual(r.status_code, 301)
self.assertEqual(r._headers['location'][1], 'http://testserver/')
response = self.client.get('/301_page.php')
self.assertEqual(response.status_code, 301)
self.assertEqual(response._headers['location'][1], 'http://testserver/')

def test_302_page_redirect(self):
r_302_page = CMSRedirect(site=self.site, page=self.page, old_path='/302_page.php', response_code='302')
r_302_page = CMSRedirect(site=self.site,
page=self.page,
old_path='/302_page.php',
response_code='302')
r_302_page.save()

c = Client()
r = c.get('/302_page.php')
self.assertEqual(r.status_code, 302)
self.assertEqual(r._headers['location'][1], 'http://testserver/')
response = self.client.get('/302_page.php')
self.assertEqual(response.status_code, 302)
self.assertEqual(response._headers['location'][1], 'http://testserver/')

def test_301_path_redirect(self):
r_301_path = CMSRedirect(site=self.site, new_path='/', old_path='/301_path.php')
r_301_path = CMSRedirect(site=self.site,
new_path='/',
old_path='/301_path.php')
r_301_path.save()

c = Client()
r = c.get('/301_path.php')
self.assertEqual(r.status_code, 301)
self.assertEqual(r._headers['location'][1], 'http://testserver/')
response = self.client.get('/301_path.php')
self.assertEqual(response.status_code, 301)
self.assertEqual(response._headers['location'][1], 'http://testserver/')

def test_302_path_redirect(self):
r_302_path = CMSRedirect(site=self.site, new_path='/', old_path='/302_path.php', response_code='302')
r_302_path = CMSRedirect(site=self.site,
new_path='/',
old_path='/302_path.php',
response_code='302')
r_302_path.save()

c = Client()
r = c.get('/302_path.php')
self.assertEqual(r.status_code, 302)
self.assertEqual(r._headers['location'][1], 'http://testserver/')
response = self.client.get('/302_path.php')
self.assertEqual(response.status_code, 302)
self.assertEqual(response._headers['location'][1], 'http://testserver/')

def test_410_redirect(self):
r_410 = CMSRedirect(site=self.site, old_path='/410.php', response_code='302')
r_410 = CMSRedirect(site=self.site,
old_path='/410.php',
response_code='302')
r_410.save()

c = Client()
r = c.get('/410.php')
self.assertEqual(r.status_code, 410)
response = self.client.get('/410.php')
self.assertEqual(response.status_code, 410)

def test_redirect_can_ignore_query_string(self):
"""
Set up a redirect as in the generic 301 page case, but then try to get this page with
a query string appended. Succeed nonetheless.
"""
r_301_page = CMSRedirect(site=self.site, page=self.page, old_path='/301_page.php')
r_301_page = CMSRedirect(site=self.site,
page=self.page,
old_path='/301_page.php')
r_301_page.save()

c = Client()
r = c.get('/301_page.php?this=is&a=query&string')
self.assertEqual(r.status_code, 301)
self.assertEqual(r._headers['location'][1], 'http://testserver')
response = self.client.get('/301_page.php?this=is&a=query&string')
self.assertEqual(response.status_code, 301)
self.assertEqual(response._headers['location'][1], 'http://testserver/')