Пагинация, фильтры и сортировки Часть 1 #20
This commit is contained in:
@@ -43,25 +43,25 @@ test() ->
|
||||
{ok, {{_, 200, _}, _, StatsResp1}} = httpc:request(get, {AdminURL ++ "/v1/admin/stats", [{"Authorization", "Bearer " ++ binary_to_list(SuperadminToken)}]}, [], []),
|
||||
Stats1 = jsx:decode(list_to_binary(StatsResp1), [return_maps]),
|
||||
ct:pal(" OK (Stats 1: ~p)~n", [Stats1]),
|
||||
map_size(Stats1) > 0,
|
||||
true = map_size(Stats1) > 0,
|
||||
|
||||
ct:pal(" Admin stats (admin)... "),
|
||||
{ok, {{_, 200, _}, _, StatsResp2}} = httpc:request(get, {AdminURL ++ "/v1/admin/stats", [{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}]}, [], []),
|
||||
Stats2 = jsx:decode(list_to_binary(StatsResp2), [return_maps]),
|
||||
ct:pal(" OK (Stats 1: ~p)~n", [Stats2]),
|
||||
map_size(Stats2) > 0,
|
||||
true = map_size(Stats2) > 0,
|
||||
|
||||
ct:pal(" Admin stats (moderator)... "),
|
||||
{ok, {{_, 200, _}, _, StatsResp3}} = httpc:request(get, {AdminURL ++ "/v1/admin/stats", [{"Authorization", "Bearer " ++ binary_to_list(ModeratorToken)}]}, [], []),
|
||||
Stats3 = jsx:decode(list_to_binary(StatsResp3), [return_maps]),
|
||||
ct:pal(" OK (Stats 1: ~p)~n", [Stats3]),
|
||||
map_size(Stats3) > 0,
|
||||
true = map_size(Stats3) > 0,
|
||||
|
||||
ct:pal(" Admin stats (support)... "),
|
||||
{ok, {{_, 200, _}, _, StatsResp4}} = httpc:request(get, {AdminURL ++ "/v1/admin/stats", [{"Authorization", "Bearer " ++ binary_to_list(SupportToken)}]}, [], []),
|
||||
Stats4 = jsx:decode(list_to_binary(StatsResp4), [return_maps]),
|
||||
ct:pal(" OK (Stats 1: ~p)~n", [Stats4]),
|
||||
map_size(Stats4) > 0,
|
||||
true = map_size(Stats4) > 0,
|
||||
|
||||
%% TEST 4: List users
|
||||
ct:pal(" TEST 4: List users... "),
|
||||
@@ -356,5 +356,158 @@ test() ->
|
||||
[], []),
|
||||
ct:pal("OK~n"),
|
||||
|
||||
%% ========================================================
|
||||
%% Extended Admin Events Search & Filter Tests
|
||||
%% ========================================================
|
||||
|
||||
%% ── Подготовка изолированных данных ──
|
||||
ct:pal(" Preparing isolated search test data... "),
|
||||
UserToken = api_test_runner:get_user_token(),
|
||||
SearchCalId = api_test_runner:create_calendar(UserToken, #{title => <<"SearchTestCal">>}),
|
||||
SearchCalIdStr = binary_to_list(SearchCalId),
|
||||
AlphaId = api_test_runner:create_event(UserToken, SearchCalId, #{
|
||||
title => <<"Test Event Alpha">>,
|
||||
start_time => api_SUITE:future_date(),
|
||||
duration => 60
|
||||
}),
|
||||
BetaId = api_test_runner:create_event(UserToken, SearchCalId, #{
|
||||
title => <<"Beta Event">>,
|
||||
start_time => api_SUITE:future_date(),
|
||||
duration => 60
|
||||
}),
|
||||
_AlphaConfId = api_test_runner:create_event(UserToken, SearchCalId, #{
|
||||
title => <<"Alpha Conference">>,
|
||||
start_time => api_SUITE:future_date(),
|
||||
duration => 60
|
||||
}),
|
||||
% Отменяем BetaId через административный эндпоинт (PUT /v1/admin/events/:id)
|
||||
ct:pal(" Cancelling Beta Event (admin)... "),
|
||||
{ok, {{_, 200, _}, _, _}} =
|
||||
httpc:request(put, {AdminURL ++ "/v1/admin/events/" ++ binary_to_list(BetaId),
|
||||
[{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}],
|
||||
"application/json", jsx:encode(#{<<"status">> => <<"cancelled">>})}, [], []),
|
||||
ct:pal("OK~n"),
|
||||
|
||||
%% ── TEST 34: Filter by status=active ──
|
||||
ct:pal(" TEST 34: Filter events by status=active... "),
|
||||
{ok, {{_, 200, _}, _, Body34}} =
|
||||
httpc:request(get, {AdminURL ++ "/v1/admin/events?calendar_id=" ++ SearchCalIdStr ++ "&status=active",
|
||||
[{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}]},
|
||||
[], []),
|
||||
Events34 = jsx:decode(list_to_binary(Body34), [return_maps]),
|
||||
ct:pal("DEBUG: events34 count = ~p", [length(Events34)]),
|
||||
ct:pal("DEBUG: events34 = ~p", [Events34]),
|
||||
true = (length(Events34) >= 2),
|
||||
Ids34 = [maps:get(<<"id">>, E) || E <- Events34],
|
||||
ct:pal("OK (count: ~p, ids: ~p)~n", [length(Events34), Ids34]),
|
||||
|
||||
%% ── TEST 35: Filter by status=cancelled ──
|
||||
ct:pal(" TEST 35: Filter events by status=cancelled... "),
|
||||
{ok, {{_, 200, _}, _, Body35}} =
|
||||
httpc:request(get, {AdminURL ++ "/v1/admin/events?calendar_id=" ++ SearchCalIdStr ++ "&status=cancelled",
|
||||
[{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}]},
|
||||
[], []),
|
||||
Events35 = jsx:decode(list_to_binary(Body35), [return_maps]),
|
||||
ct:pal("DEBUG: Events35 count = ~p", [length(Events35)]),
|
||||
ct:pal("DEBUG: Events35 = ~p", [Events35]),
|
||||
true = (length(Events35) >= 1),
|
||||
ct:pal("OK (count: ~p)~n", [length(Events35)]),
|
||||
|
||||
%% ── TEST 36: Filter by status=all ──
|
||||
ct:pal(" TEST 36: Filter events by status=all... "),
|
||||
{ok, {{_, 200, _}, _, Body36}} =
|
||||
httpc:request(get, {AdminURL ++ "/v1/admin/events?calendar_id=" ++ SearchCalIdStr ++ "&status=all",
|
||||
[{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}]},
|
||||
[], []),
|
||||
Events36 = jsx:decode(list_to_binary(Body36), [return_maps]),
|
||||
ct:pal("DEBUG: Events36 count = ~p", [length(Events36)]),
|
||||
ct:pal("DEBUG: Events36 = ~p", [Events36]),
|
||||
true = (length(Events36) >= 3),
|
||||
ct:pal("OK (count: ~p)~n", [length(Events36)]),
|
||||
|
||||
%% ── TEST 37: Filter by calendar_id ──
|
||||
ct:pal(" TEST 37: Filter by calendar_id... "),
|
||||
{ok, {{_, 200, _}, _, Body37}} =
|
||||
httpc:request(get, {AdminURL ++ "/v1/admin/events?calendar_id=" ++ SearchCalIdStr,
|
||||
[{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}]},
|
||||
[], []),
|
||||
Events37 = jsx:decode(list_to_binary(Body37), [return_maps]),
|
||||
ct:pal("DEBUG: Events37 count = ~p", [length(Events37)]),
|
||||
ct:pal("DEBUG: Events37 = ~p", [Events37]),
|
||||
true = (length(Events37) >= 3),
|
||||
ct:pal("OK (count: ~p)~n", [length(Events37)]),
|
||||
|
||||
%% ── TEST 38: Exact title match ──
|
||||
ct:pal(" TEST 38: Exact title match... "),
|
||||
{ok, {{_, 200, _}, _, Body38}} =
|
||||
httpc:request(get, {AdminURL ++ "/v1/admin/events?calendar_id=" ++ SearchCalIdStr ++ "&title=Test%20Event%20Alpha",
|
||||
[{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}]},
|
||||
[], []),
|
||||
Events38 = jsx:decode(list_to_binary(Body38), [return_maps]),
|
||||
ct:pal("DEBUG: Events38 count = ~p", [length(Events38)]),
|
||||
ct:pal("DEBUG: Events38 = ~p", [Events38]),
|
||||
1 = length(Events38),
|
||||
#{<<"id">> := AlphaId} = hd(Events38),
|
||||
ct:pal("OK~n"),
|
||||
|
||||
%% ── TEST 39: Substring search (q) ──
|
||||
ct:pal(" TEST 39: Substring search (q=Alpha)... "),
|
||||
{ok, {{_, 200, _}, _, Body39}} =
|
||||
httpc:request(get, {AdminURL ++ "/v1/admin/events?calendar_id=" ++ SearchCalIdStr ++ "&q=Alpha",
|
||||
[{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}]},
|
||||
[], []),
|
||||
Events39 = jsx:decode(list_to_binary(Body39), [return_maps]),
|
||||
ct:pal("DEBUG: Events39 count = ~p", [length(Events39)]),
|
||||
ct:pal("DEBUG: Events39 = ~p", [Events39]),
|
||||
true = (length(Events39) >= 2),
|
||||
Titles39 = [maps:get(<<"title">>, E) || E <- Events39],
|
||||
ct:pal("OK (count: ~p, titles: ~p)~n", [length(Events39), Titles39]),
|
||||
|
||||
%% ── TEST 40: Combined filters (calendar_id + status) ──
|
||||
ct:pal(" TEST 40: Combined filters (calendar+status)... "),
|
||||
{ok, {{_, 200, _}, _, Body40}} =
|
||||
httpc:request(get, {AdminURL ++ "/v1/admin/events?calendar_id=" ++ SearchCalIdStr ++ "&status=active",
|
||||
[{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}]},
|
||||
[], []),
|
||||
Events40 = jsx:decode(list_to_binary(Body40), [return_maps]),
|
||||
ct:pal("DEBUG: Events40 count = ~p", [length(Events40)]),
|
||||
ct:pal("DEBUG: Events40 = ~p", [Events40]),
|
||||
true = (length(Events40) >= 2),
|
||||
ct:pal("OK (count: ~p)~n", [length(Events40)]),
|
||||
|
||||
%% ── TEST 41: Pagination (limit & offset) ──
|
||||
ct:pal(" TEST 41: Pagination... "),
|
||||
{ok, {{_, 200, _}, Headers41a, Body41a}} =
|
||||
httpc:request(get, {AdminURL ++ "/v1/admin/events?calendar_id=" ++ SearchCalIdStr ++ "&status=all&limit=2&offset=0&sort=title&order=asc",
|
||||
[{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}]},
|
||||
[], []),
|
||||
Events41a = jsx:decode(list_to_binary(Body41a), [return_maps]),
|
||||
ct:pal("DEBUG: Events41a count = ~p", [length(Events41a)]),
|
||||
ct:pal("DEBUG: Events41a = ~p", [Events41a]),
|
||||
2 = length(Events41a),
|
||||
{"content-range", ContentRange41a} = lists:keyfind("content-range", 1, Headers41a),
|
||||
ct:pal("page1: ~s; ", [ContentRange41a]),
|
||||
{ok, {{_, 200, _}, Headers41b, Body41b}} =
|
||||
httpc:request(get, {AdminURL ++ "/v1/admin/events?calendar_id=" ++ SearchCalIdStr ++ "&status=all&limit=2&offset=2&sort=title&order=asc",
|
||||
[{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}]},
|
||||
[], []),
|
||||
Events41b = jsx:decode(list_to_binary(Body41b), [return_maps]),
|
||||
ct:pal("DEBUG: Events41b count = ~p", [length(Events41b)]),
|
||||
ct:pal("DEBUG: Events41b = ~p", [Events41b]),
|
||||
1 = length(Events41b),
|
||||
{"content-range", ContentRange41b} = lists:keyfind("content-range", 1, Headers41b),
|
||||
ct:pal("page2: ~s~n", [ContentRange41b]),
|
||||
|
||||
%% ── TEST 42: Sorting (order=asc) ──
|
||||
ct:pal(" TEST 42: Sorting by title ascending... "),
|
||||
{ok, {{_, 200, _}, _, Body42}} =
|
||||
httpc:request(get, {AdminURL ++ "/v1/admin/events?calendar_id=" ++ SearchCalIdStr ++ "&status=all&sort=title&order=asc",
|
||||
[{"Authorization", "Bearer " ++ binary_to_list(AdminToken)}]},
|
||||
[], []),
|
||||
Events42 = jsx:decode(list_to_binary(Body42), [return_maps]),
|
||||
SortedTitles = [maps:get(<<"title">>, E) || E <- Events42],
|
||||
SortedTitles = lists:sort(SortedTitles),
|
||||
ct:pal("OK (titles: ~p)~n", [SortedTitles]),
|
||||
|
||||
ct:pal("~n✅ Admin API tests passed!~n"),
|
||||
{?MODULE, ok}.
|
||||
Reference in New Issue
Block a user