222 lines
11 KiB
Erlang
222 lines
11 KiB
Erlang
%%%-------------------------------------------------------------------
|
||
%%% @doc Тесты административного API для получения статистики.
|
||
%%%
|
||
%%% Покрывает эндпоинты:
|
||
%%% GET /v1/admin/stats
|
||
%%% GET /v1/admin/users/stats
|
||
%%% GET /v1/admin/events/stats
|
||
%%% GET /v1/admin/reports/stats
|
||
%%% GET /v1/admin/reviews/stats
|
||
%%% GET /v1/admin/subscriptions/stats
|
||
%%% GET /v1/admin/calendars/stats
|
||
%%%
|
||
%%% Проверяет:
|
||
%%% - получение общей статистики для всех ролей администраторов
|
||
%%% - для superadmin и admin – наличие ключевых метрик, включая pending_users_total, *_by_day
|
||
%%% - для moderator и support – ответ непустой
|
||
%%% - работу с фильтром по датам (from, to)
|
||
%%% - статистику по пользователям (users/stats)
|
||
%%% - статистику по событиям (events/stats)
|
||
%%% - статистику по жалобам (reports/stats)
|
||
%%% - статистику по отзывам (reviews/stats)
|
||
%%% - статистику по подпискам (subscriptions/stats)
|
||
%%% - статистику по календарям (calendars/stats)
|
||
%%% @end
|
||
%%%-------------------------------------------------------------------
|
||
-module(admin_stats_tests).
|
||
-include_lib("eunit/include/eunit.hrl").
|
||
-export([test/0]).
|
||
|
||
%%%===================================================================
|
||
%%% Главная тестовая функция
|
||
%%%===================================================================
|
||
-spec test() -> ok.
|
||
test() ->
|
||
ct:pal("=== Admin Stats Tests ==="),
|
||
SuperToken = api_test_runner:get_superadmin_token(),
|
||
AdminToken = api_test_runner:get_admin_token(),
|
||
ModerToken = api_test_runner:get_moderator_token(),
|
||
SupportToken = api_test_runner:get_support_token(),
|
||
|
||
% Создаём тестовые данные для ненулевой статистики
|
||
UserToken = api_test_runner:get_user_token(),
|
||
CalId = api_test_runner:create_calendar(UserToken, #{title => <<"StatsCal">>}),
|
||
EventId = api_test_runner:create_event(UserToken, CalId, #{
|
||
title => <<"Stats Event">>,
|
||
start_time => api_test_runner:future_date(),
|
||
duration => 60
|
||
}),
|
||
% Бронируем и подтверждаем, чтобы можно было оставить отзыв
|
||
#{<<"id">> := BookingId} = api_test_runner:client_post(
|
||
<<"/v1/events/", EventId/binary, "/bookings">>, UserToken, #{}),
|
||
api_test_runner:client_put(<<"/v1/bookings/", BookingId/binary>>, UserToken,
|
||
#{action => <<"confirm">>}),
|
||
% Оставляем отзыв
|
||
api_test_runner:client_post(<<"/v1/reviews">>, UserToken,
|
||
#{target_type => <<"event">>, target_id => EventId, rating => 5, comment => <<"Great!">>}),
|
||
% Жалоба
|
||
api_test_runner:client_post(<<"/v1/reports">>, UserToken,
|
||
#{<<"target_type">> => <<"event">>, <<"target_id">> => EventId, <<"reason">> => <<"Test">>}),
|
||
% Подписка
|
||
SubUserToken = api_test_runner:get_user_token(),
|
||
api_test_runner:client_post(<<"/v1/subscription">>, SubUserToken,
|
||
#{<<"action">> => <<"start_trial">>}),
|
||
|
||
% Общая статистика
|
||
test_stats_for_role("Superadmin", SuperToken, strict),
|
||
test_stats_for_role("Admin", AdminToken, strict),
|
||
test_stats_for_role("Moderator", ModerToken, loose),
|
||
test_stats_for_role("Support", SupportToken, loose),
|
||
|
||
test_stats_with_dates(SuperToken),
|
||
|
||
% Детальная статистика
|
||
test_user_stats(SuperToken),
|
||
test_event_stats(SuperToken),
|
||
test_report_stats(SuperToken),
|
||
test_review_stats(SuperToken),
|
||
test_subscription_stats(SuperToken),
|
||
test_calendar_stats(SuperToken),
|
||
|
||
ct:pal("=== All admin stats tests passed ==="),
|
||
ok.
|
||
|
||
%%%===================================================================
|
||
%%% Тестовые функции
|
||
%%%===================================================================
|
||
|
||
-spec test_stats_for_role(string(), binary(), strict | loose) -> ok.
|
||
test_stats_for_role(RoleName, Token, Strictness) ->
|
||
ct:pal(" TEST: Get stats for role ~s", [RoleName]),
|
||
Stats = api_test_runner:admin_get(<<"/v1/admin/stats">>, Token),
|
||
?assert(is_map(Stats)),
|
||
case Strictness of
|
||
strict ->
|
||
% Тотальные значения
|
||
?assert(maps:is_key(<<"users_total">>, Stats)),
|
||
?assert(maps:is_key(<<"pending_users_total">>, Stats)),
|
||
?assert(maps:is_key(<<"events_total">>, Stats)),
|
||
?assert(maps:is_key(<<"calendars_total">>, Stats)),
|
||
?assert(maps:is_key(<<"reviews_total">>, Stats)),
|
||
?assert(maps:is_key(<<"reports_total">>, Stats)),
|
||
?assert(maps:is_key(<<"reports_pending">>, Stats)),
|
||
?assert(maps:is_key(<<"reports_reviewed">>, Stats)),
|
||
?assert(maps:is_key(<<"reports_dismissed">>, Stats)),
|
||
?assert(maps:is_key(<<"tickets_total">>, Stats)),
|
||
?assert(maps:is_key(<<"tickets_open">>, Stats)),
|
||
?assert(maps:is_key(<<"subscriptions_total">>, Stats)),
|
||
?assert(maps:is_key(<<"trial_subscriptions">>, Stats)),
|
||
% Массивы по дням
|
||
?assert(maps:is_key(<<"registrations_by_day">>, Stats)),
|
||
?assert(maps:is_key(<<"events_by_day">>, Stats)),
|
||
?assert(maps:is_key(<<"reviews_by_day">>, Stats)),
|
||
?assert(maps:is_key(<<"calendars_by_day">>, Stats)),
|
||
?assert(maps:is_key(<<"reports_by_day">>, Stats)),
|
||
?assert(maps:is_key(<<"tickets_by_day">>, Stats)),
|
||
?assert(maps:is_key(<<"subscriptions_by_day">>, Stats)),
|
||
?assert(maps:is_key(<<"pending_users_by_day">>, Stats)),
|
||
% Проверка, что они действительно списки
|
||
?assert(is_list(maps:get(<<"registrations_by_day">>, Stats))),
|
||
?assert(is_list(maps:get(<<"events_by_day">>, Stats))),
|
||
?assert(is_list(maps:get(<<"reviews_by_day">>, Stats))),
|
||
?assert(is_list(maps:get(<<"calendars_by_day">>, Stats))),
|
||
?assert(is_list(maps:get(<<"reports_by_day">>, Stats))),
|
||
?assert(is_list(maps:get(<<"tickets_by_day">>, Stats))),
|
||
?assert(is_list(maps:get(<<"subscriptions_by_day">>, Stats))),
|
||
?assert(is_list(maps:get(<<"pending_users_by_day">>, Stats)));
|
||
loose ->
|
||
?assert(map_size(Stats) > 0)
|
||
end,
|
||
ct:pal(" OK: ~p keys", [length(maps:keys(Stats))]).
|
||
|
||
-spec test_stats_with_dates(binary()) -> ok.
|
||
test_stats_with_dates(Token) ->
|
||
ct:pal(" TEST: Get stats with date range"),
|
||
From = <<"2026-01-01T00:00:00Z">>,
|
||
To = <<"2026-12-31T23:59:59Z">>,
|
||
Path = <<"/v1/admin/stats?from=", From/binary, "&to=", To/binary>>,
|
||
Stats = api_test_runner:admin_get(Path, Token),
|
||
?assert(is_map(Stats)),
|
||
?assert(maps:is_key(<<"users_total">>, Stats) orelse maps:is_key(<<"users">>, Stats)),
|
||
ct:pal(" OK").
|
||
|
||
%% @doc Тестирует эндпоинт GET /v1/admin/users/stats.
|
||
-spec test_user_stats(binary()) -> ok.
|
||
test_user_stats(Token) ->
|
||
ct:pal(" TEST: User statistics"),
|
||
Stats = api_test_runner:admin_get(<<"/v1/admin/users/stats">>, Token),
|
||
?assert(is_map(Stats)),
|
||
?assert(maps:is_key(<<"total_users">>, Stats)),
|
||
?assert(maps:is_key(<<"users_by_role">>, Stats)),
|
||
?assert(maps:is_key(<<"users_by_status">>, Stats)),
|
||
?assert(maps:is_key(<<"pending_users">>, Stats)),
|
||
ct:pal(" OK: total=~p, pending=~p", [maps:get(<<"total_users">>, Stats), maps:get(<<"pending_users">>, Stats)]).
|
||
|
||
%% @doc Тестирует эндпоинт GET /v1/admin/events/stats.
|
||
-spec test_event_stats(binary()) -> ok.
|
||
test_event_stats(Token) ->
|
||
ct:pal(" TEST: Event statistics"),
|
||
Stats = api_test_runner:admin_get(<<"/v1/admin/events/stats">>, Token),
|
||
?assert(is_map(Stats)),
|
||
?assert(maps:is_key(<<"total_events">>, Stats)),
|
||
?assert(maps:is_key(<<"events_by_type">>, Stats)),
|
||
?assert(maps:is_key(<<"events_by_status">>, Stats)),
|
||
?assert(maps:is_key(<<"top_events_by_rating">>, Stats)),
|
||
?assert(is_list(maps:get(<<"top_events_by_rating">>, Stats))),
|
||
ct:pal(" OK: total=~p", [maps:get(<<"total_events">>, Stats)]).
|
||
|
||
%% @doc Тестирует эндпоинт GET /v1/admin/reports/stats.
|
||
-spec test_report_stats(binary()) -> ok.
|
||
test_report_stats(Token) ->
|
||
ct:pal(" TEST: Report statistics"),
|
||
Stats = api_test_runner:admin_get(<<"/v1/admin/reports/stats">>, Token),
|
||
?assert(is_map(Stats)),
|
||
?assert(maps:is_key(<<"total_reports">>, Stats)),
|
||
?assert(maps:is_key(<<"reports_by_target_type">>, Stats)),
|
||
?assert(maps:is_key(<<"reports_by_status">>, Stats)),
|
||
?assert(maps:is_key(<<"top_targets_by_reports">>, Stats)),
|
||
?assert(is_list(maps:get(<<"top_targets_by_reports">>, Stats))),
|
||
ct:pal(" OK: total=~p", [maps:get(<<"total_reports">>, Stats)]).
|
||
|
||
%% @doc Тестирует эндпоинт GET /v1/admin/reviews/stats.
|
||
-spec test_review_stats(binary()) -> ok.
|
||
test_review_stats(Token) ->
|
||
ct:pal(" TEST: Review statistics"),
|
||
Stats = api_test_runner:admin_get(<<"/v1/admin/reviews/stats">>, Token),
|
||
?assert(is_map(Stats)),
|
||
?assert(maps:is_key(<<"total_reviews">>, Stats)),
|
||
?assert(maps:is_key(<<"reviews_by_target_type">>, Stats)),
|
||
?assert(maps:is_key(<<"reviews_by_status">>, Stats)),
|
||
?assert(maps:is_key(<<"top_targets_by_reviews">>, Stats)),
|
||
?assert(maps:is_key(<<"top_targets_by_positive_reviews">>, Stats)),
|
||
?assert(maps:is_key(<<"top_targets_by_negative_reviews">>, Stats)),
|
||
ct:pal(" OK: total=~p", [maps:get(<<"total_reviews">>, Stats)]).
|
||
|
||
%% @doc Тестирует эндпоинт GET /v1/admin/subscriptions/stats.
|
||
-spec test_subscription_stats(binary()) -> ok.
|
||
test_subscription_stats(Token) ->
|
||
ct:pal(" TEST: Subscription statistics"),
|
||
Stats = api_test_runner:admin_get(<<"/v1/admin/subscriptions/stats">>, Token),
|
||
?assert(is_map(Stats)),
|
||
?assert(maps:is_key(<<"total_subscriptions">>, Stats)),
|
||
?assert(maps:is_key(<<"subscriptions_by_plan">>, Stats)),
|
||
?assert(maps:is_key(<<"subscriptions_by_status">>, Stats)),
|
||
?assert(maps:is_key(<<"trial_subscriptions">>, Stats)),
|
||
?assert(maps:is_key(<<"ending_paid_subscriptions">>, Stats)),
|
||
?assert(is_list(maps:get(<<"ending_paid_subscriptions">>, Stats))),
|
||
ct:pal(" OK: total=~p, trial=~p", [maps:get(<<"total_subscriptions">>, Stats), maps:get(<<"trial_subscriptions">>, Stats)]).
|
||
|
||
%% @doc Тестирует эндпоинт GET /v1/admin/calendars/stats.
|
||
-spec test_calendar_stats(binary()) -> ok.
|
||
test_calendar_stats(Token) ->
|
||
ct:pal(" TEST: Calendar statistics"),
|
||
Stats = api_test_runner:admin_get(<<"/v1/admin/calendars/stats">>, Token),
|
||
?assert(is_map(Stats)),
|
||
?assert(maps:is_key(<<"total_calendars">>, Stats)),
|
||
?assert(maps:is_key(<<"calendars_by_type">>, Stats)),
|
||
?assert(maps:is_key(<<"calendars_by_status">>, Stats)),
|
||
?assert(maps:is_key(<<"top_calendars_by_reviews">>, Stats)),
|
||
?assert(maps:is_key(<<"top_calendars_by_positive_reviews">>, Stats)),
|
||
?assert(maps:is_key(<<"top_calendars_by_negative_reviews">>, Stats)),
|
||
?assert(maps:is_key(<<"top_calendars_by_rating">>, Stats)),
|
||
ct:pal(" OK: total=~p", [maps:get(<<"total_calendars">>, Stats)]). |