Files
EventHubBack/test/api/users/user_occurrence_cancel_tests.erl

99 lines
4.7 KiB
Erlang
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
%%%-------------------------------------------------------------------
%%% @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 => <<"2026-06-01T10:00:00Z">>,
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 => <<"2026-06-02T10:00:00Z">>,
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").