diff --git a/tradein-mvp/backend/tests/test_cian_city_sweep.py b/tradein-mvp/backend/tests/test_cian_city_sweep.py index 2c839d4c..9b84de47 100644 --- a/tradein-mvp/backend/tests/test_cian_city_sweep.py +++ b/tradein-mvp/backend/tests/test_cian_city_sweep.py @@ -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.""" diff --git a/tradein-mvp/backend/tests/test_city_sweep.py b/tradein-mvp/backend/tests/test_city_sweep.py index 2dbfae1e..31684af7 100644 --- a/tradein-mvp/backend/tests/test_city_sweep.py +++ b/tradein-mvp/backend/tests/test_city_sweep.py @@ -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.""" diff --git a/tradein-mvp/backend/tests/test_sweep_imv_phase.py b/tradein-mvp/backend/tests/test_sweep_imv_phase.py index 7b501727..7a577320 100644 --- a/tradein-mvp/backend/tests/test_sweep_imv_phase.py +++ b/tradein-mvp/backend/tests/test_sweep_imv_phase.py @@ -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(): diff --git a/tradein-mvp/backend/tests/test_yandex_city_sweep.py b/tradein-mvp/backend/tests/test_yandex_city_sweep.py index 3eeaa61a..32b31898 100644 --- a/tradein-mvp/backend/tests/test_yandex_city_sweep.py +++ b/tradein-mvp/backend/tests/test_yandex_city_sweep.py @@ -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."""