feat: migrate parser data to source records
Some checks failed
CI/CD Pipeline / Quality Gate (push) Failing after 14s
CI/CD Pipeline / Build and Push Images (push) Has been skipped
CI/CD Pipeline / Deploy Dev in Dokploy (push) Has been skipped
CI/CD Pipeline / Internal Notify (push) Successful in 0s

This commit is contained in:
2026-05-19 20:21:31 +02:00
parent 1c7c7238be
commit b8a18d6da4
46 changed files with 2689 additions and 6179 deletions

View File

@@ -12,8 +12,10 @@ from apps.parsers.source_cards import (
SourceCardService,
SourceItemDefinition,
)
from django.db import connection
from django.http import Http404
from django.test import SimpleTestCase, TestCase, override_settings
from django.test.utils import CaptureQueriesContext
from django.utils import timezone
from organizations.source_ingestion import (
OrganizationSourceIngestionService,
@@ -390,6 +392,9 @@ class SourceCardServiceUnitTest(SimpleTestCase):
@override_settings(PARSER_STALE_LOAD_MAX_AGE_MINUTES=90)
class SourceCardServiceDatabaseTest(TestCase):
def setUp(self):
SourceCardService.clear_cache()
def test_defense_unreliable_suppliers_counts_unique_generic_organizations(self):
_save_source_record(
source=ParserLoadLog.Source.UNFAIR_SUPPLIERS,
@@ -494,6 +499,82 @@ class SourceCardServiceDatabaseTest(TestCase):
self.assertEqual(source_items["procurements_223fz"]["organizations_count"], 1)
self.assertEqual(source_items["contracts"]["organizations_count"], 1)
def test_list_cards_uses_batched_aggregations(self):
_save_source_record(
source=ParserLoadLog.Source.PROCUREMENTS_44FZ,
external_id="notice-1",
inn="7701234567",
organization_name="ГБУ Заказчик",
title="Закупка 44-ФЗ",
)
_save_source_record(
source=ParserLoadLog.Source.CONTRACTS,
external_id="contract-1",
inn="7701234567",
organization_name="ГБУ Заказчик",
title="Контракт ЕИС",
)
ParserLoadLog.objects.create(
source=ParserLoadLog.Source.PROCUREMENTS_44FZ,
batch_id=1,
records_count=1,
status=ParserLoadLog.Status.SUCCESS,
)
ParserLoadLog.objects.create(
source=ParserLoadLog.Source.CONTRACTS,
batch_id=1,
records_count=1,
status=ParserLoadLog.Status.SUCCESS,
)
with CaptureQueriesContext(connection) as captured:
cards = SourceCardService.list_cards()
self.assertLessEqual(len(captured), 7)
procurements_card = next(
card for card in cards if card["slug"] == "public-procurements"
)
self.assertEqual(procurements_card["records_count"], 2)
self.assertEqual(procurements_card["organizations_count"], 1)
def test_list_cards_reuses_cached_aggregate_stats(self):
_save_source_record(
source=ParserLoadLog.Source.PROCUREMENTS_44FZ,
external_id="notice-1",
inn="7701234567",
organization_name="ГБУ Заказчик",
title="Закупка 44-ФЗ",
)
SourceCardService.list_cards()
with CaptureQueriesContext(connection) as captured:
cards = SourceCardService.list_cards()
self.assertLessEqual(len(captured), 2)
procurements_card = next(
card for card in cards if card["slug"] == "public-procurements"
)
self.assertEqual(procurements_card["records_count"], 1)
def test_ingestion_invalidates_source_card_aggregate_cache(self):
SourceCardService.list_cards()
_save_source_record(
source=ParserLoadLog.Source.PROCUREMENTS_44FZ,
external_id="notice-1",
inn="7701234567",
organization_name="ГБУ Заказчик",
title="Закупка 44-ФЗ",
)
cards = SourceCardService.list_cards()
procurements_card = next(
card for card in cards if card["slug"] == "public-procurements"
)
self.assertEqual(procurements_card["records_count"], 1)
def test_get_active_tasks_ignores_old_jobs_even_when_updated_recently(self):
job = BackgroundJob.objects.create(
task_id="old-source-task",