mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-10-29 03:18:14 +08:00
138 lines
4.4 KiB
Python
138 lines
4.4 KiB
Python
"""
|
||
验证系统版本比较、显示与更新判断。
|
||
"""
|
||
|
||
from pathlib import Path
|
||
from types import SimpleNamespace
|
||
from unittest.mock import Mock
|
||
|
||
import pytest
|
||
|
||
from app.chain import system as system_module
|
||
from app.chain.system import SystemChain
|
||
from app.runtime import version as runtime_version
|
||
|
||
|
||
def test_installed_frontend_version_prefers_deployed_resource(
|
||
tmp_path: Path,
|
||
monkeypatch,
|
||
) -> None:
|
||
"""
|
||
当前前端版本优先读取已部署资源中的版本声明。
|
||
"""
|
||
frontend_path = tmp_path / "public"
|
||
frontend_path.mkdir()
|
||
(frontend_path / "version.txt").write_text("v3.2.1\n", encoding="utf-8")
|
||
monkeypatch.setattr(runtime_version, "is_frozen", lambda: False)
|
||
monkeypatch.setattr(runtime_version, "is_windows", lambda: False)
|
||
monkeypatch.setattr(
|
||
runtime_version,
|
||
"get_runtime_setting",
|
||
lambda key: frontend_path if key == "FRONTEND_PATH" else tmp_path / "config",
|
||
)
|
||
|
||
assert runtime_version.get_frontend_version() == "v3.2.1"
|
||
assert SystemChain.get_frontend_version() == "v3.2.1"
|
||
|
||
|
||
def test_installed_frontend_version_falls_back_to_release_declaration(
|
||
tmp_path: Path,
|
||
monkeypatch,
|
||
) -> None:
|
||
"""
|
||
未部署前端时按调用约定回退到构建声明。
|
||
"""
|
||
monkeypatch.setattr(runtime_version, "is_frozen", lambda: False)
|
||
monkeypatch.setattr(runtime_version, "is_windows", lambda: False)
|
||
monkeypatch.setattr(runtime_version, "_FRONTEND_VERSION", "v3.0.0")
|
||
monkeypatch.setattr(
|
||
runtime_version,
|
||
"get_runtime_setting",
|
||
lambda key: tmp_path / key.lower(),
|
||
)
|
||
|
||
assert runtime_version.get_frontend_version() == "v3.0.0"
|
||
assert (
|
||
runtime_version.get_frontend_version(fallback_to_declared=False) is None
|
||
)
|
||
|
||
|
||
@pytest.fixture
|
||
def release_http(monkeypatch):
|
||
"""
|
||
隔离发布查询的 HTTP 与运行配置,禁止访问真实 GitHub。
|
||
"""
|
||
http = Mock()
|
||
monkeypatch.setattr(system_module, "_system_ports_snapshot", lambda: (http, None))
|
||
monkeypatch.setattr(
|
||
system_module,
|
||
"get_chain_runtime_config_snapshot",
|
||
lambda: SimpleNamespace(proxy=None, github_headers={}),
|
||
)
|
||
return http
|
||
|
||
|
||
@pytest.mark.parametrize(
|
||
("getter", "repository"),
|
||
[
|
||
(SystemChain._SystemChain__get_server_release_version, "MoviePilot"),
|
||
(SystemChain._SystemChain__get_front_release_version, "MoviePilot-Frontend"),
|
||
],
|
||
)
|
||
@pytest.mark.parametrize(
|
||
("tags", "expected"),
|
||
[
|
||
(["v2.15.6", "v3.0.9", "v3.1.0", "v3.0.10", "v4.0.0"], "v3.1.0"),
|
||
(["v3.0.9", "v3.0.10", "v3.0.10-1"], "v3.0.10-1"),
|
||
(["v2.15.6", "v30.1.0", "v4.0.0"], None),
|
||
([], None),
|
||
],
|
||
)
|
||
def test_remote_version_selects_v3(release_http, getter, repository, tags, expected):
|
||
"""
|
||
前后端只比较 V3 标签的数值版本,缺少 V3 时不回退到其他代际。
|
||
"""
|
||
response = release_http.get.return_value
|
||
response.json.return_value = [{"tag_name": tag} for tag in tags]
|
||
|
||
assert getter() == expected
|
||
release_http.get.assert_called_once_with(
|
||
f"https://api.github.com/repos/jxxghp/{repository}/releases",
|
||
proxies=None,
|
||
headers={},
|
||
)
|
||
response.close.assert_called_once_with()
|
||
|
||
|
||
def test_remote_version_closes_invalid_response(release_http):
|
||
"""
|
||
发布响应解析失败仍释放连接,并维持查询失败返回空值的约定。
|
||
"""
|
||
response = release_http.get.return_value
|
||
response.json.side_effect = ValueError("invalid JSON")
|
||
|
||
assert SystemChain._SystemChain__get_server_release_version() is None
|
||
response.close.assert_called_once_with()
|
||
|
||
|
||
def test_version_command_reports_current_v3(release_http, monkeypatch):
|
||
"""
|
||
重现当前前后端均为 V3 时,命令应报告最新版本而非 V2 远程版本。
|
||
"""
|
||
release_http.get.return_value.json.return_value = [
|
||
{"tag_name": "v2.15.6"},
|
||
{"tag_name": "v3.1.0"},
|
||
]
|
||
monkeypatch.setattr(runtime_version, "get_app_version", lambda: "v3.1.0")
|
||
monkeypatch.setattr(runtime_version, "get_frontend_version", lambda: "v3.1.0")
|
||
post_message = Mock()
|
||
monkeypatch.setattr(SystemChain, "post_message", post_message)
|
||
|
||
SystemChain.version(object.__new__(SystemChain), channel=None, userid="test")
|
||
|
||
post_message.assert_called_once()
|
||
assert post_message.call_args.args[0].title == (
|
||
"当前后端版本:v3.1.0,已是最新版本\n"
|
||
"当前前端版本:v3.1.0,已是最新版本"
|
||
)
|