Skip to content

Commit

Permalink
Trailing/Leading slash validations in RedirectForm
Browse files Browse the repository at this point in the history
Validate that leading/trailing slash is used in PREFIX redirects when
using $rest keyword.

Add other minor test cases for other types of redirects.
  • Loading branch information
humitos committed Aug 21, 2018
1 parent 829af19 commit f6fed2d
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 2 deletions.
23 changes: 23 additions & 0 deletions readthedocs/projects/forms.py
Expand Up @@ -613,6 +613,29 @@ def __init__(self, *args, **kwargs):
self.project = kwargs.pop('project', None)
super(RedirectForm, self).__init__(*args, **kwargs)

def clean(self):
redirect_type = self.cleaned_data['redirect_type']
from_url = self.cleaned_data['from_url']
to_url = self.cleaned_data['to_url']
if redirect_type == 'exact':
if '$rest' in from_url:
# Leading slash
if not from_url.startswith('/') or not to_url.startswith('/'):
raise forms.ValidationError(
_('Exact Redirects require the leading slash (/) in both URLs when using $rest keyword'), # noqa
)
# Trailing slash
if from_url.endswith('/'):
raise forms.ValidationError(
_("Exact Redirects doesn't allow trailing slash (/) in From URL when using $rest keyword"), # noqa
)
if not to_url.endswith('/'):
raise forms.ValidationError(
_('Exact Redirects require a trailing slash (/) in To URL when using $rest keyword'), # noqa
)

return self.cleaned_data

def save(self, **_): # pylint: disable=arguments-differ
# TODO this should respect the unused argument `commit`. It's not clear
# why this needs to be a call to `create`, instead of relying on the
Expand Down
84 changes: 82 additions & 2 deletions readthedocs/rtd_tests/tests/test_redirects.py
@@ -1,5 +1,5 @@
from __future__ import absolute_import
from django.core.urlresolvers import reverse
# -*- coding: utf-8 -*-

from django.http import Http404
from django.test import TestCase
from django.test.utils import override_settings
Expand All @@ -9,6 +9,7 @@
from mock import patch

from readthedocs.builds.constants import LATEST
from readthedocs.projects.forms import RedirectForm
from readthedocs.projects.models import Project
from readthedocs.redirects.models import Redirect

Expand Down Expand Up @@ -352,3 +353,82 @@ def test_single_version_no_subdomain(self):
self.redirect.get_full_path('faq.html'),
'/docs/read-the-docs/faq.html'
)


class RedirectFormTests(TestCase):

def test_sphinx_html_redirect(self):
data = {
'redirect_type': 'sphinx_html',
}
form = RedirectForm(data=data)
self.assertTrue(form.is_valid())

def test_sphinx_htmldir_redirect(self):
data = {
'redirect_type': 'sphinx_htmldir',
}
form = RedirectForm(data=data)
self.assertTrue(form.is_valid())

def test_prefix_redirect(self):
data = {
'from_url': '/oldurl/',
'redirect_type': 'prefix',
}
form = RedirectForm(data=data)
self.assertTrue(form.is_valid())

def test_page_redirect(self):
data = {
'from_url': '/install.html',
'to_url': '/tutorial/install.html',
'redirect_type': 'page',
}
form = RedirectForm(data=data)
self.assertTrue(form.is_valid())

def test_exact_redirect(self):
data = {
'from_url': '/en/2.0/$rest',
'to_url': '/en/3.0/',
'redirect_type': 'exact',
}
form = RedirectForm(data=data)
self.assertTrue(form.is_valid())

def test_exact_redirect_leading_slash_from_url(self):
data = {
'from_url': 'no/leading/slash/$rest',
'to_url': '/en/latest/',
'redirect_type': 'exact',
}
form = RedirectForm(data=data)
self.assertFalse(form.is_valid())

def test_exact_redirect_leading_slash_to_url(self):
data = {
'from_url': '/jp/latest/$rest',
'to_url': 'no/leading/slash/',
'redirect_type': 'exact',
}
form = RedirectForm(data=data)
self.assertFalse(form.is_valid())

def test_exact_redirect_trailing_slash_from_url(self):
data = {
'from_url': '/trailing/slash/$rest/',
'to_url': '/en/latest/',
'redirect_type': 'exact',
}
form = RedirectForm(data=data)
self.assertFalse(form.is_valid())

def test_exact_redirect_trailing_slash_to_url(self):
data = {
'from_url': '/jp/latest/$rest',
'to_url': '/no/trailing/slash',
'redirect_type': 'exact',
}
form = RedirectForm(data=data)
self.assertFalse(form.is_valid())

0 comments on commit f6fed2d

Please sign in to comment.