Files
mostovik-backend/tests/apps/user/test_serializers.py
Aleksandr Meshchriakov f121445313 feat(core): add core module with mixins, services, and background jobs
- Add Model Mixins: TimestampMixin, SoftDeleteMixin, AuditMixin, etc.
- Add Base Services: BaseService, BulkOperationsMixin, QueryOptimizerMixin
- Add Base ViewSets with bulk operations
- Add BackgroundJob model for Celery task tracking
- Add BaseAppCommand for management commands
- Add permissions, pagination, filters, cache, logging
- Migrate tests to factory_boy + faker
- Add CHANGELOG.md
- 297 tests passing
2026-01-21 11:47:26 +01:00

292 lines
10 KiB
Python

"""Tests for user serializers"""
from apps.user.serializers import (
LoginSerializer,
PasswordChangeSerializer,
ProfileUpdateSerializer,
TokenSerializer,
UserRegistrationSerializer,
UserSerializer,
UserUpdateSerializer,
)
from django.contrib.auth import get_user_model
from django.test import TestCase
from faker import Faker
from .factories import ProfileFactory, UserFactory
User = get_user_model()
fake = Faker("ru_RU")
class UserRegistrationSerializerTest(TestCase):
"""Tests for UserRegistrationSerializer"""
def setUp(self):
self.password = fake.password(length=12, special_chars=False)
self.user_data = {
"email": fake.unique.email(),
"username": fake.unique.user_name(),
"password": self.password,
"password_confirm": self.password,
"phone": f"+7{fake.numerify('##########')}",
}
def test_valid_registration_data(self):
"""Test valid registration data"""
serializer = UserRegistrationSerializer(data=self.user_data)
self.assertTrue(serializer.is_valid())
def test_passwords_do_not_match(self):
"""Test validation fails when passwords don't match"""
data = self.user_data.copy()
data["password_confirm"] = fake.password(length=12, special_chars=False)
serializer = UserRegistrationSerializer(data=data)
self.assertFalse(serializer.is_valid())
self.assertIn("non_field_errors", serializer.errors)
def test_short_password(self):
"""Test validation fails with short password"""
short_password = fake.pystr(min_chars=3, max_chars=5)
data = self.user_data.copy()
data["password"] = short_password
data["password_confirm"] = short_password
serializer = UserRegistrationSerializer(data=data)
self.assertFalse(serializer.is_valid())
self.assertIn("password", serializer.errors)
def test_duplicate_email(self):
"""Test validation fails with duplicate email"""
existing_user = UserFactory.create_user()
data = self.user_data.copy()
data["email"] = existing_user.email
serializer = UserRegistrationSerializer(data=data)
self.assertFalse(serializer.is_valid())
self.assertIn("email", serializer.errors)
def test_duplicate_username(self):
"""Test validation fails with duplicate username"""
existing_user = UserFactory.create_user()
data = self.user_data.copy()
data["username"] = existing_user.username
serializer = UserRegistrationSerializer(data=data)
self.assertFalse(serializer.is_valid())
self.assertIn("username", serializer.errors)
def test_create_user(self):
"""Test user creation through serializer"""
serializer = UserRegistrationSerializer(data=self.user_data)
self.assertTrue(serializer.is_valid())
user = serializer.save()
self.assertIsInstance(user, User)
self.assertEqual(user.email, self.user_data["email"])
self.assertEqual(user.username, self.user_data["username"])
self.assertTrue(user.check_password(self.user_data["password"]))
class UserSerializerTest(TestCase):
"""Tests for UserSerializer"""
def setUp(self):
self.user = UserFactory.create_user()
ProfileFactory.create_profile(user=self.user)
def test_user_serialization(self):
"""Test user serialization"""
serializer = UserSerializer(self.user)
data = serializer.data
self.assertEqual(data["id"], self.user.id)
self.assertEqual(data["email"], self.user.email)
self.assertEqual(data["username"], self.user.username)
self.assertEqual(data["phone"], self.user.phone)
self.assertEqual(data["is_verified"], self.user.is_verified)
self.assertIn("profile", data)
self.assertIn("created_at", data)
self.assertIn("updated_at", data)
def test_read_only_fields(self):
"""Test that read-only fields are not writable"""
read_only_fields = ["id", "is_verified", "created_at", "updated_at"]
serializer = UserSerializer()
for field_name in read_only_fields:
self.assertIn(field_name, serializer.Meta.read_only_fields)
class UserUpdateSerializerTest(TestCase):
"""Tests for UserUpdateSerializer"""
def setUp(self):
self.user = UserFactory.create_user()
def test_valid_update_data(self):
"""Test valid update data"""
update_data = {
"username": fake.unique.user_name(),
"phone": f"+7{fake.numerify('##########')}",
}
serializer = UserUpdateSerializer(self.user, data=update_data, partial=True)
self.assertTrue(serializer.is_valid())
updated_user = serializer.save()
self.assertEqual(updated_user.username, update_data["username"])
self.assertEqual(updated_user.phone, update_data["phone"])
def test_fields_allowed(self):
"""Test only allowed fields can be updated"""
serializer = UserUpdateSerializer()
allowed_fields = ["username", "phone"]
self.assertEqual(set(serializer.Meta.fields), set(allowed_fields))
class ProfileUpdateSerializerTest(TestCase):
"""Tests for ProfileUpdateSerializer"""
def setUp(self):
self.user = UserFactory.create_user()
self.profile = ProfileFactory.create_profile(user=self.user)
def test_valid_profile_update_data(self):
"""Test valid profile update data"""
update_data = {
"first_name": fake.first_name(),
"last_name": fake.last_name(),
"bio": fake.text(max_nb_chars=200),
"date_of_birth": str(fake.date_of_birth(minimum_age=18, maximum_age=80)),
}
serializer = ProfileUpdateSerializer(
self.profile, data=update_data, partial=True
)
self.assertTrue(serializer.is_valid())
updated_profile = serializer.save()
self.assertEqual(updated_profile.first_name, update_data["first_name"])
self.assertEqual(updated_profile.last_name, update_data["last_name"])
self.assertEqual(updated_profile.bio, update_data["bio"])
def test_fields_allowed(self):
"""Test only allowed fields can be updated"""
serializer = ProfileUpdateSerializer()
allowed_fields = ["first_name", "last_name", "bio", "avatar", "date_of_birth"]
self.assertEqual(set(serializer.Meta.fields), set(allowed_fields))
class LoginSerializerTest(TestCase):
"""Tests for LoginSerializer"""
def setUp(self):
self.login_data = {
"email": fake.email(),
"password": fake.password(length=12, special_chars=False),
}
def test_valid_login_data(self):
"""Test valid login data"""
serializer = LoginSerializer(data=self.login_data)
self.assertTrue(serializer.is_valid())
def test_missing_email(self):
"""Test validation fails without email"""
data = {"password": fake.password(length=12, special_chars=False)}
serializer = LoginSerializer(data=data)
self.assertFalse(serializer.is_valid())
self.assertIn("email", serializer.errors)
def test_missing_password(self):
"""Test validation fails without password"""
data = {"email": fake.email()}
serializer = LoginSerializer(data=data)
self.assertFalse(serializer.is_valid())
self.assertIn("password", serializer.errors)
class TokenSerializerTest(TestCase):
"""Tests for TokenSerializer"""
def test_valid_token_data(self):
"""Test valid token data"""
token_data = {
"access": fake.pystr(min_chars=50, max_chars=100),
"refresh": fake.pystr(min_chars=50, max_chars=100),
}
serializer = TokenSerializer(data=token_data)
self.assertTrue(serializer.is_valid())
def test_missing_access_token(self):
"""Test validation fails without access token"""
data = {"refresh": fake.pystr(min_chars=50, max_chars=100)}
serializer = TokenSerializer(data=data)
self.assertFalse(serializer.is_valid())
self.assertIn("access", serializer.errors)
def test_missing_refresh_token(self):
"""Test validation fails without refresh token"""
data = {"access": fake.pystr(min_chars=50, max_chars=100)}
serializer = TokenSerializer(data=data)
self.assertFalse(serializer.is_valid())
self.assertIn("refresh", serializer.errors)
class PasswordChangeSerializerTest(TestCase):
"""Tests for PasswordChangeSerializer"""
def setUp(self):
self.old_password = fake.password(length=12, special_chars=False)
self.new_password = fake.password(length=12, special_chars=False)
self.password_data = {
"old_password": self.old_password,
"new_password": self.new_password,
"new_password_confirm": self.new_password,
}
def test_valid_password_change_data(self):
"""Test valid password change data"""
serializer = PasswordChangeSerializer(data=self.password_data)
self.assertTrue(serializer.is_valid())
def test_passwords_do_not_match(self):
"""Test validation fails when new passwords don't match"""
data = self.password_data.copy()
data["new_password_confirm"] = fake.password(length=12, special_chars=False)
serializer = PasswordChangeSerializer(data=data)
self.assertFalse(serializer.is_valid())
self.assertIn("non_field_errors", serializer.errors)
def test_short_new_password(self):
"""Test validation fails with short new password"""
short_password = fake.pystr(min_chars=3, max_chars=5)
data = self.password_data.copy()
data["new_password"] = short_password
data["new_password_confirm"] = short_password
serializer = PasswordChangeSerializer(data=data)
self.assertFalse(serializer.is_valid())
self.assertIn("new_password", serializer.errors)
def test_missing_old_password(self):
"""Test validation fails without old password"""
new_password = fake.password(length=12, special_chars=False)
data = {"new_password": new_password, "new_password_confirm": new_password}
serializer = PasswordChangeSerializer(data=data)
self.assertFalse(serializer.is_valid())
self.assertIn("old_password", serializer.errors)