-module(api_SUITE). -include_lib("common_test/include/ct.hrl"). -export([all/0, init_per_suite/1, end_per_suite/1]). -export([auth_test/1, calendar_test/1, event_test/1, booking_test/1, search_test/1, reviews_test/1, moderation_test/1, tickets_test/1, subscription_test/1, admin_test/1, websocket_test/1]). -export([future_date/0]). all() -> [ auth_test, calendar_test, event_test, booking_test, search_test, reviews_test, moderation_test, tickets_test, subscription_test, admin_test, websocket_test ]. init_per_suite(Config) -> ct:pal("Start Api Testing ~n"), Mode = os:getenv("CT_MODE", "local"), ct:pal(" Mode: ~s", [Mode]), AdminURL = os:getenv("ADMIN_API_HOST"), ct:pal(" AdminURL: ~s", [AdminURL]), AdminWsURL = os:getenv("ADMIN_WS_HOST"), ct:pal(" AdminWsURL: ~s", [AdminWsURL]), UserURL = os:getenv("API_HOST"), ct:pal(" UserURL: ~s", [UserURL]), UserWsURL = os:getenv("WS_HOST"), ct:pal(" UserWsURL: ~s", [UserWsURL]), case Mode of "remote" -> inets:start(), ssl:start(), % Отключаем авто-редирект и проверку сертификатов httpc:set_options([ {autoredirect, false}, {ssl, [{verify, verify_none}]} ]), wait_for_server(), timer:sleep(1000), % Извлекаем учётные данные администраторов из переменных окружения % и сохраняем их в словаре процесса для api_test_runner put(admin_super_email, list_to_binary(os:getenv("ADMIN_SUPER_EMAIL", "superadmin@eventhub.local"))), put(admin_super_password, list_to_binary(os:getenv("ADMIN_SUPER_PASSWORD", "123456"))), put(admin_moder_email, list_to_binary(os:getenv("ADMIN_MODER_EMAIL", "moderator@eventhub.local"))), put(admin_moder_password, list_to_binary(os:getenv("ADMIN_MODER_PASSWORD", "123456"))), put(admin_support_email, list_to_binary(os:getenv("ADMIN_SUPPORT_EMAIL", "support@eventhub.local"))), put(admin_support_password, list_to_binary(os:getenv("ADMIN_SUPPORT_PASSWORD", "123456"))), Config; _ -> application:ensure_all_started(eventhub), timer:sleep(3000), check_admins(), Config end. end_per_suite(Config) -> Mode = os:getenv("CT_MODE", "local"), case Mode of "remote" -> ok; _ -> application:stop(eventhub) end, Config. %% ── Тестовые обёртки ────────────────────────────────── auth_test(_) -> api_auth_tests:test(). calendar_test(_) -> api_calendar_tests:test(). event_test(_) -> api_event_tests:test(). booking_test(_) -> api_booking_tests:test(). search_test(_) -> api_search_tests:test(). reviews_test(_) -> api_reviews_tests:test(). moderation_test(_) -> api_moderation_tests:test(). tickets_test(_) -> api_tickets_tests:test(). subscription_test(_) -> api_subscription_tests:test(). admin_test(_) -> api_admin_tests:test(). websocket_test(_) -> api_websocket_tests:test(). %% @doc Проверка наличия администраторов (только в remote‑режиме) %% Если таблица admin пуста – роняем тест явно, чтобы не гадать. check_admins() -> case core_admin:list_all() of [] -> ct:fail("No admins found in remote cluster. Run init_default_admins first."); Admins -> ct:pal("Admins present: ~p", [length(Admins)]) end. %% @doc Ожидание доступности healthcheck-эндпоинта (/health) wait_for_server() -> URL = case os:getenv("API_HOST") of false -> "http://localhost:8080/health"; Host -> Host ++ "/health" end, wait_for_server(URL, 30). wait_for_server(URL, 0) -> ct:fail("Healthcheck ~s not responding after 30 seconds", [URL]); wait_for_server(URL, Attempts) -> case httpc:request(get, {URL, []}, [{timeout, 2000}, {ssl, [{verify, verify_none}]}], []) of {ok, {{_, 200, _}, _, _}} -> ct:pal("Healthcheck OK", []); _ -> timer:sleep(1000), wait_for_server(URL, Attempts - 1) end. future_date() -> Now = calendar:universal_time(), Tomorrow = calendar:gregorian_seconds_to_datetime( calendar:datetime_to_gregorian_seconds(Now) + 86400 ), {{Y, M, D}, {H, Min, S}} = Tomorrow, iolist_to_binary(io_lib:format("~4..0B-~2..0B-~2..0BT~2..0B:~2..0B:~2..0BZ", [Y, M, D, H, Min, S])).