From 32d99f3f2d77f5e2edceb3da81508408670cfe95 Mon Sep 17 00:00:00 2001 From: Artem Date: Wed, 18 Feb 2026 01:36:31 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA?= =?UTF-8?q?=D1=83=20=D0=BF=D0=B5=D1=80=D0=B5=D1=83=D0=BF=D0=BE=D1=80=D1=8F?= =?UTF-8?q?=D0=B4=D0=BE=D1=87=D0=B8=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=84=D0=B8=D0=BB=D0=B5=D0=B9,=20=D0=B2=D0=BD?= =?UTF-8?q?=D0=B5=D1=88=D0=BD=D0=B8=D1=85=20=D0=B8=20=D0=B2=D0=BD=D1=83?= =?UTF-8?q?=D1=82=D1=80=D0=B5=D0=BD=D0=BD=D0=B8=D1=85=20=D0=BE=D1=82=D1=80?= =?UTF-8?q?=D1=8F=D0=B4=D0=BE=D0=B2,=20=D0=B0=20=D1=82=D0=B0=D0=BA=D0=B6?= =?UTF-8?q?=D0=B5=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=BF=D0=B8=D1=81=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- remnawave/controllers/config_profiles.py | 10 ++++++ remnawave/controllers/external_squads.py | 9 ++++++ remnawave/controllers/internal_squads.py | 10 ++++++ remnawave/controllers/nodes.py | 8 +++++ .../controllers/subscriptions_controller.py | 19 +++++++++++- .../controllers/subscriptions_template.py | 9 ++++++ remnawave/models/__init__.py | 31 +++++++++++++++++++ remnawave/models/config_profiles.py | 13 ++++++++ remnawave/models/external_squads.py | 20 ++++++++++++ remnawave/models/internal_squads.py | 13 ++++++++ remnawave/models/nodes.py | 4 +++ remnawave/models/subscription_page.py | 24 +++++++++++++- remnawave/models/subscriptions_template.py | 13 ++++++++ test_imports.py | 20 ++++++++++++ tests/test_config_profiles.py | 18 +++++++++++ tests/test_internal_squads.py | 18 +++++++++++ tests/test_nodes.py | 5 +++ tests/test_subscription.py | 19 ++++++++++-- tests/test_subscriptions_template.py | 25 ++++++++++++++- 19 files changed, 283 insertions(+), 5 deletions(-) create mode 100644 test_imports.py diff --git a/remnawave/controllers/config_profiles.py b/remnawave/controllers/config_profiles.py index 0dfb441..d3affe0 100644 --- a/remnawave/controllers/config_profiles.py +++ b/remnawave/controllers/config_profiles.py @@ -11,6 +11,8 @@ from remnawave.models import ( GetAllInboundsResponseDto, GetConfigProfileByUuidResponseDto, GetInboundsByProfileUuidResponseDto, + ReorderConfigProfilesRequestDto, + ReorderConfigProfilesResponseDto, UpdateConfigProfileRequestDto, UpdateConfigProfileResponseDto, ) @@ -68,6 +70,14 @@ class ConfigProfilesController(BaseController): """Delete config profile""" ... + @post("/config-profiles/actions/reorder", response_class=ReorderConfigProfilesResponseDto) + async def reorder_config_profiles( + self, + body: Annotated[ReorderConfigProfilesRequestDto, PydanticBody()], + ) -> ReorderConfigProfilesResponseDto: + """Reorder config profiles""" + ... + # Get computed config profile by uuid​ @get("/config-profiles/{uuid}/computed-config", response_class=GetConfigProfileByUuidResponseDto) async def get_computed_config_profile_by_uuid( diff --git a/remnawave/controllers/external_squads.py b/remnawave/controllers/external_squads.py index 0b62504..84a2e58 100644 --- a/remnawave/controllers/external_squads.py +++ b/remnawave/controllers/external_squads.py @@ -10,6 +10,8 @@ from remnawave.models import ( GetExternalSquadByUuidResponseDto, GetExternalSquadsResponseDto, RemoveUsersFromExternalSquadResponseDto, + ReorderExternalSquadsRequestDto, + ReorderExternalSquadsResponseDto, UpdateExternalSquadRequestDto, UpdateExternalSquadResponseDto, ) @@ -70,4 +72,11 @@ class ExternalSquadsController(BaseController): uuid: str, ) -> RemoveUsersFromExternalSquadResponseDto: """Delete users from external squad""" + ... + @post("/external-squads/actions/reorder", response_class=ReorderExternalSquadsResponseDto) + async def reorder_external_squads( + self, + body: Annotated[ReorderExternalSquadsRequestDto, PydanticBody()], + ) -> ReorderExternalSquadsResponseDto: + """Reorder external squads""" ... \ No newline at end of file diff --git a/remnawave/controllers/internal_squads.py b/remnawave/controllers/internal_squads.py index efbdf39..9767072 100644 --- a/remnawave/controllers/internal_squads.py +++ b/remnawave/controllers/internal_squads.py @@ -13,6 +13,8 @@ from remnawave.models import ( DeleteUsersFromInternalSquadResponseDto, GetAllInternalSquadsResponseDto, GetInternalSquadByUuidResponseDto, + ReorderInternalSquadsRequestDto, + ReorderInternalSquadsResponseDto, UpdateInternalSquadRequestDto, UpdateInternalSquadResponseDto, GetInternalSquadAccessibleNodesResponseDto, @@ -90,3 +92,11 @@ class InternalSquadsController(BaseController): ) -> GetInternalSquadAccessibleNodesResponseDto: """Get accessible nodes for internal squad""" ... + + @post("/internal-squads/actions/reorder", response_class=ReorderInternalSquadsResponseDto) + async def reorder_internal_squads( + self, + body: Annotated[ReorderInternalSquadsRequestDto, PydanticBody()], + ) -> ReorderInternalSquadsResponseDto: + """Reorder internal squads""" + ... diff --git a/remnawave/controllers/nodes.py b/remnawave/controllers/nodes.py index 746a42e..52a9836 100644 --- a/remnawave/controllers/nodes.py +++ b/remnawave/controllers/nodes.py @@ -115,6 +115,14 @@ class NodesController(BaseController): ) -> ReorderNodeResponseDto: """Reorder Nodes""" ... + + @post("/nodes/{uuid}/actions/reset-traffic", response_class=ResetNodeTrafficResponseDto) + async def reset_node_traffic( + self, + uuid: Annotated[str, Path(description="UUID of the node")], + ) -> ResetNodeTrafficResponseDto: + """Reset traffic for individual node""" + ... @post("/nodes/actions/reset-traffic", response_class=ResetNodeTrafficResponseDto) async def reset_traffic_all_nodes( diff --git a/remnawave/controllers/subscriptions_controller.py b/remnawave/controllers/subscriptions_controller.py index ff7b80d..270c114 100644 --- a/remnawave/controllers/subscriptions_controller.py +++ b/remnawave/controllers/subscriptions_controller.py @@ -1,11 +1,19 @@ from typing import Annotated from rapid_api_client import Path, Query +from rapid_api_client.annotations import PydanticBody from remnawave.enums import ClientType from remnawave.models.subscription import GetRawSubscriptionByShortUuidResponseDto from remnawave.rapid import BaseController, get -from remnawave.models import GetAllSubscriptionsResponseDto, GetSubscriptionByUsernameResponseDto, GetSubscriptionByShortUUIDResponseDto, GetSubscriptionByUUIDResponseDto +from remnawave.models import ( + GetAllSubscriptionsResponseDto, + GetSubscriptionByUsernameResponseDto, + GetSubscriptionByShortUUIDResponseDto, + GetSubscriptionByUUIDResponseDto, + GetSubpageConfigByShortUuidRequestBodyDto, + GetSubpageConfigByShortUuidResponseDto, +) class SubscriptionsController(BaseController): @@ -47,6 +55,15 @@ class SubscriptionsController(BaseController): """None""" ... + @get("/subscriptions/subpage-config/{short_uuid}", response_class=GetSubpageConfigByShortUuidResponseDto) + async def get_subpage_config( + self, + short_uuid: Annotated[str, Path(description="Short UUID of the subscription")], + body: Annotated[GetSubpageConfigByShortUuidRequestBodyDto, PydanticBody()], + ) -> GetSubpageConfigByShortUuidResponseDto: + """Get subscription page config by short UUID""" + ... + @get("/subscriptions/by-short-uuid/{short_uuid}/raw", response_class=GetRawSubscriptionByShortUuidResponseDto) async def get_raw_subscription( self, diff --git a/remnawave/controllers/subscriptions_template.py b/remnawave/controllers/subscriptions_template.py index 72d497f..3c9baef 100644 --- a/remnawave/controllers/subscriptions_template.py +++ b/remnawave/controllers/subscriptions_template.py @@ -9,6 +9,8 @@ from remnawave.models import ( DeleteSubscriptionTemplateResponseDto, GetTemplateResponseDto, GetTemplatesResponseDto, + ReorderSubscriptionTemplatesRequestDto, + ReorderSubscriptionTemplatesResponseDto, UpdateTemplateRequestDto, UpdateTemplateResponseDto, ) @@ -51,4 +53,11 @@ class SubscriptionsTemplateController(BaseController): uuid: Annotated[str, Path(description="Template UUID")], ) -> DeleteSubscriptionTemplateResponseDto: """Delete subscription template""" + ... + @post("/subscription-templates/actions/reorder", response_class=ReorderSubscriptionTemplatesResponseDto) + async def reorder_templates( + self, + body: Annotated[ReorderSubscriptionTemplatesRequestDto, PydanticBody()], + ) -> ReorderSubscriptionTemplatesResponseDto: + """Reorder subscription templates""" ... \ No newline at end of file diff --git a/remnawave/models/__init__.py b/remnawave/models/__init__.py index 126fcc4..d1f8328 100644 --- a/remnawave/models/__init__.py +++ b/remnawave/models/__init__.py @@ -61,6 +61,9 @@ from .config_profiles import ( GetInboundsByProfileUuidResponseDto, InboundDto, NodesProfileDto, + ReorderConfigProfileItem, + ReorderConfigProfilesRequestDto, + ReorderConfigProfilesResponseDto, UpdateConfigProfileRequestDto, UpdateConfigProfileResponseDto, ) @@ -166,6 +169,9 @@ from .internal_squads import ( GetAllInternalSquadsResponseDto, GetInternalSquadByUuidResponseDto, InternalSquadDto, + ReorderInternalSquadItem, + ReorderInternalSquadsRequestDto, + ReorderInternalSquadsResponseDto, UpdateInternalSquadRequestDto, UpdateInternalSquadResponseDto, GetInternalSquadAccessibleNodesResponseDto, @@ -243,6 +249,9 @@ from .subscriptions_template import ( GetTemplatesResponseDto, TemplateInfoDto, GetTemplateResponseDto, + ReorderTemplateItem, + ReorderSubscriptionTemplatesRequestDto, + ReorderSubscriptionTemplatesResponseDto, TemplateResponseDto, UpdateTemplateRequestDto, UpdateTemplateResponseDto, @@ -406,6 +415,9 @@ from .external_squads import ( GetExternalSquadByUuidResponseDto, GetExternalSquadsResponseDto, RemoveUsersFromExternalSquadResponseDto, + ReorderExternalSquadItem, + ReorderExternalSquadsRequestDto, + ReorderExternalSquadsResponseDto, TemplateType, UpdateExternalSquadRequestDto, UpdateExternalSquadResponseDto, @@ -445,6 +457,9 @@ from .subscription_page import ( DeleteSubscriptionPageConfigResponseDto, GetSubscriptionPageConfigResponseDto, GetSubscriptionPageConfigsResponseDto, + GetSubpageConfigByShortUuidRequestBodyDto, + GetSubpageConfigByShortUuidResponseDto, + SubpageConfigData, ReorderSubscriptionPageConfigItem, ReorderSubscriptionPageConfigsRequestDto, ReorderSubscriptionPageConfigsResponseDto, @@ -564,6 +579,9 @@ __all__ = [ "CreateSubscriptionTemplateResponseDto", "DeleteSubscriptionTemplateResponseDto", "GetTemplatesResponseDto", + "ReorderTemplateItem", + "ReorderSubscriptionTemplatesRequestDto", + "ReorderSubscriptionTemplatesResponseDto", "TemplateInfoDto", # System models "BandwidthStatistic", @@ -723,6 +741,9 @@ __all__ = [ "GetInboundsByProfileUuidResponseDto", "InboundDto", "NodesProfileDto", + "ReorderConfigProfileItem", + "ReorderConfigProfilesRequestDto", + "ReorderConfigProfilesResponseDto", "UpdateConfigProfileRequestDto", "UpdateConfigProfileResponseDto", "GetAllConfigProfilesResponsePaginated", @@ -766,8 +787,12 @@ __all__ = [ "GetAllInternalSquadsResponseDto", "GetInternalSquadByUuidResponseDto", "InternalSquadDto", + "ReorderInternalSquadItem", + "ReorderInternalSquadsRequestDto", + "ReorderInternalSquadsResponseDto", "UpdateInternalSquadRequestDto", "UpdateInternalSquadResponseDto", + "GetInternalSquadAccessibleNodesResponseDto", # Nodes usage history models "GetNodeUserUsageByRangeResponseDto", "GetNodesUsageByRangeResponseDto", @@ -838,6 +863,9 @@ __all__ = [ "GetExternalSquadByUuidResponseDto", "GetExternalSquadsResponseDto", "RemoveUsersFromExternalSquadResponseDto", + "ReorderExternalSquadItem", + "ReorderExternalSquadsRequestDto", + "ReorderExternalSquadsResponseDto", "TemplateType", "UpdateExternalSquadRequestDto", "UpdateExternalSquadResponseDto", @@ -879,6 +907,9 @@ __all__ = [ "DeleteSubscriptionPageConfigResponseDto", "GetSubscriptionPageConfigResponseDto", "GetSubscriptionPageConfigsResponseDto", + "GetSubpageConfigByShortUuidRequestBodyDto", + "GetSubpageConfigByShortUuidResponseDto", + "SubpageConfigData", "ReorderSubscriptionPageConfigItem", "ReorderSubscriptionPageConfigsRequestDto", "ReorderSubscriptionPageConfigsResponseDto", diff --git a/remnawave/models/config_profiles.py b/remnawave/models/config_profiles.py index f3625ef..e094c62 100644 --- a/remnawave/models/config_profiles.py +++ b/remnawave/models/config_profiles.py @@ -73,3 +73,16 @@ class GetAllInboundsResponseDto(List[InboundDto]): class GetInboundsByProfileUuidResponseDto(List[InboundDto]): pass + + +class ReorderConfigProfileItem(BaseModel): + view_position: int = Field(serialization_alias="viewPosition") + uuid: UUID + + +class ReorderConfigProfilesRequestDto(BaseModel): + items: List[ReorderConfigProfileItem] + + +class ReorderConfigProfilesResponseDto(GetAllConfigProfilesResponsePaginated): + pass diff --git a/remnawave/models/external_squads.py b/remnawave/models/external_squads.py index bae2d41..de9b020 100644 --- a/remnawave/models/external_squads.py +++ b/remnawave/models/external_squads.py @@ -106,6 +106,26 @@ class DeleteExternalSquadResponseDto(BaseModel): is_deleted: bool = Field(alias="isDeleted") +class ReorderExternalSquadItem(BaseModel): + view_position: int = Field(serialization_alias="viewPosition") + uuid: UUID + + +class ReorderExternalSquadsRequestDto(BaseModel): + items: List[ReorderExternalSquadItem] + + +class ReorderExternalSquadsResponseDto(BaseModel): + """Response after reordering external squads""" + total: int = Field(alias="total") + external_squads: List[ExternalSquadDto] = Field(alias="externalSquads") + + +class DeleteExternalSquadResponseDto(BaseModel): + """Response after deleting external squad""" + is_deleted: bool = Field(alias="isDeleted") + + class AddUsersToExternalSquadResponseDto(BaseModel): """Response after adding users to external squad""" event_sent: bool = Field(alias="eventSent") diff --git a/remnawave/models/internal_squads.py b/remnawave/models/internal_squads.py index 5034dcf..a00a440 100644 --- a/remnawave/models/internal_squads.py +++ b/remnawave/models/internal_squads.py @@ -101,3 +101,16 @@ class AccessibleNodeDto(BaseModel): class GetInternalSquadAccessibleNodesResponseDto(BaseModel): squad_uuid: UUID = Field(alias="squadUuid") accessible_nodes: List[AccessibleNodeDto] = Field(alias="accessibleNodes") + + +class ReorderInternalSquadItem(BaseModel): + view_position: int = Field(serialization_alias="viewPosition") + uuid: UUID + + +class ReorderInternalSquadsRequestDto(BaseModel): + items: List[ReorderInternalSquadItem] + + +class ReorderInternalSquadsResponseDto(GetAllInternalSquadsResponse): + pass diff --git a/remnawave/models/nodes.py b/remnawave/models/nodes.py index 9f2383d..6d807bc 100644 --- a/remnawave/models/nodes.py +++ b/remnawave/models/nodes.py @@ -212,6 +212,10 @@ class RestartAllNodesResponseDto(BaseModel): event_sent: bool = Field(alias="eventSent") +class ResetNodeTrafficResponseDto(BaseModel): + event_sent: bool = Field(alias="eventSent") + + class ReorderNodeResponseDto(RootModel[List[NodeResponseDto]]): root: List[NodeResponseDto] diff --git a/remnawave/models/subscription_page.py b/remnawave/models/subscription_page.py index eccc716..5958abc 100644 --- a/remnawave/models/subscription_page.py +++ b/remnawave/models/subscription_page.py @@ -104,4 +104,26 @@ class CloneSubscriptionPageConfigRequestDto(BaseModel): class CloneSubscriptionPageConfigResponseDto(SubscriptionPageConfigDto): """Response after cloning subscription page config""" - pass \ No newline at end of file + pass + + +class GetSubpageConfigByShortUuidRequestBodyDto(BaseModel): + """Request body for getting subpage config by short UUID""" + model_config = ConfigDict(populate_by_name=True) + + request_headers: dict[str, str] = Field(default_factory=dict, serialization_alias="requestHeaders") + + +class SubpageConfigData(BaseModel): + """Data inside GetSubpageConfigByShortUuidResponseDto""" + model_config = ConfigDict(populate_by_name=True) + + subpage_config_uuid: UUID | None = Field(alias="subpageConfigUuid") + webpage_allowed: bool = Field(alias="webpageAllowed") + + +class GetSubpageConfigByShortUuidResponseDto(BaseModel): + """Response for getting subpage config by short UUID""" + model_config = ConfigDict(populate_by_name=True) + + response: SubpageConfigData \ No newline at end of file diff --git a/remnawave/models/subscriptions_template.py b/remnawave/models/subscriptions_template.py index 254d7b9..eaf43aa 100644 --- a/remnawave/models/subscriptions_template.py +++ b/remnawave/models/subscriptions_template.py @@ -65,6 +65,19 @@ class DeleteSubscriptionTemplateResponseDto(DeleteTemplateData): pass +class ReorderTemplateItem(BaseModel): + view_position: int = Field(serialization_alias="viewPosition") + uuid: UUID + + +class ReorderSubscriptionTemplatesRequestDto(BaseModel): + items: List[ReorderTemplateItem] + + +class ReorderSubscriptionTemplatesResponseDto(GetTemplatesData): + pass + + # Legacy aliases for backward compatibility class UpdateTemplateRequestDtoLegacy(BaseModel): template_type: TemplateType = Field(serialization_alias="templateType") diff --git a/test_imports.py b/test_imports.py new file mode 100644 index 0000000..fc5dcdd --- /dev/null +++ b/test_imports.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +"""Quick test to verify all new imports work""" + +try: + from remnawave.models import ( + ReorderConfigProfilesRequestDto, + ReorderSubscriptionTemplatesRequestDto, + ReorderInternalSquadsRequestDto, + ReorderExternalSquadsRequestDto, + GetSubpageConfigByShortUuidResponseDto, + ) + print("✅ Все новые модели успешно импортируются!") + print(" - ReorderConfigProfilesRequestDto") + print(" - ReorderSubscriptionTemplatesRequestDto") + print(" - ReorderInternalSquadsRequestDto") + print(" - ReorderExternalSquadsRequestDto") + print(" - GetSubpageConfigByShortUuidResponseDto") +except ImportError as e: + print(f"❌ Ошибка импорта: {e}") + exit(1) diff --git a/tests/test_config_profiles.py b/tests/test_config_profiles.py index b48a8b9..0738f9f 100644 --- a/tests/test_config_profiles.py +++ b/tests/test_config_profiles.py @@ -8,6 +8,9 @@ from remnawave.models import ( GetAllInboundsResponseDto, GetConfigProfileByUuidResponseDto, GetInboundsByProfileUuidResponseDto, + ReorderConfigProfileItem, + ReorderConfigProfilesRequestDto, + ReorderConfigProfilesResponseDto, UpdateConfigProfileRequestDto, UpdateConfigProfileResponseDto, ) @@ -128,6 +131,21 @@ async def test_config_profiles(remnawave) -> None: inbounds_by_profile = await remnawave.config_profiles.get_inbounds_by_profile_uuid(profile_uuid) assert isinstance(inbounds_by_profile, GetInboundsByProfileUuidResponseDto) + # Test reorder config profiles + all_profiles_before_reorder = await remnawave.config_profiles.get_config_profiles() + if len(all_profiles_before_reorder.config_profiles) >= 2: + items = [ + ReorderConfigProfileItem( + uuid=profile.uuid, + view_position=idx + ) + for idx, profile in enumerate(all_profiles_before_reorder.config_profiles) + ] + reorder_result = await remnawave.config_profiles.reorder_config_profiles( + ReorderConfigProfilesRequestDto(items=items) + ) + assert isinstance(reorder_result, ReorderConfigProfilesResponseDto) + # Test delete config profile delete_profile = await remnawave.config_profiles.delete_config_profile_by_uuid(profile_uuid) assert isinstance(delete_profile, DeleteConfigProfileResponseDto) diff --git a/tests/test_internal_squads.py b/tests/test_internal_squads.py index c4f587c..a7970aa 100644 --- a/tests/test_internal_squads.py +++ b/tests/test_internal_squads.py @@ -11,6 +11,9 @@ from remnawave.models import ( DeleteUsersFromInternalSquadResponseDto, GetAllInternalSquadsResponseDto, GetInternalSquadByUuidResponseDto, + ReorderInternalSquadItem, + ReorderInternalSquadsRequestDto, + ReorderInternalSquadsResponseDto, UpdateInternalSquadRequestDto, UpdateInternalSquadResponseDto, ) @@ -69,6 +72,21 @@ async def test_internal_squads(remnawave) -> None: ) assert isinstance(remove_users, DeleteUsersFromInternalSquadResponseDto) + + # Test reorder internal squads + all_squads = await remnawave.internal_squads.get_internal_squads() + if len(all_squads.internal_squads) >= 2: + items = [ + ReorderInternalSquadItem( + uuid=squad.uuid, + view_position=idx + ) + for idx, squad in enumerate(all_squads.internal_squads) + ] + reorder_result = await remnawave.internal_squads.reorder_internal_squads( + ReorderInternalSquadsRequestDto(items=items) + ) + assert isinstance(reorder_result, ReorderInternalSquadsResponseDto) # Test delete internal squad delete_squad = await remnawave.internal_squads.delete_internal_squad(squad_uuid) diff --git a/tests/test_nodes.py b/tests/test_nodes.py index 843ef95..64a8ea9 100644 --- a/tests/test_nodes.py +++ b/tests/test_nodes.py @@ -11,6 +11,7 @@ from remnawave.models import ( NodesResponseDto, ReorderNodeRequestDto, ReorderNodeResponseDto, + ResetNodeTrafficResponseDto, UpdateNodeRequestDto, ) from remnawave.models.nodes import ReorderNodeItem @@ -64,6 +65,10 @@ async def test_nodes(remnawave): assert update_node.uuid == create_node.uuid assert update_node.name == update_name + reset_traffic = await remnawave.nodes.reset_node_traffic(uuid=string_uuid) + assert isinstance(reset_traffic, ResetNodeTrafficResponseDto) + assert reset_traffic.event_sent is True + delete_node = await remnawave.nodes.delete_node(uuid=string_uuid) assert isinstance(delete_node, DeleteNodeResponseDto) assert delete_node.is_deleted is True diff --git a/tests/test_subscription.py b/tests/test_subscription.py index 9cb2f99..92ae5c5 100644 --- a/tests/test_subscription.py +++ b/tests/test_subscription.py @@ -6,7 +6,10 @@ from remnawave.models import ( GetSubscriptionInfoResponseDto, GetRawSubscriptionByShortUuidResponseDto, GetAllSubscriptionsResponseDto, - GetSubscriptionByUsernameResponseDto + GetSubscriptionByUsernameResponseDto, + GetSubpageConfigByShortUuidRequestBodyDto, + GetSubpageConfigByShortUuidResponseDto, + SubpageConfigData, ) from tests.conftest import REMNAWAVE_SHORT_UUID, REMNAWAVE_USER_USERNAME @@ -71,4 +74,16 @@ class TestSubscriptionsManagement: subscription_by_username = await remnawave.subscriptions.get_subscription_by_username( username=REMNAWAVE_USER_USERNAME ) - assert isinstance(subscription_by_username, GetSubscriptionByUsernameResponseDto) \ No newline at end of file + assert isinstance(subscription_by_username, GetSubscriptionByUsernameResponseDto) + + @pytest.mark.asyncio + async def test_get_subpage_config(self, remnawave): + """Тест получения конфига страницы подписки по short UUID""" + body = GetSubpageConfigByShortUuidRequestBodyDto(request_headers={}) + subpage_config = await remnawave.subscriptions.get_subpage_config( + short_uuid=REMNAWAVE_SHORT_UUID, + body=body, + ) + # Client auto-unwraps single "response" field → returns SubpageConfigData + assert isinstance(subpage_config, (GetSubpageConfigByShortUuidResponseDto, SubpageConfigData)) + assert hasattr(subpage_config, 'webpage_allowed') \ No newline at end of file diff --git a/tests/test_subscriptions_template.py b/tests/test_subscriptions_template.py index 3093bbc..250048c 100644 --- a/tests/test_subscriptions_template.py +++ b/tests/test_subscriptions_template.py @@ -6,6 +6,9 @@ from remnawave.models import ( DeleteSubscriptionTemplateResponseDto, GetTemplateResponseDto, GetTemplatesResponseDto, + ReorderTemplateItem, + ReorderSubscriptionTemplatesRequestDto, + ReorderSubscriptionTemplatesResponseDto, UpdateTemplateRequestDto, UpdateTemplateResponseDto, ) @@ -88,4 +91,24 @@ async def test_delete_template(remnawave): str(created.uuid) ) assert isinstance(delete_response, DeleteSubscriptionTemplateResponseDto) - assert delete_response.is_deleted is True \ No newline at end of file + assert delete_response.is_deleted is True + + +@pytest.mark.asyncio +async def test_reorder_templates(remnawave): + """Проверка изменения порядка шаблонов""" + templates = await remnawave.subscriptions_template.get_all_templates() + assert isinstance(templates, GetTemplatesResponseDto) + + if len(templates.templates) >= 2: + items = [ + ReorderTemplateItem( + uuid=tmpl.uuid, + view_position=idx + ) + for idx, tmpl in enumerate(templates.templates) + ] + reorder_result = await remnawave.subscriptions_template.reorder_templates( + ReorderSubscriptionTemplatesRequestDto(items=items) + ) + assert isinstance(reorder_result, ReorderSubscriptionTemplatesResponseDto) \ No newline at end of file