"""Explicit dev collection does not fabricate upstream approval or perform HTTP.""" from importlib import import_module from unittest.mock import Mock, patch from uuid import UUID import pytest from apps.core.exceptions import ConflictError from apps.core.models import BackgroundJob, JobStatus from apps.parsers.sro_http import SroHttpClient, require_sro_access_approved from core.celery import app as celery_app from django.core.cache import cache from rest_framework.test import APIClient from tests.apps.user.factories import UserFactory @pytest.fixture(autouse=True) def closed_sro_gate(settings): settings.SRO_DEV_COLLECTION_ENABLED = False settings.SRO_UPSTREAM_ACCESS_APPROVED = False settings.SRO_UPSTREAM_APPROVAL_REFERENCE = "" @pytest.fixture def admin_client(db): cache.clear() client = APIClient() client.force_authenticate(UserFactory.create_user(is_staff=True)) return client @pytest.mark.parametrize( "dev_enabled,approved,reference,allowed", ( (False, False, "", False), (False, True, "", False), (False, False, "written approval", False), (False, True, "written approval", True), (True, False, "", True), (True, True, "", True), ), ) def test_gate_keeps_dev_override_separate_from_upstream_approval( settings, dev_enabled, approved, reference, allowed ): settings.SRO_DEV_COLLECTION_ENABLED = dev_enabled settings.SRO_UPSTREAM_ACCESS_APPROVED = approved settings.SRO_UPSTREAM_APPROVAL_REFERENCE = reference if allowed: require_sro_access_approved() else: with pytest.raises(ConflictError) as error: require_sro_access_approved() assert error.value.code == "upstream_access_not_approved" assert settings.SRO_UPSTREAM_ACCESS_APPROVED is approved assert reference == settings.SRO_UPSTREAM_APPROVAL_REFERENCE @pytest.mark.parametrize( "url", ( "/api/v1/sources/sro-membership-check/refresh/", "/api/v1/parsers/run/sro_membership_check/", ), ) @pytest.mark.parametrize("enabled", (False, True)) def test_dev_refresh_entrypoints_enqueue_only_with_explicit_opt_in( admin_client, settings, url, enabled ): settings.SRO_DEV_COLLECTION_ENABLED = enabled import_module("apps.parsers.tasks") task = celery_app.tasks["parsers.sro_membership_check.refresh"] with ( patch.object(task, "apply_async") as dispatch, patch("apps.parsers.sro_http.requests.Session") as http_session, ): response = admin_client.post(url, {}, format="json") http_session.assert_not_called() if not enabled: assert response.status_code == 409 assert response.data["errors"][0]["code"] == "upstream_access_not_approved" assert not BackgroundJob.objects.exists() dispatch.assert_not_called() return assert response.status_code == 202 payload = response.data.get("data", response.data) assert payload["status"] == "queued" assert payload["task_ids"] == [payload["task_id"]] assert str(UUID(payload["task_id"])) == payload["task_id"] job = BackgroundJob.objects.get(task_id=payload["task_id"]) assert job.status == JobStatus.PENDING assert job.task_name == "parsers.sro_membership_check.refresh" dispatch.assert_called_once() assert settings.SRO_UPSTREAM_ACCESS_APPROVED is False assert settings.SRO_UPSTREAM_APPROVAL_REFERENCE == "" def test_dev_http_client_uses_neutral_user_agent(settings): settings.SRO_DEV_COLLECTION_ENABLED = True session = Mock(headers={}) with patch("apps.parsers.sro_http.requests.Session", return_value=session): client = SroHttpClient() client.close() assert session.headers["User-Agent"] == "Mostovik SRO integration" assert session.trust_env is False session.get.assert_not_called() session.close.assert_called_once() def test_revoking_dev_override_stops_before_http(settings): settings.SRO_DEV_COLLECTION_ENABLED = True session = Mock() client = SroHttpClient(session=session) settings.SRO_DEV_COLLECTION_ENABLED = False with pytest.raises(ConflictError) as error: client.get("https://reestr-sro.ru/") assert error.value.code == "upstream_access_not_approved" session.get.assert_not_called()