"""Фабрики для создания тестовых объектов с использованием factory_boy и faker""" import factory from apps.user.models import Profile, User from faker import Faker fake = Faker("ru_RU") class UserFactory(factory.django.DjangoModelFactory): """Фабрика для создания пользователей""" class Meta: model = User skip_postgeneration_save = True email = factory.LazyAttribute(lambda _: fake.unique.email()) username = factory.LazyAttribute(lambda _: fake.unique.user_name()) phone = factory.LazyAttribute( lambda _: f"+7{fake.numerify('##########')}" ) is_verified = False is_staff = False is_superuser = False is_active = True @factory.lazy_attribute def password(self): return "testpass123" @classmethod def _create(cls, model_class, *args, **kwargs): """Переопределяем создание для корректной установки пароля""" password = kwargs.pop("password", "testpass123") obj = super()._create(model_class, *args, **kwargs) obj.set_password(password) obj.save() return obj @classmethod def create_user(cls, **kwargs): """Создать обычного пользователя (для обратной совместимости)""" return cls.create(**kwargs) @classmethod def create_superuser(cls, **kwargs): """Создать суперпользователя""" defaults = { "is_staff": True, "is_superuser": True, } defaults.update(kwargs) return cls.create(**defaults) class ProfileFactory(factory.django.DjangoModelFactory): """Фабрика для создания профилей""" class Meta: model = Profile django_get_or_create = ("user",) # Используем get_or_create для избежания дубликатов user = factory.SubFactory(UserFactory) first_name = factory.LazyAttribute(lambda _: fake.first_name()) last_name = factory.LazyAttribute(lambda _: fake.last_name()) bio = factory.LazyAttribute(lambda _: fake.text(max_nb_chars=200)) date_of_birth = factory.LazyAttribute( lambda _: fake.date_of_birth(minimum_age=18, maximum_age=80) ) @classmethod def create_profile(cls, user=None, **kwargs): """Создать профиль (для обратной совместимости)""" if user is not None: # Проверяем, существует ли уже профиль (сигнал мог создать) try: profile = user.profile # Обновляем существующий профиль for key, value in kwargs.items(): setattr(profile, key, value) # Заполняем поля faker'ом, если не переданы if "first_name" not in kwargs: profile.first_name = fake.first_name() if "last_name" not in kwargs: profile.last_name = fake.last_name() if "bio" not in kwargs: profile.bio = fake.text(max_nb_chars=200) profile.save() return profile except Profile.DoesNotExist: pass kwargs["user"] = user return cls.create(**kwargs)