1 Commits

Author SHA1 Message Date
7879d54958 feat: add parser source dashboard and scheduling
Some checks failed
CI/CD Pipeline / Code Quality Checks (pull_request) Failing after 10m20s
CI/CD Pipeline / Run Tests (pull_request) Failing after 11m5s
CI/CD Pipeline / Build Docker Images (pull_request) Has been skipped
CI/CD Pipeline / Push to Gitea Registry (pull_request) Has been skipped
2026-04-27 23:56:16 +02:00
5 changed files with 26 additions and 11 deletions

View File

@@ -2,9 +2,9 @@ name: CI/CD Pipeline
on: on:
push: push:
branches: [ main, develop ] branches: [ main, dev ]
pull_request: pull_request:
branches: [ main, develop ] branches: [ main, dev ]
jobs: jobs:
lint: lint:
@@ -113,7 +113,7 @@ jobs:
cd src cd src
python manage.py test --verbosity=2 python manage.py test --verbosity=2
env: env:
DJANGO_SETTINGS_MODULE: config.settings.development DJANGO_SETTINGS_MODULE: config.settings.test
DATABASE_URL: postgres://postgres:postgres@localhost:5432/test_db DATABASE_URL: postgres://postgres:postgres@localhost:5432/test_db
REDIS_URL: redis://localhost:6379/0 REDIS_URL: redis://localhost:6379/0
CELERY_BROKER_URL: redis://localhost:6379/0 CELERY_BROKER_URL: redis://localhost:6379/0
@@ -181,7 +181,7 @@ jobs:
name: Push to Gitea Registry name: Push to Gitea Registry
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [build] needs: [build]
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev'
steps: steps:
- name: Checkout code - name: Checkout code

View File

@@ -541,8 +541,7 @@ class StructuredDataClient:
result = [] result = []
for row in rows: for row in rows:
values = [ values = [
cell.get_text(" ", strip=True) cell.get_text(" ", strip=True) for cell in row.find_all(["td", "th"])
for cell in row.find_all(["td", "th"])
] ]
if len(values) < 8 or self._is_fas_goz_header_number_row(values): if len(values) < 8 or self._is_fas_goz_header_number_row(values):
continue continue

View File

@@ -10,7 +10,9 @@ from apps.backups.models import BackupExportJob
from apps.backups.services import BackupExportService from apps.backups.services import BackupExportService
from apps.core.models import BackgroundJob, JobStatus from apps.core.models import BackgroundJob, JobStatus
from apps.parsers.models import ParserLoadLog from apps.parsers.models import ParserLoadLog
from apps.registers.models import Register
from apps.user.services import UserService from apps.user.services import UserService
from django.test import override_settings
from django.urls import reverse from django.urls import reverse
from rest_framework import status from rest_framework import status
from rest_framework.test import APITestCase from rest_framework.test import APITestCase
@@ -18,19 +20,25 @@ from rest_framework.test import APITestCase
from tests.apps.parsers.factories import GenericParserRecordFactory from tests.apps.parsers.factories import GenericParserRecordFactory
from tests.apps.registers.factories import ( from tests.apps.registers.factories import (
OrganizationFactory, OrganizationFactory,
RegisterFactory,
RegistryMembershipPeriodFactory, RegistryMembershipPeriodFactory,
) )
from tests.apps.user.factories import UserFactory from tests.apps.user.factories import UserFactory
@override_settings(
BACKUP_ENCRYPTION_KEY="MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA=",
CELERY_TASK_ALWAYS_EAGER=True,
CELERY_TASK_EAGER_PROPAGATES=True,
)
class BackupExportTest(APITestCase): class BackupExportTest(APITestCase):
"""Tests for registry backup service and API.""" """Tests for registry backup service and API."""
def setUp(self): def setUp(self):
self.admin = UserFactory.create_user(is_staff=True) self.admin = UserFactory.create_user(is_staff=True)
self.user = UserFactory.create_user() self.user = UserFactory.create_user()
self.registry = RegisterFactory(name="Реестр предприятий ОПК") self.registry, _ = Register.objects.get_or_create(
name="Реестр предприятий ОПК"
)
self.organization = OrganizationFactory( self.organization = OrganizationFactory(
pn_name='АО "ОПК"', pn_name='АО "ОПК"',
mn_ogrn=1027600980990, mn_ogrn=1027600980990,

View File

@@ -132,8 +132,15 @@ class ExchangeApiTest(APITestCase):
self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(list_response.status_code, status.HTTP_200_OK) self.assertEqual(list_response.status_code, status.HTTP_200_OK)
self.assertEqual(PeriodicTask.objects.count(), 1) self.assertTrue(
payload = list_response.data["data"][0]["payload"] PeriodicTask.objects.filter(id=response.data["data"]["id"]).exists()
)
created_task = next(
item
for item in list_response.data["data"]
if item["id"] == response.data["data"]["id"]
)
payload = created_task["payload"]
self.assertEqual(payload["mode"], "single") self.assertEqual(payload["mode"], "single")
self.assertEqual(payload["table"], "registers_organization") self.assertEqual(payload["table"], "registers_organization")

View File

@@ -7,6 +7,7 @@ from unittest.mock import patch
from apps.core.models import BackgroundJob, JobStatus from apps.core.models import BackgroundJob, JobStatus
from apps.parsers.clients.common.schemas import GenericParserItem from apps.parsers.clients.common.schemas import GenericParserItem
from apps.parsers.models import GenericParserRecord, ParserLoadLog from apps.parsers.models import GenericParserRecord, ParserLoadLog
from apps.parsers.source_registry import PARSER_SOURCES
from apps.parsers.tasks import ( from apps.parsers.tasks import (
import_parser_upload, import_parser_upload,
parse_all_sources, parse_all_sources,
@@ -73,7 +74,7 @@ class GenericParserTasksTest(TestCase):
self.assertEqual(result["status"], "success") self.assertEqual(result["status"], "success")
self.assertEqual( self.assertEqual(
mock_fetch_records.call_args.kwargs["file_url"], mock_fetch_records.call_args.kwargs["file_url"],
"https://bo.nalog.gov.ru/advanced-search/organizations/search", PARSER_SOURCES["fns_financial"].upstream_url,
) )
def test_import_parser_upload_saves_records_and_removes_file(self): def test_import_parser_upload_saves_records_and_removes_file(self):