"""Тесты для POST /admin/scrape/ekburg-permits. Проверяет: - валидный запрос без year → scope all_years_2022_2026, task_id в ответе - валидный запрос с year=2026 → scope year_2026 - year < 2022 или > 2030 → 422 - отсутствие X-Admin-Token → 401/503 """ from __future__ import annotations from unittest.mock import MagicMock, patch import pytest from fastapi.testclient import TestClient from app.main import app ADMIN_TOKEN = "test-admin-token" ADMIN_HEADERS = {"X-Admin-Token": ADMIN_TOKEN} ENDPOINT = "/api/v1/admin/scrape/ekburg-permits" def _mock_task(task_id: str = "fake-task-id-123") -> MagicMock: result = MagicMock() result.id = task_id return result @patch("app.core.config.settings.scrape_admin_token", ADMIN_TOKEN) def test_trigger_refresh_all_returns_task_id() -> None: """POST без year → refresh_all queued, scope=all_years_2022_2026.""" mock_result = _mock_task("task-all-001") with ( patch("app.workers.tasks.ekburg_permits_sync.refresh_all") as mock_refresh_all, patch("app.workers.tasks.ekburg_permits_sync.refresh_year"), ): mock_refresh_all.apply_async.return_value = mock_result client = TestClient(app) response = client.post(ENDPOINT, json={}, headers=ADMIN_HEADERS) assert response.status_code == 200, response.text body = response.json() assert body["task_id"] == "task-all-001" assert body["scope"] == "all_years_2022_2026" assert "queued_at" in body @patch("app.core.config.settings.scrape_admin_token", ADMIN_TOKEN) def test_trigger_refresh_year_returns_task_id() -> None: """POST year=2026 → refresh_year queued, scope=year_2026.""" mock_result = _mock_task("task-year-002") with ( patch("app.workers.tasks.ekburg_permits_sync.refresh_year") as mock_refresh_year, patch("app.workers.tasks.ekburg_permits_sync.refresh_all"), ): mock_refresh_year.apply_async.return_value = mock_result client = TestClient(app) response = client.post(ENDPOINT, json={"year": 2026}, headers=ADMIN_HEADERS) assert response.status_code == 200, response.text body = response.json() assert body["task_id"] == "task-year-002" assert body["scope"] == "year_2026" @pytest.mark.parametrize("bad_year", [2021, 2031, 1999, 9999]) @patch("app.core.config.settings.scrape_admin_token", ADMIN_TOKEN) def test_trigger_invalid_year_returns_422(bad_year: int) -> None: """year вне диапазона [2022, 2030] → 422 Unprocessable Entity.""" client = TestClient(app) response = client.post(ENDPOINT, json={"year": bad_year}, headers=ADMIN_HEADERS) assert response.status_code == 422, f"year={bad_year} должен возвращать 422" def test_trigger_no_token_returns_401_or_503() -> None: """Без X-Admin-Token → 401 или 503.""" client = TestClient(app) response = client.post(ENDPOINT, json={}) assert response.status_code in (401, 503), response.text