%%%------------------------------------------------------------------- %%% @doc API-тесты forgot/reset password. %%% @end %%%------------------------------------------------------------------- -module(user_password_reset_tests). -include_lib("eunit/include/eunit.hrl"). -export([test/0]). -spec test() -> ok. test() -> ct:pal("=== User Password Reset Tests ==="), AdminToken = api_test_runner:get_admin_token(), Email = api_test_runner:unique_email(<<"pwreset">>), OldPass = <<"OldPass123">>, NewPass = <<"NewPass456">>, %% register + verify {ok, 201, _, RegBody} = api_test_runner:client_request(post, <<"/v1/register">>, <<>>, jsx:encode(#{email => Email, password => OldPass})), #{<<"user">> := #{<<"id">> := UserId}} = jsx:decode(list_to_binary(RegBody), [return_maps]), #{<<"token">> := VerifyToken} = api_test_runner:admin_get( <<"/v1/admin/users/", UserId/binary, "/verification-token">>, AdminToken), {ok, 200, _, _} = api_test_runner:client_request(post, <<"/v1/verify">>, <<>>, jsx:encode(#{<<"token">> => VerifyToken})), %% forgot always 200 (known + unknown) {ok, 200, _, _} = api_test_runner:client_request(post, <<"/v1/forgot-password">>, <<>>, jsx:encode(#{email => Email})), {ok, 200, _, _} = api_test_runner:client_request(post, <<"/v1/forgot-password">>, <<>>, jsx:encode(#{email => <<"nobody-reset@test.local">>})), %% admin token + reset #{<<"token">> := ResetToken} = api_test_runner:admin_get( <<"/v1/admin/users/", UserId/binary, "/password-reset-token">>, AdminToken), {ok, 200, _, _} = api_test_runner:client_request(post, <<"/v1/reset-password">>, <<>>, jsx:encode(#{<<"token">> => ResetToken, <<"password">> => NewPass})), %% old password fails, new works {ok, 401, _, _} = api_test_runner:client_request(post, <<"/v1/login">>, <<>>, jsx:encode(#{email => Email, password => OldPass})), {ok, 200, _, _} = api_test_runner:client_request(post, <<"/v1/login">>, <<>>, jsx:encode(#{email => Email, password => NewPass})), %% token reuse → 404 {ok, 404, _, _} = api_test_runner:client_request(post, <<"/v1/reset-password">>, <<>>, jsx:encode(#{<<"token">> => ResetToken, <<"password">> => <<"AnotherPass9">>})), %% short password → 400 #{<<"token">> := ResetToken2} = api_test_runner:admin_get( <<"/v1/admin/users/", UserId/binary, "/password-reset-token">>, AdminToken), {ok, 400, _, _} = api_test_runner:client_request(post, <<"/v1/reset-password">>, <<>>, jsx:encode(#{<<"token">> => ResetToken2, <<"password">> => <<"short">>})), %% invalid token → 404 {ok, 404, _, _} = api_test_runner:client_request(post, <<"/v1/reset-password">>, <<>>, jsx:encode(#{<<"token">> => <<"nope">>, <<"password">> => NewPass})), ct:pal("=== All user password reset tests passed ==="), ok.