spazio-solazzo/test/spazio_solazzo/booking_system/time_slot_template_test.exs
Víctor Martínez 69f992f8f6
feat: new booking system + admin dashboard (#12)
feat: implement a new booking system and admin dashboard
2026-02-07 19:08:39 +01:00

267 lines
7.5 KiB
Elixir

defmodule SpazioSolazzo.BookingSystem.TimeSlotTemplateTest do
use ExUnit.Case, async: true
use SpazioSolazzo.DataCase
alias SpazioSolazzo.BookingSystem
setup do
{:ok, space} =
BookingSystem.create_space(
"Test Space",
"test-space",
"Test description",
10
)
%{space: space}
end
describe "create_time_slot_template/4" do
test "creates a time slot template successfully", %{space: space} do
assert {:ok, slot} =
BookingSystem.create_time_slot_template(
~T[09:00:00],
~T[10:00:00],
:monday,
space.id
)
assert slot.start_time == ~T[09:00:00]
assert slot.end_time == ~T[10:00:00]
assert slot.day_of_week == :monday
assert slot.space_id == space.id
end
test "creates templates for all days of the week", %{space: space} do
days = [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday]
for day <- days do
assert {:ok, slot} =
BookingSystem.create_time_slot_template(
~T[09:00:00],
~T[10:00:00],
day,
space.id
)
assert slot.day_of_week == day
end
end
test "prevents overlapping time slots on same day", %{space: space} do
assert {:ok, _slot1} =
BookingSystem.create_time_slot_template(
~T[09:00:00],
~T[11:00:00],
:monday,
space.id
)
assert {:error, error} =
BookingSystem.create_time_slot_template(
~T[10:00:00],
~T[12:00:00],
:monday,
space.id
)
error_messages = Ash.Error.error_descriptions(error)
assert String.contains?(
error_messages,
"time slot overlaps with existing template for this space and day."
)
end
test "allows same time slot on different days", %{space: space} do
assert {:ok, _slot1} =
BookingSystem.create_time_slot_template(
~T[09:00:00],
~T[11:00:00],
:monday,
space.id
)
assert {:ok, slot2} =
BookingSystem.create_time_slot_template(
~T[09:00:00],
~T[11:00:00],
:tuesday,
space.id
)
assert slot2.day_of_week == :tuesday
end
test "allows adjacent time slots on same day", %{space: space} do
assert {:ok, _slot1} =
BookingSystem.create_time_slot_template(
~T[09:00:00],
~T[11:00:00],
:monday,
space.id
)
assert {:ok, slot2} =
BookingSystem.create_time_slot_template(
~T[11:00:00],
~T[13:00:00],
:monday,
space.id
)
assert slot2.start_time == ~T[11:00:00]
end
test "rejects invalid day of week", %{space: space} do
assert {:error, error} =
BookingSystem.create_time_slot_template(
~T[09:00:00],
~T[10:00:00],
:invalid_day,
space.id
)
error_messages = Ash.Error.error_descriptions(error)
assert String.contains?(error_messages, "atom must be one of")
end
test "rejects end time before start time", %{space: space} do
assert {:error, error} =
BookingSystem.create_time_slot_template(
~T[10:00:00],
~T[09:00:00],
:monday,
space.id
)
error_messages = Ash.Error.error_descriptions(error)
assert String.contains?(error_messages, "must be after start_time")
end
test "rejects equal start and end times", %{space: space} do
assert {:error, error} =
BookingSystem.create_time_slot_template(
~T[10:00:00],
~T[10:00:00],
:monday,
space.id
)
error_messages = Ash.Error.error_descriptions(error)
assert String.contains?(error_messages, "must be after start_time")
end
end
describe "get_space_time_slots_by_date/2" do
setup %{space: space} do
{:ok, monday_morning} =
BookingSystem.create_time_slot_template(
~T[09:00:00],
~T[13:00:00],
:monday,
space.id
)
{:ok, monday_afternoon} =
BookingSystem.create_time_slot_template(
~T[14:00:00],
~T[18:00:00],
:monday,
space.id
)
{:ok, tuesday_slot} =
BookingSystem.create_time_slot_template(
~T[09:00:00],
~T[13:00:00],
:tuesday,
space.id
)
%{
monday_morning: monday_morning,
monday_afternoon: monday_afternoon,
tuesday_slot: tuesday_slot
}
end
test "returns time slots for specific date's day of week", %{space: space} do
monday_date = ~D[2026-02-02]
assert Date.day_of_week(monday_date) == 1
{:ok, slots} = BookingSystem.get_space_time_slots_by_date(space.id, monday_date)
assert length(slots) == 2
assert Enum.any?(slots, &(&1.start_time == ~T[09:00:00]))
assert Enum.any?(slots, &(&1.start_time == ~T[14:00:00]))
end
test "returns different slots for different days", %{space: space} do
tuesday_date = ~D[2026-02-03]
assert Date.day_of_week(tuesday_date) == 2
{:ok, slots} = BookingSystem.get_space_time_slots_by_date(space.id, tuesday_date)
assert length(slots) == 1
assert hd(slots).start_time == ~T[09:00:00]
end
test "returns empty list when no slots for that day", %{space: space} do
wednesday_date = ~D[2026-02-04]
assert Date.day_of_week(wednesday_date) == 3
{:ok, slots} = BookingSystem.get_space_time_slots_by_date(space.id, wednesday_date)
assert slots == []
end
test "handles all days of the week correctly", %{space: space} do
days_and_dates = [
{:monday, ~D[2026-02-02]},
{:tuesday, ~D[2026-02-03]},
{:wednesday, ~D[2026-02-04]},
{:thursday, ~D[2026-02-05]},
{:friday, ~D[2026-02-06]},
{:saturday, ~D[2026-02-07]},
{:sunday, ~D[2026-02-01]}
]
for {day_atom, date} <- days_and_dates do
BookingSystem.create_time_slot_template(
~T[20:00:00],
~T[21:00:00],
day_atom,
space.id
)
{:ok, slots} = BookingSystem.get_space_time_slots_by_date(space.id, date)
assert Enum.any?(slots, &(&1.start_time == ~T[20:00:00]))
end
end
test "only returns slots for specified space", %{space: space} do
{:ok, other_space} =
BookingSystem.create_space(
"Other Space",
"other-space",
"Other description",
5
)
{:ok, _other_slot} =
BookingSystem.create_time_slot_template(
~T[20:00:00],
~T[22:00:00],
:monday,
other_space.id
)
monday_date = ~D[2026-02-02]
{:ok, slots} = BookingSystem.get_space_time_slots_by_date(space.id, monday_date)
assert Enum.all?(slots, &(&1.space_id == space.id))
refute Enum.any?(slots, &(&1.start_time == ~T[20:00:00]))
end
end
end