feat(booking): materialize occurrence on POST bookings. Refs EventHub/EventHubBack#67
This commit is contained in:
@@ -47,6 +47,7 @@ test() ->
|
||||
test_cancel_booking(ParticipantToken, EventId),
|
||||
test_duplicate_booking(ParticipantToken, EventId),
|
||||
test_booking_unauthorized(EventId),
|
||||
test_recurring_booking(OwnerToken, ParticipantToken),
|
||||
|
||||
ct:pal("=== All user bookings tests passed ==="),
|
||||
ok.
|
||||
@@ -116,4 +117,30 @@ test_booking_unauthorized(EventId) ->
|
||||
Path = <<"/v1/events/", EventId/binary, "/bookings">>,
|
||||
Resp = api_test_runner:client_request(post, Path, <<>>, <<"{}">>),
|
||||
?assertMatch({ok, 401, _, _}, Resp),
|
||||
ct:pal(" OK: got 401").
|
||||
ct:pal(" OK: got 401").
|
||||
|
||||
%% @doc Серия: без occurrence_start — 400; с датой вхождения — 201 на instance.
|
||||
-spec test_recurring_booking(binary(), binary()) -> ok.
|
||||
test_recurring_booking(OwnerToken, ParticipantToken) ->
|
||||
ct:pal(" TEST: Recurring booking occurrence_start"),
|
||||
CalId = api_test_runner:create_calendar(OwnerToken, #{
|
||||
title => <<"SeriesBooking">>,
|
||||
type => <<"commercial">>,
|
||||
confirmation => <<"auto">>
|
||||
}),
|
||||
Start = api_test_runner:future_date(),
|
||||
StartIso = api_test_runner:iso8601_utc(Start),
|
||||
#{<<"id">> := MasterId} = api_test_runner:client_post(
|
||||
<<"/v1/calendars/", CalId/binary, "/events">>, OwnerToken,
|
||||
#{title => <<"Weekly slot">>,
|
||||
start_time => StartIso,
|
||||
duration => 60,
|
||||
recurrence => #{freq => <<"WEEKLY">>, interval => 1}}),
|
||||
Path = <<"/v1/events/", MasterId/binary, "/bookings">>,
|
||||
{ok, 400, _, _} = api_test_runner:client_request(post, Path, ParticipantToken, <<"{}">>),
|
||||
OccSec = calendar:datetime_to_gregorian_seconds(Start) + 7 * 86400,
|
||||
OccIso = api_test_runner:iso8601_utc(calendar:gregorian_seconds_to_datetime(OccSec)),
|
||||
#{<<"id">> := _Bid, <<"event_id">> := InstId} =
|
||||
api_test_runner:client_post(Path, ParticipantToken, #{occurrence_start => OccIso}),
|
||||
?assertNotEqual(MasterId, InstId),
|
||||
ct:pal(" OK: booked instance ~s", [InstId]).
|
||||
@@ -2,7 +2,8 @@
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include("records.hrl").
|
||||
|
||||
-define(TABLES, [user, calendar, event, booking, admin, subscription, calendar_specialist]).
|
||||
-define(TABLES, [user, calendar, event, booking, admin, subscription, calendar_specialist,
|
||||
recurrence_exception]).
|
||||
|
||||
setup() ->
|
||||
eh_test_support:start_mnesia(),
|
||||
@@ -21,6 +22,10 @@ logic_booking_test_() ->
|
||||
[
|
||||
{"Create booking auto confirms", fun test_create_booking_auto/0},
|
||||
{"Create booking manual pending", fun test_create_booking_pending/0},
|
||||
{"Recurring booking requires occurrence_start", fun test_recurring_requires_occurrence/0},
|
||||
{"Recurring booking materializes occurrence", fun test_recurring_books_occurrence/0},
|
||||
{"Recurring booking rejects invalid occurrence", fun test_recurring_invalid_occurrence/0},
|
||||
{"Recurring booking rejects cancelled occurrence", fun test_recurring_cancelled_occurrence/0},
|
||||
{"Create booking personal denied", fun test_booking_personal_denied/0},
|
||||
{"Create duplicate booking", fun test_create_duplicate_booking/0},
|
||||
{"Create booking for missing event", fun test_booking_missing_event/0},
|
||||
@@ -96,6 +101,16 @@ past_start() ->
|
||||
Sec = calendar:datetime_to_gregorian_seconds(calendar:universal_time()) - 3600,
|
||||
calendar:gregorian_seconds_to_datetime(Sec).
|
||||
|
||||
add_days(DateTime, Days) ->
|
||||
Sec = calendar:datetime_to_gregorian_seconds(DateTime) + Days * 86400,
|
||||
calendar:gregorian_seconds_to_datetime(Sec).
|
||||
|
||||
create_recurring_event(CalendarId) ->
|
||||
StartTime = eh_test_support:future_start(),
|
||||
RRule = #{<<"freq">> => <<"WEEKLY">>, <<"interval">> => 1},
|
||||
{ok, Event} = core_event:create_recurring(CalendarId, <<"Series">>, StartTime, 60, RRule),
|
||||
{Event#event.id, StartTime}.
|
||||
|
||||
create_test_event_with_capacity(CalendarId, Capacity) ->
|
||||
StartTime = eh_test_support:future_start(),
|
||||
{ok, Event} = core_event:create(CalendarId, <<"Test Event">>, StartTime, 60),
|
||||
@@ -124,6 +139,48 @@ test_create_booking_pending() ->
|
||||
{ok, Stored} = core_booking:get_by_id(Booking#booking.id),
|
||||
?assertEqual(pending, Stored#booking.status).
|
||||
|
||||
test_recurring_requires_occurrence() ->
|
||||
OwnerId = create_test_user(user),
|
||||
ParticipantId = create_test_user(user),
|
||||
CalendarId = create_test_calendar(OwnerId, auto),
|
||||
{MasterId, _} = create_recurring_event(CalendarId),
|
||||
{error, occurrence_start_required} = logic_booking:create_booking(ParticipantId, MasterId).
|
||||
|
||||
test_recurring_books_occurrence() ->
|
||||
OwnerId = create_test_user(user),
|
||||
ParticipantId = create_test_user(user),
|
||||
CalendarId = create_test_calendar(OwnerId, auto),
|
||||
{MasterId, StartTime} = create_recurring_event(CalendarId),
|
||||
Occ = add_days(StartTime, 7),
|
||||
{ok, Booking} = logic_booking:create_booking(ParticipantId, MasterId, Occ),
|
||||
{ok, BookedEvent} = core_event:get_by_id(Booking#booking.event_id),
|
||||
?assertEqual(true, BookedEvent#event.is_instance),
|
||||
?assertEqual(MasterId, BookedEvent#event.master_id),
|
||||
?assertEqual(Occ, BookedEvent#event.start_time),
|
||||
?assertNotEqual(MasterId, Booking#booking.event_id).
|
||||
|
||||
test_recurring_invalid_occurrence() ->
|
||||
OwnerId = create_test_user(user),
|
||||
ParticipantId = create_test_user(user),
|
||||
CalendarId = create_test_calendar(OwnerId, auto),
|
||||
{MasterId, StartTime} = create_recurring_event(CalendarId),
|
||||
Bad = add_days(StartTime, 1),
|
||||
{error, invalid_occurrence} = logic_booking:create_booking(ParticipantId, MasterId, Bad).
|
||||
|
||||
test_recurring_cancelled_occurrence() ->
|
||||
OwnerId = create_test_user(user),
|
||||
ParticipantId = create_test_user(user),
|
||||
CalendarId = create_test_calendar(OwnerId, auto),
|
||||
{MasterId, StartTime} = create_recurring_event(CalendarId),
|
||||
Occ = add_days(StartTime, 7),
|
||||
mnesia:dirty_write(#recurrence_exception{
|
||||
master_id = MasterId,
|
||||
original_start = Occ,
|
||||
action = cancel,
|
||||
new_start = undefined
|
||||
}),
|
||||
{error, invalid_occurrence} = logic_booking:create_booking(ParticipantId, MasterId, Occ).
|
||||
|
||||
test_booking_personal_denied() ->
|
||||
OwnerId = create_test_user(user),
|
||||
ParticipantId = create_test_user(user),
|
||||
|
||||
Reference in New Issue
Block a user