"""Test the conversion of Markdown pages. SPDX-FileCopyrightText: © 2025 Brian S. Stephan SPDX-License-Identifier: GPL-3.0-or-later """ import os from unittest.mock import patch import pytest from incorporealcms import init_instance from incorporealcms.markdown import (generate_parent_navs, handle_markdown_file_path, instance_resource_path_to_request_path, parse_md) HERE = os.path.dirname(os.path.abspath(__file__)) INSTANCE_DIR = os.path.join(HERE, 'instance') PAGES_DIR = os.path.join(INSTANCE_DIR, 'pages/') # initialize in order to configure debug logging init_instance(INSTANCE_DIR) def test_generate_page_navs_index(): """Test that the index page has navs to the root (itself).""" assert generate_parent_navs('index.md', PAGES_DIR) == [('example.org', '/')] def test_generate_page_navs_title_from_h1(): """Test that the index page has navs to the root (itself).""" assert generate_parent_navs('no-title.md', PAGES_DIR) == [('example.org', '/'), ('this page doesn\'t have a title!', '/no-title')] def test_generate_page_navs_subdir_index(): """Test that dir pages have navs to the root and themselves.""" assert generate_parent_navs('subdir/index.md', PAGES_DIR) == [('example.org', '/'), ('another page', '/subdir/')] def test_generate_page_navs_subdir_real_page(): """Test that real pages have navs to the root, their parent, and themselves.""" assert generate_parent_navs('subdir/page.md', PAGES_DIR) == [('example.org', '/'), ('another page', '/subdir/'), ('Page', '/subdir/page')] def test_generate_page_navs_subdir_with_title_parsing_real_page(): """Test that title metadata is used in the nav text.""" assert generate_parent_navs('subdir-with-title/page.md', PAGES_DIR) == [ ('example.org', '/'), ('SUB!', '/subdir-with-title/'), ('/page', '/subdir-with-title/page') ] def test_generate_page_navs_subdir_with_no_index(): """Test that breadcrumbs still generate even if a subdir doesn't have an index.md.""" assert generate_parent_navs('no-index-dir/page.md', PAGES_DIR) == [ ('example.org', '/'), ('/no-index-dir/', '/no-index-dir/'), ('/page', '/no-index-dir/page') ] def test_page_includes_themes_with_default(): """Test that a request contains the configured themes and sets the default as appropriate.""" assert ''\ in handle_markdown_file_path('index.md', PAGES_DIR) assert ''\ in handle_markdown_file_path('index.md', PAGES_DIR) assert '[light]'\ in handle_markdown_file_path('index.md', PAGES_DIR) assert '[dark]'\ in handle_markdown_file_path('index.md', PAGES_DIR) def test_render_with_style_overrides(): """Test that the default can be changed.""" with patch('incorporealcms.Config.DEFAULT_PAGE_STYLE', 'dark'): assert ''\ in handle_markdown_file_path('index.md', PAGES_DIR) assert ''\ in handle_markdown_file_path('index.md', PAGES_DIR) assert '[light]'\ in handle_markdown_file_path('index.md', PAGES_DIR) assert '[dark]'\ in handle_markdown_file_path('index.md', PAGES_DIR) def test_render_with_default_style_override(): """Test that theme overrides work, and if a requested theme doesn't exist, the default is loaded.""" with patch('incorporealcms.Config.PAGE_STYLES', {'cool': '/static/css/cool.css', 'warm': '/static/css/warm.css'}): with patch('incorporealcms.Config.DEFAULT_PAGE_STYLE', 'warm'): assert ''\ in handle_markdown_file_path('index.md', PAGES_DIR) assert ''\ in handle_markdown_file_path('index.md', PAGES_DIR) assert ''\ not in handle_markdown_file_path('index.md', PAGES_DIR) assert '[warm]'\ in handle_markdown_file_path('index.md', PAGES_DIR) assert '[cool]'\ in handle_markdown_file_path('index.md', PAGES_DIR) def test_redirects_error_unsupported(): """Test that we throw a warning about the barely-used Markdown redirect tag, which we can't support via SSG.""" with pytest.raises(NotImplementedError): handle_markdown_file_path('redirect.md', os.path.join(INSTANCE_DIR, 'broken')) def test_instance_resource_path_to_request_path_on_index(): """Test index.md -> /.""" assert instance_resource_path_to_request_path('index.md') == '/' def test_instance_resource_path_to_request_path_on_page(): """Test no-title.md -> no-title.""" assert instance_resource_path_to_request_path('no-title.md') == '/no-title' def test_instance_resource_path_to_request_path_on_subdir(): """Test subdir/index.md -> subdir/.""" assert instance_resource_path_to_request_path('subdir/index.md') == '/subdir/' def test_instance_resource_path_to_request_path_on_subdir_and_page(): """Test subdir/page.md -> subdir/page.""" assert instance_resource_path_to_request_path('subdir/page.md') == '/subdir/page' def test_parse_md_metadata(): """Test the direct results of parsing a markdown file.""" content, md, page_name, page_title, page_desc, mtime = parse_md( os.path.join(PAGES_DIR, 'more-metadata.md'), PAGES_DIR ) assert page_name == 'title for the page' assert page_title == 'title for the page - example.org' assert page_desc == 'description of this page made even longer' def test_parse_md_metadata_forced_no_title(): """Test the direct results of parsing a markdown file.""" content, md, page_name, page_title, _, mtime = parse_md(os.path.join(PAGES_DIR, 'forced-no-title.md'), PAGES_DIR) assert page_name == '' assert page_title == 'example.org' def test_parse_md_metadata_no_title_so_h1(): """Test the direct results of parsing a markdown file.""" content, md, page_name, page_title, _, mtime = parse_md(os.path.join(PAGES_DIR, 'subdir/index.md'), PAGES_DIR) assert page_name == 'another page' assert page_title == 'another page - example.org' def test_parse_md_metadata_no_title_or_h1_so_path(): """Test the direct results of parsing a markdown file.""" content, md, page_name, page_title, _, mtime = parse_md(os.path.join(PAGES_DIR, 'no-title-or-h1.md'), PAGES_DIR) assert page_name == '/no-title-or-h1' assert page_title == '/no-title-or-h1 - example.org' def test_parse_md_metadata_no_title_or_h1_so_path_dir(): """Test the direct results of parsing a markdown file.""" content, md, page_name, page_title, _, mtime = parse_md(os.path.join(PAGES_DIR, 'no-title-subdir/index.md'), PAGES_DIR) assert page_name == '/no-title-subdir/' assert page_title == '/no-title-subdir/ - example.org' def test_parse_md_metadata_no_title_or_h1_so_path_dir_file(): """Test the direct results of parsing a markdown file.""" content, md, page_name, page_title, _, mtime = parse_md(os.path.join(PAGES_DIR, 'no-title-subdir/no-title-or-h1.md'), PAGES_DIR) assert page_name == '/no-title-subdir/no-title-or-h1' assert page_title == '/no-title-subdir/no-title-or-h1 - example.org' def test_parse_md_derive_description_from_p(): """Test that we can get a description from the first paragraph in the file.""" content, md, page_name, page_title, page_desc, mtime = parse_md( os.path.join(PAGES_DIR, 'rambling.md'), PAGES_DIR ) assert page_desc == 'this is a long string of text where I am typing a lot over multiple lines' def test_parse_md_no_file(): """Test the direct results of parsing a markdown file.""" with pytest.raises(FileNotFoundError): content, md, page_name, page_title, _, mtime = parse_md(os.path.join(PAGES_DIR, 'nope.md'), PAGES_DIR) def test_parse_md_bad_file(): """Test the direct results of parsing a markdown file.""" with pytest.raises(ValueError): content, md, page_name, page_title, _, mtime = parse_md(os.path.join(PAGES_DIR, 'actually-a-png.md'), PAGES_DIR) def test_md_extension_in_source_link_is_stripped(): """Test that if a foo.md file link is specified in the Markdown, it is foo in the HTML.""" content, _, _, _, _, _ = parse_md(os.path.join(PAGES_DIR, 'file-with-md-link.md'), PAGES_DIR) assert 'Foo' in content assert 'Anchored Foo' in content assert 'Sub Foo' in content assert 'Anchored Sub Foo' in content def test_index_in_source_link_is_stripped(): """Test that if a index.md file link is specified in the Markdown, it is just the dir in the HTML.""" content, _, _, _, _, _ = parse_md(os.path.join(PAGES_DIR, 'file-with-index.md-link.md'), PAGES_DIR) assert 'Cool' in content assert 'Anchored Cool' in content assert 'This Index' in content assert 'Anchored This Index' in content assert 'Parent' in content assert 'Anchored Parent' in content def test_license_link(): """Test that the config's license HTML is displayed in the footer.""" with patch('incorporealcms.Config.LICENSE', 'CC BY-SA 4.0', create=True): assert 'Available via CC BY-SA 4.0.'\ in handle_markdown_file_path('index.md', PAGES_DIR) # default, no config assert 'CC BY-SA 4.0'\ not in handle_markdown_file_path('index.md', PAGES_DIR)