diff --git a/tests/test_server.py b/tests/test_server.py index 37ac9be..ed83500 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -1,4 +1,4 @@ -from bddrest import status, response +from bddrest import status, response, when def test_server_index(ymdapp, ymdserver, mockupfs): @@ -17,4 +17,92 @@ def test_server_css(ymdapp, ymdserver): ymdapp.ready() with ymdserver(url='/index.css'): assert status == 200 - assert response.text.startswith('') + assert response.text.startswith('/* yhttp-markdown css */') + + +def test_server_exclude(ymdapp, ymdserver, mockupfs): + root = mockupfs(**{ + 'index.md': '# index', + 'foo.md': '# foo', + 'bar': { + 'index.md': '# bar index' + } + }) + + ymdapp.settings.merge(f''' + root: {root} + exclude: + - foo\\.md + - bar/?.* + ''') + + ymdapp.ready() + with ymdserver(): + assert status == 200 + assert response.text.startswith('') + + when(url='/index.md') + assert status == 200 + + when(url='/foo.md') + assert status == 404 + + when(url='/bar') + assert status == 404 + + when(url='/bar/index.md') + assert status == 404 + + ymdapp.settings.merge(''' + root: . + exclude: [] + ''') + + +def test_server_fallback(ymdapp, ymdserver, mockupfs): + root = mockupfs(**{ + 'index.md': '# index', + 'bar': { + 'index.md': '# bar index' + }, + 'baz': { + 'baz.md': '# baz' + } + }) + ymdapp.settings.root = root + + ymdapp.ready() + with ymdserver(): + assert status == 200 + + when(url='/bar.md') + assert status == 302 + assert response.headers['location'] == 'index.md' + + when(url='/bar/bar.md') + assert status == 302 + assert response.headers['location'] == 'index.md' + + when(url='/baz/bar.md') + assert status == 302 + assert response.headers['location'] == '/index.md' + + +def test_server_webmanifest(ymdapp, ymdserver): + ymdapp.ready() + with ymdserver('/webmanifest.json'): + assert status == 200 + assert response.json == { + 'icons': [ + { + 'sizes': '192x192', + 'src': '/.ymdmetadata/android-chrome-192x192.png', + 'type': 'image/png', + }, + { + 'sizes': '512x512', + 'src': '/.ymdmetadata/android-chrome-512x512.png', + 'type': 'image/png', + }, + ], + } diff --git a/yhttp/markdown/server.py b/yhttp/markdown/server.py index 699711b..8c3c62b 100644 --- a/yhttp/markdown/server.py +++ b/yhttp/markdown/server.py @@ -21,8 +21,8 @@ debug: true # app specific -default_document: index.md -fallback_document: notfound.md +default: index.md +fallback: index.md root: . title: HTTP Markdown Server @@ -87,16 +87,17 @@ def get(req): @y.html def get(req, path=None): # FIXME: (security) prevent to get parent directories + curpath = os.path.dirname(path) if path else '/' targetpath = os.path.join(app.settings.root, path or '') targetfile = None # Check exclusiono for pat in app.excludes: - if pat.mathc(path): + if pat.match(path): raise y.statuses.notfound() # Default document - default = app.settings.default_document + default = app.settings.default if os.path.isdir(targetpath): if default: default = os.path.join(targetpath, default) @@ -109,11 +110,16 @@ def get(req, path=None): # Fallback if not targetfile or not os.path.isfile(targetfile): - fallback = app.settings.fallback_document + fallback = app.settings.fallback if fallback: - fallback = os.path.join(app.settings.root, fallback) + fallback = os.path.join(app.settings.root, curpath, fallback) if os.path.exists(fallback): - targetfile = fallback + raise y.statuses.found(app.settings.fallback) + + fallback = os.path.join(app.settings.root, app.settings.fallback) + if os.path.exists(fallback): + redurl = os.path.join('/', app.settings.fallback) + raise y.statuses.found(redurl) # 404 not found if not targetfile or not os.path.isfile(targetfile): diff --git a/yhttp/markdown/styles/index.sass b/yhttp/markdown/styles/index.sass index 7ea48c1..851c30e 100644 --- a/yhttp/markdown/styles/index.sass +++ b/yhttp/markdown/styles/index.sass @@ -1,3 +1,4 @@ +/* yhttp-markdown css */ @import 'variables.sass' @import 'reset.sass' @import 'layout.sass'