%%%------------------------------------------------------------------- %%% @doc Тесты процесса подтверждения регистрации. %%% %%% Проверяет: %%% - регистрация создаёт пользователя со статусом `pending` %%% - вход до подтверждения возвращает 403 %%% - получение верификационного токена через админку %%% - подтверждение аккаунта через публичный эндпоинт %%% - после подтверждения вход успешен %%% - повторное использование токена возвращает ошибку %%% - невалидный токен возвращает 404 %%% @end %%%------------------------------------------------------------------- -module(user_verification_tests). -include_lib("eunit/include/eunit.hrl"). -export([test/0]). -spec test() -> ok. test() -> ct:pal("=== User Verification Tests ==="), AdminToken = api_test_runner:get_admin_token(), Email = api_test_runner:unique_email(<<"verify">>), Password = <<"TestPass123">>, % 1. Регистрируем пользователя (должен получить статус pending) {ok, 201, _, RegBody} = api_test_runner:client_request(post, <<"/v1/register">>, <<>>, jsx:encode(#{email => Email, password => Password})), #{<<"user">> := #{<<"id">> := UserId, <<"status">> := UserStatus}} = jsx:decode(list_to_binary(RegBody), [return_maps]), ?assertEqual(<<"pending">>, UserStatus), % 2. Попытка входа до подтверждения – должна вернуть 403 {ok, 403, _, _} = api_test_runner:client_request(post, <<"/v1/login">>, <<>>, jsx:encode(#{email => Email, password => Password})), % 3. Получаем верификационный токен через админку #{<<"token">> := Token} = api_test_runner:admin_get( <<"/v1/admin/users/", UserId/binary, "/verification-token">>, AdminToken), % 4. Подтверждаем аккаунт через публичный эндпоинт {ok, 200, _, _} = api_test_runner:client_request(post, <<"/v1/verify">>, <<>>, jsx:encode(#{<<"token">> => Token})), % 5. Теперь вход должен быть успешным {ok, 200, _, LoginBody} = api_test_runner:client_request(post, <<"/v1/login">>, <<>>, jsx:encode(#{email => Email, password => Password})), #{<<"token">> := AuthToken} = jsx:decode(list_to_binary(LoginBody), [return_maps]), ?assert(is_binary(AuthToken)), % 6. После активации — дефолтный приватный personal-календарь Calendars = api_test_runner:client_get(<<"/v1/calendars">>, AuthToken), ?assertEqual(1, length(Calendars)), [DefaultCal] = Calendars, ?assertEqual(<<"personal">>, maps:get(<<"type">>, DefaultCal)), ?assertEqual(<<>>, maps:get(<<"short_name">>, DefaultCal)), ExpectedTitle = case string:split(Email, <<"@">>) of [Local, _] when byte_size(Local) > 0 -> Local; _ -> <<"Мой календарь">> end, ?assertEqual(ExpectedTitle, maps:get(<<"title">>, DefaultCal)), % 7. Повторное использование того же токена – ошибка 404 {ok, 404, _, _} = api_test_runner:client_request(post, <<"/v1/verify">>, <<>>, jsx:encode(#{<<"token">> => Token})), % 7. Повторное использование того же токена – ошибка 404 {ok, 404, _, _} = api_test_runner:client_request(post, <<"/v1/verify">>, <<>>, jsx:encode(#{<<"token">> => Token})), % 8. Невалидный токен – ошибка 404 {ok, 404, _, _} = api_test_runner:client_request(post, <<"/v1/verify">>, <<>>, jsx:encode(#{<<"token">> => <<"invalid_token">>})), ct:pal("=== All user verification tests passed ==="), ok.