fix(plugin): optimize release cache loading (#5966)

This commit is contained in:
InfinityPacer
2026-06-18 18:52:28 +08:00
committed by GitHub
parent d2e2435be7
commit 84eee40e81
5 changed files with 430 additions and 58 deletions
+54 -20
View File
@@ -6,6 +6,7 @@ from app.api.endpoints.plugin import plugin_history
from app.api.endpoints.plugin import plugin_releases
from app.api.endpoints.plugin import reset_plugin
from app.api.endpoints.system import sync_plugin_market_from_wiki
from app.core.config import settings
from app.schemas.event import PluginDataResetEventData
from app.schemas.types import ChainEventType
@@ -75,14 +76,10 @@ def test_plugin_releases_returns_supported_versions_with_latest_and_current(monk
repo_url="https://github.com/demo/plugins",
release=True,
)
installed_plugin = schemas.Plugin(
id="DemoPlugin",
plugin_version="1.2.0",
installed=True,
)
plugin_manager = MagicMock()
plugin_manager.async_get_online_plugins = AsyncMock(return_value=[market_plugin])
plugin_manager.get_local_plugins.return_value = [installed_plugin]
plugin_manager.async_get_plugins_from_market = AsyncMock(return_value=[market_plugin])
plugin_manager.get_local_plugin_version.return_value = "1.2.0"
plugin_helper = MagicMock()
plugin_helper.async_get_plugin_release_versions = AsyncMock(return_value=[
{"version": "1.2.3", "tag_name": "DemoPlugin_v1.2.3", "asset_name": "demoplugin_v1.2.3.zip"},
@@ -102,7 +99,11 @@ def test_plugin_releases_returns_supported_versions_with_latest_and_current(monk
assert result["items"][0]["is_current"] is False
assert result["items"][1]["is_latest"] is False
assert result["items"][1]["is_current"] is True
plugin_manager.async_get_online_plugins.assert_awaited_once_with(force=False)
plugin_manager.async_get_plugins_from_market.assert_awaited_once_with(
"https://github.com/demo/plugins", settings.VERSION_FLAG, False
)
plugin_manager.async_get_online_plugins.assert_not_awaited()
plugin_manager.get_local_plugins.assert_not_called()
def test_plugin_releases_does_not_mutate_cached_release_items(monkeypatch):
@@ -115,17 +116,12 @@ def test_plugin_releases_does_not_mutate_cached_release_items(monkeypatch):
repo_url="https://github.com/demo/plugins",
release=True,
)
installed_plugin = schemas.Plugin(
id="DemoPlugin",
plugin_version="1.2.0",
installed=True,
)
release_items = [
{"version": "1.2.3", "tag_name": "DemoPlugin_v1.2.3", "asset_name": "demoplugin_v1.2.3.zip"},
]
plugin_manager = MagicMock()
plugin_manager.async_get_online_plugins = AsyncMock(return_value=[market_plugin])
plugin_manager.get_local_plugins.return_value = [installed_plugin]
plugin_manager.async_get_plugins_from_market = AsyncMock(return_value=[market_plugin])
plugin_manager.get_local_plugin_version.return_value = "1.2.0"
plugin_helper = MagicMock()
plugin_helper.async_get_plugin_release_versions = AsyncMock(return_value=release_items)
@@ -140,6 +136,39 @@ def test_plugin_releases_does_not_mutate_cached_release_items(monkeypatch):
assert "is_current" not in release_items[0]
def test_plugin_releases_falls_back_to_compatible_base_package(monkeypatch):
"""
当前版本 package 未包含插件时,再读取基础 package 兼容项,不扫描其他市场。
"""
market_plugin = schemas.Plugin(
id="DemoPlugin",
plugin_version="1.2.3",
repo_url="https://github.com/demo/plugins",
release=True,
)
plugin_manager = MagicMock()
plugin_manager.async_get_plugins_from_market = AsyncMock(
side_effect=[[], [market_plugin]]
)
plugin_manager.get_local_plugin_version.return_value = None
plugin_helper = MagicMock()
plugin_helper.async_get_plugin_release_versions = AsyncMock(return_value=[])
with (
patch("app.api.endpoints.plugin.PluginManager", return_value=plugin_manager),
patch("app.api.endpoints.plugin.PluginHelper", return_value=plugin_helper),
):
result = asyncio.run(
plugin_releases("DemoPlugin", None, "https://github.com/demo/plugins", False)
)
assert result["latest_version"] == "1.2.3"
assert plugin_manager.async_get_plugins_from_market.await_args_list == [
(("https://github.com/demo/plugins", settings.VERSION_FLAG, False), {}),
(("https://github.com/demo/plugins", None, False), {}),
]
def test_plugin_releases_uses_force_refresh_for_market_metadata(monkeypatch):
"""
release 列表接口沿用插件市场的 force 语义,供前端手动刷新时绕过缓存。
@@ -151,8 +180,8 @@ def test_plugin_releases_uses_force_refresh_for_market_metadata(monkeypatch):
release=True,
)
plugin_manager = MagicMock()
plugin_manager.async_get_online_plugins = AsyncMock(return_value=[market_plugin])
plugin_manager.get_local_plugins.return_value = []
plugin_manager.async_get_plugins_from_market = AsyncMock(return_value=[market_plugin])
plugin_manager.get_local_plugin_version.return_value = None
plugin_helper = MagicMock()
plugin_helper.async_get_plugin_release_versions = AsyncMock(return_value=[])
@@ -163,8 +192,13 @@ def test_plugin_releases_uses_force_refresh_for_market_metadata(monkeypatch):
result = asyncio.run(plugin_releases("DemoPlugin", None, "https://github.com/demo/plugins", True))
assert result["release_supported"] is False
plugin_manager.async_get_online_plugins.assert_awaited_once_with(force=True)
assert plugin_helper.async_get_plugin_release_versions.await_args.args == ("DemoPlugin", "https://github.com/demo/plugins")
plugin_manager.async_get_plugins_from_market.assert_awaited_once_with(
"https://github.com/demo/plugins", settings.VERSION_FLAG, True
)
assert plugin_helper.async_get_plugin_release_versions.await_args.args == (
"DemoPlugin",
"https://github.com/demo/plugins",
)
def test_plugin_releases_hides_items_when_market_plugin_does_not_enable_release(monkeypatch):
@@ -178,8 +212,8 @@ def test_plugin_releases_hides_items_when_market_plugin_does_not_enable_release(
release=False,
)
plugin_manager = MagicMock()
plugin_manager.async_get_online_plugins = AsyncMock(return_value=[market_plugin])
plugin_manager.get_local_plugins.return_value = []
plugin_manager.async_get_plugins_from_market = AsyncMock(return_value=[market_plugin])
plugin_manager.get_local_plugin_version.return_value = None
plugin_helper = MagicMock()
plugin_helper.async_get_plugin_release_versions = AsyncMock(return_value=[
{"version": "1.2.3", "tag_name": "DemoPlugin_v1.2.3", "asset_name": "demoplugin_v1.2.3.zip"},