Corp/backend/scripts/update_test_helpers.py
igor_nadein ad8208789f feat: add LDAP testing infrastructure
- Add LDAP docker container structure (01-base-structure.ldif)
- Add .env.test with LDAP configuration for tests
- Create tests/ldap_fixtures.py with LDAP-specific fixtures
- Create tests/api/v1/employees/test_helpers.py with centralized helpers
- Add LDAP markers to pytest.ini (ldap_required, ldap_optional)
- Add comprehensive LDAP testing documentation
- Fix test_department_head_rights.py to use centralized helpers

New fixtures:
- ldap_available: checks if LDAP server is accessible
- ldap_config: returns LDAP configuration
- ensure_ldap_enabled/disabled: force LDAP state for test
- ldap_cleanup: auto-cleanup LDAP entries after test

New helpers:
- make_user(): centralized user creation
- grant_permission(): permission assignment
- make_department/position/role(): entity creation
- extract_results(): paginated response helper

Infrastructure:
- OU=Users, OU=Departments, OU=Groups, OU=Positions, OU=Dismissed
- Test groups: Developers, Managers
- Test departments: IT, HR
2026-02-16 17:31:48 +03:00

131 lines
4.2 KiB
Python
Raw 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 python
"""
Скрипт для обновления тестов - заменяет локальные helper функции на импорты из test_helpers.
"""
import re
import sys
from pathlib import Path
# Файлы для обработки
test_dir = Path("tests/api/v1/employees")
files_to_update = [
"test_department_head_rights.py",
"test_department_membership_separation.py",
"test_department_roles.py",
"test_department_roles_extra.py",
"test_departments.py",
"test_email_verification_security.py",
"test_employee_actions.py",
"test_employees.py",
"test_employees_fields_in_list.py",
"test_ldap_optional_groups.py",
"test_positions.py",
"test_role_assignment.py",
"test_skills.py",
]
def add_import_if_missing(content: str) -> str:
"""Добавляет импорт test_helpers если его нет."""
import_line = "from tests.api.v1.employees.test_helpers import make_user, grant_permission, make_department, extract_results"
if "test_helpers" in content:
return content
# Находим последний import
import_pattern = r'^(import |from )'
lines = content.split('\n')
last_import_idx = 0
for i, line in enumerate(lines):
if re.match(import_pattern, line):
last_import_idx = i
# Вставляем после последнего импорта
lines.insert(last_import_idx + 1, import_line)
return '\n'.join(lines)
def remove_local_functions(content: str) -> str:
"""Удаляет локальные определения helper функций."""
# Паттерны для удаления
patterns = [
# make_user fixture
r'@pytest\.fixture\s+def make_user\([^)]*\)[^:]*:.*?(?=\n(?:def |class |@pytest|$))',
# make_user обычная функция
r'def make_user\([^)]*\)[^:]*:.*?(?=\n(?:def |class |@pytest|$))',
# _make_user
r'def _make_user\([^)]*\)[^:]*:.*?(?=\n(?:def |class |@pytest|$))',
# _user
r'def _user\([^)]*\)[^:]*:.*?(?=\n(?:def |class |@pytest|$))',
# _grant, _grant_perm
r'def _grant(?:_perm)?\([^)]*\)[^:]*:.*?(?=\n(?:def |class |@pytest|$))',
# _unique_phone, _unique_email
r'def _unique_(?:phone|email)\([^)]*\)[^:]*:.*?(?=\n(?:def |class |@pytest|$))',
# extract_results
r'def extract_results\([^)]*\)[^:]*:.*?(?=\n(?:def |class |@pytest|$))',
]
for pattern in patterns:
content = re.sub(pattern, '', content, flags=re.DOTALL | re.MULTILINE)
return content
def replace_function_calls(content: str) -> str:
"""Заменяет вызовы локальных функций на импортированные."""
replacements = {
r'\b_make_user\(': 'make_user(',
r'\b_user\(': 'make_user(',
r'\b_grant\(': 'grant_permission(',
r'\b_grant_perm\(': 'grant_permission(',
}
for old, new in replacements.items():
content = re.sub(old, new, content)
return content
def update_file(filepath: Path):
"""Обновляет один файл."""
print(f"Обновляем {filepath.name}...")
content = filepath.read_text(encoding='utf-8')
# Добавляем импорт
content = add_import_if_missing(content)
# Удаляем локальные функции
content = remove_local_functions(content)
# Заменяем вызовы
content = replace_function_calls(content)
# Убираем лишние пустые строки
content = re.sub(r'\n{3,}', '\n\n', content)
filepath.write_text(content, encoding='utf-8')
print(f" ✓ {filepath.name} обновлен")
def main():
"""Главная функция."""
for filename in files_to_update:
filepath = test_dir / filename
if filepath.exists():
try:
update_file(filepath)
except Exception as e:
print(f" ✗ Ошибка в {filename}: {e}", file=sys.stderr)
else:
print(f" ! {filename} не найден")
print("\n✅ Обновление завершено!")
if __name__ == "__main__":
main()