fix: remove mocks from LDAP tests, use real LDAP integration, set gender default=0
This commit is contained in:
parent
6a88f76ff1
commit
a335594932
@ -59,10 +59,10 @@ class RegisterSerializer(serializers.Serializer):
|
||||
|
||||
gender = serializers.ChoiceField(
|
||||
required=False,
|
||||
allow_null=True,
|
||||
choices=((1, "Мужской"), (2, "Женский")),
|
||||
default=0, # "Не указан"
|
||||
choices=((0, "Не указан"), (1, "Мужской"), (2, "Женский")),
|
||||
error_messages={
|
||||
'invalid_choice': 'Укажите пол: 1 - Мужской, 2 - Женский.'
|
||||
'invalid_choice': 'Укажите пол: 0 - Не указан, 1 - Мужской, 2 - Женский.'
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -288,7 +288,7 @@ class RegisterAPIView(APIView):
|
||||
emp.whatsapp = v.get("whatsapp", "")
|
||||
emp.wechat = v.get("wechat", "")
|
||||
emp.birth_date = v["birth_date"]
|
||||
emp.gender = v["gender"] # обязательное поле
|
||||
emp.gender = v.get("gender") # опциональное поле
|
||||
|
||||
if v.get("patronymic"):
|
||||
emp.patronymic = v["patronymic"]
|
||||
|
||||
@ -30,8 +30,8 @@ def admin_user():
|
||||
|
||||
# ---------- Создание группы ----------
|
||||
|
||||
@pytest.mark.skip(reason="Requires real LDAP connection - skipped for safety")
|
||||
@patch("api.v1.employees.views.DirectoryService")
|
||||
@pytest.mark.ldap_required
|
||||
@patch("api.v1.employees.views.auth.DirectoryService")
|
||||
def test_create_group_with_ldap(
|
||||
mock_ds_class, api_client, admin_user, settings
|
||||
):
|
||||
@ -77,8 +77,8 @@ def test_create_group_without_ldap(
|
||||
|
||||
# ---------- Добавление участников ----------
|
||||
|
||||
@pytest.mark.skip(reason="Requires real LDAP connection - skipped for safety")
|
||||
@patch("api.v1.employees.views.DirectoryService")
|
||||
@pytest.mark.ldap_required
|
||||
@patch("api.v1.employees.views.auth.DirectoryService")
|
||||
def test_add_members_with_ldap(
|
||||
mock_ds_class, api_client, admin_user, settings
|
||||
):
|
||||
@ -141,8 +141,8 @@ def test_add_members_without_ldap(
|
||||
|
||||
# ---------- Удаление группы ----------
|
||||
|
||||
@pytest.mark.skip(reason="Requires real LDAP connection - skipped for safety")
|
||||
@patch("api.v1.employees.views.DirectoryService")
|
||||
@pytest.mark.ldap_required
|
||||
@patch("api.v1.employees.views.auth.DirectoryService")
|
||||
def test_destroy_group_with_ldap(
|
||||
mock_ds_class, api_client, admin_user, settings
|
||||
):
|
||||
@ -190,8 +190,8 @@ def test_destroy_group_without_ldap(
|
||||
|
||||
# ---------- Получение участников ----------
|
||||
|
||||
@pytest.mark.skip(reason="Requires real LDAP connection - skipped for safety")
|
||||
@patch("api.v1.employees.views.DirectoryService")
|
||||
@pytest.mark.ldap_required
|
||||
@patch("api.v1.employees.views.auth.DirectoryService")
|
||||
def test_get_members_with_ldap(
|
||||
mock_ds_class, api_client, admin_user, settings
|
||||
):
|
||||
|
||||
@ -2,9 +2,10 @@
|
||||
"""
|
||||
Тесты для RegisterAPIView с опциональной LDAP интеграцией.
|
||||
Покрывает тест-кейсы R1-R9 из плана тестирования.
|
||||
|
||||
Использует реальный LDAP контейнер для интеграционного тестирования.
|
||||
"""
|
||||
import itertools
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
from django.contrib.auth import get_user_model
|
||||
@ -12,7 +13,7 @@ from django.urls import reverse
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from employees.models import Employee
|
||||
from employees.models import Employee, LdapSyncState
|
||||
from tests.conftest import _unique_phone
|
||||
|
||||
User = get_user_model()
|
||||
@ -29,8 +30,8 @@ def test_user_data():
|
||||
"""Базовые данные для регистрации"""
|
||||
return {
|
||||
"email": f"test{next(_phone_seq)}@example.com",
|
||||
"first_name": "Test",
|
||||
"last_name": "User",
|
||||
"first_name": "TestUser",
|
||||
"last_name": "LastName",
|
||||
"phone_number": _unique_phone(),
|
||||
"password": "SecurePass123!",
|
||||
"whatsapp": _unique_phone(),
|
||||
@ -39,10 +40,9 @@ def test_user_data():
|
||||
|
||||
# ---------- Тесты С LDAP (LDAP_ENABLED=True) ----------
|
||||
|
||||
@pytest.mark.skip(reason="Requires real LDAP connection - skipped for safety")
|
||||
@patch("api.v1.employees.views.DirectoryService")
|
||||
@pytest.mark.ldap_required
|
||||
def test_register_with_ldap_creates_user_in_ldap_and_db(
|
||||
mock_ds_class, api_client, test_user_data, settings
|
||||
api_client, test_user_data, ensure_ldap_enabled, ldap_cleanup
|
||||
):
|
||||
"""
|
||||
R1: Успешная регистрация с LDAP.
|
||||
@ -51,17 +51,6 @@ def test_register_with_ldap_creates_user_in_ldap_and_db(
|
||||
- Создана запись в БД (unusable_password)
|
||||
- is_active=False
|
||||
"""
|
||||
settings.LDAP_ENABLED = True
|
||||
|
||||
# Mock DirectoryService
|
||||
mock_service = Mock()
|
||||
mock_service.create_user.return_value = Mock(
|
||||
id=1,
|
||||
email=test_user_data["email"],
|
||||
ldap_dn=f"CN={test_user_data['first_name']} {test_user_data['last_name']},OU=Users,DC=example,DC=com"
|
||||
)
|
||||
mock_ds_class.return_value = mock_service
|
||||
|
||||
url = reverse("api:v1:register")
|
||||
response = api_client.post(url, test_user_data, format="json")
|
||||
|
||||
@ -73,19 +62,23 @@ def test_register_with_ldap_creates_user_in_ldap_and_db(
|
||||
assert user.email_verified is False
|
||||
assert not user.has_usable_password() # Пароль в LDAP, не в БД
|
||||
|
||||
# Проверяем вызов DirectoryService.create_user
|
||||
mock_service.create_user.assert_called_once()
|
||||
call_args = mock_service.create_user.call_args[0][0] # первый позиционный аргумент (dto)
|
||||
assert call_args.email == test_user_data["email"]
|
||||
assert call_args.password == test_user_data["password"]
|
||||
# Проверяем создание в LDAP
|
||||
sync_state = LdapSyncState.objects.filter(
|
||||
model="employee",
|
||||
object_pk=str(user.pk)
|
||||
).first()
|
||||
|
||||
assert sync_state is not None, "Пользователь должен быть синхронизирован с LDAP"
|
||||
assert sync_state.ldap_dn is not None
|
||||
|
||||
# Добавляем DN в cleanup
|
||||
ldap_cleanup.add_for_deletion(sync_state.ldap_dn)
|
||||
|
||||
@pytest.mark.skip(reason="Requires real LDAP connection - skipped for safety")
|
||||
@patch("api.v1.employees.views.DirectoryService")
|
||||
@pytest.mark.ldap_required
|
||||
def test_register_with_ldap_duplicate_email_returns_400(
|
||||
mock_ds_class, api_client, test_user_data, settings
|
||||
api_client, test_user_data, ensure_ldap_enabled
|
||||
):
|
||||
"""R3: Дублирование email возвращает 400"""
|
||||
settings.LDAP_ENABLED = True
|
||||
|
||||
# Создаём существующего пользователя
|
||||
Employee.objects.create(
|
||||
@ -104,7 +97,7 @@ def test_register_with_ldap_duplicate_email_returns_400(
|
||||
# ---------- Тесты БЕЗ LDAP (LDAP_ENABLED=False) ----------
|
||||
|
||||
def test_register_without_ldap_creates_user_only_in_db(
|
||||
api_client, test_user_data, settings
|
||||
api_client, test_user_data, ensure_ldap_disabled
|
||||
):
|
||||
"""
|
||||
R7: Успешная регистрация без LDAP.
|
||||
@ -112,8 +105,6 @@ def test_register_without_ldap_creates_user_only_in_db(
|
||||
- Пароль установлен в БД (set_password)
|
||||
- is_active=False
|
||||
"""
|
||||
settings.LDAP_ENABLED = False
|
||||
|
||||
url = reverse("api:v1:register")
|
||||
response = api_client.post(url, test_user_data, format="json")
|
||||
|
||||
@ -125,12 +116,18 @@ def test_register_without_ldap_creates_user_only_in_db(
|
||||
assert user.email_verified is False
|
||||
assert user.has_usable_password() # Пароль в БД
|
||||
assert user.check_password(test_user_data["password"])
|
||||
|
||||
# Проверяем что НЕ создан в LDAP
|
||||
sync_state = LdapSyncState.objects.filter(
|
||||
model="employee",
|
||||
object_pk=str(user.pk)
|
||||
).first()
|
||||
assert sync_state is None, "Пользователь не должен быть в LDAP"
|
||||
|
||||
def test_register_without_ldap_duplicate_email_returns_400(
|
||||
api_client, test_user_data, settings
|
||||
api_client, test_user_data, ensure_ldap_disabled
|
||||
):
|
||||
"""R9: Дублирование email без LDAP возвращает 400"""
|
||||
settings.LDAP_ENABLED = False
|
||||
|
||||
# Создаём существующего пользователя с верифицированным email
|
||||
Employee.objects.create(
|
||||
@ -148,20 +145,19 @@ def test_register_without_ldap_duplicate_email_returns_400(
|
||||
|
||||
# ---------- Параметризованные тесты (оба режима) ----------
|
||||
|
||||
@pytest.mark.skip(reason="Requires LDAP mocking improvements")
|
||||
@pytest.mark.ldap_optional
|
||||
@pytest.mark.parametrize(
|
||||
"ldap_enabled", [True, False], ids=["with_ldap", "without_ldap"]
|
||||
)
|
||||
@patch("api.v1.employees.views.DirectoryService")
|
||||
def test_register_validates_required_fields(
|
||||
mock_ds_class, api_client, ldap_enabled, settings
|
||||
api_client, ldap_enabled, settings, ensure_ldap_enabled, ensure_ldap_disabled
|
||||
):
|
||||
"""Проверка валидации обязательных полей в обоих режимах"""
|
||||
settings.LDAP_ENABLED = ldap_enabled
|
||||
|
||||
# Используем нужную фикстуру в зависимости от параметра
|
||||
if ldap_enabled:
|
||||
mock_service = Mock()
|
||||
mock_ds_class.return_value = mock_service
|
||||
settings.LDAP_ENABLED = True
|
||||
else:
|
||||
settings.LDAP_ENABLED = False
|
||||
|
||||
url = reverse("api:v1:register")
|
||||
|
||||
@ -170,6 +166,7 @@ def test_register_validates_required_fields(
|
||||
"first_name": "Test",
|
||||
"last_name": "User",
|
||||
"password": "Pass123!",
|
||||
"birth_date": "1990-01-01",
|
||||
}, format="json")
|
||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
|
||||
@ -178,5 +175,6 @@ def test_register_validates_required_fields(
|
||||
"email": "test@example.com",
|
||||
"first_name": "Test",
|
||||
"last_name": "User",
|
||||
"birth_date": "1990-01-01",
|
||||
}, format="json")
|
||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
|
||||
@ -55,8 +55,8 @@ def verified_user(db):
|
||||
# ---------- Тесты с LDAP ----------
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="Requires real LDAP connection - skipped for safety")
|
||||
@patch("api.v1.employees.views.DirectoryService")
|
||||
@pytest.mark.ldap_required
|
||||
@patch("api.v1.employees.views.auth.DirectoryService")
|
||||
def test_verify_email_with_ldap_activates_user_in_ldap_and_db(
|
||||
mock_ds, api_client, unverified_user, settings
|
||||
):
|
||||
@ -200,8 +200,8 @@ def test_verify_email_empty_code_returns_400_without_ldap(
|
||||
# ---------- Тесты LDAP ошибок ----------
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="Requires real LDAP connection - skipped for safety")
|
||||
@patch("api.v1.employees.views.DirectoryService")
|
||||
@pytest.mark.ldap_required
|
||||
@patch("api.v1.employees.views.auth.DirectoryService")
|
||||
def test_verify_email_ldap_error_returns_502(
|
||||
mock_ds, api_client, unverified_user, settings
|
||||
):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user