changeset 484:d4321317beae

internal: Correctly split sub URIs. Add unit tests.
author Ludovic Chabant <ludovic@chabant.com>
date Wed, 22 Jul 2015 00:07:25 -0700
parents 64e1cd71b30b
children c40b7923c474
files piecrust/uriutil.py tests/test_uriutil.py
diffstat 2 files changed, 73 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/piecrust/uriutil.py	Tue Jul 21 22:42:47 2015 -0700
+++ b/piecrust/uriutil.py	Wed Jul 22 00:07:25 2015 -0700
@@ -89,20 +89,32 @@
         raise Exception("URI '%s' is not a full URI." % uri)
 
     pretty_urls = app.config.get('site/pretty_urls')
+    trailing_slash = app.config.get('site/trailing_slash')
     if not pretty_urls:
         uri, ext = os.path.splitext(uri)
+    elif trailing_slash:
+        uri = uri.rstrip('/')
 
     page_num = 1
     pgn_suffix_re = app.config.get('__cache/pagination_suffix_re')
     m = re.search(pgn_suffix_re, uri)
     if m:
         uri = uri[:m.start()]
-        if uri == '':
-            uri = '/'
         page_num = int(m.group('num'))
 
-    if not pretty_urls:
-        uri += ext
+    if len(uri) < len(root):
+        # The only reasons the URI could have gotten shorter are:
+        # - if the regexp "ate" the trailing slash of the root.
+        # - if we stripped the trailing slash on a root URL.
+        uri += '/'
+
+    if len(uri) > len(root):
+        # Now if we don't have a root URI, make it conform to the rules
+        # (re-add the extension, or re-add the trailing slash).
+        if not pretty_urls:
+            uri += ext
+        elif trailing_slash:
+            uri += '/'
 
     return uri, page_num
 
--- a/tests/test_uriutil.py	Tue Jul 21 22:42:47 2015 -0700
+++ b/tests/test_uriutil.py	Wed Jul 22 00:07:25 2015 -0700
@@ -27,21 +27,68 @@
 
 
 @pytest.mark.parametrize('uri, expected, pretty_urls', [
-    ('foo/bar', ('foo/bar', 1), True),
-    ('foo/bar/2', ('foo/bar', 2), True),
-    ('foo/bar.ext', ('foo/bar.ext', 1), True),
-    ('foo/bar.ext/2', ('foo/bar.ext', 2), True),
-    ('foo/bar.html', ('foo/bar.html', 1), False),
-    ('foo/bar/2.html', ('foo/bar.html', 2), False),
-    ('foo/bar.ext', ('foo/bar.ext', 1), False),
-    ('foo/bar/2.ext', ('foo/bar.ext', 2), False)
+    ('/', ('/', 1), True),
+    ('/2', ('/', 2), True),
+    ('/foo/bar', ('/foo/bar', 1), True),
+    ('/foo/bar/2', ('/foo/bar', 2), True),
+    ('/foo/bar.ext', ('/foo/bar.ext', 1), True),
+    ('/foo/bar.ext/2', ('/foo/bar.ext', 2), True),
+    ('/', ('/', 1), False),
+    ('/2.html', ('/', 2), False),
+    ('/foo/bar.html', ('/foo/bar.html', 1), False),
+    ('/foo/bar/2.html', ('/foo/bar.html', 2), False),
+    ('/foo/bar.ext', ('/foo/bar.ext', 1), False),
+    ('/foo/bar/2.ext', ('/foo/bar.ext', 2), False)
     ])
 def test_split_sub_uri(uri, expected, pretty_urls):
     app = mock.MagicMock()
     app.config = {
+            'site/root': '/',
+            'site/pretty_urls': pretty_urls,
+            '__cache/pagination_suffix_re': '/(?P<num>\\d+)$'}
+    actual = split_sub_uri(app, uri)
+    assert actual == (expected[0], expected[1])
+
+
+@pytest.mark.parametrize('uri, expected, pretty_urls', [
+    ('/', ('/', 1), True),
+    ('/2/', ('/', 2), True),
+    ('/foo/bar/', ('/foo/bar/', 1), True),
+    ('/foo/bar/2/', ('/foo/bar/', 2), True),
+    ('/foo/bar.ext/', ('/foo/bar.ext/', 1), True),
+    ('/foo/bar.ext/2/', ('/foo/bar.ext/', 2), True),
+    ])
+def test_split_sub_uri_trailing_slash(uri, expected, pretty_urls):
+    app = mock.MagicMock()
+    app.config = {
+            'site/root': '/',
+            'site/pretty_urls': pretty_urls,
+            'site/trailing_slash': True,
+            '__cache/pagination_suffix_re': '/(?P<num>\\d+)$'}
+    actual = split_sub_uri(app, uri)
+    assert actual == (expected[0], expected[1])
+
+
+@pytest.mark.parametrize('uri, expected, pretty_urls', [
+    ('/', ('/', 1), True),
+    ('/2', ('/', 2), True),
+    ('/foo/bar', ('/foo/bar', 1), True),
+    ('/foo/bar/2', ('/foo/bar', 2), True),
+    ('/foo/bar.ext', ('/foo/bar.ext', 1), True),
+    ('/foo/bar.ext/2', ('/foo/bar.ext', 2), True),
+    ('/', ('/', 1), False),
+    ('/2.html', ('/', 2), False),
+    ('/foo/bar.html', ('/foo/bar.html', 1), False),
+    ('/foo/bar/2.html', ('/foo/bar.html', 2), False),
+    ('/foo/bar.ext', ('/foo/bar.ext', 1), False),
+    ('/foo/bar/2.ext', ('/foo/bar.ext', 2), False)
+    ])
+def test_split_sub_uri_with_root(uri, expected, pretty_urls):
+    app = mock.MagicMock()
+    app.config = {
             'site/root': '/whatever/',
             'site/pretty_urls': pretty_urls,
             '__cache/pagination_suffix_re': '/(?P<num>\\d+)$'}
-    actual = split_sub_uri(app, '/whatever/' + uri)
-    assert actual == ('/whatever/' + expected[0], expected[1])
+    actual = split_sub_uri(app, '/whatever' + uri)
+    assert actual == ('/whatever' + expected[0], expected[1])