Перенести все админские эндпоинты на порт 8445 и добавить отдельную авторизацию для админов. Часть 2. Final #3
This commit is contained in:
@@ -2,9 +2,16 @@
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include("records.hrl").
|
||||
|
||||
%% ----------------------------------------------------------------
|
||||
%% Фикстуры
|
||||
%% ----------------------------------------------------------------
|
||||
setup() ->
|
||||
mnesia:start(),
|
||||
mnesia:create_table(ticket, [
|
||||
catch mnesia:stop(),
|
||||
case mnesia:start() of
|
||||
{atomic, ok} -> ok;
|
||||
ok -> ok
|
||||
end,
|
||||
{atomic, ok} = mnesia:create_table(ticket, [
|
||||
{attributes, record_info(fields, ticket)},
|
||||
{ram_copies, [node()]}
|
||||
]),
|
||||
@@ -12,110 +19,118 @@ setup() ->
|
||||
|
||||
cleanup(_) ->
|
||||
mnesia:delete_table(ticket),
|
||||
mnesia:stop(),
|
||||
ok.
|
||||
mnesia:stop().
|
||||
|
||||
%% ----------------------------------------------------------------
|
||||
%% Тесты
|
||||
%% ----------------------------------------------------------------
|
||||
core_ticket_test_() ->
|
||||
{foreach,
|
||||
fun setup/0,
|
||||
fun cleanup/1,
|
||||
[
|
||||
{"Create ticket test", fun test_create_ticket/0},
|
||||
{"Update existing ticket test", fun test_update_ticket/0},
|
||||
{"Get ticket by id test", fun test_get_by_id/0},
|
||||
{"Get ticket by error hash test", fun test_get_by_error_hash/0},
|
||||
{"List all tickets test", fun test_list_all/0},
|
||||
{"List by status test", fun test_list_by_status/0},
|
||||
{"Update status test", fun test_update_status/0},
|
||||
{"Assign ticket test", fun test_assign_ticket/0},
|
||||
{"Add resolution test", fun test_add_resolution/0}
|
||||
]}.
|
||||
{foreach, fun setup/0, fun cleanup/1, [
|
||||
{"Create ticket and retrieve it", fun test_create_and_get/0},
|
||||
{"Update ticket status", fun test_update_status/0},
|
||||
{"Delete ticket and verify removal", fun test_delete_ticket/0},
|
||||
{"List all tickets returns created ones", fun test_list_all/0},
|
||||
{"List tickets by user filters correctly", fun test_list_by_user/0},
|
||||
{"Get ticket stats reflects real counts", fun test_stats/0},
|
||||
{"Update ticket with unknown id fails", fun test_update_not_found/0},
|
||||
{"Delete ticket with unknown id fails", fun test_delete_not_found/0},
|
||||
{"Get ticket with unknown id fails", fun test_get_not_found/0}
|
||||
]}.
|
||||
|
||||
test_create_ticket() ->
|
||||
ErrorMsg = <<"Test error">>,
|
||||
Stacktrace = <<"line 1\nline 2">>,
|
||||
Context = #{user_id => <<"user123">>},
|
||||
%% ── Вспомогательная функция для создания тикета ─────────
|
||||
make_ticket(ErrorMsg) ->
|
||||
Data = #{
|
||||
<<"error_message">> => list_to_binary(ErrorMsg),
|
||||
<<"stacktrace">> => <<"trace">>,
|
||||
<<"reporter_id">> => <<"user123">>,
|
||||
<<"status">> => <<"open">>
|
||||
},
|
||||
{ok, Ticket} = core_ticket:create_ticket(Data),
|
||||
Ticket.
|
||||
|
||||
{ok, Ticket} = core_ticket:create_or_update(ErrorMsg, Stacktrace, Context),
|
||||
%% ── Тесты ─────────────────────────────────────────────────
|
||||
|
||||
?assertEqual(ErrorMsg, Ticket#ticket.error_message),
|
||||
?assertEqual(Stacktrace, Ticket#ticket.stacktrace),
|
||||
?assertEqual(1, Ticket#ticket.count),
|
||||
?assertEqual(open, Ticket#ticket.status),
|
||||
test_create_and_get() ->
|
||||
Ticket = make_ticket("Bug1"),
|
||||
?assert(is_binary(Ticket#ticket.id)),
|
||||
?assert(is_binary(Ticket#ticket.error_hash)).
|
||||
|
||||
test_update_ticket() ->
|
||||
ErrorMsg = <<"Test error">>,
|
||||
Stacktrace = <<"line 1">>,
|
||||
Context = #{},
|
||||
|
||||
{ok, Ticket1} = core_ticket:create_or_update(ErrorMsg, Stacktrace, Context),
|
||||
?assertEqual(1, Ticket1#ticket.count),
|
||||
|
||||
{ok, Ticket2} = core_ticket:create_or_update(ErrorMsg, Stacktrace, Context),
|
||||
?assertEqual(Ticket1#ticket.id, Ticket2#ticket.id),
|
||||
?assertEqual(2, Ticket2#ticket.count),
|
||||
?assert(Ticket2#ticket.last_seen >= Ticket1#ticket.last_seen).
|
||||
|
||||
test_get_by_id() ->
|
||||
{ok, Ticket} = core_ticket:create_or_update(<<"Error">>, <<"">>, #{}),
|
||||
|
||||
{ok, Found} = core_ticket:get_by_id(Ticket#ticket.id),
|
||||
?assertEqual(Ticket#ticket.id, Found#ticket.id),
|
||||
|
||||
{error, not_found} = core_ticket:get_by_id(<<"nonexistent">>).
|
||||
|
||||
test_get_by_error_hash() ->
|
||||
ErrorMsg = <<"Unique error">>,
|
||||
Stacktrace = <<"stack">>,
|
||||
{ok, Ticket} = core_ticket:create_or_update(ErrorMsg, Stacktrace, #{}),
|
||||
|
||||
{ok, Found} = core_ticket:get_by_error_hash(Ticket#ticket.error_hash),
|
||||
?assertEqual(Ticket#ticket.id, Found#ticket.id),
|
||||
|
||||
{error, not_found} = core_ticket:get_by_error_hash(<<"badhash">>).
|
||||
|
||||
test_list_all() ->
|
||||
{ok, _} = core_ticket:create_or_update(<<"Error 1">>, <<"">>, #{}),
|
||||
{ok, _} = core_ticket:create_or_update(<<"Error 2">>, <<"">>, #{}),
|
||||
{ok, _} = core_ticket:create_or_update(<<"Error 3">>, <<"">>, #{}),
|
||||
|
||||
{ok, Tickets} = core_ticket:list_all(),
|
||||
?assertEqual(3, length(Tickets)).
|
||||
|
||||
test_list_by_status() ->
|
||||
{ok, _T1} = core_ticket:create_or_update(<<"E1">>, <<"">>, #{}),
|
||||
{ok, T2} = core_ticket:create_or_update(<<"E2">>, <<"">>, #{}),
|
||||
|
||||
core_ticket:update_status(T2#ticket.id, resolved),
|
||||
|
||||
{ok, Open} = core_ticket:list_by_status(open),
|
||||
?assertEqual(1, length(Open)),
|
||||
|
||||
{ok, Resolved} = core_ticket:list_by_status(resolved),
|
||||
?assertEqual(1, length(Resolved)).
|
||||
{ok, Retrieved} = core_ticket:get_by_id(Ticket#ticket.id),
|
||||
?assertEqual(Ticket#ticket.id, Retrieved#ticket.id).
|
||||
|
||||
test_update_status() ->
|
||||
{ok, Ticket} = core_ticket:create_or_update(<<"Error">>, <<"">>, #{}),
|
||||
Ticket = make_ticket("Bug2"),
|
||||
{ok, Updated} = core_ticket:update_ticket(Ticket#ticket.id,
|
||||
#{<<"status">> => <<"closed">>}),
|
||||
?assertEqual(closed, Updated#ticket.status),
|
||||
{ok, Stored} = core_ticket:get_by_id(Ticket#ticket.id),
|
||||
?assertEqual(closed, Stored#ticket.status).
|
||||
|
||||
{ok, Updated} = core_ticket:update_status(Ticket#ticket.id, in_progress),
|
||||
?assertEqual(in_progress, Updated#ticket.status),
|
||||
test_delete_ticket() ->
|
||||
Ticket = make_ticket("Bug3"),
|
||||
Id = Ticket#ticket.id,
|
||||
{ok, deleted} = core_ticket:delete_ticket(Id),
|
||||
% Проверяем, что тикет больше не читается
|
||||
?assertMatch({error, not_found}, core_ticket:get_by_id(Id)).
|
||||
|
||||
{ok, Resolved} = core_ticket:update_status(Ticket#ticket.id, resolved),
|
||||
?assertEqual(resolved, Resolved#ticket.status).
|
||||
test_list_all() ->
|
||||
T1 = make_ticket("E1"),
|
||||
T2 = make_ticket("E2"),
|
||||
All = core_ticket:list_all(),
|
||||
?assert(length(All) >= 2),
|
||||
Ids = [T#ticket.id || T <- All],
|
||||
?assert(lists:member(T1#ticket.id, Ids)),
|
||||
?assert(lists:member(T2#ticket.id, Ids)).
|
||||
|
||||
test_assign_ticket() ->
|
||||
AdminId = <<"admin123">>,
|
||||
{ok, Ticket} = core_ticket:create_or_update(<<"Error">>, <<"">>, #{}),
|
||||
test_list_by_user() ->
|
||||
% Создаём тикет от пользователя test_user
|
||||
Data = #{
|
||||
<<"error_message">> => <<"from_test_user">>,
|
||||
<<"stacktrace">> => <<"trace">>,
|
||||
<<"reporter_id">> => <<"test_user">>,
|
||||
<<"status">> => <<"open">>
|
||||
},
|
||||
{ok, T1} = core_ticket:create_ticket(Data),
|
||||
% Ещё один тикет от другого пользователя
|
||||
DataOther = #{
|
||||
<<"error_message">> => <<"other">>,
|
||||
<<"stacktrace">> => <<"trace">>,
|
||||
<<"reporter_id">> => <<"other_user">>,
|
||||
<<"status">> => <<"open">>
|
||||
},
|
||||
{ok, _T2} = core_ticket:create_ticket(DataOther),
|
||||
% list_by_user("test_user") должен вернуть ровно один тикет (T1)
|
||||
UserTickets = core_ticket:list_by_user(<<"test_user">>),
|
||||
?assertEqual(1, length(UserTickets)),
|
||||
?assertEqual(T1#ticket.id, (hd(UserTickets))#ticket.id).
|
||||
|
||||
{ok, Assigned} = core_ticket:assign(Ticket#ticket.id, AdminId),
|
||||
?assertEqual(AdminId, Assigned#ticket.assigned_to),
|
||||
?assertEqual(in_progress, Assigned#ticket.status).
|
||||
test_stats() ->
|
||||
Data1 = #{
|
||||
<<"error_message">> => <<"stat1">>,
|
||||
<<"stacktrace">> => <<"trace">>,
|
||||
<<"reporter_id">> => <<"reporter123">>,
|
||||
<<"status">> => <<"open">>
|
||||
},
|
||||
Data2 = #{
|
||||
<<"error_message">> => <<"stat2">>,
|
||||
<<"stacktrace">> => <<"trace">>,
|
||||
<<"reporter_id">> => <<"reporter456">>,
|
||||
<<"status">> => <<"open">>
|
||||
},
|
||||
{ok, _} = core_ticket:create_ticket(Data1),
|
||||
{ok, _} = core_ticket:create_ticket(Data2),
|
||||
Stats = core_ticket:stats(),
|
||||
?assert(is_map(Stats)),
|
||||
?assert(maps:is_key(open, Stats)),
|
||||
?assert(maps:is_key(total, Stats)),
|
||||
% Проверяем, что общее количество тикетов не меньше 2
|
||||
Total = maps:get(total, Stats),
|
||||
?assert(Total >= 2).
|
||||
|
||||
test_add_resolution() ->
|
||||
Note = <<"Fixed in version 1.0">>,
|
||||
{ok, Ticket} = core_ticket:create_or_update(<<"Error">>, <<"">>, #{}),
|
||||
test_update_not_found() ->
|
||||
{error, not_found} = core_ticket:update_ticket(<<"nonexistent">>,
|
||||
#{<<"status">> => <<"closed">>}).
|
||||
|
||||
{ok, Updated} = core_ticket:add_resolution(Ticket#ticket.id, Note),
|
||||
?assertEqual(Note, Updated#ticket.resolution_note).
|
||||
test_delete_not_found() ->
|
||||
{error, not_found} = core_ticket:delete_ticket(<<"nonexistent">>).
|
||||
|
||||
test_get_not_found() ->
|
||||
{error, not_found} = core_ticket:get_by_id(<<"nonexistent">>).
|
||||
Reference in New Issue
Block a user