Files
Dokogenerator-152FZ/test_defence.py
LocoAgent 230a392a15 fix: аудит ветки source — критические и высокие замечания
- api_settings: убраны реальные API-ключи из кода (чтение из env/файла) — 1.1
- variables: {{is_security_requirements}} больше не подставляет всегда УЗ-4;
  extended_fields/defence_level передаются в контекст — 1.2
- defence.py: эталонная таблица ПП-1119 (п.9-12), 48 комбинаций;
  ui.py: авторасчёт УЗ переведён на неё (public больше не 'всегда 4',
  спец/био/общедоступные/иные разделены) — 2.1
- generator: убран дубль хвоста параграфа в _highlight_unmatched — 2.2
- importer: категории ПДн взаимоисключающие ('иные' только если нет
  спец/био); УЗ пересчитывается при импорте — 2.3
- import_settings(.py/.json): убран перехват 'администратора безопасности'
  правилом ответственного за ПДн — 3.1
- variables: {{category}}/{{is.category}} резолвятся из personal_data_category — 3.2
- verify: ИИ-предложения ИНН/ОГРН/КПП валидируются контрольными суммами
  перед применением — 3.3
- models: defence_level None вместо '' (не маскирует 'не рассчитано')
- .gitignore: api_settings.json/.env не попадают в git
- test_defence.py: юнит-тест всех 48 комбинаций таблицы УЗ
2026-08-05 08:58:17 +04:00

70 lines
3.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Юнит-тесты расчёта УЗ по ПП РФ № 1119 (все комбинации таблицы).
Эталонные значения — из текста ПП-1119 п. 9–12 (сверено с legalacts.ru).
Комбинации: 4 группы категорий × 2 признака «только сотрудники» ×
2 объёма (>100к) × 3 типа угроз = 48.
"""
import sys, os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from dokogen.defence import calc_defence_level
def _cases():
"""(categories, employees, large, threat, expected_uz)"""
c = []
# --- Специальные ---
for emp in (False, True):
for large in (False, True):
c.append((['специальные'], emp, large, '1', 1)) # п.9а
c.append((['специальные'], emp, large, '2',
1 if (not emp and large) else 2)) # п.9б / п.10б
c.append((['специальные'], emp, large, '3',
2 if (not emp and large) else 3)) # п.10е / п.11в
# --- Биометрические (без разбивки по количеству) ---
for emp in (False, True):
for large in (False, True):
c.append((['биометрические'], emp, large, '1', 1)) # п.9а
c.append((['биометрические'], emp, large, '2', 2)) # п.10в
c.append((['биометрические'], emp, large, '3', 3)) # п.11г
# --- Общедоступные ---
for emp in (False, True):
for large in (False, True):
c.append((['общедоступные'], emp, large, '1', 2)) # п.10а
c.append((['общедоступные'], emp, large, '2',
2 if (not emp and large) else 3)) # п.10г / п.11а
c.append((['общедоступные'], emp, large, '3', 4)) # п.12а
# --- Иные ---
for emp in (False, True):
for large in (False, True):
c.append((['иные'], emp, large, '1', 1)) # п.9а
c.append((['иные'], emp, large, '2',
2 if (not emp and large) else 3)) # п.10д / п.11б
c.append((['иные'], emp, large, '3',
3 if (not emp and large) else 4)) # п.11д / п.12б
return c
def main():
cases = _cases()
assert len(cases) == 48, f"ожидалось 48 комбинаций, получено {len(cases)}"
failed = 0
for cats, emp, large, threat, expected in cases:
got = calc_defence_level(cats, emp, large, threat)
if got != expected:
failed += 1
print(f"❌ {cats} emp={emp} large={large} threat={threat}: "
f"ожидалось УЗ-{expected}, получено УЗ-{got}")
if failed:
print(f"\nFAILED: {failed} из {len(cases)}")
return 1
print(f"✅ УЗ по ПП-1119: все {len(cases)} комбинаций верны")
return 0
if __name__ == '__main__':
sys.exit(main())