"""SRO queries use the directory's canonical organization without hiding conflicts.""" from apps.parsers.models import SroOrganizationLookup from apps.parsers.sro_membership import _organization_fingerprint, _sro_candidates from django.test import TestCase from django.utils import timezone from organizations.models import Organization class SroCanonicalCandidatesTest(TestCase): def create_organization(self, **overrides): values = { "name": "АО Фикстура", "inn": "1234567890", "ogrn": "1027700132195", "okpo": "00123456", "directory_imported_at": timezone.now(), } values.update(overrides) return Organization.objects.create(**values) def candidate_ids(self, mode): return [organization.uid for organization in _sro_candidates(mode)] def test_head_and_branches_are_queried_as_one_canonical_organization(self): head = self.create_organization() self.create_organization(name="Первый филиал", is_branch=True) self.create_organization(name="Второй филиал", is_branch=True) for mode in ("full", "incremental"): with self.subTest(mode=mode): self.assertEqual(self.candidate_ids(mode), [head.uid]) def test_ambiguous_heads_are_not_silently_discarded_or_chosen(self): first = self.create_organization() second = self.create_organization(name="Другой головной офис") for mode in ("full", "incremental"): with self.subTest(mode=mode): self.assertEqual(set(self.candidate_ids(mode)), {first.uid, second.uid}) def test_unchanged_head_skips_incremental_and_branches_do_not_retrigger_it(self): head = self.create_organization() self.create_organization(name="Филиал без контрольной точки", is_branch=True) SroOrganizationLookup.objects.create( organization=head, checked_at=timezone.now(), organization_fingerprint=_organization_fingerprint(head), ) self.assertEqual(self.candidate_ids("incremental"), []) self.assertEqual(self.candidate_ids("full"), [head.uid]) head.name = "Новое наименование головной организации" head.save(update_fields=["name"]) self.assertEqual(self.candidate_ids("incremental"), [head.uid]) def test_branch_with_distinct_identity_remains_a_candidate(self): head = self.create_organization() branch = self.create_organization( name="Филиал с собственными реквизитами", inn="1234567891", ogrn="1027700132196", is_branch=True, ) for mode in ("full", "incremental"): with self.subTest(mode=mode): self.assertEqual(set(self.candidate_ids(mode)), {head.uid, branch.uid}) def test_incomplete_resolution_does_not_discard_the_candidate(self): head = self.create_organization(okpo="") branch = self.create_organization(name="Филиал", is_branch=True) for mode in ("full", "incremental"): with self.subTest(mode=mode): self.assertEqual(set(self.candidate_ids(mode)), {head.uid, branch.uid}) def test_organization_outside_directory_does_not_become_a_candidate(self): head = self.create_organization() self.create_organization(directory_imported_at=None) self.assertEqual(self.candidate_ids("full"), [head.uid])