42 lines
1.6 KiB
Python
42 lines
1.6 KiB
Python
"""运行产物路径策略测试(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/<task_id>/ 子目录
|
||
|
|
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()
|