Files
2026-07-13 13:12:33 +08:00

147 lines
4.6 KiB
Python

"""Tests for explicit OpenSquilla profile home resolution."""
from __future__ import annotations
import pytest
from opensquilla.paths import (
default_opensquilla_home,
default_profile_name,
default_profiles_root,
is_valid_profile_name,
profile_home,
state_dir,
)
_VALID_NAMES = [
"default",
"agent-a",
"agent_a",
"a1",
"0",
"a" * 64,
"abc-123_xyz",
]
_INVALID_NAMES = [
"",
"-leading-dash",
"_leading-underscore",
"UPPER",
"MixedCase",
"with spaces",
"with/slash",
"with\\backslash",
"with..dot",
"a" * 65,
"../escape",
"name?q=1",
"中文",
"name!",
"name.with.dot",
"name'quote",
'name"quote',
]
@pytest.mark.parametrize("name", _VALID_NAMES)
def test_is_valid_profile_name_accepts(name: str) -> None:
assert is_valid_profile_name(name)
@pytest.mark.parametrize("name", _INVALID_NAMES)
def test_is_valid_profile_name_rejects(name: str) -> None:
assert not is_valid_profile_name(name)
def test_default_opensquilla_home_keeps_legacy_default(monkeypatch, tmp_path) -> None:
monkeypatch.delenv("OPENSQUILLA_STATE_DIR", raising=False)
monkeypatch.delenv("OPENSQUILLA_HOME", raising=False)
monkeypatch.delenv("OPENSQUILLA_PROFILE", raising=False)
monkeypatch.setenv("HOME", str(tmp_path))
assert default_opensquilla_home() == tmp_path / ".opensquilla"
def test_default_profile_name_defaults_to_default(monkeypatch) -> None:
monkeypatch.delenv("OPENSQUILLA_PROFILE", raising=False)
assert default_profile_name() == "default"
def test_default_profile_name_trims_whitespace(monkeypatch) -> None:
monkeypatch.setenv("OPENSQUILLA_PROFILE", " agent-a ")
assert default_profile_name() == "agent-a"
def test_default_profiles_root_uses_env(monkeypatch, tmp_path) -> None:
monkeypatch.setenv("OPENSQUILLA_HOME", str(tmp_path / "profiles"))
assert default_profiles_root() == tmp_path / "profiles"
def test_default_profiles_root_falls_back_under_legacy_home(
monkeypatch, tmp_path
) -> None:
monkeypatch.delenv("OPENSQUILLA_HOME", raising=False)
monkeypatch.setenv("HOME", str(tmp_path))
assert default_profiles_root() == tmp_path / ".opensquilla" / "profiles"
def test_default_profiles_root_expands_tilde(monkeypatch, tmp_path) -> None:
monkeypatch.setenv("HOME", str(tmp_path))
monkeypatch.setenv("OPENSQUILLA_HOME", "~/my-profiles")
assert default_profiles_root() == tmp_path / "my-profiles"
def test_profile_home_rejects_path_traversal(monkeypatch, tmp_path) -> None:
monkeypatch.setenv("OPENSQUILLA_HOME", str(tmp_path / "profiles"))
monkeypatch.setenv("OPENSQUILLA_PROFILE", "../escape")
with pytest.raises(ValueError, match="Invalid OpenSquilla profile name"):
profile_home()
def test_state_dir_override_wins_over_profile(monkeypatch, tmp_path) -> None:
state_path = tmp_path / "pinned"
profile_root = tmp_path / "profiles"
monkeypatch.setenv("OPENSQUILLA_STATE_DIR", str(state_path))
monkeypatch.setenv("OPENSQUILLA_HOME", str(profile_root))
monkeypatch.setenv("OPENSQUILLA_PROFILE", "agent-a")
assert default_opensquilla_home() == state_path
def test_explicit_profile_uses_profiles_root(monkeypatch, tmp_path) -> None:
monkeypatch.delenv("OPENSQUILLA_STATE_DIR", raising=False)
profile_root = tmp_path / "profiles"
monkeypatch.setenv("OPENSQUILLA_HOME", str(profile_root))
monkeypatch.setenv("OPENSQUILLA_PROFILE", "agent-b")
assert default_opensquilla_home() == profile_root / "agent-b"
def test_profile_without_home_uses_default_profiles_root(monkeypatch, tmp_path) -> None:
monkeypatch.delenv("OPENSQUILLA_STATE_DIR", raising=False)
monkeypatch.delenv("OPENSQUILLA_HOME", raising=False)
monkeypatch.setenv("OPENSQUILLA_PROFILE", "coder")
monkeypatch.setenv("HOME", str(tmp_path))
assert default_opensquilla_home() == tmp_path / ".opensquilla" / "profiles" / "coder"
def test_profile_state_dirs_are_isolated(monkeypatch, tmp_path) -> None:
profile_root = tmp_path / "profiles"
monkeypatch.delenv("OPENSQUILLA_STATE_DIR", raising=False)
monkeypatch.setenv("OPENSQUILLA_HOME", str(profile_root))
monkeypatch.setenv("OPENSQUILLA_PROFILE", "agent-a")
state_a = state_dir("agents", "main", "memory.db")
monkeypatch.setenv("OPENSQUILLA_PROFILE", "agent-b")
state_b = state_dir("agents", "main", "memory.db")
assert state_a == profile_root / "agent-a" / "state" / "agents" / "main" / "memory.db"
assert state_b == profile_root / "agent-b" / "state" / "agents" / "main" / "memory.db"
assert state_a != state_b