"""运行产物路径策略测试(T-003)。""" import tempfile import unittest from pathlib import Path from unittest import mock from src import paths class PathsTest(unittest.TestCase): def test_safe_replaces_illegal_chars(self): self.assertEqual(paths._safe("color/size..x"), "color_size__x") self.assertEqual(paths._safe("ok-_1"), "ok-_1") def test_safe_empty_fallback(self): self.assertEqual(paths._safe(""), "unknown") self.assertEqual(paths._safe("/.."), "___") def test_screenshot_and_xml_paths(self): with tempfile.TemporaryDirectory() as tmp: with mock.patch.object(paths, "ARTIFACTS_DIR", Path(tmp)): png = paths.screenshot_path("T1", "open_product") xml = paths.ui_xml_path("T1", "open_product") self.assertTrue(png.name.endswith(".png")) self.assertTrue(xml.name.endswith(".xml")) # 同一任务归到 artifacts// 子目录 self.assertEqual(png.parent.name, "T1") self.assertEqual(xml.parent.name, "T1") # 目录已被创建 self.assertTrue(png.parent.is_dir()) def test_illegal_task_id_cannot_escape_root(self): """task_id 含路径穿越字符时被安全化隔离,不逃逸 artifacts 根。""" with tempfile.TemporaryDirectory() as tmp: with mock.patch.object(paths, "ARTIFACTS_DIR", Path(tmp)): p = paths.screenshot_path("../evil", "step") self.assertTrue(str(p.resolve()).startswith(str(Path(tmp).resolve()))) if __name__ == "__main__": unittest.main()