feat: update finance exchange and source refresh jobs
All checks were successful
CI/CD Pipeline / Quality Gate (push) Successful in 31s
CI/CD Pipeline / Build and Push Images (push) Successful in 34s
CI/CD Pipeline / Internal Notify (push) Successful in 0s
CI/CD Pipeline / Deploy Dev via Compose (push) Successful in 33s

This commit is contained in:
2026-08-09 12:23:36 +02:00
parent 4da56f3823
commit a198f7e960
19 changed files with 266 additions and 52 deletions

View File

@@ -441,8 +441,8 @@ class ParserLoadLogServiceTest(TestCase):
self.assertEqual(updated, 0)
self.assertEqual(log.status, ParserLoadLog.Status.IN_PROGRESS)
def test_mark_stale_in_progress_failed_closes_precreated_job_without_batch(self):
"""Pre-created source-card jobs without batch_id are still linked by source."""
def test_mark_stale_in_progress_failed_keeps_recent_heartbeat_without_batch(self):
"""A recent heartbeat keeps a pre-created source-card job alive."""
log = ParserLoadLogFactory(
source=ParserLoadLog.Source.INDUSTRIAL_PRODUCTS,
batch_id=2,
@@ -465,9 +465,9 @@ class ParserLoadLogServiceTest(TestCase):
log.refresh_from_db()
job.refresh_from_db()
self.assertEqual(updated, 1)
self.assertEqual(log.status, ParserLoadLog.Status.FAILED)
self.assertEqual(job.status, JobStatus.FAILURE)
self.assertEqual(updated, 0)
self.assertEqual(log.status, ParserLoadLog.Status.IN_PROGRESS)
self.assertEqual(job.status, JobStatus.STARTED)
@unittest.skip(

View File

@@ -392,7 +392,7 @@ class SourceCardServiceUnitTest(SimpleTestCase):
)
stale_in_progress_load = SimpleNamespace(
status="in_progress",
updated_at=timezone.now() - timedelta(hours=3),
updated_at=timezone.now() - timedelta(hours=5),
)
self.assertEqual(
SourceCardService._get_status(
@@ -618,7 +618,7 @@ class SourceCardServiceDatabaseTest(TestCase):
)
self.assertEqual(procurements_card["records_count"], 1)
def test_get_active_tasks_ignores_old_jobs_even_when_updated_recently(self):
def test_get_active_tasks_keeps_old_job_with_recent_heartbeat(self):
job = BackgroundJob.objects.create(
task_id="old-source-task",
task_name="apps.parsers.tasks.parse_industrial_products",
@@ -637,7 +637,8 @@ class SourceCardServiceDatabaseTest(TestCase):
SourceCardService.get_definition("manufacturers-and-products")
)
self.assertEqual(tasks, [])
self.assertEqual(len(tasks), 1)
self.assertEqual(tasks[0]["task_id"], job.task_id)
def test_get_active_tasks_keeps_recent_pending_jobs(self):
BackgroundJob.objects.create(

View File

@@ -133,6 +133,11 @@ class SourcesApiE2ETest(APITestCase):
self.assertEqual(minprom_card["records_count"], 3)
self.assertEqual(minprom_card["organizations_count"], 1)
self.assertEqual(len(minprom_card["source_items"]), 3)
minprom_items = {item["code"]: item for item in minprom_card["source_items"]}
self.assertEqual(
minprom_items["industrial_products"]["refresh_key"],
"mpt_products",
)
statuses = {item["slug"]: item for item in statuses_response.data["data"]}
self.assertEqual(statuses["planned-inspections"]["progress"], 55)

View File

@@ -1086,9 +1086,16 @@ class GenericSourceFetchTestCase(TestCase):
) as jobs_cleanup_mock:
result = parser_tasks.cleanup_stale_parser_loads(max_age_minutes=45)
cleanup_mock.assert_called_once_with(max_age_minutes=45)
cleanup_mock.assert_called_once_with(
max_age_minutes=45,
pending_max_age_minutes=24 * 60,
)
jobs_cleanup_mock.assert_called_once()
self.assertEqual(jobs_cleanup_mock.call_args.kwargs["max_age_minutes"], 45)
self.assertEqual(
jobs_cleanup_mock.call_args.kwargs["pending_max_age_minutes"],
24 * 60,
)
self.assertIn(
"apps.parsers.tasks.scan_fns_directory",
jobs_cleanup_mock.call_args.kwargs["task_names"],
@@ -1101,6 +1108,7 @@ class GenericSourceFetchTestCase(TestCase):
self.assertEqual(result["marked_failed"], 2)
self.assertEqual(result["marked_jobs_failed"], 3)
self.assertEqual(result["max_age_minutes"], 45)
self.assertEqual(result["pending_max_age_minutes"], 24 * 60)
def test_get_or_create_background_job_merges_meta_for_precreated_job(self):
BackgroundJobService.create_job(

View File

@@ -11,6 +11,7 @@ import zipfile
from datetime import date
from unittest.mock import Mock, patch
from apps.core.models import BackgroundJob
from apps.parsers.models import (
FinancialReport,
FinancialReportLine,
@@ -1411,3 +1412,19 @@ class ParsersViewSetTest(APITestCase):
for key, value in payload.items():
self.assertEqual(task_kwargs[key], value)
self.assertEqual(task_kwargs["requested_by_id"], self.user.id)
def test_run_industrial_products_uses_legacy_alias(self):
self.client.force_authenticate(self.user)
url = reverse("api_v1:parsers:run-parser", args=["industrial_products"])
with patch(
"apps.parsers.views.tasks.parse_industrial_products.apply_async",
return_value=Mock(id="task-products"),
) as apply_async_mock:
response = self.client.post(url, {}, format="json")
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
apply_async_mock.assert_called_once()
queued_task_id = apply_async_mock.call_args.kwargs["task_id"]
job = BackgroundJob.objects.get(task_id=queued_task_id)
self.assertEqual(job.meta["source_key"], "mpt_products")