CI/CD: ci, deploy-ift и deploy-stage через EventHubDevOps; фиксы calendar view, archive, API-тесты, traefik-coraza
This commit is contained in:
@@ -41,7 +41,8 @@
|
||||
client_delete/2,
|
||||
admin_patch/3]).
|
||||
-export([verify_user/2]).
|
||||
-export([future_date_iso8601/0]).
|
||||
-export([future_date_iso8601/0, iso8601_utc/1, future_month_range_iso8601/0,
|
||||
next_month_start_iso8601/0, next_month_range_iso8601/0]).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Конфигурация окружения (CT_MODE, ...)
|
||||
@@ -283,11 +284,39 @@ future_date() ->
|
||||
|
||||
-spec future_date_iso8601() -> binary().
|
||||
future_date_iso8601() ->
|
||||
Seconds = calendar:datetime_to_gregorian_seconds(calendar:universal_time()) + 86400,
|
||||
{{Y,M,D},{H,Min,S}} = calendar:gregorian_seconds_to_datetime(Seconds),
|
||||
iso8601_utc(future_date()).
|
||||
|
||||
-spec iso8601_utc(calendar:datetime()) -> binary().
|
||||
iso8601_utc({{Y, M, D}, {H, Min, S}}) ->
|
||||
iolist_to_binary(io_lib:format("~4..0B-~2..0B-~2..0BT~2..0B:~2..0B:~2..0BZ",
|
||||
[Y, M, D, H, Min, S])).
|
||||
|
||||
-spec future_month_range_iso8601() -> {binary(), binary()}.
|
||||
future_month_range_iso8601() ->
|
||||
{{Y, M, _D}, _} = future_date(),
|
||||
month_range_iso8601(Y, M).
|
||||
|
||||
-spec next_month_start_iso8601() -> binary().
|
||||
next_month_start_iso8601() ->
|
||||
{{Y, M, _}, _} = future_date(),
|
||||
{NY, NM} = next_month(Y, M),
|
||||
iso8601_utc({{NY, NM, 1}, {10, 0, 0}}).
|
||||
|
||||
-spec next_month_range_iso8601() -> {binary(), binary()}.
|
||||
next_month_range_iso8601() ->
|
||||
{{Y, M, _}, _} = future_date(),
|
||||
{NY, NM} = next_month(Y, M),
|
||||
month_range_iso8601(NY, NM).
|
||||
|
||||
month_range_iso8601(Y, M) ->
|
||||
From = iso8601_utc({{Y, M, 1}, {0, 0, 0}}),
|
||||
LastDay = calendar:last_day_of_the_month(Y, M),
|
||||
To = iso8601_utc({{Y, M, LastDay}, {23, 59, 59}}),
|
||||
{From, To}.
|
||||
|
||||
next_month(Y, 12) -> {Y + 1, 1};
|
||||
next_month(Y, M) -> {Y, M + 1}.
|
||||
|
||||
-spec register_and_login(binary(), binary()) -> binary().
|
||||
register_and_login(Email, Password) ->
|
||||
% 1. Регистрируем пользователя
|
||||
|
||||
@@ -43,7 +43,9 @@ test_create_single_event(Token, CalId) ->
|
||||
%% @doc GET /v1/calendars/:calendar_id/events?from=...&to=... – список с фильтром.
|
||||
test_list_events_with_dates(Token, CalId) ->
|
||||
ct:pal(" TEST: List events with date range"),
|
||||
Path = <<"/v1/calendars/", CalId/binary, "/events?from=2026-05-01T00:00:00Z&to=2026-07-01T00:00:00Z">>,
|
||||
{From, To} = api_test_runner:future_month_range_iso8601(),
|
||||
Path = <<"/v1/calendars/", CalId/binary, "/events?from=", From/binary,
|
||||
"&to=", To/binary>>,
|
||||
Events = api_test_runner:client_get(Path, Token),
|
||||
?assert(is_list(Events)),
|
||||
?assert(length(Events) >= 1),
|
||||
@@ -58,7 +60,7 @@ test_create_recurring_event(Token, CalId) ->
|
||||
Path = <<"/v1/calendars/", CalId/binary, "/events">>,
|
||||
Body = jsx:encode(#{
|
||||
title => <<"Weekly Meeting">>,
|
||||
start_time => api_test_runner:future_date_iso8601(),
|
||||
start_time => api_test_runner:next_month_start_iso8601(),
|
||||
duration => 60,
|
||||
recurrence => #{
|
||||
freq => <<"WEEKLY">>,
|
||||
@@ -70,11 +72,12 @@ test_create_recurring_event(Token, CalId) ->
|
||||
#{<<"id">> := RecurringId} = jsx:decode(list_to_binary(RespBody), [return_maps]),
|
||||
ct:pal(" Created recurring event ~s", [RecurringId]),
|
||||
|
||||
% Запрашиваем вхождения на месяц
|
||||
OccPath = <<"/v1/events/", RecurringId/binary, "/occurrences?from=2026-06-01T00:00:00Z&to=2026-06-30T00:00:00Z">>,
|
||||
{From, To} = api_test_runner:next_month_range_iso8601(),
|
||||
OccPath = <<"/v1/events/", RecurringId/binary, "/occurrences?from=", From/binary,
|
||||
"&to=", To/binary>>,
|
||||
Occs = api_test_runner:client_get(OccPath, Token),
|
||||
?assert(is_list(Occs)),
|
||||
?assert(length(Occs) >= 4), % минимум 4 недели в июне
|
||||
?assert(length(Occs) >= 4), % минимум 4 недели в полном месяце
|
||||
FirstOcc = hd(Occs),
|
||||
?assert(maps:is_key(<<"start_time">>, FirstOcc)),
|
||||
ct:pal(" OK: ~p occurrences found", [length(Occs)]).
|
||||
@@ -36,8 +36,9 @@ test() ->
|
||||
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">>,
|
||||
{From, To} = api_test_runner:future_month_range_iso8601(),
|
||||
OccPath = <<"/v1/events/", RecurringId/binary, "/occurrences?from=", From/binary,
|
||||
"&to=", To/binary>>,
|
||||
Occurrences = api_test_runner:client_get(OccPath, OwnerToken),
|
||||
?assert(is_list(Occurrences)),
|
||||
?assert(length(Occurrences) >= 1),
|
||||
|
||||
@@ -93,9 +93,9 @@ test_tag_filter(Token) ->
|
||||
|
||||
test_date_filter(Token) ->
|
||||
ct:pal(" TEST: Search with date range"),
|
||||
Events = extract_events(
|
||||
api_test_runner:client_get(
|
||||
<<"/v1/search?from=2026-06-01T00:00:00Z&to=2026-06-15T23:59:59Z">>, Token)),
|
||||
{From, To} = api_test_runner:future_month_range_iso8601(),
|
||||
Path = <<"/v1/search?from=", From/binary, "&to=", To/binary>>,
|
||||
Events = extract_events(api_test_runner:client_get(Path, Token)),
|
||||
?assert(is_list(Events)),
|
||||
?assert(length(Events) >= 1),
|
||||
ct:pal(" OK: ~p events", [length(Events)]).
|
||||
|
||||
Reference in New Issue
Block a user