Show version-locked plugins in menu
This commit is contained in:
+103
-4
@@ -547,7 +547,7 @@ state_dir = ".state"
|
||||
check_health.assert_not_called()
|
||||
run_bootstrap.assert_not_called()
|
||||
|
||||
def test_enable_disabled_plugin_bootstraps_before_plan(self) -> None:
|
||||
def test_enable_disabled_plugin_plans_before_bootstrap(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
work = Path(tmp)
|
||||
instance = work / "instances" / "1.44.1"
|
||||
@@ -628,7 +628,55 @@ install_strategy = "dll-to-plugins"
|
||||
lockfile=str(lock_path),
|
||||
repo=work,
|
||||
)
|
||||
self.assertEqual(call_order, ["ensure", "plan", "apply"])
|
||||
self.assertEqual(call_order, ["plan", "ensure", "apply"])
|
||||
|
||||
def test_enable_locked_plugin_missing_asset_does_not_bootstrap(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
work = Path(tmp)
|
||||
instance = work / "instances" / "1.44.1"
|
||||
state = work / "state"
|
||||
instance.mkdir(parents=True)
|
||||
(instance / "Beat Saber_Data").mkdir()
|
||||
(instance / "Plugins").mkdir()
|
||||
(work / "locks").mkdir()
|
||||
(work / "registry").mkdir()
|
||||
lock_path = work / "locks" / "1.44.1.lock.toml"
|
||||
lock_path.write_text(
|
||||
"""
|
||||
beat_saber_version = "1.44.1"
|
||||
instance = "1.44.1"
|
||||
|
||||
[[plugins]]
|
||||
id = "example"
|
||||
tag = "v1.0.0"
|
||||
asset = "Missing.dll"
|
||||
""".lstrip(),
|
||||
encoding="utf-8",
|
||||
)
|
||||
registry_path = work / "registry" / "plugins.toml"
|
||||
registry_path.write_text(
|
||||
"""
|
||||
[[plugins]]
|
||||
id = "example"
|
||||
name = "Example"
|
||||
install_strategy = "dll-to-plugins"
|
||||
""".lstrip(),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
with patch("plugin_helper.operations.ensure_healthy_bootstrap") as ensure:
|
||||
with self.assertRaisesRegex(FileNotFoundError, "asset not found"):
|
||||
enable_disabled_plugin(
|
||||
instance="1.44.1",
|
||||
instance_path=instance,
|
||||
state_root=state,
|
||||
plugin_id="example",
|
||||
registry=str(registry_path),
|
||||
lockfile=str(lock_path),
|
||||
repo=work,
|
||||
)
|
||||
|
||||
ensure.assert_not_called()
|
||||
|
||||
def test_plan_apply_and_uninstall_dll(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
@@ -1399,6 +1447,33 @@ sha256 = "{sha256_file(asset)}"
|
||||
self.assertEqual(report["plugins"][0]["asset"], "Example.dll")
|
||||
self.assertEqual(report["plugins"][0]["fileCount"], 1)
|
||||
|
||||
def test_installed_plugins_report_starts_from_version_lock(self) -> None:
|
||||
registry = Registry(
|
||||
{
|
||||
"alpha": RegistryPlugin(id="alpha", name="Alpha", repo="owner/alpha"),
|
||||
"beta": RegistryPlugin(id="beta", name="Beta", repo="owner/beta"),
|
||||
}
|
||||
)
|
||||
lockfile = Lockfile(
|
||||
beat_saber_version="1.40.8",
|
||||
instance="1.40.8",
|
||||
plugins=(
|
||||
LockedPlugin(id="alpha", repo="owner/alpha", tag="v1.0.0", asset="Alpha.dll", sha256="a"),
|
||||
LockedPlugin(id="beta", repo="owner/beta", tag="v2.0.0", asset="Beta.dll", sha256="b"),
|
||||
),
|
||||
)
|
||||
|
||||
report = installed_plugins_report(
|
||||
installed_state={"instance": "1.40.8", "plugins": {}},
|
||||
registry=registry,
|
||||
lockfile=lockfile,
|
||||
)
|
||||
|
||||
self.assertEqual([plugin["id"] for plugin in report["plugins"]], ["alpha", "beta"])
|
||||
self.assertEqual([plugin["status"] for plugin in report["plugins"]], ["disabled", "disabled"])
|
||||
self.assertEqual([plugin["fileCount"] for plugin in report["plugins"]], [0, 0])
|
||||
self.assertEqual(report["plugins"][1]["version"], "v2.0.0")
|
||||
|
||||
def test_update_check_reports_current_matching_asset(self) -> None:
|
||||
registry = Registry(
|
||||
{
|
||||
@@ -1535,7 +1610,13 @@ sha256 = "{sha256_file(asset)}"
|
||||
self.assertEqual(result["plugins"][0]["latestAssetSha256"], "new")
|
||||
|
||||
|
||||
def _make_tui_fixture(root: Path, *, disabled: bool = False, hash_mismatch: bool = False) -> tuple[PluginHelperTui, Path, Path]:
|
||||
def _make_tui_fixture(
|
||||
root: Path,
|
||||
*,
|
||||
disabled: bool = False,
|
||||
hash_mismatch: bool = False,
|
||||
recorded: bool = True,
|
||||
) -> tuple[PluginHelperTui, Path, Path]:
|
||||
repo = root / "repo"
|
||||
instance_root = root / "instances"
|
||||
instance = instance_root / "1.40.8"
|
||||
@@ -1574,7 +1655,10 @@ sha256 = "{sha256_file(asset)}"
|
||||
)
|
||||
|
||||
target = instance / "Plugins" / "Example.dll"
|
||||
if disabled:
|
||||
if not recorded:
|
||||
plugins = {}
|
||||
disabled_plugins = {}
|
||||
elif disabled:
|
||||
plugins = {}
|
||||
disabled_plugins = {
|
||||
"example": {
|
||||
@@ -1762,6 +1846,21 @@ class PluginHelperTuiTests(unittest.IsolatedAsyncioTestCase):
|
||||
self.assertIn("example", updated["plugins"])
|
||||
self.assertNotIn("example", updated["disabledPlugins"])
|
||||
|
||||
async def test_space_enables_locked_unrecorded_plugin_from_asset(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
app, instance, state = _make_tui_fixture(Path(tmp), recorded=False)
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
self.assertEqual(app.mode, "plugins")
|
||||
self.assertEqual(app.plugin_rows[0]["status"], "disabled")
|
||||
await pilot.press("space")
|
||||
await pilot.pause()
|
||||
|
||||
self.assertEqual((instance / "Plugins" / "Example.dll").read_bytes(), b"managed dll")
|
||||
updated = load_installed_state(state, "1.40.8")
|
||||
self.assertIn("example", updated["plugins"])
|
||||
self.assertNotIn("example", updated.get("disabledPlugins", {}))
|
||||
|
||||
async def test_disable_all_disables_enabled_plugins(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
app, instance, state = _make_tui_fixture(Path(tmp))
|
||||
|
||||
Reference in New Issue
Block a user