refactor(tradein/admin): debug sweep endpoints на kit orchestration (#2397 slice A) #2400

Merged
lekss361 merged 2 commits from refactor/tradein-admin-debug-sweeps-to-kit into main 2026-07-04 09:16:58 +00:00
4 changed files with 62 additions and 9 deletions
Showing only changes of commit d0b011d388 - Show all commits

View file

@ -717,12 +717,14 @@ def test_cian_start_endpoint_validates_delay_too_low(app_with_admin) -> None:
def test_cian_start_endpoint_ok(app_with_admin) -> None:
"""Valid request → 200, run_id в ответе."""
"""Valid request → 200, run_id; kit sweep вызван с DI (config/matcher, БЕЗ enrichment)."""
from unittest.mock import AsyncMock, patch
from app.services.scraper_adapters import RealMatcherAdapter, RealScraperConfig
with (
patch("app.services.scrape_runs.create_run", return_value=42),
patch("app.services.scrape_pipeline.run_cian_city_sweep", new_callable=AsyncMock),
patch("app.api.v1.admin.run_cian_city_sweep", new_callable=AsyncMock) as mock_sweep,
):
r = app_with_admin.post(
"/api/v1/admin/scrape/cian-city-sweep",
@ -735,6 +737,13 @@ def test_cian_start_endpoint_ok(app_with_admin) -> None:
assert body["pages_per_anchor"] == 2
assert body["detail_top_n"] == 5
mock_sweep.assert_called_once()
kw = mock_sweep.call_args.kwargs
assert isinstance(kw["config"], RealScraperConfig)
assert isinstance(kw["matcher"], RealMatcherAdapter)
assert "proxy_provider" in kw
assert "enrichment" not in kw
def test_cian_cancel_endpoint(app_with_admin) -> None:
"""Cancel endpoint возвращает run_id + cancelled=True."""

View file

@ -313,11 +313,17 @@ def test_start_endpoint_validates_request_delay_too_low(app_with_admin) -> None:
def test_start_endpoint_ok(app_with_admin) -> None:
"""Valid request → 200, run_id в ответе."""
"""Valid request → 200, run_id в ответе; kit sweep вызван с DI (config/matcher/enrichment)."""
from app.services.scraper_adapters import (
RealEnrichmentJobs,
RealMatcherAdapter,
RealScraperConfig,
)
with (
patch("app.api.v1.admin.has_running_run", return_value=False),
patch("app.services.scrape_runs.create_run", return_value=7),
patch("app.services.scrape_pipeline.run_avito_city_sweep", new_callable=AsyncMock),
patch("app.api.v1.admin.run_avito_city_sweep", new_callable=AsyncMock) as mock_sweep,
):
r = app_with_admin.post(
"/api/v1/admin/scrape/avito-city-sweep",
@ -329,6 +335,13 @@ def test_start_endpoint_ok(app_with_admin) -> None:
assert body["status"] == "running"
assert body["pages_per_anchor"] == 2
mock_sweep.assert_called_once()
kw = mock_sweep.call_args.kwargs
assert isinstance(kw["config"], RealScraperConfig)
assert isinstance(kw["matcher"], RealMatcherAdapter)
assert isinstance(kw["enrichment"], RealEnrichmentJobs)
assert "proxy_provider" in kw
def test_cancel_endpoint_exists(app_with_admin) -> None:
"""Cancel endpoint returns run_id + cancelled flag."""

View file

@ -453,14 +453,24 @@ def test_city_sweep_start_request_enrich_imv_false() -> None:
def test_sweep_endpoint_passes_enrich_imv(app_with_admin) -> None:
"""POST /scrape/avito-city-sweep с enrich_imv=False → sweep вызывается без IMV."""
"""POST /scrape/avito-city-sweep с enrich_imv=False → sweep вызывается без IMV.
kit sweep вызван с DI (config/matcher/enrichment) mock должен перехватывать
имя, забинженное в app.api.v1.admin (kit-импорт), не устаревший scrape_pipeline.
"""
from app.services.scraper_adapters import (
RealEnrichmentJobs,
RealMatcherAdapter,
RealScraperConfig,
)
with (
patch("app.api.v1.admin.has_running_run", return_value=False),
patch("app.services.scrape_runs.create_run", return_value=42),
patch(
"app.services.scrape_pipeline.run_avito_city_sweep",
"app.api.v1.admin.run_avito_city_sweep",
new_callable=AsyncMock,
),
) as mock_sweep,
):
r = app_with_admin.post(
"/api/v1/admin/scrape/avito-city-sweep",
@ -470,6 +480,14 @@ def test_sweep_endpoint_passes_enrich_imv(app_with_admin) -> None:
body = r.json()
assert body["run_id"] == 42
mock_sweep.assert_called_once()
kw = mock_sweep.call_args.kwargs
assert isinstance(kw["config"], RealScraperConfig)
assert isinstance(kw["matcher"], RealMatcherAdapter)
assert isinstance(kw["enrichment"], RealEnrichmentJobs)
assert "proxy_provider" in kw
assert kw["enrich_imv"] is False
@pytest.fixture
def app_with_admin():

View file

@ -623,12 +623,18 @@ def test_yandex_start_endpoint_validates_delay_too_low(app_with_admin) -> None:
def test_yandex_start_endpoint_ok(app_with_admin) -> None:
"""Valid request → 200, run_id в ответе."""
"""Valid request → 200, run_id в ответе; kit sweep вызван с DI (config/matcher/enrichment)."""
from unittest.mock import patch
from app.services.scraper_adapters import (
RealEnrichmentJobs,
RealMatcherAdapter,
RealScraperConfig,
)
with (
patch("app.services.scrape_runs.create_run", return_value=55),
patch("app.services.scrape_pipeline.run_yandex_city_sweep", new_callable=AsyncMock),
patch("app.api.v1.admin.run_yandex_city_sweep", new_callable=AsyncMock) as mock_sweep,
):
r = app_with_admin.post(
"/api/v1/admin/scrape/yandex-city-sweep",
@ -641,6 +647,13 @@ def test_yandex_start_endpoint_ok(app_with_admin) -> None:
assert body["pages_per_anchor"] == 2
assert body["detail_top_n"] == 0
mock_sweep.assert_called_once()
kw = mock_sweep.call_args.kwargs
assert isinstance(kw["config"], RealScraperConfig)
assert isinstance(kw["matcher"], RealMatcherAdapter)
assert isinstance(kw["enrichment"], RealEnrichmentJobs)
assert "proxy_provider" in kw
def test_yandex_cancel_endpoint(app_with_admin) -> None:
"""Cancel endpoint возвращает run_id + cancelled=True."""