import os import pytest import pack_fs @pytest.fixture def custom_nodes(tmp_path): """A custom_nodes root wired into the mocked folder_paths.""" import folder_paths root = tmp_path / "custom_nodes" root.mkdir() folder_paths.get_folder_paths.return_value = [str(root)] return root def _make_pack(root, name): pack = root / name pack.mkdir() (pack / "__init__.py").write_text("NODE_CLASS_MAPPINGS = {}\n") return pack # --- find_active_pack_path ------------------------------------------------ def test_find_active_dir(custom_nodes): _make_pack(custom_nodes, "MyPack") found = pack_fs.find_active_pack_path("MyPack") assert found == os.path.normpath(str(custom_nodes / "MyPack")) def test_find_active_case_insensitive(custom_nodes): _make_pack(custom_nodes, "MyPack") assert pack_fs.find_active_pack_path("mypack") is not None def test_find_active_single_py_file(custom_nodes): (custom_nodes / "loose_node.py").write_text("NODE_CLASS_MAPPINGS = {}\n") found = pack_fs.find_active_pack_path("loose_node") assert found == os.path.normpath(str(custom_nodes / "loose_node.py")) def test_find_active_ignores_disabled_dir(custom_nodes): (custom_nodes / ".disabled").mkdir() _make_pack(custom_nodes / ".disabled", "MyPack") assert pack_fs.find_active_pack_path("MyPack") is None def test_find_active_rejects_path_traversal(custom_nodes): assert pack_fs.find_active_pack_path("../evil") is None assert pack_fs.find_active_pack_path("a/b") is None assert pack_fs.find_active_pack_path("") is None # --- disable_pack_native -------------------------------------------------- def test_disable_moves_dir_into_disabled(custom_nodes): _make_pack(custom_nodes, "MyPack") ok, msg = pack_fs.disable_pack_native("MyPack") assert ok, msg assert not (custom_nodes / "MyPack").exists() assert (custom_nodes / ".disabled" / "MyPack" / "__init__.py").exists() def test_disable_moves_single_py_file(custom_nodes): (custom_nodes / "loose_node.py").write_text("x = 1\n") ok, msg = pack_fs.disable_pack_native("loose_node") assert ok, msg assert not (custom_nodes / "loose_node.py").exists() assert (custom_nodes / ".disabled" / "loose_node.py").exists() def test_disable_missing_pack_fails(custom_nodes): ok, msg = pack_fs.disable_pack_native("Ghost") assert not ok assert "not found" in msg def test_disable_collision_fails(custom_nodes): _make_pack(custom_nodes, "MyPack") (custom_nodes / ".disabled").mkdir() (custom_nodes / ".disabled" / "MyPack").mkdir() # pre-existing disabled copy ok, msg = pack_fs.disable_pack_native("MyPack") assert not ok assert "already exists" in msg # original left untouched assert (custom_nodes / "MyPack").exists() # --- enable_pack_native --------------------------------------------------- def test_enable_moves_back(custom_nodes): _make_pack(custom_nodes, "MyPack") assert pack_fs.disable_pack_native("MyPack")[0] ok, msg = pack_fs.enable_pack_native("MyPack") assert ok, msg assert (custom_nodes / "MyPack" / "__init__.py").exists() assert not (custom_nodes / ".disabled" / "MyPack").exists() def test_enable_missing_fails(custom_nodes): ok, msg = pack_fs.enable_pack_native("Ghost") assert not ok assert "not found" in msg def test_enable_strips_version_suffix(custom_nodes): # A Manager-disabled pack on disk carries an @version suffix; enabling should # restore it as a clean, importable directory name. ddir = custom_nodes / ".disabled" ddir.mkdir() pack = ddir / "ComfyMath@nightly" pack.mkdir() (pack / "__init__.py").write_text("NODE_CLASS_MAPPINGS = {}\n") ok, msg = pack_fs.enable_pack_native("ComfyMath") assert ok, msg assert (custom_nodes / "ComfyMath" / "__init__.py").exists() assert not (custom_nodes / "ComfyMath@nightly").exists() assert not (ddir / "ComfyMath@nightly").exists() def test_disable_then_enable_roundtrip_py_file(custom_nodes): (custom_nodes / "loose_node.py").write_text("x = 1\n") assert pack_fs.disable_pack_native("loose_node")[0] assert pack_fs.enable_pack_native("loose_node")[0] assert (custom_nodes / "loose_node.py").exists() # --- list_disabled_packs -------------------------------------------------- def test_list_disabled_empty(custom_nodes): assert pack_fs.list_disabled_packs() == set() def test_list_disabled_strips_version_and_ext(custom_nodes): ddir = custom_nodes / ".disabled" ddir.mkdir() (ddir / "ComfyMath@nightly").mkdir() # Manager-style @version suffix (ddir / "PlainPack").mkdir() (ddir / "loose_node.py").write_text("x = 1\n") # single-file pack assert pack_fs.list_disabled_packs() == {"ComfyMath", "PlainPack", "loose_node"} def test_list_disabled_reflects_a_native_disable(custom_nodes): _make_pack(custom_nodes, "MyPack") assert pack_fs.disable_pack_native("MyPack")[0] assert "MyPack" in pack_fs.list_disabled_packs()