feat: expand registry ingestion and demo exchange
This commit is contained in:
@@ -31,6 +31,12 @@ from rest_framework.test import APITestCase
|
||||
from tests.apps.user.factories import UserFactory
|
||||
|
||||
|
||||
def create_frontend_organization(**kwargs):
|
||||
"""Create an organization visible through the frontend API by default."""
|
||||
kwargs.setdefault("opk_registry_membership", True)
|
||||
return Organization.objects.create(**kwargs)
|
||||
|
||||
|
||||
class OrganizationsApiV2Test(APITestCase):
|
||||
"""Checks v2 canonical organizations endpoints."""
|
||||
|
||||
@@ -51,13 +57,13 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
worksheet.append([key, value])
|
||||
|
||||
def test_list_is_paginated_and_available_only_under_v2(self):
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name='ООО "Альфа"',
|
||||
inn="7707083893",
|
||||
kpp="770701001",
|
||||
ogrn="1027700132195",
|
||||
)
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name="ИП Иванов Иван Иванович",
|
||||
inn="500100732259",
|
||||
ogrip="304500116000157",
|
||||
@@ -174,16 +180,13 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
"search",
|
||||
"ordering",
|
||||
"registry",
|
||||
"has_registry",
|
||||
"identity_status",
|
||||
"source_group",
|
||||
"has_financial_indicators",
|
||||
"has_planned_inspections",
|
||||
):
|
||||
self.assertIn(expected_name, list_parameters)
|
||||
self.assertIn(
|
||||
"по умолчанию true", list_parameters["has_registry"]["description"]
|
||||
)
|
||||
self.assertNotIn("has_registry", list_parameters)
|
||||
self.assertIn(
|
||||
"группе источников",
|
||||
list_parameters["source_group"]["description"],
|
||||
@@ -206,7 +209,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertIn("/api/v2/organization-sources/{uid}/records/", paths)
|
||||
|
||||
def test_retrieve_returns_item_by_uid(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Ромашка"',
|
||||
inn="7712345678",
|
||||
kpp="771201001",
|
||||
@@ -224,7 +227,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(response.data["name"], 'ООО "Ромашка"')
|
||||
|
||||
def test_response_includes_normalized_name(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='АКЦИОНЕРНОЕ ОБЩЕСТВО "СЕВЕРНЫЙ МОСТ"',
|
||||
inn="7712345679",
|
||||
kpp="771201002",
|
||||
@@ -242,7 +245,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(response.data["normalized_name"], 'АО "Северный Мост"')
|
||||
|
||||
def test_list_returns_compact_source_summaries_without_records(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Легкий список"',
|
||||
inn="7712345682",
|
||||
kpp="771201005",
|
||||
@@ -279,7 +282,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
)
|
||||
|
||||
def test_list_source_summaries_do_not_load_source_records(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Легкие источники"',
|
||||
inn="7712345685",
|
||||
kpp="771201008",
|
||||
@@ -316,7 +319,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(source_record_queries, [])
|
||||
|
||||
def test_source_records_endpoint_returns_requested_source_payload(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Явные данные"',
|
||||
full_name='Общество с ограниченной ответственностью "Явные данные"',
|
||||
short_name='ООО "Явные данные"',
|
||||
@@ -387,7 +390,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(embedded_organization["is_branch"], False)
|
||||
|
||||
def test_detail_returns_compact_source_summaries_by_default(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Полная карточка"',
|
||||
inn="7712345684",
|
||||
kpp="771201007",
|
||||
@@ -410,13 +413,13 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(response.data["sources"][0]["source_group"], "financial_indicators")
|
||||
|
||||
def test_source_group_filter_limits_organizations_by_source_extension(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Сводка данных"',
|
||||
inn="7712345681",
|
||||
kpp="771201004",
|
||||
ogrn="1027700132199",
|
||||
)
|
||||
other = Organization.objects.create(
|
||||
other = create_frontend_organization(
|
||||
name='ООО "Без промышленности"',
|
||||
inn="7712345686",
|
||||
kpp="771201009",
|
||||
@@ -446,7 +449,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(response.data["data"][0]["uid"], str(organization.uid))
|
||||
|
||||
def test_normalized_name_compacts_scientific_production_forms(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='Научно-Производственное Предприятие "ИМПУЛЬС"',
|
||||
inn="7712345680",
|
||||
kpp="771201003",
|
||||
@@ -463,13 +466,13 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(response.data["normalized_name"], 'НПП "Импульс"')
|
||||
|
||||
def test_list_filters_by_identifiers_and_searches_by_name(self):
|
||||
target = Organization.objects.create(
|
||||
target = create_frontend_organization(
|
||||
name='ООО "Северный мост"',
|
||||
inn="7711111111",
|
||||
kpp="771101001",
|
||||
ogrn="1027700132111",
|
||||
)
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name='АО "Южный путь"',
|
||||
inn="7722222222",
|
||||
kpp="772201001",
|
||||
@@ -494,13 +497,13 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(by_search.data["data"][0]["uid"], str(target.uid))
|
||||
|
||||
def test_list_searches_by_identifier_fragments_for_dashboard(self):
|
||||
target = Organization.objects.create(
|
||||
target = create_frontend_organization(
|
||||
name='ООО "Поиск по реквизитам"',
|
||||
inn="7711111122",
|
||||
kpp="771102222",
|
||||
ogrn="1027700132122",
|
||||
)
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name='ООО "Другая организация"',
|
||||
inn="7722222233",
|
||||
kpp="772203333",
|
||||
@@ -520,7 +523,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(response.data["data"][0]["uid"], str(target.uid))
|
||||
|
||||
def test_list_response_is_cached_by_query_string(self):
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name='ООО "Кеш"',
|
||||
inn="7733333333",
|
||||
kpp="773301001",
|
||||
@@ -532,7 +535,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
url,
|
||||
{"inn": "7733333333", "has_registry": "false"},
|
||||
)
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name='ООО "После кеша"',
|
||||
inn="7744444444",
|
||||
kpp="774401001",
|
||||
@@ -555,7 +558,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(different_query_response.data["data"][0]["inn"], "7744444444")
|
||||
|
||||
def test_list_response_cache_is_invalidated_by_version_bump(self):
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name='ООО "Версия кеша"',
|
||||
inn="7744444445",
|
||||
kpp="774401002",
|
||||
@@ -575,7 +578,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(third_response["X-Cache"], "MISS")
|
||||
|
||||
def test_source_update_invalidates_organization_cache(self):
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name='ООО "Источник сброса"',
|
||||
inn="7744444446",
|
||||
kpp="774401003",
|
||||
@@ -599,7 +602,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(third_response["X-Cache"], "MISS")
|
||||
|
||||
def test_explicit_invalidation_refreshes_organization_cache(self):
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name='ООО "Реестр сброса"',
|
||||
inn="7744444447",
|
||||
kpp="774401004",
|
||||
@@ -618,7 +621,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(third_response["X-Cache"], "MISS")
|
||||
|
||||
def test_retrieve_response_is_cached(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Деталь"',
|
||||
inn="7755555555",
|
||||
kpp="775501001",
|
||||
@@ -639,7 +642,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(second_response.data["name"], 'ООО "Деталь"')
|
||||
|
||||
def test_list_includes_source_groups_and_active_registries(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Данные"',
|
||||
inn="7777777777",
|
||||
kpp="777701001",
|
||||
@@ -783,8 +786,8 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(records_response.data["data"][0]["external_id"], "fin-1")
|
||||
self.assertEqual(len(records_response.data["data"][0]["financial_lines"]), 3)
|
||||
|
||||
def test_filters_by_registry_and_has_registry(self):
|
||||
with_registry = Organization.objects.create(
|
||||
def test_frontend_scope_cannot_be_lifted_by_has_registry_parameter(self):
|
||||
with_registry = create_frontend_organization(
|
||||
name='ООО "В реестре"',
|
||||
inn="7788888888",
|
||||
kpp="778801001",
|
||||
@@ -793,11 +796,32 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
ropk_razdel_num="opk-space",
|
||||
ropk_razdel_name="Роскосмос ОПК",
|
||||
)
|
||||
without_registry = Organization.objects.create(
|
||||
without_registry = create_frontend_organization(
|
||||
name='ООО "Без реестра"',
|
||||
inn="7799999999",
|
||||
kpp="779901001",
|
||||
ogrn="1027700132999",
|
||||
opk_registry_membership=False,
|
||||
)
|
||||
rosatom_without_opk = create_frontend_organization(
|
||||
name='АО "Росатом без ОПК"',
|
||||
inn="7799999998",
|
||||
kpp="779801001",
|
||||
ogrn="1027700132998",
|
||||
gk_code="rosatom",
|
||||
gk_name="Росатом",
|
||||
goz_participation=True,
|
||||
opk_registry_membership=False,
|
||||
)
|
||||
roscosmos_without_opk = create_frontend_organization(
|
||||
name='АО "Роскосмос без ОПК"',
|
||||
inn="7799999997",
|
||||
kpp="779701001",
|
||||
ogrn="1027700132997",
|
||||
gk_code="roscosmos",
|
||||
gk_name="Роскосмос",
|
||||
ropk_num="historical-number-without-membership",
|
||||
opk_registry_membership=False,
|
||||
)
|
||||
by_registry = self.client.get(
|
||||
reverse("api_v2:organizations:organizations-list"),
|
||||
@@ -820,22 +844,31 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(has_registry.data["data"][0]["uid"], str(with_registry.uid))
|
||||
|
||||
self.assertEqual(no_registry.data["meta"]["pagination"]["total_count"], 1)
|
||||
self.assertEqual(no_registry.data["data"][0]["uid"], str(without_registry.uid))
|
||||
|
||||
def test_has_registry_filter_uses_uncorrelated_identity_subqueries(self):
|
||||
filterset = OrganizationFilter(
|
||||
data={"has_registry": "true"},
|
||||
queryset=Organization.objects.all(),
|
||||
self.assertEqual(no_registry.data["data"][0]["uid"], str(with_registry.uid))
|
||||
returned_uids = {item["uid"] for item in no_registry.data["data"]}
|
||||
self.assertTrue(
|
||||
returned_uids.isdisjoint(
|
||||
{
|
||||
str(without_registry.uid),
|
||||
str(rosatom_without_opk.uid),
|
||||
str(roscosmos_without_opk.uid),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
self.assertTrue(filterset.is_valid(), filterset.errors)
|
||||
sql = str(filterset.qs.query).upper()
|
||||
hidden_detail = self.client.get(
|
||||
reverse(
|
||||
"api_v2:organizations:organizations-detail",
|
||||
args=[rosatom_without_opk.uid],
|
||||
)
|
||||
)
|
||||
self.assertEqual(hidden_detail.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
self.assertIn("OPK_REGISTRY_MEMBERSHIP", sql)
|
||||
self.assertNotIn("EXISTS", sql)
|
||||
def test_has_registry_is_not_a_public_filter(self):
|
||||
self.assertNotIn("has_registry", OrganizationFilter.base_filters)
|
||||
|
||||
def test_list_defaults_to_has_registry_true(self):
|
||||
with_registry = Organization.objects.create(
|
||||
with_registry = create_frontend_organization(
|
||||
name='ООО "Дефолтный реестр"',
|
||||
inn="7800000101",
|
||||
kpp="780001101",
|
||||
@@ -844,11 +877,21 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
ropk_razdel_num="default",
|
||||
ropk_razdel_name="Дефолтный реестр",
|
||||
)
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name='ООО "Скрыто по дефолту"',
|
||||
inn="7800000102",
|
||||
kpp="780001102",
|
||||
ogrn="1027700133102",
|
||||
opk_registry_membership=False,
|
||||
)
|
||||
create_frontend_organization(
|
||||
name='АО "Росатом без ОПК скрыт по дефолту"',
|
||||
inn="7800000103",
|
||||
kpp="780001103",
|
||||
ogrn="1027700133103",
|
||||
gk_name="Росатом",
|
||||
goz_participation=True,
|
||||
opk_registry_membership=False,
|
||||
)
|
||||
default_response = self.client.get(
|
||||
reverse("api_v2:organizations:organizations-list")
|
||||
@@ -869,24 +912,24 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
1,
|
||||
)
|
||||
self.assertEqual(
|
||||
explicit_false_response.data["data"][0]["inn"],
|
||||
"7800000102",
|
||||
{item["inn"] for item in explicit_false_response.data["data"]},
|
||||
{"7800000101"},
|
||||
)
|
||||
|
||||
def test_filters_by_data_presence(self):
|
||||
with_industrial = Organization.objects.create(
|
||||
with_industrial = create_frontend_organization(
|
||||
name='ООО "С промышленностью"',
|
||||
inn="7800000001",
|
||||
kpp="780001001",
|
||||
ogrn="1027700133001",
|
||||
)
|
||||
with_fns = Organization.objects.create(
|
||||
with_fns = create_frontend_organization(
|
||||
name='ООО "С отчетностью"',
|
||||
inn="7800000002",
|
||||
kpp="780001002",
|
||||
ogrn="1027700133002",
|
||||
)
|
||||
without_data = Organization.objects.create(
|
||||
without_data = create_frontend_organization(
|
||||
name='ООО "Без данных"',
|
||||
inn="7800000003",
|
||||
kpp="780001003",
|
||||
@@ -937,7 +980,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(has_fns.data["data"][0]["uid"], str(with_fns.uid))
|
||||
|
||||
def test_has_fns_reports_filter_does_not_preload_report_identities(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Отчетность без preload"',
|
||||
inn="7800000004",
|
||||
kpp="780001004",
|
||||
@@ -966,13 +1009,13 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(distinct_report_queries, [])
|
||||
|
||||
def test_sources_action_returns_only_current_organization_extensions(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Источник"',
|
||||
inn="7800000201",
|
||||
kpp="780002101",
|
||||
ogrn="1027700133201",
|
||||
)
|
||||
other = Organization.objects.create(
|
||||
other = create_frontend_organization(
|
||||
name='ООО "Другой источник"',
|
||||
inn="7800000205",
|
||||
kpp="780002105",
|
||||
@@ -1010,7 +1053,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(sources["industrial_production"]["uid"], str(industrial.uid))
|
||||
|
||||
def test_unknown_source_group_filter_returns_empty_page(self):
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name='ООО "Неверная группа"',
|
||||
inn="7800000202",
|
||||
kpp="780002102",
|
||||
@@ -1026,7 +1069,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(response.data["meta"]["pagination"]["total_count"], 0)
|
||||
|
||||
def test_detail_source_summaries_do_not_load_source_records(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Без N+1"',
|
||||
inn="7800000203",
|
||||
kpp="780002103",
|
||||
@@ -1084,7 +1127,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
self.assertEqual(source_record_queries, [])
|
||||
|
||||
def test_trudvsem_filter_alias_uses_vacancies_source_group(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Вакансии"',
|
||||
inn="7800000204",
|
||||
kpp="780002104",
|
||||
@@ -1128,7 +1171,7 @@ class OrganizationsApiV2Test(APITestCase):
|
||||
@override_settings(ORGANIZATIONS_V2_ALLOW_ANONYMOUS=True)
|
||||
def test_dev_flag_allows_anonymous_access(self):
|
||||
self.client.force_authenticate(user=None)
|
||||
Organization.objects.create(
|
||||
create_frontend_organization(
|
||||
name='ООО "Без токена"',
|
||||
inn="7766666666",
|
||||
kpp="776601001",
|
||||
|
||||
@@ -13,6 +13,12 @@ from rest_framework.test import APITestCase
|
||||
from tests.apps.user.factories import UserFactory
|
||||
|
||||
|
||||
def create_frontend_organization(**kwargs):
|
||||
"""Create an organization visible through the frontend API by default."""
|
||||
kwargs.setdefault("opk_registry_membership", True)
|
||||
return Organization.objects.create(**kwargs)
|
||||
|
||||
|
||||
class OrganizationSourceExtensionsApiV2Test(APITestCase):
|
||||
"""Checks organization-centric source extension API contract."""
|
||||
|
||||
@@ -22,7 +28,7 @@ class OrganizationSourceExtensionsApiV2Test(APITestCase):
|
||||
self.client.force_authenticate(self.user)
|
||||
|
||||
def test_list_returns_compact_source_summaries_instead_of_embedded_data(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "API"',
|
||||
inn="7707083810",
|
||||
ogrn="1027700132010",
|
||||
@@ -56,7 +62,7 @@ class OrganizationSourceExtensionsApiV2Test(APITestCase):
|
||||
self.assertEqual(item["sources"][0]["records_count"], 1)
|
||||
|
||||
def test_organization_sources_action_returns_extensions(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Sources"',
|
||||
inn="7707083811",
|
||||
ogrn="1027700132011",
|
||||
@@ -77,7 +83,7 @@ class OrganizationSourceExtensionsApiV2Test(APITestCase):
|
||||
self.assertEqual(response.data[0]["uid"], str(extension.uid))
|
||||
|
||||
def test_source_records_endpoint_returns_extension_records(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Records"',
|
||||
inn="7707083812",
|
||||
ogrn="1027700132012",
|
||||
@@ -110,12 +116,12 @@ class OrganizationSourceExtensionsApiV2Test(APITestCase):
|
||||
)
|
||||
|
||||
def test_flat_source_records_endpoint_filters_by_source_group(self):
|
||||
target = Organization.objects.create(
|
||||
target = create_frontend_organization(
|
||||
name='ООО "Flat Records"',
|
||||
inn="7707083813",
|
||||
ogrn="1027700132013",
|
||||
)
|
||||
other = Organization.objects.create(
|
||||
other = create_frontend_organization(
|
||||
name='ООО "Other Records"',
|
||||
inn="7707083814",
|
||||
ogrn="1027700132014",
|
||||
@@ -160,18 +166,19 @@ class OrganizationSourceExtensionsApiV2Test(APITestCase):
|
||||
self.assertEqual(record["source_group"], "planned_inspections")
|
||||
self.assertEqual(record["organization"]["uid"], str(target.uid))
|
||||
|
||||
def test_flat_source_records_endpoint_filters_by_has_registry(self):
|
||||
with_registry = Organization.objects.create(
|
||||
def test_flat_source_records_scope_cannot_be_lifted_by_has_registry(self):
|
||||
with_registry = create_frontend_organization(
|
||||
name='ООО "With Registry Source"',
|
||||
inn="7707083815",
|
||||
ogrn="1027700132015",
|
||||
opk_registry_membership=True,
|
||||
ropk_razdel_num="source-records",
|
||||
)
|
||||
without_registry = Organization.objects.create(
|
||||
without_registry = create_frontend_organization(
|
||||
name='ООО "Without Registry Source"',
|
||||
inn="7707083816",
|
||||
ogrn="1027700132016",
|
||||
opk_registry_membership=False,
|
||||
)
|
||||
with_registry_extension = PlannedInspectionExtension.objects.create(
|
||||
organization=with_registry,
|
||||
@@ -225,11 +232,11 @@ class OrganizationSourceExtensionsApiV2Test(APITestCase):
|
||||
)
|
||||
self.assertEqual(
|
||||
without_registry_response.data["data"][0]["external_id"],
|
||||
"INSP-WITHOUT-REGISTRY",
|
||||
"INSP-WITH-REGISTRY",
|
||||
)
|
||||
|
||||
def test_source_record_organization_uses_active_registry_identity(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Реестровое имя"',
|
||||
inn="1800020960",
|
||||
kpp="180001001",
|
||||
@@ -266,7 +273,7 @@ class OrganizationSourceExtensionsApiV2Test(APITestCase):
|
||||
self.assertEqual(response_organization["ogrn"], organization.ogrn)
|
||||
|
||||
def test_source_record_organization_keeps_canonical_inn_with_leading_zero(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='ООО "Башнефть-Добыча"',
|
||||
inn="0277106840",
|
||||
ogrn="1090280032699",
|
||||
@@ -298,12 +305,12 @@ class OrganizationSourceExtensionsApiV2Test(APITestCase):
|
||||
self.assertEqual(response_organization["ogrn"], organization.ogrn)
|
||||
|
||||
def test_flat_source_records_searches_payload_values_displayed_in_tables(self):
|
||||
target = Organization.objects.create(
|
||||
target = create_frontend_organization(
|
||||
name='ООО "Поиск по payload"',
|
||||
inn="7707083817",
|
||||
ogrn="1027700132017",
|
||||
)
|
||||
other = Organization.objects.create(
|
||||
other = create_frontend_organization(
|
||||
name='ООО "Другая payload"',
|
||||
inn="7707083818",
|
||||
ogrn="1027700132018",
|
||||
@@ -363,7 +370,7 @@ class OrganizationSourceExtensionsApiV2Test(APITestCase):
|
||||
)
|
||||
|
||||
def test_flat_source_records_searches_registry_identity_displayed_in_tables(self):
|
||||
organization = Organization.objects.create(
|
||||
organization = create_frontend_organization(
|
||||
name='АО "Реестровый поиск"',
|
||||
inn="1800020961",
|
||||
kpp="180001002",
|
||||
|
||||
168
tests/apps/organizations/test_test_companies_commands.py
Normal file
168
tests/apps/organizations/test_test_companies_commands.py
Normal file
@@ -0,0 +1,168 @@
|
||||
"""Tests for deterministic frontend demo company management commands."""
|
||||
|
||||
from io import StringIO
|
||||
|
||||
from apps.exchange.state_corp_services import StateCorpExchangeService
|
||||
from apps.parsers.models import ParserLoadLog
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase, override_settings
|
||||
from organizations.models import (
|
||||
Organization,
|
||||
OrganizationSourceExtension,
|
||||
OrganizationSourceFinancialLine,
|
||||
OrganizationSourceRecord,
|
||||
SourceGroup,
|
||||
)
|
||||
|
||||
TEST_EXCHANGE_TOKEN = "test-exchange-token" # noqa: S105
|
||||
|
||||
|
||||
class TestCompaniesCommandsTest(TestCase):
|
||||
"""Checks creation, refresh, and removal of the fixed demo dataset."""
|
||||
|
||||
def test_create_builds_twenty_companies_with_every_source_dataset(self):
|
||||
call_command("create_test_companies", stdout=StringIO())
|
||||
|
||||
companies = Organization.objects.filter(name__startswith="Тестовая компания ")
|
||||
self.assertEqual(companies.count(), 20)
|
||||
self.assertEqual(
|
||||
set(companies.values_list("name", flat=True)),
|
||||
{f"Тестовая компания {index}" for index in range(1, 21)},
|
||||
)
|
||||
self.assertEqual(companies.filter(opk_registry_membership=True).count(), 20)
|
||||
self.assertEqual(
|
||||
companies.filter(
|
||||
gk_code="2",
|
||||
gk_name='Госкорпорация "Росатом"',
|
||||
).count(),
|
||||
10,
|
||||
)
|
||||
self.assertEqual(
|
||||
companies.filter(
|
||||
gk_code="1",
|
||||
gk_name='Госкорпорация "Роскосмос"',
|
||||
).count(),
|
||||
10,
|
||||
)
|
||||
|
||||
expected_groups = {choice.value for choice in SourceGroup}
|
||||
expected_sources = {choice.value for choice in ParserLoadLog.Source}
|
||||
for company in companies:
|
||||
self.assertEqual(
|
||||
set(company.source_extensions.values_list("source_group", flat=True)),
|
||||
expected_groups,
|
||||
)
|
||||
self.assertEqual(
|
||||
set(
|
||||
OrganizationSourceRecord.objects.filter(
|
||||
extension__organization=company
|
||||
).values_list("source", flat=True)
|
||||
),
|
||||
expected_sources,
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
OrganizationSourceExtension.objects.filter(
|
||||
organization__in=companies
|
||||
).count(),
|
||||
20 * len(expected_groups),
|
||||
)
|
||||
self.assertEqual(
|
||||
OrganizationSourceRecord.objects.filter(
|
||||
extension__organization__in=companies
|
||||
).count(),
|
||||
20 * len(expected_sources),
|
||||
)
|
||||
self.assertEqual(
|
||||
OrganizationSourceFinancialLine.objects.filter(
|
||||
source_record__extension__organization__in=companies
|
||||
).count(),
|
||||
20 * 4,
|
||||
)
|
||||
|
||||
def test_create_updates_the_fixed_dataset_without_duplicates(self):
|
||||
call_command("create_test_companies", stdout=StringIO())
|
||||
company_uids = set(
|
||||
Organization.objects.filter(
|
||||
name__startswith="Тестовая компания "
|
||||
).values_list("uid", flat=True)
|
||||
)
|
||||
first_company = Organization.objects.get(name="Тестовая компания 1")
|
||||
first_company.name = "Поврежденное тестовое имя"
|
||||
first_company.gk_name = "Неверная корпорация"
|
||||
first_company.save(update_fields=["name", "gk_name"])
|
||||
record = OrganizationSourceRecord.objects.filter(
|
||||
extension__organization=first_company,
|
||||
source=ParserLoadLog.Source.INSPECTIONS,
|
||||
).get()
|
||||
record.title = "Устаревшие тестовые данные"
|
||||
record.payload = {"stale": True}
|
||||
record.save(update_fields=["title", "payload"])
|
||||
|
||||
call_command("create_test_companies", stdout=StringIO())
|
||||
|
||||
refreshed_uids = set(
|
||||
Organization.objects.filter(
|
||||
name__startswith="Тестовая компания "
|
||||
).values_list("uid", flat=True)
|
||||
)
|
||||
self.assertEqual(refreshed_uids, company_uids)
|
||||
self.assertEqual(len(refreshed_uids), 20)
|
||||
first_company.refresh_from_db()
|
||||
self.assertEqual(first_company.name, "Тестовая компания 1")
|
||||
self.assertEqual(first_company.gk_name, 'Госкорпорация "Росатом"')
|
||||
record.refresh_from_db()
|
||||
self.assertNotEqual(record.title, "Устаревшие тестовые данные")
|
||||
self.assertIn("registration_number", record.payload)
|
||||
self.assertEqual(OrganizationSourceRecord.objects.count(), 20 * 15)
|
||||
|
||||
@override_settings(STATE_CORP_EXCHANGE_TOKEN=TEST_EXCHANGE_TOKEN)
|
||||
def test_created_source_records_are_exported_to_state_corp_package(self):
|
||||
call_command("create_test_companies", stdout=StringIO())
|
||||
|
||||
company_inns = list(
|
||||
Organization.objects.filter(name__startswith="Тестовая компания ")
|
||||
.order_by("rn")
|
||||
.values_list("inn", flat=True)
|
||||
)
|
||||
package = StateCorpExchangeService.build_package(
|
||||
organization_inns=company_inns
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
package.payload_counts,
|
||||
{
|
||||
"organizations": 20,
|
||||
"industrial_certificates": 20,
|
||||
"manufacturers": 20,
|
||||
"industrial_products": 20,
|
||||
"prosecutor_checks": 20,
|
||||
"public_procurements": 80,
|
||||
"financial_reports": 20,
|
||||
"arbitration_cases": 20,
|
||||
"bankruptcy_procedures": 20,
|
||||
"defense_unreliable_suppliers": 40,
|
||||
"information_security_registries": 20,
|
||||
"labor_vacancies": 20,
|
||||
},
|
||||
)
|
||||
|
||||
def test_delete_removes_only_the_fixed_twenty_companies(self):
|
||||
untouched = Organization.objects.create(
|
||||
name="Тестовая компания 99",
|
||||
inn="7700000099",
|
||||
ogrn="1027700000099",
|
||||
opk_registry_membership=True,
|
||||
)
|
||||
call_command("create_test_companies", stdout=StringIO())
|
||||
|
||||
call_command("delete_test_companies", stdout=StringIO())
|
||||
|
||||
self.assertFalse(
|
||||
Organization.objects.filter(
|
||||
name__in=[f"Тестовая компания {index}" for index in range(1, 21)]
|
||||
).exists()
|
||||
)
|
||||
self.assertTrue(Organization.objects.filter(uid=untouched.uid).exists())
|
||||
self.assertEqual(OrganizationSourceExtension.objects.count(), 0)
|
||||
self.assertEqual(OrganizationSourceRecord.objects.count(), 0)
|
||||
Reference in New Issue
Block a user