From b4382b7055fc8b0078cbb50ed9c3f924635d9971 Mon Sep 17 00:00:00 2001 From: Bas Peschier Date: Sat, 21 Mar 2015 13:19:13 +0100 Subject: Fixed #16362 -- Allowed lookaround assertions in URL patterns. --- tests/urlpatterns_reverse/tests.py | 47 ++++++++++++++++++++++++++++++++++++++ tests/urlpatterns_reverse/urls.py | 4 ++++ 2 files changed, 51 insertions(+) (limited to 'tests/urlpatterns_reverse') diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index eca5bc1e64..8706c64b64 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -799,3 +799,50 @@ class IncludeTests(SimpleTestCase): msg = "Must specify a namespace if specifying app_name." with self.assertRaisesMessage(ValueError, msg): include('urls', app_name='bar') + + +@override_settings(ROOT_URLCONF='urlpatterns_reverse.urls') +class LookaheadTests(TestCase): + def test_valid_resolve(self): + test_urls = [ + '/lookahead-/a-city/', + '/lookbehind-/a-city/', + '/lookahead+/a-city/', + '/lookbehind+/a-city/', + ] + for test_url in test_urls: + match = resolve(test_url) + self.assertEqual(match.kwargs, {'city': 'a-city'}) + + def test_invalid_resolve(self): + test_urls = [ + '/lookahead-/not-a-city/', + '/lookbehind-/not-a-city/', + '/lookahead+/other-city/', + '/lookbehind+/other-city/', + ] + for test_url in test_urls: + with self.assertRaises(Resolver404): + resolve(test_url) + + def test_valid_reverse(self): + url = reverse('lookahead-positive', kwargs={'city': 'a-city'}) + self.assertEqual(url, '/lookahead+/a-city/') + url = reverse('lookahead-negative', kwargs={'city': 'a-city'}) + self.assertEqual(url, '/lookahead-/a-city/') + + url = reverse('lookbehind-positive', kwargs={'city': 'a-city'}) + self.assertEqual(url, '/lookbehind+/a-city/') + url = reverse('lookbehind-negative', kwargs={'city': 'a-city'}) + self.assertEqual(url, '/lookbehind-/a-city/') + + def test_invalid_reverse(self): + with self.assertRaises(NoReverseMatch): + reverse('lookahead-positive', kwargs={'city': 'other-city'}) + with self.assertRaises(NoReverseMatch): + reverse('lookahead-negative', kwargs={'city': 'not-a-city'}) + + with self.assertRaises(NoReverseMatch): + reverse('lookbehind-positive', kwargs={'city': 'other-city'}) + with self.assertRaises(NoReverseMatch): + reverse('lookbehind-negative', kwargs={'city': 'not-a-city'}) diff --git a/tests/urlpatterns_reverse/urls.py b/tests/urlpatterns_reverse/urls.py index d6b692d220..25609c14cf 100644 --- a/tests/urlpatterns_reverse/urls.py +++ b/tests/urlpatterns_reverse/urls.py @@ -62,6 +62,10 @@ with warnings.catch_warnings(): url(r'^outer/(?P[0-9]+)/', include('urlpatterns_reverse.included_urls')), url(r'^outer-no-kwargs/([0-9]+)/', include('urlpatterns_reverse.included_no_kwargs_urls')), url('', include('urlpatterns_reverse.extra_urls')), + url(r'^lookahead-/(?!not-a-city)(?P[^/]+)/$', empty_view, name='lookahead-negative'), + url(r'^lookahead\+/(?=a-city)(?P[^/]+)/$', empty_view, name='lookahead-positive'), + url(r'^lookbehind-/(?P[^/]+)(?[^/]+)(?<=a-city)/$', empty_view, name='lookbehind-positive'), # Partials should be fine. url(r'^partial/', empty_view_partial, name="partial"), -- cgit v1.3