This page is autogenerated. Make changes in the " + f"GitHub repository
" + "This page is autogenerated. Make changes in the ' - f'GitHub repository
' - '
+ Some text.
+ 
+ """
+ result = self.parser._get_media_references(markdown)
+ expected = ['folder/image2.jpg']
+ self.assertEqual(result, expected)
+
+ def test_get_media_references_with_special_chars(self):
+ markdown = """
+ # Title
+ 
+ Some text.
+ 
+ 
+ 
+ 
+ 
+ 
+ .gif)
+ 9.bmp)
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ """
+ result = self.parser._get_media_references(markdown)
+ expected = [
+ 'image_1.png', 'folder/image-2.jpg', 'folder/image.3.gif',
+ 'folder/image@4.bmp', 'folder/image#5.jpeg', 'folder/image$6.png',
+ 'folder/image&7.jpg', 'folder/image(8).gif', 'folder/image)9.bmp',
+ 'folder/image+10.jpeg', 'folder/image,11.png', 'folder/image;12.jpg',
+ 'folder/image=13.gif', 'folder/image[14].bmp', 'folder/image]15.jpeg',
+ 'folder/image{16}.png', 'folder/image}17.jpg', 'folder/image~18.gif',
+ 'folder/image!19.bmp', 'folder/image%20.jpeg'
+ ]
+ self.assertEqual(result, expected)
+
+ def test_get_relative_path_as_list(self):
+ base_directory = '/home/user/project'
+ file_path = '/home/user/project/docs/file.md'
+ expected = ['docs', 'file.md']
+ result = self.parser._get_relative_path_as_list(
+ file_path, base_directory)
+ self.assertEqual(result, expected)
+
+ file_path = '/home/user/project/docs/subdir/file.md'
+ expected = ['docs', 'subdir', 'file.md']
+ result = self.parser._get_relative_path_as_list(
+ file_path, base_directory)
+ self.assertEqual(result, expected)
+
+ file_path = '/home/user/project/file.md'
+ expected = ['file.md']
+ result = self.parser._get_relative_path_as_list(
+ file_path, base_directory)
+ self.assertEqual(result, expected)
+
+ file_path = '/home/user/another_project/file.md'
+ expected = ['..', 'another_project', 'file.md']
+ result = self.parser._get_relative_path_as_list(
+ file_path, base_directory)
+ self.assertEqual(result, expected)
+
+ @mock.patch('os.path.exists')
+ @mock.patch('builtins.open', new_callable=mock.mock_open, read_data='test content')
+ def test_read_file_content_success(self, mock_open, mock_exists):
+ mock_exists.return_value = True
+ result = self.parser._read_file_content('/path/to/file.md')
+ mock_open.assert_called_once_with(
+ '/path/to/file.md', 'r', encoding='utf-8')
+ self.assertEqual(result, 'test content')
+
+ @mock.patch('os.path.exists')
+ def test_read_file_content_file_not_found(self, mock_exists):
+ mock_exists.return_value = False
+ with self.assertRaises(FileNotFoundError):
+ self.parser._read_file_content('/path/to/nonexistent.md')
diff --git a/tests/unit/test_publisher.py b/tests/unit/test_publisher.py
index e69de29..18a2e75 100644
--- a/tests/unit/test_publisher.py
+++ b/tests/unit/test_publisher.py
@@ -0,0 +1,117 @@
+import unittest
+from unittest import mock
+from markdown2confluence.publisher import Publisher
+from markdown2confluence.config import Config
+from markdown2confluence.content_tree import ContentTree, ContentNode
+
+
+# Create a mock publisher inheriting from Publisher to test abstract methods
+class MockPublisher(Publisher):
+ def publish_node(self, node, parent_id):
+ return ''
+
+
+class TestPublisher(unittest.TestCase):
+ def setUp(self):
+ self.publisher = MockPublisher(config=Config.__new__(Config))
+ self.publisher.config.confluence_root_page = None
+ self.publisher.config.confluence_parent_page_id = 'mock_parent_id'
+
+ self.mock_publish_node = mock.patch.object(
+ MockPublisher, 'publish_node', autospec=True
+ ).start()
+ self.mock_publish_node.side_effect = (
+ lambda __self__, node, __parent_id__: f"mock_id_for_{node.name}"
+ )
+ self.addCleanup(mock.patch.stopall)
+
+ def test_publish_nested(self):
+ self.publisher.config.confluence_root_page = ''
+
+ # Create a simple content tree
+ root = ContentNode(name='root')
+ child1 = ContentNode(name='child1')
+ child2 = ContentNode(name='child2')
+ child3 = ContentNode(name='child3')
+ root.add_child(child1)
+ root.add_child(child2)
+ child2.add_child(child3)
+ content_tree = ContentTree(root=root)
+
+ # Call publish_content
+ self.publisher.publish_content(content_tree)
+
+ self.assertEqual(self.mock_publish_node.call_count, 3)
+ self.mock_publish_node.assert_any_call(
+ self.publisher, child1, None
+ )
+ self.mock_publish_node.assert_any_call(
+ self.publisher, child2, None
+ )
+ self.mock_publish_node.assert_any_call(
+ self.publisher, child3, 'mock_id_for_child2'
+ )
+
+ def test_publish_root_page(self):
+ self.publisher.config.confluence_root_page = 'rootpagename'
+
+ # Create a simple content tree
+ root = ContentNode(name='root')
+ child1 = ContentNode(name='child1')
+ child2 = ContentNode(name='child2')
+ root.add_child(child1)
+ root.add_child(child2)
+ content_tree = ContentTree(root=root)
+
+ # Call publish_content
+ self.publisher.publish_content(content_tree)
+
+ self.assertEqual(self.mock_publish_node.call_count, 3)
+ self.mock_publish_node.assert_any_call(
+ self.publisher, root, 'mock_parent_id'
+ )
+ self.mock_publish_node.assert_any_call(
+ self.publisher, child1, 'mock_id_for_rootpagename'
+ )
+ self.mock_publish_node.assert_any_call(
+ self.publisher, child2, 'mock_id_for_rootpagename'
+ )
+
+ def test_publish_with_circular_reference(self):
+ # Create nodes with circular references
+ node_a = ContentNode(name='A')
+ node_b = ContentNode(name='B')
+ node_a.add_child(node_b)
+ node_b.add_child(node_a)
+ content_tree = ContentTree(root=node_a)
+
+ with self.assertRaises(RuntimeError):
+ self.publisher.publish_content(content_tree)
+
+ def test_publish_with_missing_root(self):
+ # Create a content tree without a root
+ content_tree = ContentTree(root=None)
+
+ with self.assertRaises(AttributeError):
+ self.publisher.publish_content(content_tree)
+
+ def test_publish_with_none_node(self):
+ # Create a content tree with a None node
+ content_tree = ContentTree(root=None)
+
+ with self.assertRaises(AttributeError):
+ self.publisher.publish_content(content_tree)
+
+ def test_pre_post_hooks_called(self):
+ self.publisher.pre_publish_hook = mock.MagicMock()
+ self.publisher.post_publish_hook = mock.MagicMock()
+
+ # Create a simple content tree
+ root = ContentNode(name='root')
+ content_tree = ContentTree(root=root)
+
+ # Call publish_content
+ self.publisher.publish_content(content_tree)
+
+ self.publisher.pre_publish_hook.assert_called_once()
+ self.publisher.post_publish_hook.assert_called_once()