예제 #1
0
 def test_name(self):
     """
     Should return a RegexURLPattern with a matching name attribute
     """
     url_pattern = redirect(r'^the/dude$', 'abides', name='Lebowski')
     self.assertTrue(isinstance(url_pattern, RegexURLPattern))
     self.assertEqual(url_pattern.name, 'Lebowski')
예제 #2
0
 def test_urls_dont_call_reverse(self, reverse_mock):
     """
     Should not call reverse() for an obvious URL.
     """
     resolver = get_resolver([
         redirect(r'^iam/the/walrus/$', '/coo/coo/cachoo/'),
         redirect(r'^iam/the/ape-man/$', 'https://example.com/egg-man/'),
     ])
     middleware = RedirectsMiddleware(resolver)
     resp = middleware.process_request(self.rf.get('/iam/the/walrus/'))
     self.assertEqual(resp.status_code, 301)
     self.assertEqual(resp['Location'], '/coo/coo/cachoo/')
     resp = middleware.process_request(self.rf.get('/iam/the/ape-man/'))
     self.assertEqual(resp.status_code, 301)
     self.assertEqual(resp['Location'], 'https://example.com/egg-man/')
     reverse_mock.assert_not_called()
예제 #3
0
 def test_will_not_return_protocol_relative_redirect(self):
     """Allowing a protocol relative URL can allow an unintended domain redirect."""
     resolver = get_resolver([
         redirect(r'^(.+)/$', '/{}/', locale_prefix=False),
     ])
     middleware = RedirectsMiddleware(resolver)
     resp = middleware.process_request(self.rf.get('/%2fexample.com/'))
     self.assertEqual(resp['Location'], '/example.com/')
예제 #4
0
 def test_no_query(self):
     """
     Should return a 301 redirect
     """
     pattern = redirect(r'^the/dude$', 'abides')
     request = self.rf.get('the/dude')
     response = pattern.callback(request)
     self.assertEqual(response.status_code, 301)
     self.assertEqual(response['Location'], 'abides')
예제 #5
0
 def test_value_capture_and_substitution(self):
     """
     Should be able to capture info from URL and use in redirection.
     """
     resolver = get_resolver([redirect(r'^iam/the/(?P<name>.+)/$', '/donnie/the/{name}/')])
     middleware = RedirectsMiddleware(resolver)
     resp = middleware.process_request(self.rf.get('/iam/the/walrus/'))
     self.assertEqual(resp.status_code, 301)
     self.assertEqual(resp['Location'], '/donnie/the/walrus/')
예제 #6
0
 def test_anchor(self):
     """
     Should append anchor text to the end, including after any querystring
     """
     pattern = redirect(r'^the/dude$', 'abides', anchor='toe')
     request = self.rf.get('the/dude?want=a')
     response = pattern.callback(request)
     self.assertEqual(response.status_code, 301)
     self.assertEqual(response['Location'], 'abides?want=a#toe')
예제 #7
0
 def test_temporary_redirect(self):
     """
     Should use a temporary redirect (status code 302) if permanent == False
     """
     pattern = redirect(r'^the/dude$', 'abides', permanent=False)
     request = self.rf.get('the/dude')
     response = pattern.callback(request)
     self.assertEqual(response.status_code, 302)
     self.assertEqual(response['Location'], 'abides')
예제 #8
0
 def test_empty_query(self):
     """
     Should strip query params if called with empty query
     """
     pattern = redirect(r'^the/dude$', 'abides', query={})
     request = self.rf.get('the/dude?white=russian')
     response = pattern.callback(request)
     self.assertEqual(response.status_code, 301)
     self.assertEqual(response['Location'], 'abides')
예제 #9
0
 def test_preserve_query(self):
     """
     Should preserve querys from the original request by default
     """
     pattern = redirect(r'^the/dude$', 'abides')
     request = self.rf.get('the/dude?aggression=not_stand')
     response = pattern.callback(request)
     self.assertEqual(response.status_code, 301)
     self.assertEqual(response['Location'], 'abides?aggression=not_stand')
예제 #10
0
 def test_replace_query(self):
     """
     Should replace query params if any are provided
     """
     pattern = redirect(r'^the/dude$', 'abides',
                        query={'aggression': 'not_stand'})
     request = self.rf.get('the/dude?aggression=unchecked')
     response = pattern.callback(request)
     self.assertEqual(response.status_code, 301)
     self.assertEqual(response['Location'], 'abides?aggression=not_stand')
예제 #11
0
 def test_cache_headers(self):
     """
     Should add cache headers based on argument.
     """
     pattern = redirect(r'^the/dude$', 'abides', cache_timeout=2)
     request = self.rf.get('the/dude')
     response = pattern.callback(request)
     self.assertEqual(response.status_code, 301)
     self.assertEqual(response['Location'], 'abides')
     self.assertEqual(response['cache-control'], 'max-age=7200')  # 2 hours
예제 #12
0
 def test_vary_header(self):
     """
     Should add vary header based on argument.
     """
     pattern = redirect(r'^the/dude$', 'abides', vary='Accept-Language')
     request = self.rf.get('the/dude')
     response = pattern.callback(request)
     self.assertEqual(response.status_code, 301)
     self.assertEqual(response['Location'], 'abides')
     self.assertEqual(response['Vary'], 'Accept-Language')
예제 #13
0
 def test_locale_value_capture_ignore_locale(self):
     """
     Should be able to ignore the original locale.
     """
     resolver = get_resolver([redirect(r'^iam/the/(?P<name>.+)/$',
                                       '/donnie/the/{name}/', prepend_locale=False)])
     middleware = RedirectsMiddleware(resolver)
     resp = middleware.process_request(self.rf.get('/zh-TW/iam/the/walrus/'))
     self.assertEqual(resp.status_code, 301)
     self.assertEqual(resp['Location'], '/donnie/the/walrus/')
예제 #14
0
 def test_empty_unnamed_captures(self):
     """
     Should be able to define an optional unnamed capture.
     """
     resolver = get_resolver([redirect(r'^iam/the(/.+)?/$', '/donnie/the{}/',
                                       locale_prefix=False)])
     middleware = RedirectsMiddleware(resolver)
     resp = middleware.process_request(self.rf.get('/iam/the/'))
     self.assertEqual(resp.status_code, 301)
     self.assertEqual(resp['Location'], '/donnie/the/')
예제 #15
0
 def test_locale_value_capture_no_locale(self):
     """
     Should get locale value in kwargs and not break if no locale in URL.
     """
     resolver = get_resolver([redirect(r'^iam/the/(?P<name>.+)/$',
                                       '/donnie/the/{name}/')])
     middleware = RedirectsMiddleware(resolver)
     resp = middleware.process_request(self.rf.get('/iam/the/walrus/'))
     self.assertEqual(resp.status_code, 301)
     self.assertEqual(resp['Location'], '/donnie/the/walrus/')
예제 #16
0
 def test_locale_value_capture(self):
     """
     Should prepend locale value automatically.
     """
     resolver = get_resolver([redirect(r'^iam/the/(?P<name>.+)/$',
                                       '/donnie/the/{name}/')])
     middleware = RedirectsMiddleware(resolver)
     resp = middleware.process_request(self.rf.get('/pt-BR/iam/the/walrus/'))
     self.assertEqual(resp.status_code, 301)
     self.assertEqual(resp['Location'], '/pt-BR/donnie/the/walrus/')
예제 #17
0
 def test_to_view(self, mock_reverse):
     """
     Should use return value of reverse as redirect location
     """
     mock_reverse.return_value = '/just/your/opinion/man'
     pattern = redirect(r'^the/dude$', 'yeah.well.you.know.thats')
     request = self.rf.get('the/dude')
     response = pattern.callback(request)
     mock_reverse.assert_called_with('yeah.well.you.know.thats', args=None, kwargs=None)
     self.assertEqual(response.status_code, 301)
     self.assertEqual(response['Location'], '/just/your/opinion/man')
예제 #18
0
    def test_callable(self):
        """
        Should use the return value of the callable as redirect location
        """
        def opinion(request):
            return '/just/your/opinion/man'

        pattern = redirect(r'^the/dude$', opinion)
        request = self.rf.get('the/dude')
        response = pattern.callback(request)
        self.assertEqual(response.status_code, 301)
        self.assertEqual(response['Location'], '/just/your/opinion/man')
예제 #19
0
 def test_merge_query(self):
     """
     Should merge query params if requested
     """
     pattern = redirect(r'^the/dude$', 'abides',
                        query={'aggression': 'not_stand'}, merge_query=True)
     request = self.rf.get('the/dude?hates=the-eagles')
     response = pattern.callback(request)
     self.assertEqual(response.status_code, 301)
     url = urlparse(response['location'])
     query_dict = parse_qs(url.query)
     self.assertTrue(url.path, 'abides')
     self.assertEqual(query_dict, {'aggression': ['not_stand'], 'hates': ['the-eagles']})
예제 #20
0
    def test_match_flags(self):
        """
        Should be able to set regex flags for redirect URL.
        """
        resolver = get_resolver([
            redirect(r'^iam/the/walrus/$', '/coo/coo/cachoo/'),
            redirect(r'^iam/the/walrus/$', '/dammit/donnie/', re_flags='i'),
        ])
        middleware = RedirectsMiddleware(resolver)
        resp = middleware.process_request(self.rf.get('/IAm/The/Walrus/'))
        self.assertEqual(resp.status_code, 301)
        self.assertEqual(resp['Location'], '/dammit/donnie/')

        # also with locale
        resp = middleware.process_request(self.rf.get('/es-ES/Iam/The/Walrus/'))
        self.assertEqual(resp.status_code, 301)
        self.assertEqual(resp['Location'], '/es-ES/dammit/donnie/')

        # sanity check
        resp = middleware.process_request(self.rf.get('/iam/the/walrus/'))
        self.assertEqual(resp.status_code, 301)
        self.assertEqual(resp['Location'], '/coo/coo/cachoo/')
예제 #21
0
 def test_to_view_args_kwargs(self, mock_reverse):
     """
     Should call reverse with specified args and/or kwargs.
     """
     mock_reverse.return_value = '/just/your/opinion/man'
     pattern = redirect(r'^the/dude$', 'yeah.well.you.know.thats',
                        to_args=['dude'], to_kwargs={'tapes': 'credence'})
     request = self.rf.get('the/dude')
     response = pattern.callback(request)
     mock_reverse.assert_called_with('yeah.well.you.know.thats',
                                     args=['dude'], kwargs={'tapes': 'credence'})
     self.assertEqual(response.status_code, 301)
     self.assertEqual(response['Location'], '/just/your/opinion/man')
예제 #22
0
    def test_no_locale_prefix(self):
        """
        Should be able to define a redirect that ignores locale prefix.

        Also when not using any named captures (like implied locale) unnamed
        captures should work. For some reason Django only allows unnamed captures
        to pass through if there are no named ones.
        """
        resolver = get_resolver([redirect(r'^iam/the/(.+)/$', '/donnie/the/{}/',
                                          locale_prefix=False)])
        middleware = RedirectsMiddleware(resolver)
        resp = middleware.process_request(self.rf.get('/iam/the/walrus/'))
        self.assertEqual(resp.status_code, 301)
        self.assertEqual(resp['Location'], '/donnie/the/walrus/')
예제 #23
0
    def test_non_ascii_strip_tags(self):
        """
        Should deal with non-ascii characters when there's a substitution as well as strip tags.

        This is from errors that happened on www.m.o. The following URL caused a 500:

        https://www.mozilla.org/editor/midasdemo/securityprefs.html%3C/span%3E%3C/a%3E%C2%A0
        """
        resolver = get_resolver([redirect(r'^editor/(?P<page>.*)$',
                                          'http://www-archive.mozilla.org/editor/{page}')])
        middleware = RedirectsMiddleware(resolver)
        resp = middleware.process_request(self.rf.get('/editor/midasdemo/securityprefs.html'
                                                      '%3C/span%3E%3C/a%3E%C2%A0'))
        self.assertEqual(resp.status_code, 301)
        self.assertEqual(resp['Location'], 'http://www-archive.mozilla.org/editor/midasdemo/'
                                           'securityprefs.html%C2%A0')
예제 #24
0
    def test_no_redirect(self):
        """Should be able to skip redirects."""
        resolver = get_resolver([
            no_redirect(r'^iam/the/walrus/$'),
            redirect(r'^iam/the/.*/$', '/coo/coo/cachoo/'),
        ])
        middleware = RedirectsMiddleware(resolver)
        resp = middleware.process_request(self.rf.get('/iam/the/walrus/'))
        self.assertIsNone(resp)

        # including locale
        middleware = RedirectsMiddleware(resolver)
        resp = middleware.process_request(self.rf.get('/pt-BR/iam/the/walrus/'))
        self.assertIsNone(resp)

        resp = middleware.process_request(self.rf.get('/iam/the/marmot/'))
        self.assertEqual(resp.status_code, 301)
        self.assertEqual(resp['Location'], '/coo/coo/cachoo/')
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from django.test import RequestFactory, TestCase

from redirect_urls.middleware import RedirectsMiddleware
from redirect_urls.utils import get_resolver, redirect

patterns = [
    redirect(r'^dude/already/10th/', '/far/out/'),
    redirect(r'^walter/prior/restraint/', '/finishes/coffee/'),
]
middleware = RedirectsMiddleware(get_resolver(patterns))


class TestRedirectsMiddleware(TestCase):
    def setUp(self):
        self.rf = RequestFactory()

    def test_finds_and_uses_redirect(self):
        resp = middleware.process_request(
            self.rf.get('/walter/prior/restraint/'))
        self.assertEqual(resp.status_code, 301)
        self.assertEqual(resp['location'], '/finishes/coffee/')

    def test_no_redirect_match(self):
        resp = middleware.process_request(self.rf.get('/donnie/out/element/'))
        self.assertIsNone(resp)