-module(admin_handler_stats_tests). -include_lib("eunit/include/eunit.hrl"). -include("records.hrl"). setup() -> ok = meck:new(cowboy_req, [non_strict]), ok = meck:new(handler_auth, [non_strict]), ok = meck:new(admin_utils, [non_strict]), ok = meck:new(core_admin, [non_strict]), ok = meck:new(logic_stats, [non_strict]), ok = meck:expect(cowboy_req, reply, fun(Code, _, _, _) -> put(test_reply, Code) end), ok. cleanup(_) -> meck:unload(logic_stats), meck:unload(core_admin), meck:unload(admin_utils), meck:unload(handler_auth), meck:unload(cowboy_req). admin_stats_test_() -> {setup, fun setup/0, fun cleanup/1, [ {"GET /admin/stats as superadmin returns 200 with system metrics", fun test_superadmin/0}, {"GET /admin/stats as superadmin with date filter", fun test_superadmin_dates/0}, {"GET /admin/stats as moderator returns 200 with own metrics", fun test_moderator/0}, {"GET /admin/stats as support returns 200 with assigned tickets", fun test_support/0}, {"GET /admin/stats with non‑admin token returns 403", fun test_forbidden/0}, {"POST /admin/stats returns 405", fun test_wrong_method/0} ]}. %% --- Суперадмин (без дат) --- test_superadmin() -> ok = meck:expect(cowboy_req, method, fun(_) -> <<"GET">> end), ok = meck:expect(cowboy_req, parse_qs, fun(_) -> [] end), ok = meck:expect(handler_auth, authenticate, fun(Req) -> {ok, <<"adm1">>, Req} end), ok = meck:expect(admin_utils, is_admin, fun(_) -> true end), ok = meck:expect(core_admin, get_by_id, fun(<<"adm1">>) -> {ok, #admin{id = <<"adm1">>, role = superadmin}} end), ok = meck:expect(logic_stats, get_stats, fun(superadmin, _) -> #{users => 10, events => 25} end), {ok, _, _} = admin_handler_stats:init(req, []), ?assertEqual(200, erase(test_reply)). %% --- Суперадмин (с датами) --- test_superadmin_dates() -> ok = meck:expect(cowboy_req, method, fun(_) -> <<"GET">> end), ok = meck:expect(cowboy_req, parse_qs, fun(_) -> [{<<"from">>, <<"2026-01-01T00:00:00">>}, {<<"to">>, <<"2026-06-01T00:00:00">>}] end), ok = meck:expect(handler_auth, authenticate, fun(Req) -> {ok, <<"adm1">>, Req} end), ok = meck:expect(admin_utils, is_admin, fun(_) -> true end), ok = meck:expect(core_admin, get_by_id, fun(<<"adm1">>) -> {ok, #admin{id = <<"adm1">>, role = superadmin}} end), ok = meck:expect(logic_stats, get_stats, fun(superadmin, _, _, _) -> #{users => 10} end), {ok, _, _} = admin_handler_stats:init(req, []), ?assertEqual(200, erase(test_reply)). %% --- Модератор --- test_moderator() -> ok = meck:expect(cowboy_req, method, fun(_) -> <<"GET">> end), ok = meck:expect(cowboy_req, parse_qs, fun(_) -> [] end), ok = meck:expect(handler_auth, authenticate, fun(Req) -> {ok, <<"mod1">>, Req} end), ok = meck:expect(admin_utils, is_admin, fun(_) -> true end), ok = meck:expect(core_admin, get_by_id, fun(<<"mod1">>) -> {ok, #admin{id = <<"mod1">>, role = moderator}} end), ok = meck:expect(logic_stats, get_stats, fun(moderator, _) -> #{reports_reviewed => 5} end), {ok, _, _} = admin_handler_stats:init(req, []), ?assertEqual(200, erase(test_reply)). %% --- Поддержка --- test_support() -> ok = meck:expect(cowboy_req, method, fun(_) -> <<"GET">> end), ok = meck:expect(cowboy_req, parse_qs, fun(_) -> [] end), ok = meck:expect(handler_auth, authenticate, fun(Req) -> {ok, <<"sup1">>, Req} end), ok = meck:expect(admin_utils, is_admin, fun(_) -> true end), ok = meck:expect(core_admin, get_by_id, fun(<<"sup1">>) -> {ok, #admin{id = <<"sup1">>, role = support}} end), ok = meck:expect(logic_stats, get_stats, fun(support, _) -> #{tickets_assigned => 3} end), {ok, _, _} = admin_handler_stats:init(req, []), ?assertEqual(200, erase(test_reply)). %% --- Не админ --- test_forbidden() -> ok = meck:expect(cowboy_req, method, fun(_) -> <<"GET">> end), ok = meck:expect(handler_auth, authenticate, fun(Req) -> {error, 403, <<"Admin access required">>, Req} end), {ok, _, _} = admin_handler_stats:init(req, []), ?assertEqual(403, erase(test_reply)). %% --- Неверный метод --- test_wrong_method() -> ok = meck:expect(cowboy_req, method, fun(_) -> <<"POST">> end), {ok, _, _} = admin_handler_stats:init(req, []), ?assertEqual(405, erase(test_reply)).