Files
mostovik-backend/tests/apps/parsers/test_sro_dev_access.py
Aleksandr Meshchryakov 3d7fb78678
All checks were successful
Mostovik Backend CI/CD / Tests and lint (push) Successful in 3m12s
Mostovik Backend CI/CD / Build linux/amd64 release images (push) Successful in 4m0s
Mostovik Backend CI/CD / Deploy and verify internal main (push) Has been skipped
Mostovik Backend CI/CD / Deploy customer main (push) Has been skipped
Mostovik Backend CI/CD / Deploy dev (push) Successful in 2m44s
fix: enable dev SRO collection and handle real lookup responses
2026-09-15 12:47:16 +02:00

120 lines
4.2 KiB
Python

"""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()