%%%------------------------------------------------------------------- %%% @doc Тесты клиентского API для управления подпиской. %%% %%% Покрывает эндпоинты: %%% GET /v1/subscription %%% POST /v1/subscription %%% %%% Проверяет: %%% - получение информации о подписке (200) %%% - активацию пробного периода (start_trial, 201) %%% - ошибку 409 при повторной активации %%% - ошибку 401 без токена %%% @end %%%------------------------------------------------------------------- -module(user_subscription_tests). -include_lib("eunit/include/eunit.hrl"). -export([test/0]). %%%=================================================================== %%% Главная тестовая функция %%%=================================================================== -spec test() -> ok. test() -> ct:pal("=== User Subscription Tests ==="), % Создаём уникального пользователя – у него точно нет активной подписки Email = api_test_runner:unique_email(<<"subtest">>), Token = api_test_runner:register_and_login(Email, <<"StrongPass1!">>), test_get_subscription(Token), test_start_trial(Token), test_start_trial_duplicate(Token), test_get_subscription_unauthorized(), ct:pal("=== All user subscription tests passed ==="), ok. %%%=================================================================== %%% Тестовые функции %%%=================================================================== %% @doc GET /v1/subscription – получение подписки (может быть пустой). -spec test_get_subscription(binary()) -> ok. test_get_subscription(Token) -> ct:pal(" TEST: Get subscription"), Sub = api_test_runner:client_get(<<"/v1/subscription">>, Token), ?assert(is_map(Sub)), ct:pal(" OK: subscription info received"). %% @doc POST /v1/subscription – успешная активация пробного периода. -spec test_start_trial(binary()) -> ok. test_start_trial(Token) -> ct:pal(" TEST: Start trial"), Resp = api_test_runner:client_request(post, <<"/v1/subscription">>, Token, jsx:encode(#{action => <<"start_trial">>})), {ok, 201, _, Body} = Resp, #{<<"status">> := Status, <<"plan">> := Plan} = jsx:decode(list_to_binary(Body), [return_maps]), ?assertEqual(<<"active">>, Status), ?assert(is_binary(Plan)), ct:pal(" OK: trial activated with plan ~s", [Plan]). %% @doc POST /v1/subscription – повторная активация (409). -spec test_start_trial_duplicate(binary()) -> ok. test_start_trial_duplicate(Token) -> ct:pal(" TEST: Start trial again (duplicate)"), Resp = api_test_runner:client_request(post, <<"/v1/subscription">>, Token, jsx:encode(#{action => <<"start_trial">>})), ?assertMatch({ok, 409, _, _}, Resp), ct:pal(" OK: got 409 conflict"). %% @doc GET /v1/subscription без токена (401). -spec test_get_subscription_unauthorized() -> ok. test_get_subscription_unauthorized() -> ct:pal(" TEST: Get subscription without token"), Resp = api_test_runner:client_request(get, <<"/v1/subscription">>, <<>>), ?assertMatch({ok, 401, _, _}, Resp), ct:pal(" OK: got 401").