%%%------------------------------------------------------------------- %%% @doc Тесты административного API для управления подписками. %%% %%% Покрывает эндпоинты: %%% GET /v1/admin/subscriptions %%% GET /v1/admin/subscriptions/:id %%% PUT /v1/admin/subscriptions/:id %%% DELETE /v1/admin/subscriptions/:id %%% %%% Проверяет: %%% - получение списка подписок %%% - получение подписки по ID %%% - обновление подписки (изменение плана, статуса) %%% - удаление подписки %%% - фильтрацию по статусу и плану %%% - пагинацию %%% @end %%%------------------------------------------------------------------- -module(admin_subscriptions_tests). -include_lib("eunit/include/eunit.hrl"). -export([test/0]). %%%=================================================================== %%% Главная тестовая функция %%%=================================================================== -spec test() -> ok. test() -> ct:pal("=== Admin Subscriptions Tests ==="), Token = api_test_runner:get_admin_token(), UserToken = api_test_runner:get_user_token(), % Создаём две подписки для разных проверок #{<<"id">> := Sub1Id} = api_test_runner:client_post(<<"/v1/subscription">>, UserToken, #{<<"action">> => <<"start_trial">>}), % Для второй подписки создаём нового пользователя User2Email = api_test_runner:unique_email(<<"sub2">>), User2Token = api_test_runner:register_and_login(User2Email, <<"pass2">>), #{<<"id">> := Sub2Id} = api_test_runner:client_post(<<"/v1/subscription">>, User2Token, #{<<"action">> => <<"start_trial">>}), % Теперь две подписки в системе test_list_subscriptions(Token, Sub1Id), test_get_subscription(Token, Sub1Id), test_update_subscription(Token, Sub1Id), % После обновления Sub1Id имеет план biannual и статус active test_filter_subscriptions(Token), test_subscription_pagination(Token), % Удаляем вторую подписку, чтобы проверить delete test_delete_subscription(Token, Sub2Id), ct:pal("=== All admin subscriptions tests passed ==="), ok. %%%=================================================================== %%% Тестовые функции %%%=================================================================== %% @doc GET /v1/admin/subscriptions – список подписок. -spec test_list_subscriptions(binary(), binary()) -> ok. test_list_subscriptions(Token, SubId) -> ct:pal(" TEST: List all subscriptions"), Subs = api_test_runner:admin_get(<<"/v1/admin/subscriptions">>, Token), ?assert(is_list(Subs)), ?assert(length(Subs) >= 2), ?assert(lists:any(fun(S) -> maps:get(<<"id">>, S) =:= SubId end, Subs)), ct:pal(" OK: ~p subscriptions", [length(Subs)]). %% @doc GET /v1/admin/subscriptions/:id – получение подписки по ID. -spec test_get_subscription(binary(), binary()) -> ok. test_get_subscription(Token, SubId) -> ct:pal(" TEST: Get subscription by ID"), Path = <<"/v1/admin/subscriptions/", SubId/binary>>, Sub = api_test_runner:admin_get(Path, Token), ?assertEqual(SubId, maps:get(<<"id">>, Sub)), ?assert(maps:is_key(<<"plan">>, Sub)), ct:pal(" OK"). %% @doc PUT /v1/admin/subscriptions/:id – обновление подписки (план + статус). -spec test_update_subscription(binary(), binary()) -> ok. test_update_subscription(Token, SubId) -> ct:pal(" TEST: Update subscription (change plan)"), Path = <<"/v1/admin/subscriptions/", SubId/binary>>, Updated = api_test_runner:admin_put(Path, Token, #{ <<"plan">> => <<"biannual">>, <<"status">> => <<"active">> }), ?assertEqual(<<"biannual">>, maps:get(<<"plan">>, Updated)), ?assertEqual(<<"active">>, maps:get(<<"status">>, Updated)), ct:pal(" OK"). %% @doc DELETE /v1/admin/subscriptions/:id – удаление подписки. -spec test_delete_subscription(binary(), binary()) -> ok. test_delete_subscription(Token, SubId) -> ct:pal(" TEST: Delete subscription"), Path = <<"/v1/admin/subscriptions/", SubId/binary>>, Deleted = api_test_runner:admin_delete(Path, Token), ?assertEqual(<<"deleted">>, maps:get(<<"status">>, Deleted)), ct:pal(" OK"). %% @doc GET /v1/admin/subscriptions?status=...&plan=... – фильтрация. -spec test_filter_subscriptions(binary()) -> ok. test_filter_subscriptions(Token) -> ct:pal(" TEST: Filter subscriptions by status=active"), Subs = api_test_runner:admin_get(<<"/v1/admin/subscriptions?status=active">>, Token), ?assert(is_list(Subs)), ?assert(length(Subs) >= 1), [?assertEqual(<<"active">>, maps:get(<<"status">>, S)) || S <- Subs], ct:pal(" OK: ~p active subscriptions", [length(Subs)]), ct:pal(" TEST: Filter subscriptions by plan=biannual"), Subs2 = api_test_runner:admin_get(<<"/v1/admin/subscriptions?plan=biannual">>, Token), ?assert(is_list(Subs2)), ?assert(length(Subs2) >= 1), [?assertEqual(<<"biannual">>, maps:get(<<"plan">>, S)) || S <- Subs2], ct:pal(" OK: ~p biannual subscriptions", [length(Subs2)]). %% @doc GET /v1/admin/subscriptions?limit=...&offset=... – пагинация. -spec test_subscription_pagination(binary()) -> ok. test_subscription_pagination(Token) -> ct:pal(" TEST: Subscription pagination"), Page1 = api_test_runner:admin_get(<<"/v1/admin/subscriptions?limit=1&offset=0">>, Token), ?assert(length(Page1) >= 1), Page2 = api_test_runner:admin_get(<<"/v1/admin/subscriptions?limit=1&offset=1">>, Token), ?assert(length(Page2) >= 1), Id1 = maps:get(<<"id">>, hd(Page1)), Id2 = maps:get(<<"id">>, hd(Page2)), ?assertNotEqual(Id1, Id2), ct:pal(" OK").