feat(parsers): support FNS zip uploads in admin
Some checks failed
CI/CD Pipeline / Run Tests (push) Successful in 3m0s
CI/CD Pipeline / Code Quality Checks (push) Failing after 7m39s
CI/CD Pipeline / Telegram Notify Success (push) Has been skipped

This commit is contained in:
2026-03-20 13:43:11 +01:00
parent e470189f44
commit b8015d9cdd
8 changed files with 459 additions and 198 deletions

View File

@@ -1,5 +1,10 @@
"""Tests for parsers admin configurations."""
import io
import os
import tempfile
import zipfile
from apps.parsers.admin import (
FinancialReportAdmin,
HasCertificateNumberFilter,
@@ -22,7 +27,9 @@ from apps.parsers.models import (
)
from django.contrib.admin.sites import AdminSite
from django.contrib.messages.storage.fallback import FallbackStorage
from django.test import RequestFactory, TestCase
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import RequestFactory, TestCase, override_settings
from openpyxl import Workbook
from tests.apps.parsers.factories import (
IndustrialCertificateRecordFactory,
@@ -42,6 +49,41 @@ def _digits(length: int) -> str:
return "".join(str(fake.random_int(0, 9)) for _ in range(length))
def _build_fns_excel_bytes() -> bytes:
workbook = Workbook()
worksheet = workbook.active
year = fake.random_int(min=2020, max=2025)
worksheet.append(["Форма №1", None, year, None])
worksheet.append([None, "Код", "Начало", "Конец"])
worksheet.append(
[
fake.word(),
_digits(4),
fake.random_int(min=10, max=999),
fake.random_int(min=10, max=999),
]
)
buffer = io.BytesIO()
workbook.save(buffer)
workbook.close()
return buffer.getvalue()
def _build_fns_zip_upload() -> SimpleUploadedFile:
buffer = io.BytesIO()
with zipfile.ZipFile(buffer, "w", compression=zipfile.ZIP_DEFLATED) as archive:
archive.writestr(
f"fin_{_digits(5)}_{_digits(13)}.xlsx",
_build_fns_excel_bytes(),
)
archive.writestr("ignored.txt", b"invalid")
return SimpleUploadedFile(
"fin_ropk.zip",
buffer.getvalue(),
content_type="application/zip",
)
class ParsersAdminTest(TestCase):
def setUp(self):
self.site = AdminSite()
@@ -55,6 +97,13 @@ class ParsersAdminTest(TestCase):
request._messages = FallbackStorage(request)
return request
def _post_request(self, path, data):
request = self.factory.post(path, data=data)
request.user = self.user
request.session = {}
request._messages = FallbackStorage(request)
return request
def test_proxy_admin_actions(self):
admin = ProxyAdmin(Proxy, self.site)
proxy = ProxyFactory(is_active=False, fail_count=5)
@@ -248,3 +297,23 @@ class ParsersAdminTest(TestCase):
self.assertIn("registry_organization__pn_name", admin.search_fields)
route_names = [route.name for route in admin.get_urls()]
self.assertIn("parsers_financialreport_upload_excel", route_names)
self.assertIn("parsers_financialreport_upload_zip", route_names)
def test_financial_report_admin_upload_zip_view(self):
admin = FinancialReportAdmin(FinancialReport, self.site)
archive_upload = _build_fns_zip_upload()
request = self._post_request(
"/admin/parsers/financialreport/upload-zip/",
{"file": archive_upload},
)
with tempfile.TemporaryDirectory() as tmpdir, override_settings(
FNS_WATCH_DIRECTORY=os.path.join(tmpdir, "watch"),
FNS_PROCESSED_DIRECTORY=os.path.join(tmpdir, "processed"),
FNS_FAILED_DIRECTORY=os.path.join(tmpdir, "failed"),
):
response = admin.upload_zip_view(request)
self.assertEqual(response.status_code, 302)
self.assertEqual(FinancialReport.objects.count(), 1)
self.assertEqual(FinancialReportLine.objects.count(), 1)