feat: restore registry procurement collection
This commit is contained in:
252
tests/apps/parsers/test_registry_procurement_tasks.py
Normal file
252
tests/apps/parsers/test_registry_procurement_tasks.py
Normal file
@@ -0,0 +1,252 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from contextlib import ExitStack
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import patch
|
||||
|
||||
from apps.parsers import tasks as parser_tasks
|
||||
from apps.parsers.clients.common.schemas import GenericParserItem
|
||||
from apps.parsers.models import CheckoCollectionAttempt, ParserLoadLog
|
||||
from django.test import TestCase, override_settings
|
||||
|
||||
from tests.apps.parsers.organization_helpers import create_directory_organization
|
||||
|
||||
|
||||
def _organization(index: int, *, membership: bool = True):
|
||||
return create_directory_organization(
|
||||
name=f"Организация {index}",
|
||||
inn=f"7701000{index:03d}",
|
||||
ogrn=f"1027700000{index:03d}",
|
||||
opk_registry_membership=membership,
|
||||
)
|
||||
|
||||
|
||||
class RegistryProcurementTasksTest(TestCase):
|
||||
def test_daily_orchestrator_queues_addressed_sources_with_same_batch_limit(self):
|
||||
task_names = (
|
||||
"parse_procurements_44fz",
|
||||
"parse_procurements_223fz",
|
||||
"parse_registry_contracts",
|
||||
"parse_unfair_suppliers",
|
||||
"parse_arbitration_cases",
|
||||
"parse_fedresurs_bankruptcy",
|
||||
"parse_registry_inspections",
|
||||
"parse_trudvsem_vacancies",
|
||||
)
|
||||
with ExitStack() as stack:
|
||||
mocks = [
|
||||
stack.enter_context(
|
||||
patch.object(
|
||||
getattr(parser_tasks, task_name),
|
||||
"delay",
|
||||
return_value=SimpleNamespace(id=f"{task_name}-id"),
|
||||
)
|
||||
)
|
||||
for task_name in task_names
|
||||
]
|
||||
result = parser_tasks.parse_registry_enrichment_sources(
|
||||
limit=20,
|
||||
proxies=[],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
set(result),
|
||||
{
|
||||
"procurements_44fz",
|
||||
"procurements_223fz",
|
||||
"contracts",
|
||||
"unfair_suppliers",
|
||||
"arbitration",
|
||||
"bankruptcy",
|
||||
"inspections",
|
||||
"vacancies",
|
||||
},
|
||||
)
|
||||
for task_mock in mocks[:5]:
|
||||
task_mock.assert_called_once_with(
|
||||
proxies=[],
|
||||
requested_by_id=None,
|
||||
limit=20,
|
||||
)
|
||||
mocks[5].assert_called_once_with(proxies=[], requested_by_id=None)
|
||||
mocks[6].assert_called_once_with(proxies=[], requested_by_id=None, limit=20)
|
||||
mocks[7].assert_called_once_with(proxies=[], requested_by_id=None)
|
||||
|
||||
def test_eis_monthly_claims_advance_to_the_next_batch(self):
|
||||
organizations = [_organization(index) for index in range(1, 4)]
|
||||
outside_registry = _organization(9, membership=False)
|
||||
requested_inns: list[str] = []
|
||||
|
||||
class _Client:
|
||||
def __init__(self, **_kwargs):
|
||||
return
|
||||
|
||||
def fetch_for_customer(self, **kwargs):
|
||||
requested_inns.append(kwargs["inn"])
|
||||
return [
|
||||
GenericParserItem(
|
||||
source=ParserLoadLog.Source.PROCUREMENTS_44FZ,
|
||||
external_id=f"notice-{kwargs['inn']}",
|
||||
inn=kwargs["inn"],
|
||||
organisation_name=kwargs["organization_name"],
|
||||
)
|
||||
]
|
||||
|
||||
with patch.object(parser_tasks, "EisRegistryProcurementClient", _Client):
|
||||
first = parser_tasks._fetch_eis_registry_procurement_records(
|
||||
source=ParserLoadLog.Source.PROCUREMENTS_44FZ,
|
||||
law="44",
|
||||
limit=2,
|
||||
proxies=[],
|
||||
)
|
||||
second = parser_tasks._fetch_eis_registry_procurement_records(
|
||||
source=ParserLoadLog.Source.PROCUREMENTS_44FZ,
|
||||
law="44",
|
||||
limit=2,
|
||||
proxies=[],
|
||||
)
|
||||
|
||||
self.assertEqual(len(first), 2)
|
||||
self.assertEqual(len(second), 1)
|
||||
self.assertEqual(requested_inns, [item.inn for item in organizations])
|
||||
self.assertNotIn(outside_registry.inn, requested_inns)
|
||||
self.assertEqual(
|
||||
CheckoCollectionAttempt.objects.filter(
|
||||
source=CheckoCollectionAttempt.Source.PROCUREMENTS_44FZ,
|
||||
status=CheckoCollectionAttempt.Status.SUCCESS,
|
||||
).count(),
|
||||
3,
|
||||
)
|
||||
|
||||
def test_eis_request_error_creates_failed_monthly_claim(self):
|
||||
organization = _organization(1)
|
||||
|
||||
class _Client:
|
||||
def __init__(self, **_kwargs):
|
||||
return
|
||||
|
||||
def fetch_for_customer(self, **_kwargs):
|
||||
raise parser_tasks.HTTPClientError("EIS unavailable")
|
||||
|
||||
with (
|
||||
patch.object(parser_tasks, "EisRegistryProcurementClient", _Client),
|
||||
self.assertRaises(parser_tasks.ParserSourceSkipped),
|
||||
):
|
||||
parser_tasks._fetch_eis_registry_procurement_records(
|
||||
source=ParserLoadLog.Source.PROCUREMENTS_223FZ,
|
||||
law="223",
|
||||
limit=1,
|
||||
proxies=[],
|
||||
)
|
||||
|
||||
attempt = CheckoCollectionAttempt.objects.get(
|
||||
organization=organization,
|
||||
source=CheckoCollectionAttempt.Source.PROCUREMENTS_223FZ,
|
||||
)
|
||||
self.assertEqual(attempt.status, CheckoCollectionAttempt.Status.FAILED)
|
||||
|
||||
def test_explicit_organization_ids_do_not_fall_through_to_next_batch(self):
|
||||
selected = _organization(1)
|
||||
_organization(2)
|
||||
calls: list[str] = []
|
||||
|
||||
class _Client:
|
||||
def __init__(self, **_kwargs):
|
||||
return
|
||||
|
||||
def fetch_for_customer(self, **kwargs):
|
||||
calls.append(kwargs["inn"])
|
||||
return []
|
||||
|
||||
kwargs = {
|
||||
"source": ParserLoadLog.Source.PROCUREMENTS_44FZ,
|
||||
"law": "44",
|
||||
"limit": 20,
|
||||
"proxies": [],
|
||||
"organization_ids": [str(selected.uid)],
|
||||
}
|
||||
with patch.object(parser_tasks, "EisRegistryProcurementClient", _Client):
|
||||
self.assertEqual(
|
||||
parser_tasks._fetch_eis_registry_procurement_records(**kwargs),
|
||||
[],
|
||||
)
|
||||
with self.assertRaises(parser_tasks.ParserSourceSkipped):
|
||||
parser_tasks._fetch_eis_registry_procurement_records(**kwargs)
|
||||
|
||||
self.assertEqual(calls, [selected.inn])
|
||||
|
||||
@override_settings(CHECKO_API_KEY="test-key")
|
||||
def test_checko_rnp_is_supplier_bound_and_not_requested_twice(self):
|
||||
organization = _organization(1)
|
||||
calls: list[str] = []
|
||||
|
||||
class _Client:
|
||||
def __init__(self, **_kwargs):
|
||||
return
|
||||
|
||||
def get_company(self, request):
|
||||
calls.append(request.inn)
|
||||
return SimpleNamespace(
|
||||
data=SimpleNamespace(
|
||||
inn=organization.inn,
|
||||
ogrn=organization.ogrn,
|
||||
unfair_supplier=(
|
||||
SimpleNamespace(
|
||||
registry_number="RNP-1",
|
||||
publish_date="2026-07-01",
|
||||
approval_date="2026-06-30",
|
||||
customer_short_name="Заказчик",
|
||||
customer_full_name="Заказчик полный",
|
||||
customer_inn="7702000002",
|
||||
customer_kpp="770201001",
|
||||
purchase_number="PURCHASE-1",
|
||||
purchase_description="Поставка оборудования",
|
||||
contract_price=1500000,
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
with patch.object(parser_tasks, "CheckoClient", _Client):
|
||||
records = parser_tasks._fetch_checko_unfair_supplier_records(
|
||||
limit=1,
|
||||
proxies=[],
|
||||
)
|
||||
with self.assertRaises(parser_tasks.ParserSourceSkipped):
|
||||
parser_tasks._fetch_checko_unfair_supplier_records(
|
||||
limit=1,
|
||||
proxies=[],
|
||||
)
|
||||
|
||||
self.assertEqual(calls, [organization.inn])
|
||||
self.assertEqual(len(records), 1)
|
||||
self.assertEqual(records[0].inn, organization.inn)
|
||||
self.assertEqual(records[0].payload["supplier"]["inn"], organization.inn)
|
||||
self.assertEqual(records[0].payload["customer"]["inn"], "7702000002")
|
||||
self.assertEqual(records[0].amount, 1500000)
|
||||
|
||||
@override_settings(CHECKO_API_KEY="test-key")
|
||||
def test_checko_rnp_api_error_creates_failed_monthly_claim(self):
|
||||
organization = _organization(1)
|
||||
|
||||
class _Client:
|
||||
def __init__(self, **_kwargs):
|
||||
return
|
||||
|
||||
def get_company(self, _request):
|
||||
raise parser_tasks.CheckoError("Checko unavailable")
|
||||
|
||||
with (
|
||||
patch.object(parser_tasks, "CheckoClient", _Client),
|
||||
self.assertRaises(parser_tasks.ParserSourceSkipped),
|
||||
):
|
||||
parser_tasks._fetch_checko_unfair_supplier_records(
|
||||
limit=1,
|
||||
proxies=[],
|
||||
)
|
||||
|
||||
attempt = CheckoCollectionAttempt.objects.get(
|
||||
organization=organization,
|
||||
source=CheckoCollectionAttempt.Source.UNFAIR_SUPPLIERS,
|
||||
)
|
||||
self.assertEqual(attempt.status, CheckoCollectionAttempt.Status.FAILED)
|
||||
Reference in New Issue
Block a user