Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions lib/util/util.ex
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,8 @@ defmodule Util do

@doc """

Parses a string into a valid date, or returns an error.
Parses an ISO date string or a year/month parameter map into a valid date, or
returns an error.

## Examples
iex> Util.parse_valid_date("2025-12-25")
Expand All @@ -474,8 +475,11 @@ defmodule Util do
iex> Util.parse_valid_date("2025-13-35")
{:error, :invalid_date}

iex> Util.parse_valid_date(%{"year" => "2025", "month" => "7"})
{:ok, ~D[2025-07-01]}

"""
@spec parse_valid_date(String.t()) :: {:ok, Date.t()} | {:error, any}
@spec parse_valid_date(String.t() | map) :: {:ok, Date.t()} | {:error, any}
def parse_valid_date(str) when is_binary(str) do
with {:ok, date} <- Date.from_iso8601(str) do
if Timex.is_valid?(date) do
Expand All @@ -486,6 +490,17 @@ defmodule Util do
end
end

def parse_valid_date(%{"year" => year, "month" => month})
when is_binary(year) and is_binary(month) do
with {year, ""} <- Integer.parse(year),
{month, ""} <- Integer.parse(month),
{:ok, date} <- Date.new(year, month, 1) do
{:ok, date}
else
_ -> {:error, :invalid_date}
end
end

def parse_valid_date(_) do
{:error, :invalid_date}
end
Expand Down
7 changes: 7 additions & 0 deletions test/dotcom_web/controllers/event_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ defmodule DotcomWeb.EventControllerTest do
assert %{year: 2020, month: 5} = conn.assigns
end

test "assigns month and year based on nested date query params", %{conn: conn} do
conn = get(conn, event_path(conn, :index, date: [month: 7, year: 2023]))

assert conn.status == 200
assert %{year: 2023, month: 7} = conn.assigns
end

test "renders a list of events", %{conn: conn} do
conn = get(conn, event_path(conn, :index))
assert conn.assigns.year == 2019
Expand Down
10 changes: 10 additions & 0 deletions test/util/util_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,16 @@ defmodule UtilTest do
assert {:error, :invalid_date} == Util.parse_valid_date("2020-02-31")
end

test "parses valid year and month parameters" do
assert {:ok, ~D[2023-07-01]} ==
Util.parse_valid_date(%{"month" => "7", "year" => "2023"})
end

test "returns an error for invalid year and month parameters" do
assert {:error, :invalid_date} ==
Util.parse_valid_date(%{"month" => "13", "year" => "2023"})
end

test "returns an error for a argument of the wrong type" do
assert {:error, :invalid_date} == Util.parse_valid_date(%{foo: "bar"})
end
Expand Down
Loading