mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-29 03:56:43 +08:00
134 lines
5.3 KiB
Python
134 lines
5.3 KiB
Python
import importlib
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
from app.sdk.cache import Cache, cached
|
|
from app.sdk.config import settings
|
|
from app.sdk.events import Event, eventmanager
|
|
from app.sdk.logging import logger
|
|
from app.sdk.media import MediaInfo, MetaBase, MetaInfo, MetaMusic, NfoReader
|
|
from app.sdk.network import RequestUtils, RssHelper, SitesHelper
|
|
from app.sdk.plugins import ModuleManager, PluginManager
|
|
from app.sdk.services import NotificationHelper
|
|
from app.sdk.utilities import StringUtils as UtilityStringUtils
|
|
from app.sdk.utilities import decrypt, encrypt
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).parents[1]
|
|
|
|
|
|
def test_sdk_exports_canonical_plugin_interfaces():
|
|
"""SDK 应复用 canonical 对象,不复制实现或制造第二套单例。"""
|
|
from app.domain.context import MediaInfo as CanonicalMediaInfo
|
|
from app.domain.meta.metabase import MetaBase as CanonicalMetaBase
|
|
from app.domain.meta.metamusic import MetaMusic as CanonicalMetaMusic
|
|
from app.domain.metainfo import MetaInfo as CanonicalMetaInfo
|
|
from app.domain.scraper import NfoReader as CanonicalNfoReader
|
|
LegacyDomainStringUtils = importlib.import_module(
|
|
"app.domain.string"
|
|
).StringUtils
|
|
from app.foundation.crypto import CryptoJsUtils
|
|
from app.runtime.extensions.module_manager import ModuleManager as CanonicalModuleManager
|
|
from app.runtime.extensions.plugin_manager import PluginManager as CanonicalPluginManager
|
|
from app.adapters.network.http import RequestUtils as CanonicalRequestUtils
|
|
from app.application.rss import RssHelper as CanonicalRssHelper
|
|
from app.application.site.sites import SitesHelper as CanonicalSitesHelper # pylint: disable=no-name-in-module
|
|
from app.runtime.cache import Cache as CanonicalCache
|
|
from app.runtime.cache import cached as canonical_cached
|
|
from app.runtime.config import settings as canonical_settings
|
|
from app.runtime.events import Event as CanonicalEvent
|
|
from app.runtime.events import eventmanager as canonical_eventmanager
|
|
from app.runtime.log import logger as canonical_logger
|
|
from app.application.notification import NotificationHelper as CanonicalNotificationHelper
|
|
|
|
assert Cache is CanonicalCache
|
|
assert cached is canonical_cached
|
|
assert settings is canonical_settings
|
|
assert Event is CanonicalEvent
|
|
assert eventmanager is canonical_eventmanager
|
|
assert logger is canonical_logger
|
|
assert MediaInfo is CanonicalMediaInfo
|
|
assert MetaBase is CanonicalMetaBase
|
|
assert MetaInfo is CanonicalMetaInfo
|
|
assert MetaMusic is CanonicalMetaMusic
|
|
assert NfoReader is CanonicalNfoReader
|
|
assert RequestUtils is CanonicalRequestUtils
|
|
assert RssHelper is CanonicalRssHelper
|
|
assert SitesHelper is CanonicalSitesHelper
|
|
assert NotificationHelper is CanonicalNotificationHelper
|
|
assert UtilityStringUtils is LegacyDomainStringUtils
|
|
assert decrypt is CryptoJsUtils.decrypt
|
|
assert encrypt is CryptoJsUtils.encrypt
|
|
assert ModuleManager is CanonicalModuleManager
|
|
assert PluginManager is CanonicalPluginManager
|
|
assert CanonicalPluginManager.__module__ == "app.runtime.extensions.plugin_manager"
|
|
|
|
|
|
def test_legacy_common_crypto_aliases_round_trip():
|
|
"""v1 插件使用的 common 加解密符号应保持 CryptoJS 密文兼容。"""
|
|
legacy_common = importlib.import_module("app.utils.common")
|
|
legacy_decrypt = legacy_common.decrypt
|
|
legacy_encrypt = legacy_common.encrypt
|
|
|
|
message = b"moviepilot-plugin-compat"
|
|
passphrase = b"0123456789abcdef"
|
|
|
|
assert legacy_decrypt(legacy_encrypt(message, passphrase), passphrase) == message
|
|
|
|
|
|
def test_browser_sdk_import_is_provider_free():
|
|
"""仅导入浏览器 SDK 不得加载浏览器或虚拟显示实现。"""
|
|
script = """
|
|
import sys
|
|
import app.sdk.browser
|
|
|
|
for name in (
|
|
"cloakbrowser",
|
|
"pyvirtualdisplay",
|
|
"app.adapters.network.browser",
|
|
"app.adapters.system.display.resource",
|
|
):
|
|
assert name not in sys.modules, name
|
|
"""
|
|
result = subprocess.run(
|
|
[sys.executable, "-c", script],
|
|
cwd=PROJECT_ROOT,
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
|
|
assert result.returncode == 0, result.stderr
|
|
|
|
|
|
def test_browser_sdk_delegates_sync_and_async_launch(monkeypatch):
|
|
"""SDK 只转发浏览器参数,不复制宿主生命周期实现。"""
|
|
from app.sdk import browser as browser_sdk
|
|
from app.adapters.network import browser as browser_adapter
|
|
|
|
sync_context = object()
|
|
async_context = object()
|
|
sync_launch = MagicMock(return_value=sync_context)
|
|
async_launch = AsyncMock(return_value=async_context)
|
|
monkeypatch.setattr(browser_adapter, "launch_browser_context", sync_launch)
|
|
monkeypatch.setattr(browser_adapter, "launch_browser_context_async", async_launch)
|
|
|
|
assert browser_sdk.launch_browser_context(headless=False, locale="zh-CN") is sync_context
|
|
|
|
async def run_async():
|
|
return await browser_sdk.launch_browser_context_async(
|
|
headless=True,
|
|
timezone="Asia/Shanghai",
|
|
)
|
|
|
|
import asyncio
|
|
|
|
assert asyncio.run(run_async()) is async_context
|
|
sync_launch.assert_called_once_with(headless=False, locale="zh-CN")
|
|
async_launch.assert_awaited_once_with(
|
|
headless=True,
|
|
timezone="Asia/Shanghai",
|
|
)
|