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",
|
||||
|
||||
Reference in New Issue
Block a user