239 lines
10 KiB
Erlang
239 lines
10 KiB
Erlang
%%%-------------------------------------------------------------------
|
|
%%% @doc Тесты административного API для управления жалобами.
|
|
%%%
|
|
%%% Покрывает эндпоинты:
|
|
%%% GET /v1/admin/reports
|
|
%%% GET /v1/admin/reports/:id
|
|
%%% PUT /v1/admin/reports/:id
|
|
%%%
|
|
%%% Проверяет:
|
|
%%% - получение списка жалоб
|
|
%%% - получение жалобы по ID
|
|
%%% - обновление статуса жалобы (review, dismiss)
|
|
%%% - фильтрацию по статусу и типу цели
|
|
%%% - комбинации фильтров (status + target_type)
|
|
%%% - сортировку по created_at и status
|
|
%%% - комбинации фильтрации с сортировкой
|
|
%%% - пагинацию (limit/offset, x-total-count)
|
|
%%% - комбинации фильтрации, сортировки и пагинации
|
|
%%% @end
|
|
%%%-------------------------------------------------------------------
|
|
-module(admin_reports_tests).
|
|
-include_lib("eunit/include/eunit.hrl").
|
|
-export([test/0]).
|
|
|
|
%%%===================================================================
|
|
%%% Главная тестовая функция
|
|
%%%===================================================================
|
|
-spec test() -> ok.
|
|
test() ->
|
|
ct:pal("=== Admin Reports Tests ==="),
|
|
Token = api_test_runner:get_admin_token(),
|
|
UserToken = api_test_runner:get_user_token(),
|
|
CalId = api_test_runner:create_calendar(UserToken, #{title => <<"ReportsTestCal">>}),
|
|
EventId = api_test_runner:create_event(UserToken, CalId, #{
|
|
title => <<"Event for reporting">>,
|
|
start_time => api_test_runner:future_date(),
|
|
duration => 60
|
|
}),
|
|
#{<<"id">> := Report1Id} = api_test_runner:client_post(<<"/v1/reports">>, UserToken, #{
|
|
<<"target_type">> => <<"event">>,
|
|
<<"target_id">> => EventId,
|
|
<<"reason">> => <<"Inappropriate content">>
|
|
}),
|
|
#{<<"id">> := Report2Id} = api_test_runner:client_post(<<"/v1/reports">>, UserToken, #{
|
|
<<"target_type">> => <<"event">>,
|
|
<<"target_id">> => EventId,
|
|
<<"reason">> => <<"Spam">>
|
|
}),
|
|
|
|
test_list_reports(Token, Report1Id),
|
|
test_get_report(Token, Report1Id),
|
|
test_review_report(Token, Report1Id),
|
|
test_dismiss_report(Token, Report2Id),
|
|
|
|
test_filter_reports(Token),
|
|
test_filter_combined_status_target(Token),
|
|
|
|
test_sort_by_created_at_desc(Token),
|
|
test_sort_by_created_at_asc(Token),
|
|
test_sort_by_status_asc(Token),
|
|
|
|
test_filter_status_sort_created_at(Token),
|
|
test_filter_target_sort_status(Token),
|
|
|
|
test_report_pagination(Token),
|
|
test_pagination_headers(Token),
|
|
|
|
test_filter_status_with_pagination(Token),
|
|
test_filter_sort_pagination_combined(Token),
|
|
|
|
ct:pal("=== All admin reports tests passed ==="),
|
|
ok.
|
|
|
|
%%%===================================================================
|
|
%%% Тестовые функции
|
|
%%%===================================================================
|
|
|
|
-spec test_list_reports(binary(), binary()) -> ok.
|
|
test_list_reports(Token, ReportId) ->
|
|
ct:pal(" TEST: List all reports"),
|
|
Reports = api_test_runner:admin_get(<<"/v1/admin/reports">>, Token),
|
|
?assert(is_list(Reports)),
|
|
?assert(length(Reports) >= 2),
|
|
?assert(lists:any(fun(R) -> maps:get(<<"id">>, R) =:= ReportId end, Reports)),
|
|
ct:pal(" OK: ~p reports", [length(Reports)]).
|
|
|
|
-spec test_get_report(binary(), binary()) -> ok.
|
|
test_get_report(Token, ReportId) ->
|
|
ct:pal(" TEST: Get report by ID"),
|
|
Path = <<"/v1/admin/reports/", ReportId/binary>>,
|
|
Report = api_test_runner:admin_get(Path, Token),
|
|
?assertEqual(ReportId, maps:get(<<"id">>, Report)),
|
|
?assertEqual(<<"pending">>, maps:get(<<"status">>, Report)),
|
|
ct:pal(" OK").
|
|
|
|
-spec test_review_report(binary(), binary()) -> ok.
|
|
test_review_report(Token, ReportId) ->
|
|
ct:pal(" TEST: Review report (set status to reviewed)"),
|
|
Path = <<"/v1/admin/reports/", ReportId/binary>>,
|
|
Updated = api_test_runner:admin_put(Path, Token, #{<<"status">> => <<"reviewed">>}),
|
|
?assertEqual(<<"reviewed">>, maps:get(<<"status">>, Updated)),
|
|
ct:pal(" OK").
|
|
|
|
-spec test_dismiss_report(binary(), binary()) -> ok.
|
|
test_dismiss_report(Token, ReportId) ->
|
|
ct:pal(" TEST: Dismiss report (set status to dismissed)"),
|
|
Path = <<"/v1/admin/reports/", ReportId/binary>>,
|
|
Updated = api_test_runner:admin_put(Path, Token, #{<<"status">> => <<"dismissed">>}),
|
|
?assertEqual(<<"dismissed">>, maps:get(<<"status">>, Updated)),
|
|
ct:pal(" OK").
|
|
|
|
-spec test_filter_reports(binary()) -> ok.
|
|
test_filter_reports(Token) ->
|
|
ct:pal(" TEST: Filter reports by status=reviewed"),
|
|
Reports = api_test_runner:admin_get(<<"/v1/admin/reports?status=reviewed">>, Token),
|
|
?assert(is_list(Reports)),
|
|
[?assertEqual(<<"reviewed">>, maps:get(<<"status">>, R)) || R <- Reports],
|
|
ct:pal(" OK: ~p reviewed reports", [length(Reports)]),
|
|
|
|
ct:pal(" TEST: Filter reports by target_type=event"),
|
|
Reports2 = api_test_runner:admin_get(<<"/v1/admin/reports?target_type=event">>, Token),
|
|
?assert(is_list(Reports2)),
|
|
[?assertEqual(<<"event">>, maps:get(<<"target_type">>, R)) || R <- Reports2],
|
|
ct:pal(" OK: ~p reports for events", [length(Reports2)]).
|
|
|
|
-spec test_filter_combined_status_target(binary()) -> ok.
|
|
test_filter_combined_status_target(Token) ->
|
|
ct:pal(" TEST: Combined filter (status=dismissed & target_type=event)"),
|
|
Reports = api_test_runner:admin_get(
|
|
<<"/v1/admin/reports?status=dismissed&target_type=event">>, Token),
|
|
?assert(is_list(Reports)),
|
|
[?assertEqual(<<"dismissed">>, maps:get(<<"status">>, R)) || R <- Reports],
|
|
[?assertEqual(<<"event">>, maps:get(<<"target_type">>, R)) || R <- Reports],
|
|
ct:pal(" OK: ~p reports match both criteria", [length(Reports)]).
|
|
|
|
-spec test_sort_by_created_at_desc(binary()) -> ok.
|
|
test_sort_by_created_at_desc(Token) ->
|
|
ct:pal(" TEST: Sort by created_at desc"),
|
|
{ok, 200, _, Body} = api_test_runner:admin_request(get,
|
|
<<"/v1/admin/reports?sort=created_at&order=desc">>, Token, <<"">>),
|
|
Reports = jsx:decode(list_to_binary(Body), [return_maps]),
|
|
Dates = [maps:get(<<"created_at">>, R) || R <- Reports],
|
|
Sorted = lists:reverse(lists:sort(Dates)),
|
|
?assertEqual(Sorted, Dates),
|
|
ct:pal(" OK: sorted by created_at desc").
|
|
|
|
-spec test_sort_by_created_at_asc(binary()) -> ok.
|
|
test_sort_by_created_at_asc(Token) ->
|
|
ct:pal(" TEST: Sort by created_at asc"),
|
|
{ok, 200, _, Body} = api_test_runner:admin_request(get,
|
|
<<"/v1/admin/reports?sort=created_at&order=asc">>, Token, <<"">>),
|
|
Reports = jsx:decode(list_to_binary(Body), [return_maps]),
|
|
Dates = [maps:get(<<"created_at">>, R) || R <- Reports],
|
|
?assertEqual(lists:sort(Dates), Dates),
|
|
ct:pal(" OK: sorted by created_at asc").
|
|
|
|
-spec test_sort_by_status_asc(binary()) -> ok.
|
|
test_sort_by_status_asc(Token) ->
|
|
ct:pal(" TEST: Sort by status asc"),
|
|
{ok, 200, _, Body} = api_test_runner:admin_request(get,
|
|
<<"/v1/admin/reports?sort=status&order=asc">>, Token, <<"">>),
|
|
Reports = jsx:decode(list_to_binary(Body), [return_maps]),
|
|
Statuses = [maps:get(<<"status">>, R) || R <- Reports],
|
|
?assertEqual(lists:sort(Statuses), Statuses),
|
|
ct:pal(" OK: sorted by status asc").
|
|
|
|
-spec test_filter_status_sort_created_at(binary()) -> ok.
|
|
test_filter_status_sort_created_at(Token) ->
|
|
ct:pal(" TEST: Filter status=reviewed + sort by created_at asc"),
|
|
{ok, 200, _, Body} = api_test_runner:admin_request(get,
|
|
<<"/v1/admin/reports?status=reviewed&sort=created_at&order=asc">>, Token, <<"">>),
|
|
Reports = jsx:decode(list_to_binary(Body), [return_maps]),
|
|
[?assertEqual(<<"reviewed">>, maps:get(<<"status">>, R)) || R <- Reports],
|
|
Dates = [maps:get(<<"created_at">>, R) || R <- Reports],
|
|
?assertEqual(lists:sort(Dates), Dates),
|
|
ct:pal(" OK: ~p reports sorted", [length(Reports)]).
|
|
|
|
-spec test_filter_target_sort_status(binary()) -> ok.
|
|
test_filter_target_sort_status(Token) ->
|
|
ct:pal(" TEST: Filter target_type=event + sort by status desc"),
|
|
{ok, 200, _, Body} = api_test_runner:admin_request(get,
|
|
<<"/v1/admin/reports?target_type=event&sort=status&order=desc">>, Token, <<"">>),
|
|
Reports = jsx:decode(list_to_binary(Body), [return_maps]),
|
|
[?assertEqual(<<"event">>, maps:get(<<"target_type">>, R)) || R <- Reports],
|
|
Statuses = [maps:get(<<"status">>, R) || R <- Reports],
|
|
?assertEqual(lists:reverse(lists:sort(Statuses)), Statuses),
|
|
ct:pal(" OK: ~p reports sorted", [length(Reports)]).
|
|
|
|
-spec test_report_pagination(binary()) -> ok.
|
|
test_report_pagination(Token) ->
|
|
ct:pal(" TEST: Report pagination"),
|
|
Page1 = api_test_runner:admin_get(<<"/v1/admin/reports?limit=1&offset=0">>, Token),
|
|
?assert(length(Page1) >= 1),
|
|
Page2 = api_test_runner:admin_get(<<"/v1/admin/reports?limit=1&offset=1">>, Token),
|
|
?assert(length(Page2) >= 0),
|
|
case {Page1, Page2} of
|
|
{[First|_], [Second|_]} ->
|
|
Id1 = maps:get(<<"id">>, First),
|
|
Id2 = maps:get(<<"id">>, Second),
|
|
?assertNotEqual(Id1, Id2);
|
|
_ -> ok
|
|
end,
|
|
ct:pal(" OK").
|
|
|
|
-spec test_pagination_headers(binary()) -> ok.
|
|
test_pagination_headers(Token) ->
|
|
ct:pal(" TEST: Pagination headers (x-total-count)"),
|
|
{ok, 200, Headers, _} = api_test_runner:admin_request(get,
|
|
<<"/v1/admin/reports?limit=2&offset=0">>, Token, <<"">>),
|
|
Total = list_to_integer(
|
|
proplists:get_value("x-total-count", Headers, "0")),
|
|
?assert(Total >= 1),
|
|
ct:pal(" OK: total count = ~p", [Total]).
|
|
|
|
-spec test_filter_status_with_pagination(binary()) -> ok.
|
|
test_filter_status_with_pagination(Token) ->
|
|
ct:pal(" TEST: Filter status=dismissed + pagination (limit=1)"),
|
|
{ok, 200, Headers, Body} = api_test_runner:admin_request(get,
|
|
<<"/v1/admin/reports?status=dismissed&limit=1&offset=0">>, Token, <<"">>),
|
|
Reports = jsx:decode(list_to_binary(Body), [return_maps]),
|
|
?assert(length(Reports) =< 1),
|
|
[?assertEqual(<<"dismissed">>, maps:get(<<"status">>, R)) || R <- Reports],
|
|
Total = list_to_integer(
|
|
proplists:get_value("x-total-count", Headers, "0")),
|
|
?assert(Total >= 1),
|
|
ct:pal(" OK: total count = ~p", [Total]).
|
|
|
|
-spec test_filter_sort_pagination_combined(binary()) -> ok.
|
|
test_filter_sort_pagination_combined(Token) ->
|
|
ct:pal(" TEST: Filter target_type=event + sort by created_at desc + pagination (limit=1)"),
|
|
{ok, 200, Headers, Body} = api_test_runner:admin_request(get,
|
|
<<"/v1/admin/reports?target_type=event&sort=created_at&order=desc&limit=1&offset=0">>, Token, <<"">>),
|
|
Reports = jsx:decode(list_to_binary(Body), [return_maps]),
|
|
?assert(length(Reports) =< 1),
|
|
[?assertEqual(<<"event">>, maps:get(<<"target_type">>, R)) || R <- Reports],
|
|
Total = list_to_integer(
|
|
proplists:get_value("x-total-count", Headers, "0")),
|
|
?assert(Total >= 1),
|
|
ct:pal(" OK: total count = ~p", [Total]). |