90 lines
3.7 KiB
Erlang
90 lines
3.7 KiB
Erlang
%%%-------------------------------------------------------------------
|
||
%%% @doc Тесты клиентского API для входа пользователей.
|
||
%%%
|
||
%%% Покрывает эндпоинты:
|
||
%%% POST /v1/login
|
||
%%%
|
||
%%% Проверяет:
|
||
%%% - успешный вход с правильными email и паролем
|
||
%%% - ошибку при неверном пароле
|
||
%%% - ошибку при несуществующем email
|
||
%%% - ошибку при отсутствии обязательных полей
|
||
%%% @end
|
||
%%%-------------------------------------------------------------------
|
||
-module(user_login_tests).
|
||
-include_lib("eunit/include/eunit.hrl").
|
||
|
||
-export([test/0]).
|
||
|
||
%%%===================================================================
|
||
%%% Главная тестовая функция
|
||
%%%===================================================================
|
||
|
||
-spec test() -> ok.
|
||
test() ->
|
||
ct:pal("=== Client Login Tests ==="),
|
||
Email = api_test_runner:unique_email(<<"login">>),
|
||
Password = <<"StrongPass1!">>,
|
||
|
||
% Создаём пользователя для тестов входа
|
||
api_test_runner:register_and_login(Email, Password),
|
||
|
||
test_successful_login(Email, Password),
|
||
test_wrong_password(Email),
|
||
test_nonexistent_email(),
|
||
test_missing_fields(),
|
||
|
||
ct:pal("=== All client login tests passed ==="),
|
||
ok.
|
||
|
||
%%%===================================================================
|
||
%%% Тестовые функции
|
||
%%%===================================================================
|
||
|
||
%% @doc Успешный вход: 200 OK, возвращает токен и данные пользователя.
|
||
-spec test_successful_login(binary(), binary()) -> ok.
|
||
test_successful_login(Email, Password) ->
|
||
ct:pal(" TEST: Successful login"),
|
||
Resp = api_test_runner:client_request(post, <<"/v1/login">>, <<>>,
|
||
jsx:encode(#{email => Email, password => Password})),
|
||
{ok, 200, _, Body} = Resp,
|
||
#{<<"token">> := Token, <<"user">> := User} = jsx:decode(list_to_binary(Body), [return_maps]),
|
||
?assert(is_binary(Token)),
|
||
?assertEqual(Email, maps:get(<<"email">>, User)),
|
||
ct:pal(" OK: user ~s logged in", [maps:get(<<"id">>, User)]).
|
||
|
||
%% @doc Неверный пароль: 401 Unauthorized.
|
||
-spec test_wrong_password(binary()) -> ok.
|
||
test_wrong_password(Email) ->
|
||
ct:pal(" TEST: Wrong password"),
|
||
Resp = api_test_runner:client_request(post, <<"/v1/login">>, <<>>,
|
||
jsx:encode(#{email => Email, password => <<"WrongPass1">>})),
|
||
{ok, 401, _, Body} = Resp,
|
||
#{<<"error">> := Msg} = jsx:decode(list_to_binary(Body), [return_maps]),
|
||
?assertEqual(<<"Invalid credentials">>, Msg),
|
||
ct:pal(" OK: got 401 unauthorized").
|
||
|
||
%% @doc Несуществующий email: 401 Unauthorized.
|
||
-spec test_nonexistent_email() -> ok.
|
||
test_nonexistent_email() ->
|
||
ct:pal(" TEST: Nonexistent email"),
|
||
Resp = api_test_runner:client_request(post, <<"/v1/login">>, <<>>,
|
||
jsx:encode(#{email => <<"no@such.user">>, password => <<"Anything1">>})),
|
||
{ok, 401, _, Body} = Resp,
|
||
#{<<"error">> := Msg} = jsx:decode(list_to_binary(Body), [return_maps]),
|
||
?assertEqual(<<"Invalid credentials">>, Msg),
|
||
ct:pal(" OK: got 401 unauthorized").
|
||
|
||
%% @doc Отсутствие обязательных полей: 400 Bad Request.
|
||
-spec test_missing_fields() -> ok.
|
||
test_missing_fields() ->
|
||
ct:pal(" TEST: Missing required fields"),
|
||
Resp1 = api_test_runner:client_request(post, <<"/v1/login">>, <<>>,
|
||
jsx:encode(#{email => <<"a@b.com">>})),
|
||
?assertMatch({ok, 400, _, _}, Resp1),
|
||
|
||
Resp2 = api_test_runner:client_request(post, <<"/v1/login">>, <<>>,
|
||
jsx:encode(#{password => <<"NoEmail1">>})),
|
||
?assertMatch({ok, 400, _, _}, Resp2),
|
||
|
||
ct:pal(" OK: 400 on missing fields"). |