99 lines
4.7 KiB
Erlang
99 lines
4.7 KiB
Erlang
%%%-------------------------------------------------------------------
|
|
%%% @doc Тесты клиентского API для отмены вхождения повторяющегося события.
|
|
%%%
|
|
%%% Покрывает эндпоинты:
|
|
%%% DELETE /v1/events/:id/occurrences/:start_time
|
|
%%%
|
|
%%% Проверяет:
|
|
%%% - успешную отмену конкретного вхождения
|
|
%%% - ошибку 400 для не-recurring события
|
|
%%% - ошибку 403 при попытке отмены чужим пользователем
|
|
%%% - ошибку 401 без токена
|
|
%%% @end
|
|
%%%-------------------------------------------------------------------
|
|
-module(user_occurrence_cancel_tests).
|
|
-include_lib("eunit/include/eunit.hrl").
|
|
|
|
-export([test/0]).
|
|
|
|
%%%===================================================================
|
|
%%% Главная тестовая функция
|
|
%%%===================================================================
|
|
|
|
-spec test() -> ok.
|
|
test() ->
|
|
ct:pal("=== User Occurrence Cancel Tests ==="),
|
|
OwnerToken = api_test_runner:get_user_token(),
|
|
OtherToken = api_test_runner:register_and_login(
|
|
api_test_runner:unique_email(<<"other">>), <<"pass">>),
|
|
|
|
% Создаём календарь и повторяющееся событие
|
|
CalId = api_test_runner:create_calendar(OwnerToken, #{title => <<"OccCancel">>}),
|
|
#{<<"id">> := RecurringId} = api_test_runner:client_post(
|
|
<<"/v1/calendars/", CalId/binary, "/events">>, OwnerToken,
|
|
#{title => <<"Weekly Standup">>,
|
|
start_time => api_test_runner:future_date_iso8601(),
|
|
duration => 30,
|
|
recurrence => #{freq => <<"WEEKLY">>, interval => 1}}),
|
|
|
|
% Получаем вхождения (ответ – список карт)
|
|
OccPath = <<"/v1/events/", RecurringId/binary, "/occurrences?from=2026-06-01T00:00:00Z&to=2026-06-30T00:00:00Z">>,
|
|
Occurrences = api_test_runner:client_get(OccPath, OwnerToken),
|
|
?assert(is_list(Occurrences)),
|
|
?assert(length(Occurrences) >= 1),
|
|
#{<<"start_time">> := FirstStart} = hd(Occurrences),
|
|
|
|
test_cancel_occurrence(OwnerToken, RecurringId, FirstStart),
|
|
test_cancel_occurrence_on_single_event(OwnerToken, CalId),
|
|
test_cancel_occurrence_forbidden(OtherToken, RecurringId, FirstStart),
|
|
test_cancel_occurrence_unauthorized(RecurringId, FirstStart),
|
|
|
|
ct:pal("=== All user occurrence cancel tests passed ==="),
|
|
ok.
|
|
|
|
%%%===================================================================
|
|
%%% Тестовые функции
|
|
%%%===================================================================
|
|
|
|
%% @doc Успешная отмена вхождения: 200 OK.
|
|
-spec test_cancel_occurrence(binary(), binary(), binary()) -> ok.
|
|
test_cancel_occurrence(Token, EventId, StartTime) ->
|
|
ct:pal(" TEST: Cancel occurrence"),
|
|
Path = <<"/v1/events/", EventId/binary, "/occurrences/", StartTime/binary>>,
|
|
Resp = api_test_runner:client_request(delete, Path, Token),
|
|
{ok, 200, _, Body} = Resp,
|
|
#{<<"status">> := Status} = jsx:decode(list_to_binary(Body), [return_maps]),
|
|
?assertEqual(<<"cancelled">>, Status),
|
|
ct:pal(" OK: occurrence cancelled").
|
|
|
|
%% @doc Попытка отменить вхождение для одиночного события: 400.
|
|
-spec test_cancel_occurrence_on_single_event(binary(), binary()) -> ok.
|
|
test_cancel_occurrence_on_single_event(Token, CalId) ->
|
|
ct:pal(" TEST: Cancel occurrence on non-recurring event"),
|
|
#{<<"id">> := SingleId} = api_test_runner:client_post(
|
|
<<"/v1/calendars/", CalId/binary, "/events">>, Token,
|
|
#{title => <<"Single">>,
|
|
start_time => api_test_runner:future_date_iso8601(),
|
|
duration => 30}),
|
|
Path = <<"/v1/events/", SingleId/binary, "/occurrences/2026-06-02T10:00:00Z">>,
|
|
Resp = api_test_runner:client_request(delete, Path, Token),
|
|
?assertMatch({ok, 400, _, _}, Resp),
|
|
ct:pal(" OK: got 400").
|
|
|
|
%% @doc Попытка отмены чужим пользователем: 403.
|
|
-spec test_cancel_occurrence_forbidden(binary(), binary(), binary()) -> ok.
|
|
test_cancel_occurrence_forbidden(OtherToken, EventId, StartTime) ->
|
|
ct:pal(" TEST: Cancel occurrence by non-owner"),
|
|
Path = <<"/v1/events/", EventId/binary, "/occurrences/", StartTime/binary>>,
|
|
Resp = api_test_runner:client_request(delete, Path, OtherToken),
|
|
?assertMatch({ok, 403, _, _}, Resp),
|
|
ct:pal(" OK: got 403").
|
|
|
|
%% @doc Запрос без токена: 401.
|
|
-spec test_cancel_occurrence_unauthorized(binary(), binary()) -> ok.
|
|
test_cancel_occurrence_unauthorized(EventId, StartTime) ->
|
|
ct:pal(" TEST: Cancel occurrence without token"),
|
|
Path = <<"/v1/events/", EventId/binary, "/occurrences/", StartTime/binary>>,
|
|
Resp = api_test_runner:client_request(delete, Path, <<>>),
|
|
?assertMatch({ok, 401, _, _}, Resp),
|
|
ct:pal(" OK: got 401"). |