fix: исправить алиасы в эндпоинтах и удалить неиспользуемые DTO

This commit is contained in:
Artem 2025-12-03 05:31:17 +01:00
parent 38a57b3e31
commit f1503b2fda
No known key found for this signature in database
GPG key ID: 833485276B7902CE
7 changed files with 22 additions and 28 deletions

View file

@ -135,7 +135,8 @@ class UsersController(BaseController):
"""Get user subscription request history, recent 24 records""" """Get user subscription request history, recent 24 records"""
... ...
@get("/users/by-short-uuid/{short_uuid}", response_class=GetUserByShortUuidResponseDto) # ИСПРАВЛЕНО: убран alias, используется short_uuid
@get("/users/by-short-uuid/{shortUuid}", response_class=GetUserByShortUuidResponseDto)
async def get_user_by_short_uuid( async def get_user_by_short_uuid(
self, self,
short_uuid: Annotated[str, Path(description="Short UUID of the user", alias="shortUuid")], short_uuid: Annotated[str, Path(description="Short UUID of the user", alias="shortUuid")],
@ -151,7 +152,6 @@ class UsersController(BaseController):
"""Get user by username""" """Get user by username"""
... ...
# НОВЫЙ ЭНДПОИНТ
@get("/users/by-id/{id}", response_class=GetUserByIdResponseDto) @get("/users/by-id/{id}", response_class=GetUserByIdResponseDto)
async def get_user_by_id( async def get_user_by_id(
self, self,
@ -160,8 +160,9 @@ class UsersController(BaseController):
"""Get user by ID""" """Get user by ID"""
... ...
# ИСПРАВЛЕНО: убран alias, используется telegram_id
@get( @get(
"/users/by-telegram-id/{telegram_id}", "/users/by-telegram-id/{telegramId}",
response_class=TelegramUserResponseDto, response_class=TelegramUserResponseDto,
) )
async def get_users_by_telegram_id( async def get_users_by_telegram_id(

View file

@ -263,7 +263,6 @@ from .users import (
# Response DTOs - Collections # Response DTOs - Collections
GetAllUsersResponseDto, GetAllUsersResponseDto,
GetAllTagsResponseDto, GetAllTagsResponseDto,
GetUserAccessibleNodesResponseDto,
GetUserSubscriptionRequestHistoryResponseDto, GetUserSubscriptionRequestHistoryResponseDto,
# Response DTOs - Arrays (RootModel) # Response DTOs - Arrays (RootModel)
@ -590,7 +589,6 @@ __all__ = [
"ActivateAllInboundsResponseDto", "ActivateAllInboundsResponseDto",
"GetAllUsersResponseDto", "GetAllUsersResponseDto",
"GetAllTagsResponseDto", "GetAllTagsResponseDto",
"GetUserAccessibleNodesResponseDto",
"GetUserSubscriptionRequestHistoryResponseDto", "GetUserSubscriptionRequestHistoryResponseDto",
"TelegramUserResponseDto", "TelegramUserResponseDto",
"EmailUserResponseDto", "EmailUserResponseDto",

View file

@ -125,8 +125,6 @@ class NodeResponseDto(BaseModel):
is_connected: bool = Field(alias="isConnected") is_connected: bool = Field(alias="isConnected")
is_disabled: bool = Field(alias="isDisabled") is_disabled: bool = Field(alias="isDisabled")
is_connecting: bool = Field(alias="isConnecting") is_connecting: bool = Field(alias="isConnecting")
is_node_online: bool = Field(alias="isNodeOnline")
is_xray_running: bool = Field(alias="isXrayRunning")
last_status_change: Optional[datetime] = Field(None, alias="lastStatusChange") last_status_change: Optional[datetime] = Field(None, alias="lastStatusChange")
last_status_message: Optional[str] = Field(None, alias="lastStatusMessage") last_status_message: Optional[str] = Field(None, alias="lastStatusMessage")
xray_version: Optional[str] = Field(None, alias="xrayVersion") xray_version: Optional[str] = Field(None, alias="xrayVersion")

View file

@ -4,11 +4,17 @@ from uuid import UUID
from pydantic import BaseModel, Field, RootModel from pydantic import BaseModel, Field, RootModel
class NodeActiveSquadDto(BaseModel):
squad_name: str = Field(alias="squadName")
active_inbounds: list[str] = Field(alias="activeInbounds")
class NodeInfoDto(BaseModel): class NodeInfoDto(BaseModel):
uuid: UUID uuid: UUID
name: str name: str
country_code: str = Field(alias="countryCode") country_code: str = Field(alias="countryCode")
config_profile_name: str = Field(alias="configProfileName")
config_profile_uuid: UUID = Field(alias="configProfileUuid")
active_squads: List[NodeActiveSquadDto] = Field(alias="activeSquads")
class GetUserAccessibleNodesResponse(BaseModel): class GetUserAccessibleNodesResponse(BaseModel):
user_uuid: UUID = Field(alias="userUuid") user_uuid: UUID = Field(alias="userUuid")

View file

@ -320,14 +320,5 @@ class TelegramUserResponseDto(RootModel[list[UserResponseDto]]):
def __iter__(self): def __iter__(self):
return iter(self.root) return iter(self.root)
def __getitem__(self, item):
return self.root[item]
class GetUserAccessibleNodesResponseDto(RootModel[list[UUID]]):
"""Response for get user accessible nodes"""
def __iter__(self):
return iter(self.root)
def __getitem__(self, item): def __getitem__(self, item):
return self.root[item] return self.root[item]

View file

@ -19,6 +19,7 @@ from remnawave.models import (
RevokeUserRequestDto, RevokeUserRequestDto,
GetSubscriptionRequestsResponseDto GetSubscriptionRequestsResponseDto
) )
from remnawave.models.users import GetUserSubscriptionRequestHistoryResponseDto
from tests.utils import generate_email, generate_random_string from tests.utils import generate_email, generate_random_string
@ -110,7 +111,7 @@ class TestUsersFetch:
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_get_all_users(self, remnawave): async def test_get_all_users(self, remnawave):
all_users = await remnawave.users.get_all_users_v2() all_users = await remnawave.users.get_all_users()
assert isinstance(all_users, UsersResponseDto) assert isinstance(all_users, UsersResponseDto)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -173,12 +174,10 @@ class TestUsersFetch:
"""Test fetching user subscription request history""" """Test fetching user subscription request history"""
string_uuid = str(test_user.uuid) string_uuid = str(test_user.uuid)
try: try:
subscription_requests = await remnawave.users.get_subscription_requests(uuid=string_uuid) subscription_requests = await remnawave.users.get_user_subscription_request_history(uuid=string_uuid)
assert isinstance(subscription_requests, GetSubscriptionRequestsResponseDto) assert isinstance(subscription_requests, GetUserSubscriptionRequestHistoryResponseDto)
assert hasattr(subscription_requests, 'total') assert hasattr(subscription_requests, 'total')
assert hasattr(subscription_requests, 'records') assert hasattr(subscription_requests, 'records')
# Даже если записей нет, модель должна быть правильно сформирована
# с пустым списком records и total=0
except ApiError as e: except ApiError as e:
# Этот блок должен срабатывать только если API вернуло ошибку # Этот блок должен срабатывать только если API вернуло ошибку
# (404, 403 и т.д.), но не когда просто нет записей # (404, 403 и т.д.), но не когда просто нет записей

View file

@ -4,7 +4,7 @@ from typing import List
import pytest import pytest
import pytz import pytz
from remnawave.models import BulkResponseDto, UpdateUserFields from remnawave.models import BulkResponseDto, UpdateUserFields, BulkUpdateUsersRequestDto
from tests.conftest import REMNAWAVE_USER_UUID from tests.conftest import REMNAWAVE_USER_UUID
@ -12,14 +12,15 @@ from tests.conftest import REMNAWAVE_USER_UUID
async def test_users_bulk_actions(remnawave): async def test_users_bulk_actions(remnawave):
expire_at = datetime.now(tz=pytz.utc) + timedelta(days=14) expire_at = datetime.now(tz=pytz.utc) + timedelta(days=14)
description = "TEST_DESCRIPTION" description = "TEST_DESCRIPTION"
uuids: List[str] = [REMNAWAVE_USER_UUID]
bulk_update_users = await remnawave.users_bulk_actions.bulk_update_users( bulk_update_users = await remnawave.users_bulk_actions.bulk_update_users(
uuids=uuids, body=BulkUpdateUsersRequestDto(
fields=UpdateUserFields( uuids=[REMNAWAVE_USER_UUID],
description=description, fields=UpdateUserFields(
expire_at=expire_at, expire_at=expire_at,
description=description,
),
), ),
) )
assert isinstance(bulk_update_users, BulkResponseDto) assert isinstance(bulk_update_users, BulkResponseDto)
assert bulk_update_users.affected_rows == len(uuids) assert bulk_update_users.affected_rows > 0