Remnawave_python-sdk/tests/test_users.py

289 lines
No EOL
11 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.

import random
from datetime import datetime, timedelta
import pytest
import pytz
from remnawave.enums import ErrorCode, UserStatus
from remnawave.exceptions import ApiError
from remnawave.models import (
CreateUserRequestDto,
DeleteUserResponseDto,
EmailUserResponseDto,
GetUserAccessibleNodesResponseDto,
TelegramUserResponseDto,
UpdateUserRequestDto,
UserResponseDto,
UsersResponseDto,
TagsResponseDto,
RevokeUserRequestDto,
GetSubscriptionRequestsResponseDto
)
from remnawave.models.users import GetUserSubscriptionRequestHistoryResponseDto
from tests.utils import generate_email, generate_random_string
class TestUsersCRUD:
"""Тесты базовых CRUD операций для пользователей"""
@pytest.mark.asyncio
async def test_create_user(self, remnawave):
email: str = generate_email(length=8)
username: str = generate_random_string(length=8)
telegram_id: int = random.randint(100000000, 999999999)
expire_at: datetime = datetime.now(tz=pytz.UTC) + timedelta(days=7)
create_user = await remnawave.users.create_user(
CreateUserRequestDto(
username=username,
email=email,
telegram_id=telegram_id,
expire_at=expire_at,
)
)
assert isinstance(create_user, UserResponseDto)
assert create_user.username == username
assert create_user.email == email
assert create_user.telegram_id == telegram_id
assert create_user.expire_at.isoformat(timespec="seconds") == expire_at.isoformat(
timespec="seconds"
)
# Clean up - delete the test user
string_uuid = str(create_user.uuid)
await remnawave.users.delete_user(uuid=string_uuid)
@pytest.mark.asyncio
async def test_update_user(self, remnawave):
# Create test user first
username: str = generate_random_string(length=8)
expire_at: datetime = datetime.now(tz=pytz.UTC) + timedelta(days=7)
create_user = await remnawave.users.create_user(
CreateUserRequestDto(
username=username,
expire_at=expire_at,
)
)
string_uuid = str(create_user.uuid)
# Update user
update_description: str = "TEST"
update_status: UserStatus = UserStatus.DISABLED
update_user = await remnawave.users.update_user(
UpdateUserRequestDto(
uuid=string_uuid, status=update_status, description=update_description
)
)
assert isinstance(update_user, UserResponseDto)
assert update_user.uuid == create_user.uuid
assert update_user.status == update_status
assert update_user.description == update_description
# Clean up
await remnawave.users.delete_user(uuid=string_uuid)
@pytest.mark.asyncio
async def test_delete_user(self, remnawave):
# Create test user first
username: str = generate_random_string(length=8)
expire_at: datetime = datetime.now(tz=pytz.UTC) + timedelta(days=7)
create_user = await remnawave.users.create_user(
CreateUserRequestDto(
username=username,
expire_at=expire_at,
)
)
string_uuid = str(create_user.uuid)
# Delete user
delete_user = await remnawave.users.delete_user(uuid=string_uuid)
assert isinstance(delete_user, DeleteUserResponseDto)
assert delete_user.is_deleted is True
class TestUsersFetch:
"""Тесты получения информации о пользователях"""
@pytest.mark.asyncio
async def test_get_all_users(self, remnawave):
all_users = await remnawave.users.get_all_users()
assert isinstance(all_users, UsersResponseDto)
@pytest.mark.asyncio
async def test_get_user_by_uuid(self, remnawave, test_user):
string_uuid = str(test_user.uuid)
user_uuid = await remnawave.users.get_user_by_uuid(uuid=string_uuid)
assert isinstance(user_uuid, UserResponseDto)
assert user_uuid.uuid == test_user.uuid
@pytest.mark.asyncio
async def test_get_user_by_short_uuid(self, remnawave, test_user):
user_short_uuid = await remnawave.users.get_user_by_short_uuid(
short_uuid=test_user.short_uuid
)
assert isinstance(user_short_uuid, UserResponseDto)
assert user_short_uuid.uuid == test_user.uuid
@pytest.mark.asyncio
async def test_get_user_by_username(self, remnawave, test_user):
user_username = await remnawave.users.get_user_by_username(
username=test_user.username
)
assert isinstance(user_username, UserResponseDto)
assert user_username.uuid == test_user.uuid
@pytest.mark.asyncio
async def test_get_users_by_telegram_id(self, remnawave, test_user_with_telegram):
string_telegram_id = str(test_user_with_telegram.telegram_id)
user_telegram_id = await remnawave.users.get_users_by_telegram_id(
telegram_id=string_telegram_id
)
assert isinstance(user_telegram_id, TelegramUserResponseDto)
assert any(user.uuid == test_user_with_telegram.uuid for user in user_telegram_id)
@pytest.mark.asyncio
async def test_get_users_by_email(self, remnawave, test_user_with_email):
user_email = await remnawave.users.get_users_by_email(email=test_user_with_email.email)
assert isinstance(user_email, EmailUserResponseDto)
assert any(user.uuid == test_user_with_email.uuid for user in user_email)
@pytest.mark.asyncio
async def test_get_all_tags(self, remnawave):
users_tags = await remnawave.users.get_all_tags()
assert isinstance(users_tags, TagsResponseDto)
@pytest.mark.asyncio
async def test_get_user_accessible_nodes(self, remnawave, test_user):
try:
string_uuid = str(test_user.uuid)
user_accessible_nodes = await remnawave.users.get_user_accessible_nodes(uuid=string_uuid)
assert isinstance(user_accessible_nodes, GetUserAccessibleNodesResponseDto)
assert isinstance(user_accessible_nodes.nodes, list)
except ApiError as e:
# This might fail if the user doesn't have access to any nodes
# or if the feature is not available, which is acceptable for testing
assert e.error.code in [ErrorCode.USER_NOT_FOUND, ]
@pytest.mark.asyncio
async def test_get_subscription_requests(self, remnawave, test_user):
"""Test fetching user subscription request history"""
string_uuid = str(test_user.uuid)
try:
subscription_requests = await remnawave.users.get_user_subscription_request_history(uuid=string_uuid)
assert isinstance(subscription_requests, GetUserSubscriptionRequestHistoryResponseDto)
assert hasattr(subscription_requests, 'total')
assert hasattr(subscription_requests, 'records')
except ApiError as e:
# Этот блок должен срабатывать только если API вернуло ошибку
# (404, 403 и т.д.), но не когда просто нет записей
assert e.error.code in [ErrorCode.USER_NOT_FOUND]
class TestUserActions:
"""Тесты действий над пользователями"""
@pytest.mark.asyncio
async def test_reset_user_traffic(self, remnawave, test_user):
string_uuid = str(test_user.uuid)
user_reset_traffic = await remnawave.users.reset_user_traffic(uuid=string_uuid)
assert isinstance(user_reset_traffic, UserResponseDto)
assert user_reset_traffic.uuid == test_user.uuid
assert user_reset_traffic.used_traffic_bytes == 0
@pytest.mark.asyncio
async def test_disable_enable_user(self, remnawave, test_user):
string_uuid = str(test_user.uuid)
# Disable user
try:
disable_user = await remnawave.users.disable_user(uuid=string_uuid)
assert isinstance(disable_user, UserResponseDto)
assert disable_user.uuid == test_user.uuid
assert disable_user.status == UserStatus.DISABLED
except ApiError as e:
assert e.error.code == ErrorCode.USER_ALREADY_DISABLED
# Enable user
try:
enable_user = await remnawave.users.enable_user(uuid=string_uuid)
assert isinstance(enable_user, UserResponseDto)
assert enable_user.uuid == test_user.uuid
assert enable_user.status == UserStatus.ACTIVE
except ApiError as e:
assert e.error.code == ErrorCode.USER_ALREADY_ENABLED
@pytest.mark.asyncio
async def test_revoke_user_subscription(self, remnawave, test_user):
string_uuid = str(test_user.uuid)
old_short_uuid = test_user.short_uuid
revoke_user_subscription = await remnawave.users.revoke_user_subscription(uuid=string_uuid)
assert isinstance(revoke_user_subscription, UserResponseDto)
assert revoke_user_subscription.uuid == test_user.uuid
assert revoke_user_subscription.short_uuid != old_short_uuid
@pytest.fixture
async def test_user(remnawave):
"""Fixture to create a test user for tests"""
username = generate_random_string(length=8)
expire_at = datetime.now(tz=pytz.UTC) + timedelta(days=7)
user = await remnawave.users.create_user(
CreateUserRequestDto(
username=username,
expire_at=expire_at,
)
)
yield user
# Clean up
await remnawave.users.delete_user(uuid=str(user.uuid))
@pytest.fixture
async def test_user_with_email(remnawave):
"""Fixture to create a test user with email for tests"""
username = generate_random_string(length=8)
email = generate_email(length=8)
expire_at = datetime.now(tz=pytz.UTC) + timedelta(days=7)
user = await remnawave.users.create_user(
CreateUserRequestDto(
username=username,
email=email,
expire_at=expire_at,
)
)
yield user
# Clean up
await remnawave.users.delete_user(uuid=str(user.uuid))
@pytest.fixture
async def test_user_with_telegram(remnawave):
"""Fixture to create a test user with telegram ID for tests"""
username = generate_random_string(length=8)
telegram_id = random.randint(100000000, 999999999)
expire_at = datetime.now(tz=pytz.UTC) + timedelta(days=7)
user = await remnawave.users.create_user(
CreateUserRequestDto(
username=username,
telegram_id=telegram_id,
expire_at=expire_at,
)
)
yield user
# Clean up
await remnawave.users.delete_user(uuid=str(user.uuid))