fix: align source API and exchange demo data
All checks were successful
CI/CD Pipeline / Quality Gate (push) Successful in 30s
CI/CD Pipeline / Build and Push Images (push) Successful in 0s
CI/CD Pipeline / Internal Notify (push) Successful in 1s
CI/CD Pipeline / Deploy Dev via Compose (push) Successful in 0s
CI/CD Pipeline / Quality Gate (pull_request) Successful in 31s
CI/CD Pipeline / Build and Push Images (pull_request) Successful in 1s
CI/CD Pipeline / Internal Notify (pull_request) Successful in 1s
CI/CD Pipeline / Deploy Dev via Compose (pull_request) Successful in 1s

This commit is contained in:
2026-07-22 17:20:39 +02:00
parent 9635cd81d7
commit 4be9e702c3
8 changed files with 411 additions and 40 deletions

View File

@@ -1,11 +1,15 @@
"""Tests for organization API v2 backed by source extensions."""
from uuid import UUID
from django.core.cache import cache
from django.urls import reverse
from organizations.models import (
ArbitrationExtension,
Organization,
OrganizationSourceRecord,
PlannedInspectionExtension,
VacancyExtension,
)
from rest_framework import status
from rest_framework.test import APITestCase
@@ -166,6 +170,191 @@ class OrganizationSourceExtensionsApiV2Test(APITestCase):
self.assertEqual(record["source_group"], "planned_inspections")
self.assertEqual(record["organization"]["uid"], str(target.uid))
def test_flat_source_records_filters_supported_groups_by_canonical_date(self):
organization = create_frontend_organization(
name='ООО "Canonical dates"',
inn="7707083890",
ogrn="1027700132090",
)
extensions = {
"planned_inspections": PlannedInspectionExtension.objects.create(
organization=organization,
title="Проверки",
),
"vacancies": VacancyExtension.objects.create(
organization=organization,
title="Вакансии",
),
"arbitration": ArbitrationExtension.objects.create(
organization=organization,
title="Арбитраж",
),
}
OrganizationSourceRecord.objects.create(
extension=extensions["planned_inspections"],
record_type="inspection",
source="inspections",
external_id="DATE-INSPECTION",
record_date="12.03.2026",
payload={"start_date_normalized": "2026-03-12"},
)
OrganizationSourceRecord.objects.create(
extension=extensions["vacancies"],
record_type="vacancy",
source="trudvsem",
external_id="DATE-VACANCY",
record_date="2026-03-31",
)
OrganizationSourceRecord.objects.create(
extension=extensions["arbitration"],
record_type="arbitration_case",
source="arbitration",
external_id="DATE-ARBITRATION",
record_date="2026-04-01",
)
OrganizationSourceRecord.objects.create(
extension=extensions["vacancies"],
record_type="vacancy",
source="trudvsem",
external_id="DATE-NULL",
record_date="",
)
response = self.client.get(
reverse("api_v2:organizations:organization-source-records-list"),
{
"date_from": "2026-03-12",
"date_to": "2026-03-31",
"ordering": "record_date",
},
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["meta"]["pagination"]["total_count"], 2)
self.assertEqual(
[item["external_id"] for item in response.data["data"]],
["DATE-INSPECTION", "DATE-VACANCY"],
)
self.assertEqual(
[item["record_date"] for item in response.data["data"]],
["2026-03-12", "2026-03-31"],
)
def test_flat_source_records_orders_dates_stably_with_nulls_last(self):
organization = create_frontend_organization(
name='ООО "Stable dates"',
inn="7707083891",
ogrn="1027700132091",
)
extension = VacancyExtension.objects.create(
organization=organization,
title="Вакансии",
)
records = [
("00000000-0000-0000-0000-000000000004", "DATE-NULL", ""),
("00000000-0000-0000-0000-000000000003", "DATE-LATE", "2026-05-01"),
("00000000-0000-0000-0000-000000000002", "DATE-EQUAL-2", "2026-04-01"),
("00000000-0000-0000-0000-000000000001", "DATE-EQUAL-1", "2026-04-01"),
]
for uid, external_id, record_date in records:
OrganizationSourceRecord.objects.create(
uid=UUID(uid),
extension=extension,
record_type="vacancy",
source="trudvsem",
external_id=external_id,
record_date=record_date,
)
endpoint = reverse("api_v2:organizations:organization-source-records-list")
ascending = self.client.get(endpoint, {"ordering": "record_date"})
descending = self.client.get(endpoint, {"ordering": "-record_date"})
self.assertEqual(ascending.status_code, status.HTTP_200_OK)
self.assertEqual(
[item["external_id"] for item in ascending.data["data"]],
["DATE-EQUAL-1", "DATE-EQUAL-2", "DATE-LATE", "DATE-NULL"],
)
self.assertEqual(
[item["external_id"] for item in descending.data["data"]],
["DATE-LATE", "DATE-EQUAL-1", "DATE-EQUAL-2", "DATE-NULL"],
)
self.assertIsNone(ascending.data["data"][-1]["record_date"])
self.assertIsNone(descending.data["data"][-1]["record_date"])
def test_flat_source_records_rejects_invalid_date_range_and_ordering(self):
response = self.client.get(
reverse("api_v2:organizations:organization-source-records-list"),
{
"date_from": "2026-04-01",
"date_to": "2026-03-01",
"ordering": "unknown_date",
},
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertFalse(response.data["success"])
self.assertEqual(response.data["data"], [])
self.assertEqual(
{error["code"] for error in response.data["errors"]},
{"invalid_date_range", "invalid_ordering"},
)
def test_flat_source_records_rejects_invalid_date_format(self):
for invalid_date in ("01.04.2026", "2026-4-1"):
with self.subTest(invalid_date=invalid_date):
response = self.client.get(
reverse("api_v2:organizations:organization-source-records-list"),
{"date_from": invalid_date},
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data["errors"][0]["code"], "invalid_date")
self.assertEqual(response.data["errors"][0]["field"], "date_from")
self.assertIn("YYYY-MM-DD", response.data["errors"][0]["message"])
def test_flat_source_record_date_filter_precedes_pagination(self):
organization = create_frontend_organization(
name='ООО "Filtered pagination"',
inn="7707083892",
ogrn="1027700132092",
)
extension = ArbitrationExtension.objects.create(
organization=organization,
title="Арбитраж",
)
for index, record_date in enumerate(
("2026-01-01", "2026-02-01", "2026-03-01"),
start=1,
):
OrganizationSourceRecord.objects.create(
extension=extension,
record_type="arbitration_case",
source="arbitration",
external_id=f"PAGE-{index}",
title="Искомое дело",
record_date=record_date,
)
response = self.client.get(
reverse("api_v2:organizations:organization-source-records-list"),
{
"source_group": "arbitration",
"source": "arbitration",
"organization": str(organization.uid),
"search": "Искомое",
"date_from": "2026-02-01",
"ordering": "record_date",
"page_size": 1,
"page": 2,
},
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["meta"]["pagination"]["total_count"], 2)
self.assertEqual(response.data["meta"]["pagination"]["total_pages"], 2)
self.assertEqual(response.data["data"][0]["external_id"], "PAGE-3")
def test_flat_source_records_scope_cannot_be_lifted_by_has_registry(self):
with_registry = create_frontend_organization(
name='ООО "With Registry Source"',

View File

@@ -133,7 +133,7 @@ class TestCompaniesCommandsTest(TestCase):
self.assertEqual(OrganizationSourceRecord.objects.count(), 20 * 15)
@override_settings(STATE_CORP_EXCHANGE_TOKEN=TEST_EXCHANGE_TOKEN)
def test_created_source_records_are_excluded_from_state_corp_package(self):
def test_created_source_records_are_exported_to_state_corp_package(self):
call_command("create_test_companies", stdout=StringIO())
company_inns = list(
@@ -146,18 +146,18 @@ class TestCompaniesCommandsTest(TestCase):
self.assertEqual(
package.payload_counts,
{
"organizations": 0,
"industrial_certificates": 0,
"manufacturers": 0,
"industrial_products": 0,
"prosecutor_checks": 0,
"public_procurements": 0,
"financial_reports": 0,
"arbitration_cases": 0,
"bankruptcy_procedures": 0,
"defense_unreliable_suppliers": 0,
"information_security_registries": 0,
"labor_vacancies": 0,
"organizations": 20,
"industrial_certificates": 20,
"manufacturers": 20,
"industrial_products": 20,
"prosecutor_checks": 20,
"public_procurements": 60,
"financial_reports": 20,
"arbitration_cases": 20,
"bankruptcy_procedures": 20,
"defense_unreliable_suppliers": 40,
"information_security_registries": 20,
"labor_vacancies": 20,
},
)