fix: enable dev SRO collection and handle real lookup responses
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
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
This commit is contained in:
119
tests/apps/parsers/test_sro_dev_access.py
Normal file
119
tests/apps/parsers/test_sro_dev_access.py
Normal file
@@ -0,0 +1,119 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user