nanobot/tests/extensions/test_catalog.py

74 lines
2.2 KiB
Python

import json
from unittest.mock import patch
from nanobot.config.schema import Config
from nanobot.extensions import build_extension_catalog
def _write_extension(root, extension_id: str) -> None:
package = root / extension_id
package.mkdir(parents=True)
(package / "nanobot.extension.json").write_text(
json.dumps(
{
"id": extension_id,
"name": extension_id,
"version": "1.0.0",
"runtime": "python",
"contributions": [{"kind": "tool", "name": f"{extension_id}_tool"}],
}
)
)
def _catalog(config: Config, user_root):
with (
patch("nanobot.channels.registry.discover_plugins", return_value={}),
patch("nanobot.providers.registry.PROVIDERS", ()),
patch("nanobot.audio.transcription_registry.TRANSCRIPTION_PROVIDERS", ()),
patch(
"nanobot.providers.image_generation.image_gen_provider_names",
return_value=(),
),
):
return build_extension_catalog(config, user_root=user_root)
def test_installed_extension_requires_explicit_trust(tmp_path) -> None:
_write_extension(tmp_path, "acme")
catalog = _catalog(Config(), tmp_path)
assert [item.manifest.id for item in catalog.candidates] == ["acme"]
assert catalog.snapshot.extensions == ()
def test_entry_config_trust_activates_installed_extension(tmp_path) -> None:
_write_extension(tmp_path, "acme")
config = Config.model_validate(
{
"extensions": {
"entries": {
"acme": {
"enabled": True,
"trusted": True,
}
}
}
}
)
catalog = _catalog(config, tmp_path)
assert [item.manifest.id for item in catalog.snapshot.extensions] == ["acme"]
assert catalog.snapshot.contributions[0].contribution.name == "acme_tool"
def test_extensions_disabled_keeps_native_catalog_only(tmp_path) -> None:
_write_extension(tmp_path, "acme")
config = Config.model_validate({"extensions": {"enabled": False}})
catalog = _catalog(config, tmp_path)
assert all(item.manifest.id != "acme" for item in catalog.candidates)