"""Фикстуры unit-тестов: окружение воркера шлюза `make_env` (обвязка — `tests/worker_helpers.py`).""" import json from collections.abc import AsyncIterator, Awaitable, Callable from datetime import datetime from pathlib import Path from typing import Any import pytest from src.core.config import get_settings from src.core.nats import NatsGateway from src.core.worker import Worker from src.gateway.hotfolder import LocalHotFolder from src.normalizer import NullNormalizer from tests.worker_helpers import SUCCESS_ANSWER, Env, EnvFactory, FakeNatsClient, FakeStorage, SpyHotFolder @pytest.fixture async def make_env(tmp_path: Path) -> AsyncIterator[EnvFactory]: """Фабрика окружений воркера на `tmp_path`: настройки — `get_settings()` с короткими опросом и тайм-аутом (`**overrides` — поверх), подмены `normalizer`, `clock`, `sleep` (пауза между опросами горячей папки). Воркер запущен (`start()`); после теста все созданные воркеры останавливаются. """ created: list[Env] = [] async def build( *, normalizer: Any = None, root_exists: bool = True, clock: Callable[[], datetime] | None = None, sleep: Callable[[float], Awaitable[None]] | None = None, **overrides: Any, ) -> Env: root = tmp_path / f"hotfolder-{len(created)}" if root_exists: root.mkdir() fixtures = tmp_path / "fixtures" fixtures.mkdir(exist_ok=True) (fixtures / "ok_doc.json").write_text(json.dumps(SUCCESS_ANSWER, ensure_ascii=False), encoding="utf-8") settings = get_settings().model_copy( update={ "SCAN_HOTFOLDER_PATH": str(root), "SCAN_POLL_SECONDS": 0.01, "SCAN_TIMEOUT_SECONDS": 5, "SCAN_SETTLE_SECONDS": 0, # R-23: набор ответа готов сразу, тесты не ждут стабилизации "PUBLISH_RETRIES": 1, **overrides, } ) events: list[tuple[str, str]] = [] storage = FakeStorage(events) client = FakeNatsClient(events) gateway = NatsGateway(settings, client_factory=lambda: client, retry_delay=0) await gateway.connect() local = LocalHotFolder( root, settings.SCAN_INPUT_DIR, settings.SCAN_OUTPUT_DIR, settings.SCAN_TMP_DIR, settle_seconds=settings.SCAN_SETTLE_SECONDS, ) hotfolder = SpyHotFolder(local, events) kwargs: dict[str, Any] = {} if clock is not None: kwargs["clock"] = clock if sleep is not None: kwargs["sleep"] = sleep worker = Worker( settings, storage=storage, publisher=gateway, hotfolder=hotfolder, normalizer=normalizer or NullNormalizer(), **kwargs, ) worker.start() env = Env(settings, root, fixtures, events, storage, client, gateway, hotfolder, worker) created.append(env) return env yield build for env in created: await env.worker.stop()