%%%------------------------------------------------------------------- %%% @doc EUnit: logic_user:update_me/2 (PATCH /v1/user/me). %%% @end %%%------------------------------------------------------------------- -module(logic_user_tests). -include_lib("eunit/include/eunit.hrl"). -include("records.hrl"). -define(TABLES, [user]). -define(PASS, <<"oldpass1">>). -define(PASS2, <<"newpass2">>). setup() -> eh_test_support:start_mnesia(), eh_test_support:ensure_tables(?TABLES), case mnesia:add_table_index(user, email) of {atomic, ok} -> ok; {aborted, {already_exists, user, email}} -> ok; {aborted, Reason} -> error({add_index_failed, Reason}) end, ok. cleanup(_) -> eh_test_support:clear_tables(?TABLES), eh_test_support:delete_tables(?TABLES), eh_test_support:stop_mnesia(), ok. logic_user_update_me_test_() -> {foreach, fun setup/0, fun cleanup/1, [ {"Success profile fields", fun test_success_profile_fields/0}, {"Language validation", fun test_language_validation/0}, {"Unknown field", fun test_unknown_field/0}, {"Password pair required", fun test_password_pair_required/0}, {"Wrong password", fun test_wrong_password/0}, {"Successful password change", fun test_password_change_ok/0}, {"Empty body", fun test_empty_body/0}, {"Non-active user forbidden", fun test_non_active_forbidden/0} ]}. %%%=================================================================== %%% Helpers %%%=================================================================== seed_active_user() -> {ok, Hash} = logic_auth:hash_password(?PASS), User = eh_test_support:make_user(#{ id => <<"me_user_1">>, email => <<"me@test.local">>, password_hash => Hash, status => active, nickname => <<"oldnick">>, language => <<"ru">>, timezone => <<"UTC">>, phone => <<"+1000">>, avatar_url => <<"http://old/avatar.png">>, preferences => #{<<"theme">> => <<"light">>} }), ok = mnesia:dirty_write(User), User. %%%=================================================================== %%% Cases %%%=================================================================== test_success_profile_fields() -> User = seed_active_user(), Body = #{ <<"language">> => <<"en">>, <<"nickname">> => <<"Nick">>, <<"timezone">> => <<"Europe/Moscow">>, <<"phone">> => <<"+7000">>, <<"avatar_url">> => <<"http://cdn/a.png">>, <<"preferences">> => #{<<"theme">> => <<"dark">>} }, {ok, Updated} = logic_user:update_me(User#user.id, Body), ?assertEqual(<<"en">>, Updated#user.language), ?assertEqual(<<"Nick">>, Updated#user.nickname), ?assertEqual(<<"Europe/Moscow">>, Updated#user.timezone), ?assertEqual(<<"+7000">>, Updated#user.phone), ?assertEqual(<<"http://cdn/a.png">>, Updated#user.avatar_url), ?assertEqual(#{<<"theme">> => <<"dark">>}, Updated#user.preferences). test_language_validation() -> User = seed_active_user(), ?assertEqual({error, invalid_language}, logic_user:update_me(User#user.id, #{<<"language">> => <<"de">>})), ?assertEqual({error, invalid_language}, logic_user:update_me(User#user.id, #{<<"language">> => <<"RU">>})), {ok, Ok} = logic_user:update_me(User#user.id, #{<<"language">> => <<"en">>}), ?assertEqual(<<"en">>, Ok#user.language). test_unknown_field() -> User = seed_active_user(), ?assertEqual({error, unknown_field}, logic_user:update_me(User#user.id, #{<<"email">> => <<"x@y.z">>})), ?assertEqual({error, unknown_field}, logic_user:update_me(User#user.id, #{<<"role">> => <<"bot">>})). test_password_pair_required() -> User = seed_active_user(), ?assertEqual({error, password_pair_required}, logic_user:update_me(User#user.id, #{<<"password">> => ?PASS2})), ?assertEqual({error, password_pair_required}, logic_user:update_me(User#user.id, #{<<"current_password">> => ?PASS})). test_wrong_password() -> User = seed_active_user(), ?assertEqual({error, wrong_password}, logic_user:update_me(User#user.id, #{ <<"current_password">> => <<"nope">>, <<"password">> => ?PASS2 })). test_password_change_ok() -> User = seed_active_user(), {ok, Updated} = logic_user:update_me(User#user.id, #{ <<"current_password">> => ?PASS, <<"password">> => ?PASS2 }), ?assertEqual({ok, true}, logic_auth:verify_password(?PASS2, Updated#user.password_hash)), ?assertEqual({ok, false}, logic_auth:verify_password(?PASS, Updated#user.password_hash)). test_empty_body() -> User = seed_active_user(), ?assertEqual({error, empty_body}, logic_user:update_me(User#user.id, #{})), ?assertEqual({error, invalid_json}, logic_user:update_me(User#user.id, not_a_map)). test_non_active_forbidden() -> {ok, Hash} = logic_auth:hash_password(?PASS), Frozen = eh_test_support:make_user(#{ id => <<"me_frozen">>, email => <<"frozen@test.local">>, password_hash => Hash, status => frozen }), ok = mnesia:dirty_write(Frozen), ?assertEqual({error, forbidden}, logic_user:update_me(Frozen#user.id, #{<<"nickname">> => <<"x">>})), Pending = Frozen#user{id = <<"me_pending">>, email = <<"pending@test.local">>, status = pending}, ok = mnesia:dirty_write(Pending), ?assertEqual({error, forbidden}, logic_user:update_me(Pending#user.id, #{<<"nickname">> => <<"x">>})).