- модели LegalEntity.kpp / LegalEntityHistory.kpp (последней колонкой), миграция 0005_dbml_v5_17 (upgrade/downgrade); - domain/kpp.py: 9 символов (4 цифры, 2 цифры/латинские A-Z, 3 цифры), у ИП запрещён, иначе 422 INVALID_KPP; - схемы Create/Update/Out/Detail/HistoryOut, PATCH пишет снимок history и аудит before/after с kpp, поиск q по КПП; - импорт справочника: необязательная колонка КПП (синоним kpp), код INVALID_KPP, update обновляет непустой КПП; - dev-seed: необязательный ключ kpp (значений в данных нет, не выдумываем); - сверка с DBML, Makefile, README, CLAUDE.md, openspec/config.yaml — на v5.17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EAKRDNzXtRrwmWz9z6PZu3
55 lines
2.0 KiB
Python
55 lines
2.0 KiB
Python
"""КПП: нормализация и проверка формата (05-domain-rules §13.5, DBML v5.17, OQ-31)."""
|
||
|
||
import pytest
|
||
|
||
from src.common.exceptions import DomainValidationError
|
||
from src.domain.kpp import normalize_kpp, validate_kpp
|
||
from src.models.enums import EntityType
|
||
|
||
|
||
@pytest.mark.parametrize("raw", ["352801001", "352845001", "3528AB001", "35280A001", "3528A1001", "000000000"])
|
||
def test_valid_kpp_for_legal_entity(raw: str) -> None:
|
||
assert validate_kpp(raw, EntityType.ЮЛ) == raw
|
||
|
||
|
||
def test_kpp_is_normalized_whitespace_removed_and_uppercased() -> None:
|
||
assert validate_kpp(" 3528 ab 001 ", EntityType.ЮЛ) == "3528AB001"
|
||
|
||
|
||
@pytest.mark.parametrize("raw", [None, "", " "])
|
||
def test_empty_kpp_is_none(raw: str | None) -> None:
|
||
assert normalize_kpp(raw) is None
|
||
assert validate_kpp(raw, EntityType.ЮЛ) is None
|
||
assert validate_kpp(raw, EntityType.ИП) is None # у ИП пустой КПП — норма
|
||
|
||
|
||
@pytest.mark.parametrize(
|
||
"raw",
|
||
[
|
||
"35280100", # 8 символов
|
||
"3528010011", # 10 символов
|
||
"A52801001", # буква в первых четырёх
|
||
"3528010A1", # буква в последних трёх
|
||
"35280100A",
|
||
"3528ab00", # короткий
|
||
"3528я1001", # кириллица
|
||
"٣٥٢٨٠١٠٠١", # не ASCII-цифры
|
||
"3528-1001",
|
||
],
|
||
)
|
||
def test_wrong_format_is_invalid_kpp(raw: str) -> None:
|
||
with pytest.raises(DomainValidationError) as error:
|
||
validate_kpp(raw, EntityType.ЮЛ)
|
||
assert error.value.code == "INVALID_KPP"
|
||
|
||
|
||
def test_kpp_is_forbidden_for_sole_proprietor() -> None:
|
||
with pytest.raises(DomainValidationError) as error:
|
||
validate_kpp("352801001", EntityType.ИП)
|
||
assert error.value.code == "INVALID_KPP"
|
||
assert error.value.message == "у ИП КПП не бывает"
|
||
|
||
|
||
def test_unknown_entity_type_is_treated_as_legal_entity() -> None:
|
||
assert validate_kpp("352801001", None) == "352801001"
|