Hugoifier

hugoifier / tests / test_decapify.py
Source Blame History 191 lines
6272677… lmata 1 """Tests for utils.decapify."""
6272677… lmata 2 import os
6272677… lmata 3 import tempfile
48176db… ragelink 4 import unittest
6272677… lmata 5
91515c0… lmata 6 from hugoifier.utils.decapify import (
91515c0… lmata 7 _build_collections,
91515c0… lmata 8 _infer_fields_for_file,
91515c0… lmata 9 _infer_fields_for_folder,
91515c0… lmata 10 _parse_frontmatter,
6272677… lmata 11 _sanitize_color,
6272677… lmata 12 _widget_for_value,
6272677… lmata 13 decapify,
6272677… lmata 14 )
6272677… lmata 15
6272677… lmata 16
6272677… lmata 17 class TestSanitizeColor(unittest.TestCase):
6272677… lmata 18 def test_valid_hex6(self):
6272677… lmata 19 self.assertEqual(_sanitize_color("#2e3748"), "#2e3748")
6272677… lmata 20
6272677… lmata 21 def test_valid_hex3(self):
6272677… lmata 22 self.assertEqual(_sanitize_color("#fff"), "#fff")
6272677… lmata 23
6272677… lmata 24 def test_uppercase(self):
6272677… lmata 25 self.assertEqual(_sanitize_color("#AABBCC"), "#AABBCC")
6272677… lmata 26
6272677… lmata 27 def test_invalid_falls_back(self):
6272677… lmata 28 self.assertEqual(_sanitize_color("red"), "#2e3748")
6272677… lmata 29 self.assertEqual(_sanitize_color("javascript:alert(1)"), "#2e3748")
6272677… lmata 30 self.assertEqual(_sanitize_color("#gggggg"), "#2e3748")
6272677… lmata 31
6272677… lmata 32
6272677… lmata 33 class TestWidgetForValue(unittest.TestCase):
6272677… lmata 34 def test_bool(self):
6272677… lmata 35 self.assertEqual(_widget_for_value(True), "boolean")
6272677… lmata 36 self.assertEqual(_widget_for_value(False), "boolean")
6272677… lmata 37
6272677… lmata 38 def test_number(self):
6272677… lmata 39 self.assertEqual(_widget_for_value(42), "number")
6272677… lmata 40 self.assertEqual(_widget_for_value(3.14), "number")
6272677… lmata 41
6272677… lmata 42 def test_list(self):
6272677… lmata 43 self.assertEqual(_widget_for_value([]), "list")
6272677… lmata 44 self.assertEqual(_widget_for_value(["a", "b"]), "list")
6272677… lmata 45
6272677… lmata 46 def test_string_default(self):
6272677… lmata 47 self.assertEqual(_widget_for_value("hello"), "string")
6272677… lmata 48 self.assertEqual(_widget_for_value(None), "string")
6272677… lmata 49
6272677… lmata 50
6272677… lmata 51 class TestParseFrontmatter(unittest.TestCase):
6272677… lmata 52 def test_parses_yaml_frontmatter(self):
6272677… lmata 53 with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f:
6272677… lmata 54 f.write("---\ntitle: Hello\ndate: 2024-01-01\ndraft: false\n---\n\nBody text.\n")
6272677… lmata 55 path = f.name
6272677… lmata 56 try:
6272677… lmata 57 result = _parse_frontmatter(path)
6272677… lmata 58 self.assertEqual(result["title"], "Hello")
6272677… lmata 59 self.assertEqual(result["draft"], False)
6272677… lmata 60 finally:
6272677… lmata 61 os.unlink(path)
6272677… lmata 62
6272677… lmata 63 def test_empty_on_missing_frontmatter(self):
6272677… lmata 64 with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f:
6272677… lmata 65 f.write("No frontmatter here.\n")
6272677… lmata 66 path = f.name
6272677… lmata 67 try:
6272677… lmata 68 self.assertEqual(_parse_frontmatter(path), {})
6272677… lmata 69 finally:
6272677… lmata 70 os.unlink(path)
6272677… lmata 71
6272677… lmata 72 def test_empty_on_missing_file(self):
6272677… lmata 73 self.assertEqual(_parse_frontmatter("/nonexistent/path.md"), {})
6272677… lmata 74
6272677… lmata 75
6272677… lmata 76 class TestInferFields(unittest.TestCase):
6272677… lmata 77 def _make_md(self, dirpath, name, frontmatter):
6272677… lmata 78 path = os.path.join(dirpath, name)
6272677… lmata 79 with open(path, "w") as f:
6272677… lmata 80 f.write("---\n")
6272677… lmata 81 for k, v in frontmatter.items():
6272677… lmata 82 f.write(f"{k}: {v!r}\n")
6272677… lmata 83 f.write("---\n\nBody.\n")
6272677… lmata 84 return path
6272677… lmata 85
6272677… lmata 86 def test_folder_fields_include_known_keys(self):
6272677… lmata 87 with tempfile.TemporaryDirectory() as tmp:
6272677… lmata 88 self._make_md(tmp, "post1.md", {"title": "Hello", "date": "2024-01-01", "tags": ["a"]})
6272677… lmata 89 fields = _infer_fields_for_folder(tmp, ["post1.md"])
6272677… lmata 90 names = [f["name"] for f in fields]
6272677… lmata 91 self.assertIn("title", names)
6272677… lmata 92 self.assertIn("date", names)
6272677… lmata 93 self.assertIn("tags", names)
6272677… lmata 94 self.assertIn("body", names)
6272677… lmata 95
6272677… lmata 96 def test_folder_fields_always_end_with_body(self):
6272677… lmata 97 with tempfile.TemporaryDirectory() as tmp:
6272677… lmata 98 self._make_md(tmp, "post.md", {"title": "Test"})
6272677… lmata 99 fields = _infer_fields_for_folder(tmp, ["post.md"])
6272677… lmata 100 self.assertEqual(fields[-1]["name"], "body")
6272677… lmata 101 self.assertEqual(fields[-1]["widget"], "markdown")
6272677… lmata 102
6272677… lmata 103 def test_file_fields_include_all_frontmatter_keys(self):
6272677… lmata 104 with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f:
6272677… lmata 105 f.write("---\ntitle: About\nsubtitle: Us\n---\n")
6272677… lmata 106 path = f.name
6272677… lmata 107 try:
6272677… lmata 108 fields = _infer_fields_for_file(path)
6272677… lmata 109 names = [fi["name"] for fi in fields]
6272677… lmata 110 self.assertIn("title", names)
6272677… lmata 111 self.assertIn("subtitle", names)
6272677… lmata 112 self.assertIn("body", names)
6272677… lmata 113 finally:
6272677… lmata 114 os.unlink(path)
6272677… lmata 115
6272677… lmata 116
6272677… lmata 117 class TestBuildCollections(unittest.TestCase):
6272677… lmata 118 def test_folder_collection_from_md_files(self):
6272677… lmata 119 with tempfile.TemporaryDirectory() as tmp:
6272677… lmata 120 blog = os.path.join(tmp, "blog")
6272677… lmata 121 os.makedirs(blog)
6272677… lmata 122 for i in range(3):
6272677… lmata 123 with open(os.path.join(blog, f"post{i}.md"), "w") as f:
6272677… lmata 124 f.write("---\ntitle: Post\n---\n")
6272677… lmata 125 collections = _build_collections(tmp)
6272677… lmata 126 self.assertEqual(len(collections), 1)
6272677… lmata 127 self.assertEqual(collections[0]["name"], "blog")
6272677… lmata 128 self.assertIn("folder", collections[0])
6272677… lmata 129
6272677… lmata 130 def test_file_collection_from_index_only(self):
6272677… lmata 131 with tempfile.TemporaryDirectory() as tmp:
6272677… lmata 132 about = os.path.join(tmp, "about")
6272677… lmata 133 os.makedirs(about)
6272677… lmata 134 with open(os.path.join(about, "_index.md"), "w") as f:
6272677… lmata 135 f.write("---\ntitle: About\n---\n")
6272677… lmata 136 collections = _build_collections(tmp)
6272677… lmata 137 self.assertEqual(len(collections), 1)
6272677… lmata 138 self.assertIn("files", collections[0])
6272677… lmata 139
6272677… lmata 140 def test_recursive_md_discovery(self):
6272677… lmata 141 with tempfile.TemporaryDirectory() as tmp:
6272677… lmata 142 deep = os.path.join(tmp, "blog", "2024")
6272677… lmata 143 os.makedirs(deep)
6272677… lmata 144 with open(os.path.join(deep, "post.md"), "w") as f:
6272677… lmata 145 f.write("---\ntitle: Deep Post\n---\n")
6272677… lmata 146 collections = _build_collections(tmp)
6272677… lmata 147 self.assertEqual(len(collections), 1)
6272677… lmata 148 self.assertEqual(collections[0]["name"], "blog")
6272677… lmata 149
6272677… lmata 150 def test_default_collection_when_empty(self):
6272677… lmata 151 with tempfile.TemporaryDirectory() as tmp:
6272677… lmata 152 collections = _build_collections(tmp)
6272677… lmata 153 self.assertEqual(len(collections), 1)
6272677… lmata 154 self.assertEqual(collections[0]["name"], "pages")
6272677… lmata 155
6272677… lmata 156 def test_nonexistent_dir_returns_default(self):
6272677… lmata 157 collections = _build_collections("/nonexistent/content")
6272677… lmata 158 self.assertEqual(len(collections), 1)
6272677… lmata 159 self.assertEqual(collections[0]["name"], "pages")
6272677… lmata 160
48176db… ragelink 161
48176db… ragelink 162 class TestDecapify(unittest.TestCase):
6272677… lmata 163 def test_creates_admin_files(self):
6272677… lmata 164 with tempfile.TemporaryDirectory() as tmp:
6272677… lmata 165 content = os.path.join(tmp, "content")
6272677… lmata 166 os.makedirs(content)
6272677… lmata 167 with open(os.path.join(content, "_index.md"), "w") as f:
6272677… lmata 168 f.write("---\ntitle: Home\n---\n")
6272677… lmata 169 result = decapify(tmp)
6272677… lmata 170 self.assertIn("complete", result.lower())
6272677… lmata 171 self.assertTrue(os.path.exists(os.path.join(tmp, "static", "admin", "index.html")))
6272677… lmata 172 self.assertTrue(os.path.exists(os.path.join(tmp, "static", "admin", "config.yml")))
6272677… lmata 173
6272677… lmata 174 def test_admin_index_escapes_name(self):
6272677… lmata 175 with tempfile.TemporaryDirectory() as tmp:
6272677… lmata 176 decapify(tmp, cms_name='<script>alert("xss")</script>')
6272677… lmata 177 with open(os.path.join(tmp, "static", "admin", "index.html")) as f:
6272677… lmata 178 html = f.read()
6272677… lmata 179 self.assertNotIn("<script>alert", html)
6272677… lmata 180 self.assertIn("&lt;script&gt;", html)
6272677… lmata 181
6272677… lmata 182 def test_invalid_color_falls_back(self):
6272677… lmata 183 with tempfile.TemporaryDirectory() as tmp:
6272677… lmata 184 decapify(tmp, cms_color="not-a-color")
6272677… lmata 185 with open(os.path.join(tmp, "static", "admin", "index.html")) as f:
6272677… lmata 186 html = f.read()
6272677… lmata 187 self.assertIn("#2e3748", html)
6272677… lmata 188
6272677… lmata 189
6272677… lmata 190 if __name__ == "__main__":
6272677… lmata 191 unittest.main()

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button