mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 15:38:19 +08:00
refactor(transfer): complete durable recovery state machine
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import threading
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import Mock
|
||||
|
||||
from app.application.transfer.execution import TransferExecutionCheckpoint
|
||||
from app.application.transfer.workflow import TransferTask
|
||||
from app.chain.transfer import TransferChain
|
||||
from app.domain.context import MediaInfo
|
||||
@@ -76,6 +79,43 @@ def test_transfer_stops_when_automatic_category_has_no_tmdb_result(monkeypatch)
|
||||
"""启用自动类别目录时,缺少 TMDB 分类必须在文件操作前明确失败。"""
|
||||
chain = object.__new__(TransferChain)
|
||||
chain.jobview = SimpleNamespace(try_remove_job=lambda _task: None)
|
||||
chain._transfer_admissions = Mock()
|
||||
chain._worker_owner_id = "category-owner"
|
||||
chain._owned_leases = {
|
||||
"task-before-category": ("lease-before-category", float("inf"))
|
||||
}
|
||||
chain._worker_state_lock = threading.RLock()
|
||||
chain.durable_event_writer = Mock()
|
||||
chain.runtime_config = SimpleNamespace(
|
||||
scrape_follow_tmdb=True,
|
||||
ai_agent_enable=True,
|
||||
ai_agent_retry_transfer=True,
|
||||
)
|
||||
chain.queue_failed_transfer_notification = Mock()
|
||||
chain._TransferChain__mark_torrent_completed_if_done = Mock()
|
||||
record_transfer_failure = Mock()
|
||||
add_transfer_fail = Mock()
|
||||
monkeypatch.setattr(
|
||||
"app.chain.transfer.record_transfer_failure",
|
||||
record_transfer_failure,
|
||||
)
|
||||
monkeypatch.setattr("app.chain.transfer.add_transfer_fail", add_transfer_fail)
|
||||
chain._transfer_admissions.checkpoint_plan.side_effect = (
|
||||
lambda **kwargs: SimpleNamespace(checkpoint=kwargs["checkpoint"])
|
||||
)
|
||||
step_runner = Mock()
|
||||
step_runner.checkpoint.side_effect = lambda transferinfo: (
|
||||
TransferExecutionCheckpoint.create(
|
||||
payload={
|
||||
"outcome": "failed",
|
||||
"transferinfo": transferinfo.model_dump(mode="json"),
|
||||
},
|
||||
operation_ids=("planning-reject",),
|
||||
)
|
||||
)
|
||||
chain._TransferChain__build_durable_step_runner = Mock(
|
||||
return_value=step_runner
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"app.chain.transfer.get_chain_transfer_history_port",
|
||||
lambda: SimpleNamespace(),
|
||||
@@ -114,7 +154,12 @@ def test_transfer_stops_when_automatic_category_has_no_tmdb_result(monkeypatch)
|
||||
library_category_folder=True,
|
||||
),
|
||||
library_category_folder=True,
|
||||
preview=True,
|
||||
preview=False,
|
||||
)
|
||||
task.bind_admission_task_id("task-before-category")
|
||||
task.bind_execution_lease(
|
||||
owner_id="category-owner",
|
||||
lease_token="lease-before-category",
|
||||
)
|
||||
|
||||
state, message = chain._TransferChain__handle_transfer(task)
|
||||
@@ -123,3 +168,11 @@ def test_transfer_stops_when_automatic_category_has_no_tmdb_result(monkeypatch)
|
||||
assert message == "未识别到 TMDB 辅助信息,无法按媒体类别整理"
|
||||
assert task.mediainfo.media_source == MediaSource.AniList
|
||||
assert task.mediainfo.media_id == "1234"
|
||||
assert task.plan_checkpoint is not None
|
||||
assert task.plan_checkpoint.rejection_error == message
|
||||
assert task.execution_checkpoint is not None
|
||||
chain._transfer_admissions.record_planning_failure.assert_not_called()
|
||||
record_transfer_failure.assert_not_called()
|
||||
add_transfer_fail.assert_not_called()
|
||||
chain.queue_failed_transfer_notification.assert_not_called()
|
||||
chain._TransferChain__mark_torrent_completed_if_done.assert_not_called()
|
||||
|
||||
Reference in New Issue
Block a user