-module(logic_ticket_tests). -include_lib("eunit/include/eunit.hrl"). -include("records.hrl"). %% ---------------------------------------------------------------- %% Фикстуры %% ---------------------------------------------------------------- setup() -> catch mnesia:stop(), case mnesia:start() of {atomic, ok} -> ok; ok -> ok end, {atomic, ok} = mnesia:create_table(user, [ {attributes, record_info(fields, user)}, {ram_copies, [node()]}]), {atomic, ok} = mnesia:create_table(ticket, [ {attributes, record_info(fields, ticket)}, {ram_copies, [node()]}]), % Создаём админа и обычного пользователя Admin = #user{id = <<"admin1">>, email = <<"a@a.a">>, password_hash = <<"h">>, role = admin, status = active, created_at = calendar:universal_time(), updated_at = calendar:universal_time()}, User = #user{id = <<"user1">>, email = <<"u@u.u">>, password_hash = <<"h">>, role = user, status = active, created_at = calendar:universal_time(), updated_at = calendar:universal_time()}, mnesia:dirty_write(Admin), mnesia:dirty_write(User), ok. cleanup(_) -> mnesia:delete_table(user), mnesia:delete_table(ticket), mnesia:stop(). %% ---------------------------------------------------------------- %% Тесты %% ---------------------------------------------------------------- logic_ticket_test_() -> {foreach, fun setup/0, fun cleanup/1, [ {"Report error creates ticket", fun test_report_error/0}, {"Report duplicate error increments count", fun test_report_duplicate/0}, {"List tickets as admin", fun test_list_tickets/0}, {"List tickets as non-admin returns error", fun test_list_tickets_forbidden/0}, {"Update status as admin", fun test_update_status/0}, {"Assign ticket as admin", fun test_assign_ticket/0}, {"Resolve ticket as admin", fun test_resolve_ticket/0}, {"Close ticket as admin", fun test_close_ticket/0}, {"Get statistics as admin", fun test_get_statistics/0} ]}. %% --- Вспомогательная функция для создания тикета --- report(ErrorMsg) -> logic_ticket:report_error(ErrorMsg, <<"stack">>, #{}). %% --- Тесты --- test_report_error() -> {ok, Ticket} = report(<<"Error1">>), ?assertEqual(<<"Error1">>, Ticket#ticket.error_message), ?assertEqual(1, Ticket#ticket.count). test_report_duplicate() -> {ok, T1} = report(<<"Dup">>), ?assertEqual(1, T1#ticket.count), {ok, T2} = report(<<"Dup">>), ?assertEqual(2, T2#ticket.count), % Проверяем, что это тот же тикет, а не новый ?assertEqual(T1#ticket.id, T2#ticket.id). test_list_tickets() -> {ok, _} = report(<<"E1">>), Tickets = logic_ticket:list_tickets(<<"admin1">>), ?assert(length(Tickets) =:= 1). test_list_tickets_forbidden() -> {error, access_denied} = logic_ticket:list_tickets(<<"user1">>). test_update_status() -> {ok, Ticket} = report(<<"E2">>), {ok, Updated} = logic_ticket:update_status(<<"admin1">>, Ticket#ticket.id, <<"closed">>), ?assertEqual(closed, Updated#ticket.status). test_assign_ticket() -> {ok, Ticket} = report(<<"E3">>), {ok, Updated} = logic_ticket:assign_ticket(<<"admin1">>, Ticket#ticket.id, <<"dev1">>), ?assertEqual(<<"dev1">>, Updated#ticket.assigned_to). test_resolve_ticket() -> {ok, Ticket} = report(<<"E4">>), {ok, Updated} = logic_ticket:resolve_ticket(<<"admin1">>, Ticket#ticket.id, <<"Fixed">>), ?assertEqual(closed, Updated#ticket.status), ?assertEqual(<<"Fixed">>, Updated#ticket.resolution_note). test_close_ticket() -> {ok, Ticket} = report(<<"E5">>), {ok, Updated} = logic_ticket:close_ticket(<<"admin1">>, Ticket#ticket.id), ?assertEqual(closed, Updated#ticket.status). test_get_statistics() -> {ok, _} = report(<<"E6">>), {ok, _} = report(<<"E7">>), {ok, T3} = report(<<"E8">>), logic_ticket:close_ticket(<<"admin1">>, T3#ticket.id), Stats = logic_ticket:get_statistics(<<"admin1">>), ?assertEqual(3, maps:get(total_tickets, Stats)), ?assertEqual(2, maps:get(open, Stats)), ?assertEqual(1, maps:get(closed, Stats)), ?assertEqual(3, maps:get(total_errors, Stats)).