%%%------------------------------------------------------------------- %%% @doc Тесты клиентского API для работы с жалобами. %%% %%% Покрывает эндпоинты: %%% POST /v1/reports %%% GET /v1/reports (требует прав администратора) %%% %%% Проверяет: %%% - успешное создание жалобы (201 Created) %%% - ошибку 400 при отсутствии обязательных полей %%% - ошибку 401 при создании без токена %%% - ошибку 403 при попытке получения списка обычным пользователем %%% @end %%%------------------------------------------------------------------- -module(user_reports_tests). -include_lib("eunit/include/eunit.hrl"). -export([test/0]). %%%=================================================================== %%% Главная тестовая функция %%%=================================================================== -spec test() -> ok. test() -> ct:pal("=== User Reports Tests ==="), UserToken = api_test_runner:get_user_token(), % Создаём событие, на которое можно пожаловаться CalId = api_test_runner:create_calendar(UserToken, #{title => <<"ReportTest">>}), #{<<"id">> := EventId} = api_test_runner:client_post( <<"/v1/calendars/", CalId/binary, "/events">>, UserToken, #{title => <<"Event to report">>, start_time => <<"2026-06-01T10:00:00Z">>, duration => 60}), test_create_report(UserToken, EventId), test_create_report_missing_fields(UserToken), test_create_report_unauthorized(EventId), test_list_reports_forbidden(UserToken), ct:pal("=== All user reports tests passed ==="), ok. %%%=================================================================== %%% Тестовые функции %%%=================================================================== %% @doc Успешное создание жалобы: 201 Created. -spec test_create_report(binary(), binary()) -> ok. test_create_report(Token, EventId) -> ct:pal(" TEST: Create a report"), Resp = api_test_runner:client_request(post, <<"/v1/reports">>, Token, jsx:encode(#{ target_type => <<"event">>, target_id => EventId, reason => <<"Inappropriate content">> })), {ok, 201, _, Body} = Resp, #{<<"id">> := ReportId, <<"status">> := Status} = jsx:decode(list_to_binary(Body), [return_maps]), ?assert(is_binary(ReportId)), ?assertEqual(<<"pending">>, Status), ct:pal(" OK: report ~s created", [ReportId]). %% @doc Отсутствие обязательных полей: 400 Bad Request. -spec test_create_report_missing_fields(binary()) -> ok. test_create_report_missing_fields(Token) -> ct:pal(" TEST: Create report with missing fields"), Resp1 = api_test_runner:client_request(post, <<"/v1/reports">>, Token, jsx:encode(#{target_id => <<"id">>, reason => <<"text">>})), ?assertMatch({ok, 400, _, _}, Resp1), Resp2 = api_test_runner:client_request(post, <<"/v1/reports">>, Token, jsx:encode(#{target_type => <<"event">>, reason => <<"text">>})), ?assertMatch({ok, 400, _, _}, Resp2), Resp3 = api_test_runner:client_request(post, <<"/v1/reports">>, Token, jsx:encode(#{target_type => <<"event">>, target_id => <<"id">>})), ?assertMatch({ok, 400, _, _}, Resp3), ct:pal(" OK: got 400"). %% @doc Создание жалобы без токена: 401 Unauthorized. -spec test_create_report_unauthorized(binary()) -> ok. test_create_report_unauthorized(EventId) -> ct:pal(" TEST: Create report without token"), Resp = api_test_runner:client_request(post, <<"/v1/reports">>, <<>>, jsx:encode(#{ target_type => <<"event">>, target_id => EventId, reason => <<"test">> })), ?assertMatch({ok, 401, _, _}, Resp), ct:pal(" OK: got 401"). %% @doc GET /v1/reports для обычного пользователя должен вернуть 403. -spec test_list_reports_forbidden(binary()) -> ok. test_list_reports_forbidden(Token) -> ct:pal(" TEST: List reports as regular user"), Resp = api_test_runner:client_request(get, <<"/v1/reports">>, Token), ?assertMatch({ok, 403, _, _}, Resp), ct:pal(" OK: got 403").