Skip to content

Instantly share code, notes, and snippets.

@cpjolicoeur
Created August 22, 2019 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cpjolicoeur/6af1a78fec5992c81a50c4ce0b434f99 to your computer and use it in GitHub Desktop.
Save cpjolicoeur/6af1a78fec5992c81a50c4ce0b434f99 to your computer and use it in GitHub Desktop.
defmodule DaydreamWeb.API.UnitAvailabilityControllerTest do
use DaydreamWeb.ConnCase
alias Daydream.{Fixtures, HomeShare, Repo}
alias Daydream.HomeShare.{UnitAvailability}
alias Daydream.Accounts.{Tenant}
import Ecto.Query, only: [from: 2]
@today Date.utc_today()
def batch_unit_availability_fixture(count, tenant, attrs \\ %{}) do
for n <- 1..count do
offset = n * 2
defaults = %{
"start_date" => Date.add(@today, offset),
"end_date" => Date.add(@today, offset + 1)
}
Fixtures.create_unit_availability(Enum.into(defaults, attrs), {:tenant, tenant})
end
end
setup %{conn: conn} do
tenant = Fixtures.create_tenant()
conn = start_session(conn, tenant)
{:ok, conn: conn, tenant: tenant}
end
describe "show" do
test "lists all of tenant's unit availabilities", %{conn: conn, tenant: tenant} do
batch_unit_availability_fixture(15, tenant)
conn = get(conn, Routes.unit_availability_path(conn, :show))
%{"unit_availabilities" => availabilities} = json_response(conn, 200)
assert length(availabilities) == 15
assert %{"start_date" => _, "end_date" => _, "locked_at" => _} = hd(availabilities)
end
test "does not list unit availabilities for other tenants", %{conn: conn, tenant: tenant} do
other_tenant = Fixtures.create_tenant(%{email_address: "other_tenant@test.test"})
refute tenant.id == other_tenant.id
batch_unit_availability_fixture(10, other_tenant)
conn = get(conn, Routes.unit_availability_path(conn, :show))
%{"unit_availabilities" => availabilities} = json_response(conn, 200)
assert availabilities == []
end
end
describe "create with dates list" do
test "create with a single date that doesn't overlap any existing availability",
%{
conn: conn,
tenant: tenant
} do
post(conn, Routes.unit_availability_path(conn, :create), dates: ["2025-01-01"])
assert length(HomeShare.list_unit_availabilities(tenant)) == 1
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-01]
)
end
end
describe "create with dates list : with a continguous set of days that overlap no existing availability" do
test "with only two dates being added",
%{
conn: conn,
tenant: tenant
} do
post(conn, Routes.unit_availability_path(conn, :create), dates: ["2025-01-01", "2025-01-02"])
assert length(HomeShare.list_unit_availabilities(tenant)) == 1
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-02]
)
end
test "with three of more consecutive dates being added",
%{
conn: conn,
tenant: tenant
} do
post(conn, Routes.unit_availability_path(conn, :create),
dates: ["2025-01-01", "2025-01-02", "2025-01-03", "2025-01-04"]
)
assert length(HomeShare.list_unit_availabilities(tenant)) == 1
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-04]
)
end
end
describe "create with dates list : with a non-sequential set of days that overlap no existing availability" do
test "with two nonsequential dates",
%{
conn: conn,
tenant: tenant
} do
post(conn, Routes.unit_availability_path(conn, :create), dates: ["2025-01-01", "2025-01-03"])
assert length(HomeShare.list_unit_availabilities(tenant)) == 2
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-01]
)
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-03] and
u.end_date == ^~D[2025-01-03]
)
end
test "with two sequential dates and one nonsequential date",
%{
conn: conn,
tenant: tenant
} do
post(conn, Routes.unit_availability_path(conn, :create),
dates: ["2025-01-01", "2025-01-03", "2025-01-04"]
)
assert length(HomeShare.list_unit_availabilities(tenant)) == 2
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-01]
)
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-03] and
u.end_date == ^~D[2025-01-04]
)
end
test "with two sets of sequential dates that are non-sequential to one another",
%{
conn: conn,
tenant: tenant
} do
post(conn, Routes.unit_availability_path(conn, :create),
dates: ["2025-01-01", "2025-01-02", "2025-01-04", "2025-01-05"]
)
assert length(HomeShare.list_unit_availabilities(tenant)) == 2
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-02]
)
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-04] and
u.end_date == ^~D[2025-01-05]
)
end
test "create with a single date which abutts an existing unit availability's end date",
%{
conn: conn,
tenant: tenant
} do
Fixtures.create_unit_availability(
%{"start_date" => ~D[2025-01-01], "end_date" => ~D[2025-01-01]},
{:tenant, tenant}
)
post(conn, Routes.unit_availability_path(conn, :create), dates: ["2025-01-02"])
assert length(HomeShare.list_unit_availabilities(tenant)) == 1
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-02]
)
end
test "create with a single date which abutts an existing unit availability's start date",
%{
conn: conn,
tenant: tenant
} do
Fixtures.create_unit_availability(
%{"start_date" => ~D[2025-01-02], "end_date" => ~D[2025-01-02]},
{:tenant, tenant}
)
post(conn, Routes.unit_availability_path(conn, :create), dates: ["2025-01-01"])
assert length(HomeShare.list_unit_availabilities(tenant)) == 1
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-02]
)
end
test "create with a single date which abutts then end and start date of two unit availabilities",
%{
conn: conn,
tenant: tenant
} do
Fixtures.create_unit_availability(
%{"start_date" => ~D[2025-01-01], "end_date" => ~D[2025-01-01]},
{:tenant, tenant}
)
Fixtures.create_unit_availability(
%{"start_date" => ~D[2025-01-03], "end_date" => ~D[2025-01-03]},
{:tenant, tenant}
)
post(conn, Routes.unit_availability_path(conn, :create), dates: ["2025-01-02"])
assert length(HomeShare.list_unit_availabilities(tenant)) == 1
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-03]
)
end
test "create with a single date which does not abutt any existing unit availability",
%{
conn: conn,
tenant: tenant
} do
Fixtures.create_unit_availability(
%{"start_date" => ~D[2025-01-01], "end_date" => ~D[2025-01-01]},
{:tenant, tenant}
)
post(conn, Routes.unit_availability_path(conn, :create), dates: ["2025-01-03"])
assert length(HomeShare.list_unit_availabilities(tenant)) == 2
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-01]
)
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-03] and
u.end_date == ^~D[2025-01-03]
)
end
end
describe "create with dates list : with a sequential set of dates which abutt an existing unit availability" do
test "with only two dates being added",
%{
conn: conn,
tenant: tenant
} do
Fixtures.create_unit_availability(
%{"start_date" => ~D[2025-01-03], "end_date" => ~D[2025-01-03]},
{:tenant, tenant}
)
post(conn, Routes.unit_availability_path(conn, :create), dates: ["2025-01-01", "2025-01-02"])
assert length(HomeShare.list_unit_availabilities(tenant)) == 1
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-03]
)
end
test "with two sets of sequential dates that surround an existing unit availability",
%{
conn: conn,
tenant: tenant
} do
Fixtures.create_unit_availability(
%{"start_date" => ~D[2025-01-03], "end_date" => ~D[2025-01-03]},
{:tenant, tenant}
)
post(conn, Routes.unit_availability_path(conn, :create),
dates: ["2025-01-01", "2025-01-02", "2025-01-04", "2025-01-05"]
)
assert length(HomeShare.list_unit_availabilities(tenant)) == 1
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-05]
)
end
test "with two sets of sequential dates that surround one existing unit availability and abutt another",
%{
conn: conn,
tenant: tenant
} do
Fixtures.create_unit_availability(
%{"start_date" => ~D[2025-01-03], "end_date" => ~D[2025-01-03]},
{:tenant, tenant}
)
Fixtures.create_unit_availability(
%{"start_date" => ~D[2025-01-06], "end_date" => ~D[2025-01-06]},
{:tenant, tenant}
)
post(conn, Routes.unit_availability_path(conn, :create),
dates: ["2025-01-01", "2025-01-02", "2025-01-04", "2025-01-05"]
)
assert length(HomeShare.list_unit_availabilities(tenant)) == 1
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-06]
)
end
test "with two sets of sequential dates, one which abutts an existing unit availabilty and one set which does not",
%{
conn: conn,
tenant: tenant
} do
Fixtures.create_unit_availability(
%{"start_date" => ~D[2025-01-03], "end_date" => ~D[2025-01-03]},
{:tenant, tenant}
)
post(conn, Routes.unit_availability_path(conn, :create),
dates: ["2025-01-01", "2025-01-02", "2025-01-05", "2025-01-05"]
)
assert length(HomeShare.list_unit_availabilities(tenant)) == 2
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-01] and
u.end_date == ^~D[2025-01-03]
)
assert Repo.exists?(
from u in UnitAvailability,
where:
u.start_date == ^~D[2025-01-05] and
u.end_date == ^~D[2025-01-05]
)
end
end
describe "create with unit_availability params" do
test "creates a new unit availability with valid date input", %{conn: conn, tenant: _tenant} do
conn =
post(conn, Routes.unit_availability_path(conn, :create),
unit_availability: %{"start_date" => "2025-01-01", "end_date" => "2025-01-10"}
)
%{"unit_availabilities" => [%{"start_date" => "2025-01-01", "end_date" => "2025-01-10"}]} =
json_response(conn, 200)
end
test "doesnt allow manually setting tenant_id from the client API", %{
conn: conn,
tenant: tenant
} do
spoofed_tenant_id = tenant.id + 100
conn =
post(conn, Routes.unit_availability_path(conn, :create),
unit_availability: %{
"start_date" => "2025-01-01",
"end_date" => "2025-01-10",
"tenant_id" => spoofed_tenant_id
}
)
%{"unit_availabilities" => [%{"start_date" => "2025-01-01", "end_date" => "2025-01-10"}]} =
json_response(conn, 200)
assert 1 == length(HomeShare.list_unit_availabilities(tenant))
assert Enum.empty?(HomeShare.list_unit_availabilities(%Tenant{id: spoofed_tenant_id}))
end
test "fails to create a new unit availability with invalid date input", %{
conn: conn,
tenant: _tenant
} do
conn = post(conn, Routes.unit_availability_path(conn, :create), unit_availability: %{})
%{"error" => _, "metadata" => meta} = json_response(conn, 409)
assert %{"end_date" => _, "start_date" => _} = meta
conn =
post(conn, Routes.unit_availability_path(conn, :create),
unit_availability: %{"start_date" => "2025-01-01"}
)
%{"metadata" => meta} = json_response(conn, 409)
assert %{"end_date" => _} = meta
refute Map.has_key?(meta, "start_date")
conn =
post(conn, Routes.unit_availability_path(conn, :create),
unit_availability: %{"start_date" => "2025-09-01", "end_date" => "2025-01-01"}
)
%{"metadata" => meta} = json_response(conn, 409)
assert %{"end_date" => [err_msg]} = meta
assert Regex.match?(~r/must be later than/, err_msg)
refute Map.has_key?(meta, "start_date")
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment