-module(auth_test). -include_lib("eunit/include/eunit.hrl"). -define(JWT_SECRET, <<"test-user-secret-key-32-byt!">>). -define(ADMIN_JWT_SECRET, <<"test-admin-secret-key-32-b">>). %% ------------------------------------------------------------------ %% EUnit фикстуры – запуск и остановка моков %% ------------------------------------------------------------------ setup() -> ok = meck:new(logic_auth, [non_strict]), application:set_env(eventhub, jwt_secret, ?JWT_SECRET), application:set_env(eventhub, admin_jwt_secret, ?ADMIN_JWT_SECRET), {ok, _} = application:ensure_all_started(jose), ok. cleanup(_) -> application:unset_env(eventhub, jwt_secret), application:unset_env(eventhub, admin_jwt_secret), application:stop(jose), meck:unload(logic_auth). %% ------------------------------------------------------------------ %% Тесты генерации токенов %% ------------------------------------------------------------------ generate_user_token_test_() -> {setup, fun setup/0, fun cleanup/1, [ {"Generate user token returns a binary", fun() -> Token = eventhub_auth:generate_user_token(<<"user123">>, <<"user">>), ?assert(is_binary(Token)), ?assert(size(Token) > 0) end}, {"Generated user token can be verified", fun() -> Token = eventhub_auth:generate_user_token(<<"user123">>, <<"user">>), {ok, UserId, Role} = eventhub_auth:verify_user_token(Token), ?assertEqual(<<"user123">>, UserId), ?assertEqual(<<"user">>, Role) end}, {"Generate admin token with superadmin role", fun() -> Token = eventhub_auth:generate_admin_token(<<"admin1">>, <<"superadmin">>), {ok, UserId, Role} = eventhub_auth:verify_admin_token(Token), ?assertEqual(<<"admin1">>, UserId), ?assertEqual(<<"superadmin">>, Role) end} ]}. %% ------------------------------------------------------------------ %% Тесты верификации токенов (граничные случаи) %% ------------------------------------------------------------------ verify_token_errors_test_() -> {setup, fun setup/0, fun cleanup/1, [ {"Invalid token signature returns error", fun() -> FakeToken = <<"not.a.valid.token">>, ?assertEqual({error, invalid_token}, eventhub_auth:verify_user_token(FakeToken)), ?assertEqual({error, invalid_token}, eventhub_auth:verify_admin_token(FakeToken)) end}, {"User token rejected by admin verifier (different secret)", fun() -> Token = eventhub_auth:generate_user_token(<<"x">>, <<"user">>), % Разные секреты → подпись недействительна для admin JWK ?assertEqual({error, invalid_signature}, eventhub_auth:verify_admin_token(Token)) end}, {"Admin token rejected by user verifier (different secret)", fun() -> Token = eventhub_auth:generate_admin_token(<<"x">>, <<"admin">>), ?assertEqual({error, invalid_signature}, eventhub_auth:verify_user_token(Token)) end} ]}. %% ------------------------------------------------------------------ %% Тесты для authenticate_user_request/3 %% ------------------------------------------------------------------ authenticate_user_request_test_() -> {setup, fun setup/0, fun cleanup/1, [ {"Successful user login returns token and user data", fun() -> UserMap = #{id => <<"user1">>, email => <<"u@test.com">>, role => <<"user">>}, ok = meck:expect(logic_auth, authenticate_user, fun(_Email, _Password) -> {ok, UserMap} end), Req = undefined, {ok, Token, ReturnedUser} = eventhub_auth:authenticate_user_request(Req, <<"u@test.com">>, <<"pass">>), ?assert(is_binary(Token)), ?assertEqual(UserMap, ReturnedUser), {ok, UserId, Role} = eventhub_auth:verify_user_token(Token), ?assertEqual(<<"user1">>, UserId), ?assertEqual(<<"user">>, Role) end}, {"User login failure propagates error from logic_auth", fun() -> ok = meck:expect(logic_auth, authenticate_user, fun(_Email, _Password) -> {error, bad_credentials} end), Req = undefined, ?assertEqual({error, bad_credentials}, eventhub_auth:authenticate_user_request(Req, <<"bad">>, <<"pwd">>)) end} ]}. %% ------------------------------------------------------------------ %% Тесты для authenticate_admin_request/3 %% ------------------------------------------------------------------ authenticate_admin_request_test_() -> {setup, fun setup/0, fun cleanup/1, [ {"Successful admin login returns admin token", fun() -> AdminMap = #{id => <<"adm1">>, email => <<"admin@test.com">>, role => <<"superadmin">>}, ok = meck:expect(logic_auth, authenticate_user, fun(_Email, _Password) -> {ok, AdminMap} end), Req = undefined, {ok, Token, ReturnedUser} = eventhub_auth:authenticate_admin_request(Req, <<"admin@test.com">>, <<"pass">>), ?assert(is_binary(Token)), ?assertEqual(AdminMap, ReturnedUser), {ok, UserId, Role} = eventhub_auth:verify_admin_token(Token), ?assertEqual(<<"adm1">>, UserId), ?assertEqual(<<"superadmin">>, Role) end}, {"Non-admin role is rejected with insufficient_permissions", fun() -> UserMap = #{id => <<"simpleuser">>, email => <<"u@test.com">>, role => <<"user">>}, ok = meck:expect(logic_auth, authenticate_user, fun(_Email, _Password) -> {ok, UserMap} end), Req = undefined, ?assertEqual({error, insufficient_permissions}, eventhub_auth:authenticate_admin_request(Req, <<"u@test.com">>, <<"pwd">>)) end}, {"Moderator role is accepted as admin", fun() -> ModMap = #{id => <<"moder1">>, email => <<"mod@test.com">>, role => <<"moderator">>}, ok = meck:expect(logic_auth, authenticate_user, fun(_Email, _Password) -> {ok, ModMap} end), Req = undefined, {ok, Token, _} = eventhub_auth:authenticate_admin_request(Req, <<"mod@test.com">>, <<"pwd">>), {ok, _, Role} = eventhub_auth:verify_admin_token(Token), ?assertEqual(<<"moderator">>, Role) end} ]}. %% ------------------------------------------------------------------ %% Тест generate_refresh_token/1 %% ------------------------------------------------------------------ generate_refresh_token_test() -> {_, _} = eventhub_auth:generate_refresh_token(<<"anyuser">>).