import importlib.util import pathlib import unittest from unittest import mock MODULE_PATH = pathlib.Path(__file__).with_name("artifact_fetch.py") spec = importlib.util.spec_from_file_location("artifact_fetch", MODULE_PATH) assert spec is not None and spec.loader is not None artifact_fetch = importlib.util.module_from_spec(spec) spec.loader.exec_module(artifact_fetch) class DingTalkOnlineDocumentExportTest(unittest.TestCase): def test_text_validation_tolerates_multibyte_char_cut_at_read_boundary(self): # A valid UTF-8 document whose 4096-byte sniff boundary lands in the # middle of a multibyte character must still pass validate_magic. header = "# 标题\n".encode("utf-8") # 7 bytes payload = header + b"a" * (4096 - len(header) - 1) + "机待\u2705".encode("utf-8") + b"\n" self.assertEqual(payload[4095:4098], b"\xe6\x9c\xba") # a char straddles the sniff boundary temp = pathlib.Path("/tmp/kg-md-boundary.md") temp.write_bytes(payload) try: artifact_fetch.validate_magic(str(temp), "md") finally: temp.unlink() def test_text_validation_still_rejects_genuinely_invalid_bytes(self): temp = pathlib.Path("/tmp/kg-md-invalid.md") temp.write_bytes(b"# \xe6\xa0\x87\xe9\xa2\x98\n\xff\xfe not utf-8\n" + b"a" * 8192) try: with self.assertRaises(artifact_fetch.FetchError) as raised: artifact_fetch.validate_magic(str(temp), "md") self.assertEqual(raised.exception.code, "invalid_format") finally: temp.unlink() def test_adoc_uses_export_job_instead_of_ordinary_file_download(self): calls = [] def api(url, headers, payload=None, extra_headers=None, method=None): calls.append((url, payload)) if "/dentry/info" in url: return {"data": {"docKey": "doc-key", "dentryKey": "dentry-key", "extension": "adoc"}} if "/api/document/data" in url: return {"data": {"documentContent": {"checkpoint": {"content": "document-json"}}}} if "/upload_info" in url: return {"data": {"storagePath": "tmp/path", "uploadUrl": "https://oss.example/upload"}} if "/submitExportJob" in url: return {"data": {"jobId": "job-1"}} if "/queryExportJobInfo" in url: return {"data": {"status": "success", "ossUrl": "https://oss.example/result.docx"}} self.fail("unexpected API " + url) with mock.patch.object(artifact_fetch, "dingtalk_json_api", side_effect=api), \ mock.patch.object(artifact_fetch, "dingtalk_put_bytes") as put, \ mock.patch.object(artifact_fetch, "http_get", return_value=("/tmp/result", 123, "a" * 64)) as download: result = artifact_fetch.live_export_dingtalk_document( "raw-node", {"a-token": "x", "x-xsrf-token": "y", "cookie": "z", "referer": "https://alidocs.dingtalk.com/"}, {"name": "说明.adoc", "relative_path": "说明.adoc"}, 1_000_000, ) self.assertEqual(result, ("/tmp/result", 123, "a" * 64, False)) self.assertTrue(any("submitExportJob" in url for url, _ in calls)) self.assertFalse(any("/file/download" in url for url, _ in calls)) put.assert_called_once() download.assert_called_once_with("https://oss.example/result.docx", {}, 180, 1_000_000) if __name__ == "__main__": unittest.main()