97 lines
3 KiB
Python
97 lines
3 KiB
Python
|
|
"""Tests for `plugins_store.py` — mirrors the Rust `plugins.rs` tests."""
|
||
|
|
|
||
|
|
import os
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
import plugins_store
|
||
|
|
|
||
|
|
|
||
|
|
def write(path, content):
|
||
|
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||
|
|
with open(path, "wt", encoding="utf8") as f:
|
||
|
|
f.write(content)
|
||
|
|
|
||
|
|
|
||
|
|
GOOD_YAML = """
|
||
|
|
my_plugin_hello:
|
||
|
|
phrases:
|
||
|
|
- привет плагин
|
||
|
|
- тест плагин
|
||
|
|
action: {type: shell, cmd: 'start "" notepad.exe'}
|
||
|
|
"""
|
||
|
|
|
||
|
|
BAD_YAML = "this is :: not valid yaml ::\n ::: -"
|
||
|
|
|
||
|
|
|
||
|
|
def test_discover_empty_dir_returns_empty(tmp_path):
|
||
|
|
assert plugins_store.discover_in(str(tmp_path)) == {}
|
||
|
|
|
||
|
|
|
||
|
|
def test_discover_loads_yaml(tmp_path):
|
||
|
|
write(str(tmp_path / "greeter" / "commands.yaml"), GOOD_YAML)
|
||
|
|
out = plugins_store.discover_in(str(tmp_path))
|
||
|
|
assert "my_plugin_hello" in out
|
||
|
|
assert out["my_plugin_hello"]["action"]["type"] == "shell"
|
||
|
|
|
||
|
|
|
||
|
|
def test_disabled_flag_skips_pack(tmp_path):
|
||
|
|
write(str(tmp_path / "muted" / "commands.yaml"), GOOD_YAML)
|
||
|
|
write(str(tmp_path / "muted" / plugins_store.DISABLED_FLAG), "")
|
||
|
|
out = plugins_store.discover_in(str(tmp_path))
|
||
|
|
assert out == {}
|
||
|
|
|
||
|
|
|
||
|
|
def test_malformed_yaml_does_not_break_other_packs(tmp_path):
|
||
|
|
write(str(tmp_path / "bad" / "commands.yaml"), BAD_YAML)
|
||
|
|
write(str(tmp_path / "good" / "commands.yaml"), GOOD_YAML)
|
||
|
|
out = plugins_store.discover_in(str(tmp_path))
|
||
|
|
assert "my_plugin_hello" in out
|
||
|
|
# bad pack contributed nothing
|
||
|
|
assert len(out) == 1
|
||
|
|
|
||
|
|
|
||
|
|
def test_duplicate_ids_across_packs_first_wins(tmp_path):
|
||
|
|
write(str(tmp_path / "pack_a" / "commands.yaml"), GOOD_YAML)
|
||
|
|
write(
|
||
|
|
str(tmp_path / "pack_b" / "commands.yaml"),
|
||
|
|
"""
|
||
|
|
my_plugin_hello:
|
||
|
|
phrases: [перезаписан]
|
||
|
|
action: {type: url, href: "http://evil.com"}
|
||
|
|
""",
|
||
|
|
)
|
||
|
|
out = plugins_store.discover_in(str(tmp_path))
|
||
|
|
# alphabetical order means pack_a wins
|
||
|
|
assert out["my_plugin_hello"]["action"]["type"] == "shell"
|
||
|
|
|
||
|
|
|
||
|
|
def test_non_dirs_ignored(tmp_path):
|
||
|
|
write(str(tmp_path / "README.md"), "# not a pack")
|
||
|
|
out = plugins_store.discover_in(str(tmp_path))
|
||
|
|
assert out == {}
|
||
|
|
|
||
|
|
|
||
|
|
def test_top_level_must_be_dict(tmp_path):
|
||
|
|
write(str(tmp_path / "weird" / "commands.yaml"), "- just\n- a\n- list\n")
|
||
|
|
out = plugins_store.discover_in(str(tmp_path))
|
||
|
|
assert out == {}
|
||
|
|
|
||
|
|
|
||
|
|
def test_list_packs_in_reports_both_states(tmp_path):
|
||
|
|
write(str(tmp_path / "alpha" / "commands.yaml"), GOOD_YAML)
|
||
|
|
write(str(tmp_path / "bravo" / "commands.yaml"), GOOD_YAML)
|
||
|
|
write(str(tmp_path / "bravo" / plugins_store.DISABLED_FLAG), "")
|
||
|
|
listing = plugins_store.list_packs_in(str(tmp_path))
|
||
|
|
by_name = {p["name"]: p for p in listing}
|
||
|
|
assert by_name["alpha"]["enabled"] is True
|
||
|
|
assert by_name["bravo"]["enabled"] is False
|
||
|
|
assert by_name["alpha"]["command_count"] == 1
|
||
|
|
|
||
|
|
|
||
|
|
def test_list_packs_reports_yaml_errors(tmp_path):
|
||
|
|
write(str(tmp_path / "bad" / "commands.yaml"), BAD_YAML)
|
||
|
|
listing = plugins_store.list_packs_in(str(tmp_path))
|
||
|
|
assert len(listing) == 1
|
||
|
|
assert listing[0]["error"] is not None
|
||
|
|
assert listing[0]["command_count"] == 0
|