Rewrite and expand EUnit suite; run unit tests in CI from shared test image. Refs EventHub/EventHubBack#36 [skip ci]

This commit is contained in:
2026-07-17 15:16:46 +03:00
parent 9d2780fef4
commit 4fa802702f
54 changed files with 4240 additions and 2281 deletions
+147
View File
@@ -0,0 +1,147 @@
-module(admin_handler_admins_tests).
-include_lib("eunit/include/eunit.hrl").
-include("records.hrl").
-define(TABLES, [admin, admin_audit, ticket]).
-define(ADMIN_ID, <<"adm_test_1">>).
-define(PLAIN_ID, <<"adm_plain_1">>).
setup() ->
eh_test_support:start_mnesia(),
eh_test_support:ensure_tables(?TABLES),
eh_test_support:ensure_jwt(),
catch application:ensure_all_started(argon2),
eh_test_support:seed_admin(#{id => ?ADMIN_ID, role => superadmin}),
ok.
cleanup(_) ->
eh_test_support:unload_cowboy(),
eh_test_support:delete_tables(?TABLES),
eh_test_support:stop_mnesia(),
ok.
admin_admins_test_() ->
{foreach, fun setup/0, fun cleanup/1, [
{"GET list success", {timeout, 60, fun test_list/0}},
{"GET list filter by role", {timeout, 60, fun test_list_filter/0}},
{"GET unauthorized", {timeout, 60, fun test_unauthorized/0}},
{"POST create success", {timeout, 60, fun test_create_ok/0}},
{"POST create forbidden for non-superadmin", {timeout, 60, fun test_create_forbidden/0}},
{"POST create missing fields", {timeout, 60, fun test_create_missing_fields/0}},
{"DELETE method not allowed", {timeout, 60, fun test_wrong_method/0}}
]}.
argon2_ready() ->
case catch argon2:hash(<<"probe">>) of
{ok, _} -> true;
_ -> false
end.
require_argon2(Fun) ->
case argon2_ready() of
true -> Fun();
false -> {skip, "argon2 NIF not available"}
end.
seed_extra_admins() ->
ok = mnesia:dirty_write(eh_test_support:make_admin(#{
id => <<"adm_mod">>,
email => <<"mod@test.local">>,
role => moderator,
nickname => <<"mod">>
})),
ok = mnesia:dirty_write(eh_test_support:make_admin(#{
id => <<"adm_sup">>,
email => <<"support@test.local">>,
role => support,
nickname => <<"sup">>
})),
ok.
test_list() ->
seed_extra_admins(),
{Status, _, Body} = eh_test_support:call(admin_handler_admins, #{
method => <<"GET">>,
path => <<"/v1/admin/admins">>,
auth => ?ADMIN_ID
}),
?assertEqual(200, Status),
Result = jsx:decode(Body, [return_maps]),
?assertEqual(3, length(Result)).
test_list_filter() ->
seed_extra_admins(),
{Status, _, Body} = eh_test_support:call(admin_handler_admins, #{
method => <<"GET">>,
path => <<"/v1/admin/admins">>,
auth => ?ADMIN_ID,
qs => [{<<"role">>, <<"moderator">>}]
}),
?assertEqual(200, Status),
Result = jsx:decode(Body, [return_maps]),
?assertEqual(1, length(Result)),
[Only] = Result,
?assertEqual(<<"mod@test.local">>, maps:get(<<"email">>, Only)).
test_unauthorized() ->
{Status, _, _} = eh_test_support:call(admin_handler_admins, #{
method => <<"GET">>,
path => <<"/v1/admin/admins">>,
auth => none
}),
?assertEqual(401, Status).
test_create_ok() ->
require_argon2(fun() ->
{Status, _, Body} = eh_test_support:call(admin_handler_admins, #{
method => <<"POST">>,
path => <<"/v1/admin/admins">>,
auth => ?ADMIN_ID,
body => jsx:encode(#{
<<"email">> => <<"newadmin@test.local">>,
<<"password">> => <<"SecretPass1!">>,
<<"role">> => <<"admin">>
})
}),
?assertEqual(201, Status),
Result = jsx:decode(Body, [return_maps]),
?assertEqual(<<"newadmin@test.local">>, maps:get(<<"email">>, Result)),
?assertEqual(<<"admin">>, maps:get(<<"role">>, Result)),
Audits = core_admin_audit:list(),
?assert(length(Audits) >= 1)
end).
test_create_forbidden() ->
ok = mnesia:dirty_write(eh_test_support:make_admin(#{
id => ?PLAIN_ID,
email => <<"plain@test.local">>,
role => admin
})),
{Status, _, _} = eh_test_support:call(admin_handler_admins, #{
method => <<"POST">>,
path => <<"/v1/admin/admins">>,
auth => ?PLAIN_ID,
body => jsx:encode(#{
<<"email">> => <<"x@test.local">>,
<<"password">> => <<"SecretPass1!">>,
<<"role">> => <<"admin">>
})
}),
?assertEqual(403, Status).
test_create_missing_fields() ->
{Status, _, _} = eh_test_support:call(admin_handler_admins, #{
method => <<"POST">>,
path => <<"/v1/admin/admins">>,
auth => ?ADMIN_ID,
body => jsx:encode(#{<<"email">> => <<"x@test.local">>})
}),
?assertEqual(400, Status).
test_wrong_method() ->
{Status, _, _} = eh_test_support:call(admin_handler_admins, #{
method => <<"DELETE">>,
path => <<"/v1/admin/admins">>,
auth => ?ADMIN_ID
}),
?assertEqual(405, Status).