diff --git a/scripts/wiki_docs.py b/scripts/wiki_docs.py index dc2a85b..5f111fd 100644 --- a/scripts/wiki_docs.py +++ b/scripts/wiki_docs.py @@ -215,7 +215,7 @@ class WikiClient: "GET", f"/repos/{quote(self.config.owner, safe='')}/" f"{quote(self.config.repository, safe='')}/wiki/page/" - f"{quote(sub_url, safe='')}", + f"{quote(sub_url, safe='%')}", ) if not isinstance(page, dict): raise WikiDocsError(f"Wiki 页面响应格式无效:{page_name}") @@ -234,7 +234,7 @@ class WikiClient: resolved_title = title if isinstance(title, str) and title else page_name html_url = ( f"{self.config.gitea_url}/{quote(self.config.owner, safe='')}/" - f"{quote(self.config.repository, safe='')}/wiki/{quote(sub_url, safe='')}" + f"{quote(self.config.repository, safe='')}/wiki/{quote(sub_url, safe='%')}" ) return WikiPage( title=resolved_title, diff --git a/tests/test_wiki_docs.py b/tests/test_wiki_docs.py index e4685cf..f85973a 100644 --- a/tests/test_wiki_docs.py +++ b/tests/test_wiki_docs.py @@ -16,6 +16,7 @@ from new_task_archive import build_archive, safe_title # noqa: E402 from wiki_docs import ( # noqa: E402 Config, Mapping, + WikiClient, WikiDocsError, WikiPage, dirty_mirror_paths, @@ -115,6 +116,36 @@ class MirrorTests(unittest.TestCase): client.get_page.assert_not_called() +class WikiClientTests(unittest.TestCase): + def test_encoded_unicode_sub_url_is_not_double_encoded(self) -> None: + config = Config( + path=Path("wiki-docs.json"), + gitea_url="http://gitea.example", + owner="o", + repository="r", + mappings=(Mapping("中文", "docs/chinese.md"),), + ) + client = WikiClient(config, token="") + client.list_pages = Mock( + return_value=[{"title": "中文", "sub_url": "%E4%B8%AD%E6%96%87.-"}] + ) + encoded = __import__("base64").b64encode("# 中文\n".encode()).decode() + with patch.object( + client, + "_request", + return_value={ + "title": "中文", + "content_base64": encoded, + "last_commit": {"sha": "b" * 40}, + }, + ) as request: + page = client.get_page("中文") + api_path = request.call_args.args[1] + self.assertIn("%E4%B8%AD%E6%96%87.-", api_path) + self.assertNotIn("%25E4", api_path) + self.assertTrue(page.html_url.endswith("/%E4%B8%AD%E6%96%87.-")) + + class ArchiveTests(unittest.TestCase): def test_safe_title_handles_windows_characters(self) -> None: self.assertEqual(safe_title(' 修复:"登录" / 超时 '), "修复-登录-超时")