test: unique ticket messages per run to avoid IFT dedupe collisions
This commit is contained in:
@@ -34,10 +34,12 @@ test() ->
|
|||||||
UserToken = api_test_runner:get_user_token(),
|
UserToken = api_test_runner:get_user_token(),
|
||||||
% Создаём два тикета для разных проверок
|
% Создаём два тикета для разных проверок
|
||||||
Ticket1 = api_test_runner:client_post(<<"/v1/tickets">>, UserToken,
|
Ticket1 = api_test_runner:client_post(<<"/v1/tickets">>, UserToken,
|
||||||
#{<<"error_message">> => <<"Test bug">>, <<"stacktrace">> => <<"trace">>}),
|
#{<<"error_message">> => api_test_runner:unique_ticket_message(<<"Test bug">>),
|
||||||
|
<<"stacktrace">> => <<"trace">>}),
|
||||||
#{<<"id">> := Ticket1Id} = Ticket1,
|
#{<<"id">> := Ticket1Id} = Ticket1,
|
||||||
Ticket2 = api_test_runner:client_post(<<"/v1/tickets">>, UserToken,
|
Ticket2 = api_test_runner:client_post(<<"/v1/tickets">>, UserToken,
|
||||||
#{<<"error_message">> => <<"Another bug">>, <<"stacktrace">> => <<"trace2">>}),
|
#{<<"error_message">> => api_test_runner:unique_ticket_message(<<"Another bug">>),
|
||||||
|
<<"stacktrace">> => <<"trace2">>}),
|
||||||
#{<<"id">> := Ticket2Id} = Ticket2,
|
#{<<"id">> := Ticket2Id} = Ticket2,
|
||||||
|
|
||||||
% Получаем ID текущего администратора для теста фильтрации по исполнителю
|
% Получаем ID текущего администратора для теста фильтрации по исполнителю
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
get_support_token/0,
|
get_support_token/0,
|
||||||
get_user_token/0,
|
get_user_token/0,
|
||||||
unique_email/1,
|
unique_email/1,
|
||||||
|
unique_ticket_message/1,
|
||||||
future_date/0,
|
future_date/0,
|
||||||
register_and_login/2,
|
register_and_login/2,
|
||||||
create_calendar/2,
|
create_calendar/2,
|
||||||
@@ -335,6 +336,13 @@ unique_email(Prefix) ->
|
|||||||
Unique = integer_to_binary(erlang:system_time()),
|
Unique = integer_to_binary(erlang:system_time()),
|
||||||
<<Prefix/binary, "_", Unique/binary, "@test.local">>.
|
<<Prefix/binary, "_", Unique/binary, "@test.local">>.
|
||||||
|
|
||||||
|
%% Уникальное сообщение тикета на прогон (IFT: иначе дедуп по error_hash
|
||||||
|
%% возвращает чужой reporter_id и list/get своих тикетов падает).
|
||||||
|
-spec unique_ticket_message(binary()) -> binary().
|
||||||
|
unique_ticket_message(Prefix) ->
|
||||||
|
Unique = integer_to_binary(erlang:unique_integer([positive, monotonic])),
|
||||||
|
<<Prefix/binary, " ", Unique/binary>>.
|
||||||
|
|
||||||
-spec future_date() -> calendar:datetime().
|
-spec future_date() -> calendar:datetime().
|
||||||
future_date() ->
|
future_date() ->
|
||||||
Seconds = calendar:datetime_to_gregorian_seconds(calendar:universal_time()) + 86400,
|
Seconds = calendar:datetime_to_gregorian_seconds(calendar:universal_time()) + 86400,
|
||||||
|
|||||||
@@ -31,18 +31,21 @@ test() ->
|
|||||||
StrangerEmail = api_test_runner:unique_email(<<"stranger">>),
|
StrangerEmail = api_test_runner:unique_email(<<"stranger">>),
|
||||||
StrangerToken = api_test_runner:register_and_login(StrangerEmail, <<"pass">>),
|
StrangerToken = api_test_runner:register_and_login(StrangerEmail, <<"pass">>),
|
||||||
|
|
||||||
|
PrimaryMsg = api_test_runner:unique_ticket_message(<<"Something broke">>),
|
||||||
|
DedupeMsg = api_test_runner:unique_ticket_message(<<"Dedupe me">>),
|
||||||
|
|
||||||
% Создаём тикет
|
% Создаём тикет
|
||||||
#{<<"id">> := TicketId} = api_test_runner:client_post(<<"/v1/tickets">>, Token,
|
#{<<"id">> := TicketId} = api_test_runner:client_post(<<"/v1/tickets">>, Token,
|
||||||
#{error_message => <<"Something broke">>, stacktrace => <<"line 42">>}),
|
#{error_message => PrimaryMsg, stacktrace => <<"line 42">>}),
|
||||||
|
|
||||||
test_create_ticket(Token),
|
test_create_ticket(Token, api_test_runner:unique_ticket_message(<<"Test bug">>)),
|
||||||
test_create_ticket_dedupe(Token),
|
test_create_ticket_dedupe(Token, DedupeMsg),
|
||||||
test_create_ticket_manual(Token),
|
test_create_ticket_manual(Token),
|
||||||
test_create_ticket_missing_fields(Token),
|
test_create_ticket_missing_fields(Token),
|
||||||
test_create_ticket_unauthorized(),
|
test_create_ticket_unauthorized(),
|
||||||
test_list_tickets(Token, TicketId),
|
test_list_tickets(Token, TicketId),
|
||||||
test_list_tickets_unauthorized(),
|
test_list_tickets_unauthorized(),
|
||||||
test_get_ticket(Token, TicketId),
|
test_get_ticket(Token, TicketId, PrimaryMsg),
|
||||||
test_get_ticket_forbidden(StrangerToken, TicketId),
|
test_get_ticket_forbidden(StrangerToken, TicketId),
|
||||||
test_get_ticket_not_found(Token),
|
test_get_ticket_not_found(Token),
|
||||||
test_get_ticket_unauthorized(TicketId),
|
test_get_ticket_unauthorized(TicketId),
|
||||||
@@ -54,12 +57,12 @@ test() ->
|
|||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
|
||||||
%% @doc Успешное создание тикета: 201 Created.
|
%% @doc Успешное создание тикета: 201 Created.
|
||||||
-spec test_create_ticket(binary()) -> ok.
|
-spec test_create_ticket(binary(), binary()) -> ok.
|
||||||
test_create_ticket(Token) ->
|
test_create_ticket(Token, ErrorMessage) ->
|
||||||
ct:pal(" TEST: Create a ticket"),
|
ct:pal(" TEST: Create a ticket"),
|
||||||
Resp = api_test_runner:client_request(post, <<"/v1/tickets">>, Token,
|
Resp = api_test_runner:client_request(post, <<"/v1/tickets">>, Token,
|
||||||
jsx:encode(#{
|
jsx:encode(#{
|
||||||
error_message => <<"Test bug">>,
|
error_message => ErrorMessage,
|
||||||
stacktrace => <<"trace">>,
|
stacktrace => <<"trace">>,
|
||||||
source => <<"frontend">>,
|
source => <<"frontend">>,
|
||||||
context => #{route => <<"/test">>, build => <<"dev">>}
|
context => #{route => <<"/test">>, build => <<"dev">>}
|
||||||
@@ -75,11 +78,11 @@ test_create_ticket(Token) ->
|
|||||||
ct:pal(" OK: ticket ~s created", [Id]).
|
ct:pal(" OK: ticket ~s created", [Id]).
|
||||||
|
|
||||||
%% @doc Повторный POST с тем же сообщением увеличивает count.
|
%% @doc Повторный POST с тем же сообщением увеличивает count.
|
||||||
-spec test_create_ticket_dedupe(binary()) -> ok.
|
-spec test_create_ticket_dedupe(binary(), binary()) -> ok.
|
||||||
test_create_ticket_dedupe(Token) ->
|
test_create_ticket_dedupe(Token, ErrorMessage) ->
|
||||||
ct:pal(" TEST: Dedupe ticket by hash"),
|
ct:pal(" TEST: Dedupe ticket by hash"),
|
||||||
Payload = jsx:encode(#{
|
Payload = jsx:encode(#{
|
||||||
error_message => <<"Dedupe me">>,
|
error_message => ErrorMessage,
|
||||||
stacktrace => <<"same stack">>,
|
stacktrace => <<"same stack">>,
|
||||||
source => <<"frontend">>
|
source => <<"frontend">>
|
||||||
}),
|
}),
|
||||||
@@ -97,7 +100,7 @@ test_create_ticket_manual(Token) ->
|
|||||||
ct:pal(" TEST: Create manual ticket"),
|
ct:pal(" TEST: Create manual ticket"),
|
||||||
Resp = api_test_runner:client_request(post, <<"/v1/tickets">>, Token,
|
Resp = api_test_runner:client_request(post, <<"/v1/tickets">>, Token,
|
||||||
jsx:encode(#{
|
jsx:encode(#{
|
||||||
error_message => <<"Button does nothing">>,
|
error_message => api_test_runner:unique_ticket_message(<<"Button does nothing">>),
|
||||||
source => <<"manual">>,
|
source => <<"manual">>,
|
||||||
context => #{steps => <<"1. Open calendar\n2. Click share">>}
|
context => #{steps => <<"1. Open calendar\n2. Click share">>}
|
||||||
})),
|
})),
|
||||||
@@ -146,13 +149,13 @@ test_list_tickets_unauthorized() ->
|
|||||||
ct:pal(" OK: got 401").
|
ct:pal(" OK: got 401").
|
||||||
|
|
||||||
%% @doc GET /v1/tickets/:id – получение своего тикета.
|
%% @doc GET /v1/tickets/:id – получение своего тикета.
|
||||||
-spec test_get_ticket(binary(), binary()) -> ok.
|
-spec test_get_ticket(binary(), binary(), binary()) -> ok.
|
||||||
test_get_ticket(Token, TicketId) ->
|
test_get_ticket(Token, TicketId, ExpectedMessage) ->
|
||||||
ct:pal(" TEST: Get my ticket by ID"),
|
ct:pal(" TEST: Get my ticket by ID"),
|
||||||
Path = <<"/v1/tickets/", TicketId/binary>>,
|
Path = <<"/v1/tickets/", TicketId/binary>>,
|
||||||
Ticket = api_test_runner:client_get(Path, Token),
|
Ticket = api_test_runner:client_get(Path, Token),
|
||||||
?assertEqual(TicketId, maps:get(<<"id">>, Ticket)),
|
?assertEqual(TicketId, maps:get(<<"id">>, Ticket)),
|
||||||
?assertEqual(<<"Something broke">>, maps:get(<<"error_message">>, Ticket)),
|
?assertEqual(ExpectedMessage, maps:get(<<"error_message">>, Ticket)),
|
||||||
ct:pal(" OK: got my ticket").
|
ct:pal(" OK: got my ticket").
|
||||||
|
|
||||||
%% @doc GET /v1/tickets/:id – попытка доступа к чужому тикету (403).
|
%% @doc GET /v1/tickets/:id – попытка доступа к чужому тикету (403).
|
||||||
@@ -179,4 +182,4 @@ test_get_ticket_unauthorized(TicketId) ->
|
|||||||
Path = <<"/v1/tickets/", TicketId/binary>>,
|
Path = <<"/v1/tickets/", TicketId/binary>>,
|
||||||
Resp = api_test_runner:client_request(get, Path, <<>>),
|
Resp = api_test_runner:client_request(get, Path, <<>>),
|
||||||
?assertMatch({ok, 401, _, _}, Resp),
|
?assertMatch({ok, 401, _, _}, Resp),
|
||||||
ct:pal(" OK: got 401").
|
ct:pal(" OK: got 401").
|
||||||
|
|||||||
Reference in New Issue
Block a user