"""Unit tests for ~ / $HOME expansion in container paths.""" import pytest from src.api.tool_instances import _resolve_git_mount_mappings from src.services.config_profile_resolver import expand_container_path from src.services.manifest_compiler import get_manifest_home_dir class TestExpandContainerPath: """Tests for expand_container_path helper.""" def test_tilde_slash_expands(self) -> None: """~/foo should expand to home_dir/foo.""" assert expand_container_path("~/workspace", "/home/user") == "/home/user/workspace" def test_tilde_alone_expands(self) -> None: """~ should expand to home_dir.""" assert expand_container_path("~", "/home/user") == "/home/user" def test_dollar_home_slash_expands(self) -> None: """$HOME/foo should expand to home_dir/foo.""" assert expand_container_path("$HOME/workspace", "/home/user") == "/home/user/workspace" def test_dollar_home_alone_expands(self) -> None: """$HOME should expand to home_dir.""" assert expand_container_path("$HOME", "/home/user") == "/home/user" def test_absolute_path_unchanged(self) -> None: """Absolute paths should not be modified.""" assert expand_container_path("/app/workspace", "/home/user") == "/app/workspace" def test_relative_path_unchanged(self) -> None: """Relative paths should not be modified.""" assert expand_container_path("workspace", "/home/user") == "workspace" def test_tilde_in_middle_unchanged(self) -> None: """~ in the middle of a path should not expand.""" assert expand_container_path("/app/~user", "/home/user") == "/app/~user" def test_dollar_home_in_middle_unchanged(self) -> None: """$HOME in the middle of a path should not expand.""" assert expand_container_path("/app/$HOMEuser", "/home/user") == "/app/$HOMEuser" def test_root_home(self) -> None: """Expansion works with /root as home.""" assert expand_container_path("~/config", "/root") == "/root/config" class TestGetManifestHomeDir: """Tests for get_manifest_home_dir helper.""" def test_with_user_block(self) -> None: """Manifest with user block returns /home/{name}.""" manifest = {"user": {"name": "developer", "uid": 1000, "gid": 1000}} assert get_manifest_home_dir(manifest) == "/home/developer" def test_without_user_block(self) -> None: """Manifest without user block returns /root.""" manifest = {"base_image": "ubuntu:24.04"} assert get_manifest_home_dir(manifest) == "/root" def test_with_empty_user_name(self) -> None: """Manifest with empty user name returns /root.""" manifest = {"user": {"name": "", "uid": 1000, "gid": 1000}} assert get_manifest_home_dir(manifest) == "/root" def test_with_none_user_name(self) -> None: """Manifest with None user name returns /root.""" manifest = {"user": {"name": None, "uid": 1000, "gid": 1000}} assert get_manifest_home_dir(manifest) == "/root" class TestResolveGitMountMappingsExpansion: """Tests that git mount mapping targets expand ~ and $HOME.""" def test_tilde_target_expansion(self, tmp_path) -> None: """Mapping with ~/repo target expands to home dir.""" (tmp_path / "src").mkdir() mappings = [{"source_path": "src", "target_path": "~/repo"}] result = _resolve_git_mount_mappings(str(tmp_path), mappings, None, "/home/user") assert len(result) == 1 assert result[0]["target"] == "/home/user/repo" def test_dollar_home_target_expansion(self, tmp_path) -> None: """Mapping with $HOME/repo target expands to home dir.""" (tmp_path / "src").mkdir() mappings = [{"source_path": "src", "target_path": "$HOME/repo"}] result = _resolve_git_mount_mappings(str(tmp_path), mappings, None, "/home/user") assert len(result) == 1 assert result[0]["target"] == "/home/user/repo" def test_absolute_target_unchanged(self, tmp_path) -> None: """Absolute target paths are not modified.""" (tmp_path / "src").mkdir() mappings = [{"source_path": "src", "target_path": "/app/src"}] result = _resolve_git_mount_mappings(str(tmp_path), mappings, None, "/home/user") assert len(result) == 1 assert result[0]["target"] == "/app/src"