Fix admin API gaps for users, exchange checks, and parser logs
This commit is contained in:
@@ -62,6 +62,7 @@ class ProfileFactory(factory.django.DjangoModelFactory):
|
||||
|
||||
user = factory.SubFactory(UserFactory)
|
||||
first_name = factory.LazyAttribute(lambda _: fake.first_name())
|
||||
middle_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(
|
||||
@@ -81,6 +82,8 @@ class ProfileFactory(factory.django.DjangoModelFactory):
|
||||
# Заполняем поля faker'ом, если не переданы
|
||||
if "first_name" not in kwargs:
|
||||
profile.first_name = fake.first_name()
|
||||
if "middle_name" not in kwargs:
|
||||
profile.middle_name = fake.first_name()
|
||||
if "last_name" not in kwargs:
|
||||
profile.last_name = fake.last_name()
|
||||
if "bio" not in kwargs:
|
||||
|
||||
@@ -65,8 +65,10 @@ class ProfileModelTest(TestCase):
|
||||
self.assertEqual(self.profile.user, self.user)
|
||||
# Проверяем, что имена заполнены faker'ом
|
||||
self.assertIsNotNone(self.profile.first_name)
|
||||
self.assertIsNotNone(self.profile.middle_name)
|
||||
self.assertIsNotNone(self.profile.last_name)
|
||||
self.assertTrue(len(self.profile.first_name) > 0)
|
||||
self.assertTrue(len(self.profile.middle_name) > 0)
|
||||
self.assertTrue(len(self.profile.last_name) > 0)
|
||||
|
||||
def test_profile_str_representation(self):
|
||||
@@ -90,6 +92,12 @@ class ProfileModelTest(TestCase):
|
||||
self.assertTrue(field.blank)
|
||||
self.assertTrue(field.null)
|
||||
|
||||
def test_profile_middle_name_optional(self):
|
||||
"""Test middle_name field is optional"""
|
||||
field = self.profile._meta.get_field("middle_name")
|
||||
self.assertTrue(field.blank)
|
||||
self.assertTrue(field.null)
|
||||
|
||||
def test_profile_bio_optional(self):
|
||||
"""Test bio field is optional"""
|
||||
field = self.profile._meta.get_field("bio")
|
||||
@@ -112,17 +120,27 @@ class ProfileModelTest(TestCase):
|
||||
"""Test full_name property"""
|
||||
# Test with both names
|
||||
first_name = fake.first_name()
|
||||
middle_name = fake.first_name()
|
||||
last_name = fake.last_name()
|
||||
self.profile.first_name = first_name
|
||||
self.profile.middle_name = middle_name
|
||||
self.profile.last_name = last_name
|
||||
self.assertEqual(self.profile.full_name, f"{first_name} {last_name}")
|
||||
self.assertEqual(
|
||||
self.profile.full_name, f"{first_name} {middle_name} {last_name}"
|
||||
)
|
||||
|
||||
# Test with only first name
|
||||
self.profile.middle_name = ""
|
||||
self.profile.last_name = ""
|
||||
self.assertEqual(self.profile.full_name, first_name)
|
||||
|
||||
# Test with first and middle name
|
||||
self.profile.middle_name = middle_name
|
||||
self.assertEqual(self.profile.full_name, f"{first_name} {middle_name}")
|
||||
|
||||
# Test with only last name
|
||||
self.profile.first_name = ""
|
||||
self.profile.middle_name = ""
|
||||
self.profile.last_name = last_name
|
||||
self.assertEqual(self.profile.full_name, last_name)
|
||||
|
||||
|
||||
@@ -181,11 +181,27 @@ class AdminUserCreateSerializerTest(TestCase):
|
||||
"is_active": True,
|
||||
"is_verified": False,
|
||||
"first_name": fake.first_name(),
|
||||
"middle_name": fake.first_name(),
|
||||
"last_name": fake.last_name(),
|
||||
}
|
||||
)
|
||||
self.assertTrue(serializer.is_valid(), serializer.errors)
|
||||
|
||||
def test_admin_user_create_requires_first_and_last_name(self):
|
||||
serializer = AdminUserCreateSerializer(
|
||||
data={
|
||||
"email": fake.unique.email(),
|
||||
"username": fake.unique.user_name(),
|
||||
"phone": f"+7{fake.numerify('##########')}",
|
||||
"password": fake.password(length=12, special_chars=False),
|
||||
"role": "user",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertIn("first_name", serializer.errors)
|
||||
self.assertIn("last_name", serializer.errors)
|
||||
|
||||
|
||||
class AdminUserUpdateSerializerTest(TestCase):
|
||||
"""Tests for AdminUserUpdateSerializer."""
|
||||
@@ -200,6 +216,7 @@ class AdminUserUpdateSerializerTest(TestCase):
|
||||
"role": "admin",
|
||||
"is_active": False,
|
||||
"first_name": fake.first_name(),
|
||||
"middle_name": fake.first_name(),
|
||||
},
|
||||
partial=True,
|
||||
)
|
||||
@@ -217,6 +234,7 @@ class ProfileUpdateSerializerTest(TestCase):
|
||||
"""Test valid profile update data"""
|
||||
update_data = {
|
||||
"first_name": fake.first_name(),
|
||||
"middle_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)),
|
||||
@@ -229,13 +247,21 @@ class ProfileUpdateSerializerTest(TestCase):
|
||||
|
||||
updated_profile = serializer.save()
|
||||
self.assertEqual(updated_profile.first_name, update_data["first_name"])
|
||||
self.assertEqual(updated_profile.middle_name, update_data["middle_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"]
|
||||
allowed_fields = [
|
||||
"first_name",
|
||||
"middle_name",
|
||||
"last_name",
|
||||
"bio",
|
||||
"avatar",
|
||||
"date_of_birth",
|
||||
]
|
||||
|
||||
self.assertEqual(set(serializer.Meta.fields), set(allowed_fields))
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@ class UserServiceTest(TestCase):
|
||||
self.user.id,
|
||||
role=UserService.ROLE_ADMIN,
|
||||
first_name="Иван",
|
||||
middle_name="Иванович",
|
||||
last_name="Иванов",
|
||||
)
|
||||
|
||||
@@ -130,6 +131,7 @@ class UserServiceTest(TestCase):
|
||||
)
|
||||
self.assertTrue(updated_user.is_staff)
|
||||
self.assertEqual(updated_user.profile.first_name, "Иван")
|
||||
self.assertEqual(updated_user.profile.middle_name, "Иванович")
|
||||
self.assertEqual(updated_user.profile.last_name, "Иванов")
|
||||
|
||||
def test_update_managed_user_updates_password(self):
|
||||
@@ -161,6 +163,37 @@ class UserServiceTest(TestCase):
|
||||
user = UserService.deactivate_user(self.user.id)
|
||||
self.assertFalse(user.is_active)
|
||||
|
||||
def test_activate_user_success(self):
|
||||
"""Test activation of user."""
|
||||
self.user.is_active = False
|
||||
self.user.save(update_fields=["is_active"])
|
||||
|
||||
user = UserService.activate_user(self.user.id)
|
||||
self.assertTrue(user.is_active)
|
||||
|
||||
def test_get_filtered_users_queryset_searches_by_profile_name(self):
|
||||
ProfileFactory.create_profile(
|
||||
user=self.user,
|
||||
first_name="Найден",
|
||||
middle_name="Тестович",
|
||||
last_name="Пользователь",
|
||||
)
|
||||
|
||||
queryset = UserService.get_filtered_users_queryset(search="Тестович")
|
||||
|
||||
self.assertEqual(list(queryset.values_list("id", flat=True)), [self.user.id])
|
||||
|
||||
def test_get_filtered_users_queryset_orders_by_profile_field(self):
|
||||
first = UserFactory.create_user()
|
||||
second = UserFactory.create_user()
|
||||
ProfileFactory.create_profile(user=first, first_name="Борис")
|
||||
ProfileFactory.create_profile(user=second, first_name="Алексей")
|
||||
|
||||
queryset = UserService.get_filtered_users_queryset(ordering="first_name")
|
||||
|
||||
ids = list(queryset.values_list("id", flat=True)[:2])
|
||||
self.assertEqual(ids, [second.id, first.id])
|
||||
|
||||
def test_get_user_capabilities_for_admin(self):
|
||||
"""Test admin capabilities set."""
|
||||
admin = UserFactory.create_user(is_staff=True)
|
||||
@@ -236,6 +269,7 @@ class ProfileServiceTest(TestCase):
|
||||
self.profile = ProfileFactory.create_profile(user=self.user)
|
||||
self.profile_data = {
|
||||
"first_name": fake.first_name(),
|
||||
"middle_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)),
|
||||
@@ -270,6 +304,7 @@ class ProfileServiceTest(TestCase):
|
||||
|
||||
self.assertIsNotNone(updated_profile)
|
||||
self.assertEqual(updated_profile.first_name, self.profile_data["first_name"])
|
||||
self.assertEqual(updated_profile.middle_name, self.profile_data["middle_name"])
|
||||
self.assertEqual(updated_profile.last_name, self.profile_data["last_name"])
|
||||
self.assertEqual(updated_profile.bio, self.profile_data["bio"])
|
||||
|
||||
@@ -288,6 +323,7 @@ class ProfileServiceTest(TestCase):
|
||||
self.assertEqual(profile_data["email"], self.user.email)
|
||||
self.assertEqual(profile_data["username"], self.user.username)
|
||||
self.assertEqual(profile_data["first_name"], self.profile.first_name)
|
||||
self.assertEqual(profile_data["middle_name"], self.profile.middle_name)
|
||||
self.assertEqual(profile_data["last_name"], self.profile.last_name)
|
||||
self.assertEqual(profile_data["full_name"], self.profile.full_name)
|
||||
self.assertEqual(profile_data["bio"], self.profile.bio)
|
||||
|
||||
@@ -224,6 +224,34 @@ class AdminUserManagementViewTest(APITestCase):
|
||||
self.assertIn(self.admin.username, usernames)
|
||||
self.assertIn(self.user.username, usernames)
|
||||
|
||||
def test_admin_can_search_users(self):
|
||||
ProfileFactory.create_profile(
|
||||
user=self.user,
|
||||
first_name="Сергей",
|
||||
middle_name="Петрович",
|
||||
last_name="Иванов",
|
||||
)
|
||||
another = UserFactory.create_user()
|
||||
ProfileFactory.create_profile(user=another, first_name="Илья")
|
||||
|
||||
response = self.client.get(self.list_url, {"search": "Петрович"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
usernames = [item["username"] for item in response.data]
|
||||
self.assertEqual(usernames, [self.user.username])
|
||||
|
||||
def test_admin_can_order_users(self):
|
||||
first = UserFactory.create_user()
|
||||
second = UserFactory.create_user()
|
||||
ProfileFactory.create_profile(user=first, first_name="Борис")
|
||||
ProfileFactory.create_profile(user=second, first_name="Алексей")
|
||||
|
||||
response = self.client.get(self.list_url, {"ordering": "first_name"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
ordered_ids = [item["id"] for item in response.data]
|
||||
self.assertLess(ordered_ids.index(second.id), ordered_ids.index(first.id))
|
||||
|
||||
def test_admin_can_create_user_with_role(self):
|
||||
password = fake.password(length=12, special_chars=False)
|
||||
payload = {
|
||||
@@ -233,6 +261,7 @@ class AdminUserManagementViewTest(APITestCase):
|
||||
"password": password,
|
||||
"role": "admin",
|
||||
"first_name": "Петр",
|
||||
"middle_name": "Петрович",
|
||||
"last_name": "Петров",
|
||||
}
|
||||
|
||||
@@ -243,13 +272,19 @@ class AdminUserManagementViewTest(APITestCase):
|
||||
self.assertTrue(created.is_staff)
|
||||
self.assertEqual(response.data["role"], "admin")
|
||||
self.assertEqual(created.profile.first_name, "Петр")
|
||||
self.assertEqual(created.profile.middle_name, "Петрович")
|
||||
|
||||
def test_admin_can_update_user_and_role(self):
|
||||
url = reverse("api_v1:user:admin-user-detail", args=[self.user.id])
|
||||
|
||||
response = self.client.patch(
|
||||
url,
|
||||
{"role": "admin", "first_name": "Иван", "is_verified": True},
|
||||
{
|
||||
"role": "admin",
|
||||
"first_name": "Иван",
|
||||
"middle_name": "Иванович",
|
||||
"is_verified": True,
|
||||
},
|
||||
format="json",
|
||||
)
|
||||
|
||||
@@ -258,6 +293,7 @@ class AdminUserManagementViewTest(APITestCase):
|
||||
self.assertTrue(self.user.is_staff)
|
||||
self.assertTrue(self.user.is_verified)
|
||||
self.assertEqual(self.user.profile.first_name, "Иван")
|
||||
self.assertEqual(self.user.profile.middle_name, "Иванович")
|
||||
|
||||
def test_admin_can_get_user_detail(self):
|
||||
url = reverse("api_v1:user:admin-user-detail", args=[self.user.id])
|
||||
@@ -302,6 +338,17 @@ class AdminUserManagementViewTest(APITestCase):
|
||||
self.user.refresh_from_db()
|
||||
self.assertFalse(self.user.is_active)
|
||||
|
||||
def test_admin_can_activate_user(self):
|
||||
self.user.is_active = False
|
||||
self.user.save(update_fields=["is_active"])
|
||||
url = reverse("api_v1:user:admin-user-activate", args=[self.user.id])
|
||||
|
||||
response = self.client.post(url, {}, format="json")
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.user.refresh_from_db()
|
||||
self.assertTrue(self.user.is_active)
|
||||
|
||||
def test_admin_cannot_deactivate_self(self):
|
||||
url = reverse("api_v1:user:admin-user-deactivate", args=[self.admin.id])
|
||||
|
||||
@@ -330,6 +377,7 @@ class ProfileDetailViewTest(APITestCase):
|
||||
|
||||
self.update_data = {
|
||||
"first_name": fake.first_name(),
|
||||
"middle_name": fake.first_name(),
|
||||
"last_name": fake.last_name(),
|
||||
"bio": fake.text(max_nb_chars=200),
|
||||
}
|
||||
@@ -340,6 +388,7 @@ class ProfileDetailViewTest(APITestCase):
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["first_name"], self.profile.first_name)
|
||||
self.assertEqual(response.data["middle_name"], self.profile.middle_name)
|
||||
|
||||
def test_update_profile_success(self):
|
||||
"""Test successful profile update"""
|
||||
@@ -347,6 +396,7 @@ class ProfileDetailViewTest(APITestCase):
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["first_name"], self.update_data["first_name"])
|
||||
self.assertEqual(response.data["middle_name"], self.update_data["middle_name"])
|
||||
self.assertEqual(response.data["last_name"], self.update_data["last_name"])
|
||||
|
||||
# Verify in database
|
||||
|
||||
Reference in New Issue
Block a user