This commit is contained in:
2026-02-25 15:32:23 +02:00
parent 6cff65f288
commit 741173f617
24 changed files with 1205 additions and 124 deletions

View File

@@ -2,7 +2,10 @@
import pytest
from flow.commands.dotfiles import _discover_packages, _resolve_edit_target, _walk_package
from flow.commands.dotfiles import _collect_home_specs, _discover_packages, _resolve_edit_target, _walk_package
from flow.core.config import AppConfig, FlowContext
from flow.core.console import ConsoleLogger
from flow.core.platform import PlatformInfo
def _make_tree(tmp_path):
@@ -20,6 +23,15 @@ def _make_tree(tmp_path):
return tmp_path
def _ctx() -> FlowContext:
return FlowContext(
config=AppConfig(),
manifest={"profiles": {"work": {"os": "linux", "configs": {"skip": []}}}},
platform=PlatformInfo(os="linux", arch="x64", platform="linux-x64"),
console=ConsoleLogger(),
)
def test_discover_packages_shared_only(tmp_path):
tree = _make_tree(tmp_path)
packages = _discover_packages(tree)
@@ -43,8 +55,7 @@ def test_discover_packages_profile_overrides_shared(tmp_path):
(profile_zsh / ".zshrc").write_text("# work zsh")
with pytest.raises(RuntimeError, match="Conflicting dotfile targets"):
from flow.commands.dotfiles import _collect_home_specs
_collect_home_specs(tree, tmp_path / "home", "work", set(), None)
_collect_home_specs(_ctx(), tree, tmp_path / "home", "work", set(), None)
def test_walk_package_returns_relative_paths(tmp_path):
@@ -70,6 +81,24 @@ def test_resolve_edit_target_repo_path(tmp_path):
assert target == tree / "_shared" / "zsh" / ".zshrc"
def test_resolve_edit_target_rejects_parent_traversal(tmp_path):
tree = _make_tree(tmp_path / "repo")
outside = tmp_path / "outside.txt"
outside.write_text("secret")
target = _resolve_edit_target("../outside.txt", dotfiles_dir=tree)
assert target is None
def test_resolve_edit_target_rejects_nested_repo_escape(tmp_path):
tree = _make_tree(tmp_path / "repo")
outside = tmp_path / "escape.txt"
outside.write_text("secret")
target = _resolve_edit_target("_shared/../../escape.txt", dotfiles_dir=tree)
assert target is None
def test_resolve_edit_target_missing_returns_none(tmp_path):
tree = _make_tree(tmp_path)
assert _resolve_edit_target("does-not-exist", dotfiles_dir=tree) is None