def test_tags_categories_archive_search(): with app.test_client() as c: resp = c.get('/tag/non-exists/') assert 'Page Not Found' in resp.data.decode('utf-8') resp = c.get('/category/non-exists/') assert 'Page Not Found' in resp.data.decode('utf-8') resp = c.get('/tag/Hello World/') assert 'Hello World - Tag - My Blog' in resp.data.decode('utf-8') assert 'My Post' in resp.data.decode('utf-8') resp = c.get('/category/Default/') assert 'Default - Category - My Blog' in resp.data.decode('utf-8') assert 'My Post' in resp.data.decode('utf-8') resp = c.get('/archive/2017/3/') assert '2017.3 - Archive - My Blog' in resp.data.decode('utf-8') assert 'My Post' in resp.data.decode('utf-8') resp = c.get('/search?q=') assert 'Page Not Found' in resp.data.decode('utf-8') resp = c.get('/search?q=no yaml') assert '"no yaml" - Search - My Blog' in resp.data.decode( 'utf-8') assert 'My Post No Yaml' in resp.data.decode('utf-8') resp = c.get('/search?q=Title') assert '"Title" - Search - My Blog' in resp.data.decode( 'utf-8') assert 'My Post No Yaml' not in resp.data.decode('utf-8') assert 'My Post' in resp.data.decode('utf-8')
def generate_pages_by_file(): """Generates custom pages of 'file' storage type.""" from veripress import app from veripress.model import storage from veripress.model.parsers import get_standard_format_name from veripress.helpers import traverse_directory deploy_dir = get_deploy_dir() def copy_file(src, dst): makedirs(os.path.dirname(dst), mode=0o755, exist_ok=True) shutil.copyfile(src, dst) with app.app_context(), app.test_client() as client: root_path = os.path.join(app.instance_path, 'pages') for path in traverse_directory(root_path): rel_path = os.path.relpath(path, root_path) # e.g. 'a/b/c/index.md' filename, ext = os.path.splitext(rel_path) # e.g. ('a/b/c/index', '.md') if get_standard_format_name(ext[1:]) is not None: # is source of custom page rel_url = filename.replace(os.path.sep, '/') + '.html' # e.g. 'a/b/c/index.html' page = storage.get_page(rel_url, include_draft=False) if page is not None: # it's not a draft, so generate the html page makedirs(os.path.join(deploy_dir, os.path.dirname(rel_path)), mode=0o755, exist_ok=True) with open(os.path.join(deploy_dir, filename + '.html'), 'wb') as f: f.write(client.get('/' + rel_url).data) if app.config['PAGE_SOURCE_ACCESSIBLE']: copy_file(path, os.path.join(deploy_dir, rel_path)) else: # is other direct files copy_file(path, os.path.join(deploy_dir, rel_path))
def test_index(): with app.test_client() as c: assert c.get( '/page/1').headers['Location'] == 'http://localhost/page/1/' assert c.get('/page/1/').headers['Location'] == 'http://localhost/' shutil.move(os.path.join(app.instance_path, 'pages', 'index.mdown'), os.path.join(app.instance_path, 'pages', 'index2.mdown')) resp = c.get('/') assert resp.status_code == 200 assert 'My Blog' in resp.data.decode('utf-8') assert '<a id="prev-url"' in resp.data.decode('utf-8') assert '<a id="next-url"' not in resp.data.decode('utf-8') assert 'My Post No Yaml' in resp.data.decode('utf-8') assert 'My Post No Yaml2' in resp.data.decode('utf-8') assert 'This is my blog. Welcome!' in resp.data.decode( 'utf-8') # parse widget in template assert '<a id="next-url"' in c.get('/page/2/').data.decode('utf-8') shutil.move(os.path.join(app.instance_path, 'pages', 'index2.mdown'), os.path.join(app.instance_path, 'pages', 'index.mdown')) resp = c.get('/') assert resp.status_code == 200 assert 'Index' in resp.data.decode('utf-8')
def test_posts(): with app.test_client() as c: data = get_json(c, '/posts') assert isinstance(data, list) assert len(data) == 3 # no drafts! assert 'My Post' in data[0]['title'] data = get_json(c, '/posts/2017/') assert len(data) == 3 data = get_json(c, '/posts?start=1&count=1') assert len(data) == 1 data = get_json(c, '/posts?created=2016-03-02,2016-03-03&updated=') assert data['code'] == Error.INVALID_ARGUMENTS.code data = get_json(c, '/posts?created=2016-03-02,2017-03-09&updated=2016-03-02,2017-03-09') assert len(data) == 2 data = get_json(c, '/posts/2017/03/09/my-post') assert isinstance(data, dict) assert data['categories'] == ['Default'] data = get_json(c, '/posts/2017/03/09/my-post/?fields=title,content,created,updated') assert 'categories' not in data data = get_json(c, '/posts/2017/03/09/non-exists') assert data['code'] == Error.RESOURCE_NOT_EXISTS.code
def test_feed(): with app.test_client() as c: resp = c.get('/feed.xml') assert 'My Post' in resp.data.decode('utf-8') assert 'My Post No Yaml' in resp.data.decode('utf-8') assert 'My Post No Yaml2' in resp.data.decode('utf-8') assert resp.content_type == 'application/atom+xml; charset=utf-8'
def test_tags_categories(): with app.test_client() as c: data = get_json(c, '/tags') assert {'name': 'Hello World', 'published': 1} in data data = get_json(c, '/categories') assert {'name': 'Default', 'published': 1} in data
def test_widgets(): with app.test_client() as c: data = get_json(c, '/widgets') assert len(data) == 2 data = get_json(c, '/widgets?position=header') assert data['code'] == Error.RESOURCE_NOT_EXISTS.code
def do_generate(): from veripress import app from veripress.model import storage deploy_dir = get_deploy_dir() # copy global static folder dst_static_folder = os.path.join(deploy_dir, 'static') if os.path.isdir(app.static_folder): shutil.copytree(app.static_folder, dst_static_folder) # copy theme static files makedirs(dst_static_folder, mode=0o755, exist_ok=True) copy_folder_content(app.theme_static_folder, dst_static_folder) # collect all possible urls (except custom pages) all_urls = {'/', '/feed.xml', '/atom.xml', '/archive/'} with app.app_context(): posts = list(storage.get_posts(include_draft=False)) index_page_count = int(math.ceil(len(posts) / app.config['ENTRIES_PER_PAGE'])) for i in range(2, index_page_count + 1): # ignore '/page/1/', this will be generated separately later all_urls.add('/page/{}/'.format(i)) for post in posts: all_urls.add(post.unique_key) all_urls.add('/archive/{}/'.format(post.created.strftime('%Y'))) all_urls.add('/archive/{}/{}/'.format(post.created.strftime('%Y'), post.created.strftime('%m'))) tags = storage.get_tags() for tag_item in tags: all_urls.add('/tag/{}/'.format(tag_item[0])) categories = storage.get_categories() for category_item in categories: all_urls.add('/category/{}/'.format(category_item[0])) with app.test_client() as client: # generate all possible urls for url in all_urls: resp = client.get(url) file_path = os.path.join(get_deploy_dir(), url.lstrip('/').replace('/', os.path.sep)) if url.endswith('/'): file_path += 'index.html' makedirs(os.path.dirname(file_path), mode=0o755, exist_ok=True) with open(file_path, 'wb') as f: f.write(resp.data) # generate 404 page resp = client.get('/post/this-is-a-page-that-never-gonna-exist' '-because-it-is-a-post-with-wrong-url-format/') with open(os.path.join(deploy_dir, '404.html'), 'wb') as f: f.write(resp.data) if app.config['STORAGE_TYPE'] == 'file': generate_pages_by_file()
def test_post(): with app.test_client() as c: resp = c.get('/post/2017/3/9/my-post') assert resp.headers['Location'].endswith('/2017/03/09/my-post/') resp = c.get('/post/2017/03/09/my-post/') assert 'My Post - My Blog' in resp.data.decode('utf-8') assert '<p>TOC</p>' in resp.data.decode('utf-8') assert '<p>TOC HTML</p>' in resp.data.decode('utf-8') resp = c.get('/post/2017/03/09/non-exists/') assert 'Page Not Found' in resp.data.decode('utf-8') app.config['SHOW_TOC'] = False with app.test_client() as c: resp = c.get('/post/2017/03/09/my-post/') assert 'My Post - My Blog' in resp.data.decode('utf-8') assert '<p>TOC</p>' not in resp.data.decode('utf-8') assert '<p>TOC HTML</p>' not in resp.data.decode('utf-8') app.config['SHOW_TOC'] = True
def test_webhook(): with app.test_client() as c: resp = c.post('/_webhook', data={'a': 'A'}) assert resp.status_code == 204 script_path = os.path.join(app.instance_path, 'webhook.py') with open(script_path, 'rb') as f: script = f.read() os.remove(script_path) resp = c.post('/_webhook', data={'a': 'A'}) assert resp.status_code == 204 # it should always return 204 although there is no 'webhook.py' with open(script_path, 'wb') as f: f.write(script)
def test_search(): with app.test_client() as c: data = get_json(c, '/search?q=') assert data['code'] == Error.INVALID_ARGUMENTS.code data = get_json(c, '/search?q=non-exist-non-exist-non-exist') assert data['code'] == Error.RESOURCE_NOT_EXISTS.code data = get_json(c, '/search?q=hello') assert len(data) == 1 assert data[0]['rel_url'] == 'a/b/hello.html' data = get_json(c, '/search/?q=Lorem ipsum') assert len(data) == 5 data = get_json(c, '/search/?q=Lorem ipsum&start=1&count=2') assert len(data) == 2
def test_pages(): with app.test_client() as c: data = get_json(c, '/pages/non-exists') assert data['code'] == Error.RESOURCE_NOT_EXISTS.code data = get_json(c, '/pages/../../../../etc/passwd') assert data['code'] == Error.NOT_ALLOWED.code resp = c.get('/api/pages/test-page.txt') assert resp.status_code == 200 assert resp.content_type.startswith('text/plain') data = get_json(c, '/pages/my-page/') assert 'Lorem ipsum dolor sit amet.' in data['content'] data = get_json(c, '/pages/test-page-draft') assert data['code'] == Error.RESOURCE_NOT_EXISTS.code
def test_page(): with app.test_client() as c: resp = c.get('/abc') assert resp.status_code == 302 assert resp.headers.get('Location').endswith('/abc.html') resp = c.get('/a/b') assert resp.status_code == 302 assert resp.headers.get('Location').endswith('/a/b/') resp = c.get('/test-page.txt') assert resp.content_type == 'text/plain; charset=utf-8' resp = c.get('/dddd/') assert '<title>D</title>' in resp.data.decode('utf-8') resp = c.get('/test-page.html') assert 'Test Page' in resp.data.decode('utf-8') resp = c.get('/..%2F..%2Fetc%2Fpasswd') assert resp.status_code == 403
def test_404(): with app.test_client() as c: resp = c.get('/non-exists.html') assert 'Page Not Found' in resp.data.decode('utf-8')
def test_site(): with app.test_client() as c: data = get_json(c, '/site') assert data == site
def test_api_basic(): with app.test_client() as c: data = get_json(c, '/non-exists') assert data['code'] == Error.NO_SUCH_API.code