This commit is contained in:
luobo 2026-04-09 00:36:05 +00:00 committed by GitHub
commit 42f50cc395
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 187 additions and 0 deletions

View file

@ -83,3 +83,7 @@ openspace = [
"local_server/config.json",
"local_server/README.md",
]
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]

View file

@ -0,0 +1,56 @@
import importlib.util
import io
import zipfile
from pathlib import Path
import pytest
def _load_module():
module_path = Path(__file__).resolve().parents[2] / "openspace" / "cloud" / "client.py"
spec = importlib.util.spec_from_file_location("openspace_cloud_client_test", module_path)
module = importlib.util.module_from_spec(spec)
assert spec and spec.loader
spec.loader.exec_module(module)
return module
_client = _load_module()
CloudError = _client.CloudError
OpenSpaceClient = _client.OpenSpaceClient
def _zip_bytes(files: dict[str, str]) -> bytes:
buffer = io.BytesIO()
with zipfile.ZipFile(buffer, mode="w") as zf:
for name, content in files.items():
zf.writestr(name, content)
return buffer.getvalue()
def test_extract_zip_skips_path_traversal_entries(tmp_path: Path):
zip_data = _zip_bytes(
{
"SKILL.md": "name: demo",
"../escape.txt": "nope",
"/absolute.txt": "nope",
"nested/file.txt": "ok",
}
)
extracted = OpenSpaceClient._extract_zip(zip_data, tmp_path)
assert extracted == ["SKILL.md", "nested/file.txt"]
assert (tmp_path / "SKILL.md").read_text(encoding="utf-8") == "name: demo"
assert (tmp_path / "nested" / "file.txt").read_text(encoding="utf-8") == "ok"
def test_validate_origin_parents_enforces_fixed_origin():
with pytest.raises(CloudError, match="exactly 1 parent_skill_id"):
OpenSpaceClient._validate_origin_parents("fixed", [])
OpenSpaceClient._validate_origin_parents("fixed", ["parent-1"])
def test_unified_diff_returns_none_when_snapshots_match():
assert OpenSpaceClient._unified_diff({"a.txt": "same\n"}, {"a.txt": "same\n"}) is None

View file

@ -0,0 +1,42 @@
import importlib.util
from pathlib import Path
def _load_module():
module_path = Path(__file__).resolve().parents[2] / "openspace" / "config" / "utils.py"
spec = importlib.util.spec_from_file_location("openspace_config_utils_test", module_path)
module = importlib.util.module_from_spec(spec)
assert spec and spec.loader
spec.loader.exec_module(module)
return module
_utils = _load_module()
get_config_value = _utils.get_config_value
load_json_file = _utils.load_json_file
save_json_file = _utils.save_json_file
def test_pytest_scaffold_uses_tests_directory(pytestconfig):
assert pytestconfig.getini("testpaths") == ["tests"]
def test_get_config_value_supports_dict_and_object():
config_dict = {"value": 42}
class ConfigObject:
value = 42
assert get_config_value(config_dict, "value") == 42
assert get_config_value(ConfigObject(), "value") == 42
assert get_config_value(config_dict, "missing", "fallback") == "fallback"
def test_save_and_load_json_round_trip(tmp_path: Path):
payload = {"name": "openspace", "nested": {"enabled": True}}
target = tmp_path / "nested" / "config.json"
save_json_file(payload, target)
assert target.exists()
assert load_json_file(target) == payload

View file

@ -0,0 +1,85 @@
import importlib.util
from pathlib import Path
def _load_module():
module_path = Path(__file__).resolve().parents[2] / "openspace" / "host_detection" / "nanobot.py"
spec = importlib.util.spec_from_file_location("openspace_nanobot_test", module_path)
module = importlib.util.module_from_spec(spec)
assert spec and spec.loader
spec.loader.exec_module(module)
return module
_nanobot = _load_module()
match_provider = _nanobot.match_provider
def test_match_provider_prefers_forced_provider():
providers = {
"openai": {"apiKey": "oa-key", "apiBase": "https://openai.example/v1"},
"minimax": {"apiKey": "mini-key", "apiBase": "https://minimax.example/v1"},
}
result = match_provider(providers, model="anything", forced_provider="minimax")
assert result == {
"api_key": "mini-key",
"api_base": "https://minimax.example/v1",
}
def test_read_nanobot_mcp_env_returns_openspace_env(tmp_path: Path, monkeypatch):
config_path = tmp_path / "config.json"
config_path.write_text(
"""
{
"tools": {
"mcpServers": {
"openspace": {
"env": {
"OPENSPACE_MODEL": "openrouter/anthropic/claude"
}
}
}
}
}
""".strip(),
encoding="utf-8",
)
monkeypatch.setattr(_nanobot, "NANOBOT_CONFIG_PATH", config_path)
assert _nanobot.read_nanobot_mcp_env() == {"OPENSPACE_MODEL": "openrouter/anthropic/claude"}
def test_try_read_nanobot_config_extracts_model_and_provider(tmp_path: Path, monkeypatch):
config_path = tmp_path / "config.json"
config_path.write_text(
"""
{
"providers": {
"minimax": {
"apiKey": "mini-key",
"apiBase": "https://minimax.example/v1"
}
},
"agents": {
"defaults": {
"model": "minimax/text-01",
"provider": "minimax"
}
}
}
""".strip(),
encoding="utf-8",
)
monkeypatch.setattr(_nanobot, "NANOBOT_CONFIG_PATH", config_path)
result = _nanobot.try_read_nanobot_config("")
assert result == {
"api_key": "mini-key",
"api_base": "https://minimax.example/v1",
"_model": "minimax/text-01",
"_forced_provider": "minimax",
}