Files
ss-tools/backend/tests/plugins/translate/test_orchestrator_runner.py

87 lines
3.5 KiB
Python

# #region Test.OrchestratorRunner [C:3] [TYPE Module] [SEMANTICS test, translate, runner, execution]
# @BRIEF Tests for orchestrator_runner.py — TranslationStageRunner delegates to sub-components.
# @RELATION BINDS_TO -> [TranslationStageRunner]
# @TEST_CONTRACT: execute_run -> TranslationRun | delegates to TranslationExecutionEngine
# @TEST_CONTRACT: retry_failed_batches -> TranslationRun | delegates to TranslationRunRetryManager
# @TEST_CONTRACT: retry_insert -> TranslationRun | delegates to TranslationRunRetryManager
# @TEST_CONTRACT: cancel_run -> TranslationRun | delegates to TranslationRunRetryManager
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / "src"))
import os
os.environ.setdefault("SECRET_KEY", "test-secret-key-for-testing")
os.environ.setdefault("DATABASE_URL", "sqlite:///:memory:")
os.environ.setdefault("AUTH_DATABASE_URL", "sqlite:///:memory:")
from unittest.mock import MagicMock, AsyncMock, patch
import pytest
from src.plugins.translate.orchestrator_runner import TranslationStageRunner
class TestTranslationStageRunner:
"""TranslationStageRunner — delegates to sub-components."""
def _make_runner(self) -> tuple[TranslationStageRunner, MagicMock, MagicMock]:
"""Create a runner with mocked sub-components."""
db = MagicMock()
config_manager = MagicMock()
event_log = MagicMock()
with patch(
"src.plugins.translate.orchestrator_runner.TranslationExecutionEngine"
) as MockExec, patch(
"src.plugins.translate.orchestrator_runner.TranslationRunRetryManager"
) as MockRetry:
runner = TranslationStageRunner(db, config_manager, event_log, "user")
mock_exec = MockExec.return_value
mock_retry = MockRetry.return_value
return runner, mock_exec, mock_retry
@pytest.mark.asyncio
async def test_execute_run_delegates(self):
"""execute_run delegates to TranslationExecutionEngine."""
runner, mock_exec, _ = self._make_runner()
mock_run = MagicMock()
mock_exec.execute_run = AsyncMock(return_value=mock_run)
result = await runner.execute_run(mock_run, on_batch_progress=None, skip_insert=False)
mock_exec.execute_run.assert_called_once_with(
run=mock_run, on_batch_progress=None, skip_insert=False,
)
assert result == mock_run
@pytest.mark.asyncio
async def test_retry_failed_batches_delegates(self):
"""retry_failed_batches delegates to TranslationRunRetryManager."""
runner, _, mock_retry = self._make_runner()
mock_retry.retry_failed_batches = AsyncMock(return_value=MagicMock())
result = await runner.retry_failed_batches("run-1")
mock_retry.retry_failed_batches.assert_called_once_with("run-1")
@pytest.mark.asyncio
async def test_retry_insert_delegates(self):
"""retry_insert delegates to TranslationRunRetryManager."""
runner, _, mock_retry = self._make_runner()
mock_retry.retry_insert = AsyncMock(return_value=MagicMock())
result = await runner.retry_insert("run-1")
mock_retry.retry_insert.assert_called_once_with("run-1")
def test_cancel_run_delegates(self):
"""cancel_run delegates to TranslationRunRetryManager."""
runner, _, mock_retry = self._make_runner()
mock_retry.cancel_run.return_value = MagicMock()
result = runner.cancel_run("run-1")
mock_retry.cancel_run.assert_called_once_with("run-1")
# #endregion Test.OrchestratorRunner