Skip to content

Commit

Permalink
fix: Refactoring erroring changeset in Timer.ex. #195
Browse files Browse the repository at this point in the history
  • Loading branch information
LuchoTurtle committed Nov 14, 2022
1 parent 5f70ee9 commit 0e5a49e
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 73 deletions.
158 changes: 92 additions & 66 deletions lib/app/timer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -88,98 +88,124 @@ defmodule App.Timer do
timer_changeset_list
) do


# Getting the changeset to change in case there's an error
changeset_obj = Enum.at(timer_changeset_list, index)

try do
start = Timex.parse!(timer_start, "%Y-%m-%dT%H:%M:%S", :strftime)
stop = Timex.parse!(timer_stop, "%Y-%m-%dT%H:%M:%S", :strftime)

# Parsing the dates
{start_op, start} =
Timex.parse(timer_start, "%Y-%m-%dT%H:%M:%S", :strftime)

{stop_op, stop} = Timex.parse(timer_stop, "%Y-%m-%dT%H:%M:%S", :strftime)

# Error guards when parsing the dates
if start_op === :error do
throw(:error_invalid_start)
end

if stop_op === :error do
throw(:error_invalid_stop)
end

case NaiveDateTime.compare(start, stop) do
:lt ->

# Creates a list of all other timers to check for overlap
other_timers_list = List.delete_at(timer_changeset_list, index)

# Timer overlap verification
try do
for chs <- other_timers_list do
chs_start = chs.data.start
chs_stop = chs.data.stop

# The condition needs to FAIL (StartA <= EndB) and (EndA >= StartB)
# so no timer overlaps one another
compareStartAEndB = NaiveDateTime.compare(start, chs_stop)
compareEndAStartB = NaiveDateTime.compare(stop, chs_start)

if(
(compareStartAEndB == :lt || compareStartAEndB == :eq) &&
(compareEndAStartB == :gt || compareEndAStartB == :eq)
) do
throw(:overlap)
end
for chs <- other_timers_list do
chs_start = chs.data.start
chs_stop = chs.data.stop

# The condition needs to FAIL (StartA <= EndB) and (EndA >= StartB)
# so no timer overlaps one another
compareStartAEndB = NaiveDateTime.compare(start, chs_stop)
compareEndAStartB = NaiveDateTime.compare(stop, chs_start)

if(
(compareStartAEndB == :lt || compareStartAEndB == :eq) &&
(compareEndAStartB == :gt || compareEndAStartB == :eq)
) do
throw(:error_overlap)
end

update_timer(%{id: timer_id, start: start, stop: stop})
{:ok, []}
# {:noreply, assign(socket, editing: nil, editing_timers: [])}
catch
:overlap ->
updated_changeset_timers_list =
Timer.error_timer_changeset(
timer_changeset_list,
changeset_obj,
index,
:id,
"This timer interval overlaps with other timers. Make sure all the timers are correct and don't overlap with each other",
:update
)

{:overlap, updated_changeset_timers_list}
# {:noreply, assign(socket, editing_timers: updated_changeset_timers_list)}
end

update_timer(%{id: timer_id, start: start, stop: stop})
{:ok, []}

:eq ->
updated_changeset_timers_list =
Timer.error_timer_changeset(
timer_changeset_list,
changeset_obj,
index,
:id,
"Start or stop are equal.",
:update
)

{:start_equal_stop, updated_changeset_timers_list}
# {:noreply, assign(socket, editing_timers: updated_changeset_timers_list)}
throw(:error_start_equal_stop)

:gt ->
updated_changeset_timers_list =
Timer.error_timer_changeset(
timer_changeset_list,
changeset_obj,
index,
:id,
"Start is newer that stop.",
:update
)

{:start_greater_than_stop, updated_changeset_timers_list}
# {:noreply, assign(socket, editing_timers: updated_changeset_timers_list)}
throw(:error_start_greater_than_stop)
end
rescue
_e ->
catch
:error_invalid_start ->
updated_changeset_timers_list =
Timer.error_timer_changeset(
timer_changeset_list,
changeset_obj,
index,
:id,
"Start field has an invalid date format.",
:update
)

{:error_invalid_start, updated_changeset_timers_list}

:error_invalid_stop ->
updated_changeset_timers_list =
Timer.error_timer_changeset(
timer_changeset_list,
changeset_obj,
index,
:id,
"Stop field has an invalid date format.",
:update
)

{:error_invalid_stop, updated_changeset_timers_list}

:error_overlap ->
updated_changeset_timers_list =
Timer.error_timer_changeset(
timer_changeset_list,
changeset_obj,
index,
:id,
"This timer interval overlaps with other timers. Make sure all the timers are correct and don't overlap with each other",
:update
)

{:error_overlap, updated_changeset_timers_list}

:error_start_equal_stop ->
updated_changeset_timers_list =
Timer.error_timer_changeset(
timer_changeset_list,
changeset_obj,
index,
:id,
"Start or stop are equal.",
:update
)

{:error_start_equal_stop, updated_changeset_timers_list}

:error_start_greater_than_stop ->
updated_changeset_timers_list =
Timer.error_timer_changeset(
timer_changeset_list,
changeset_obj,
index,
:id,
"Date format invalid on either start or stop.",
"Start is newer that stop.",
:update
)

{:invalid_format, updated_changeset_timers_list}
# {:noreply, assign(socket, editing_timers: updated_changeset_timers_list)}
{:error_start_greater_than_stop, updated_changeset_timers_list}
end
end

Expand Down
10 changes: 6 additions & 4 deletions lib/app_web/live/app_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,13 @@ defmodule AppWeb.AppLive do
index = String.to_integer(index)

case Timer.update_timer_inside_changeset_list(id, timer_start, timer_stop, index, timer_changeset_list) do
{:invalid_format, updated_list} -> {:noreply, assign(socket, editing_timers: updated_list)}
{:start_greater_than_stop, updated_list} -> {:noreply, assign(socket, editing_timers: updated_list)}
{:start_equal_stop, updated_list} -> {:noreply, assign(socket, editing_timers: updated_list)}
{:overlap, updated_list} -> {:noreply, assign(socket, editing_timers: updated_list)}
{:ok, _list} -> {:noreply, assign(socket, editing: nil, editing_timers: [])}

{:error_invalid_start, updated_list} -> {:noreply, assign(socket, editing_timers: updated_list)}
{:error_invalid_stop, updated_list} -> {:noreply, assign(socket, editing_timers: updated_list)}
{:error_start_greater_than_stop, updated_list} -> {:noreply, assign(socket, editing_timers: updated_list)}
{:error_start_equal_stop, updated_list} -> {:noreply, assign(socket, editing_timers: updated_list)}
{:error_overlap, updated_list} -> {:noreply, assign(socket, editing_timers: updated_list)}
end
end

Expand Down
16 changes: 13 additions & 3 deletions test/app_web/live/app_live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -253,15 +253,25 @@ defmodule AppWeb.AppLiveTest do
"timer_stop" => start
}) =~ "Start is newer that stop."

# Trying to update with equal start greater than stop
# Trying to update with start as invalid format
render_click(view, "edit-item", %{"id" => Integer.to_string(item.id)})

assert render_submit(view, "update-item-timer", %{
"timer_id" => timer.id,
"index" => 0,
"timer_start" => "invalid",
"timer_stop" => "invalid"
}) =~ "Date format invalid on either start or stop."
"timer_stop" => stop
}) =~ "Start field has an invalid date format."

# Trying to update with stop as invalid format
render_click(view, "edit-item", %{"id" => Integer.to_string(item.id)})

assert render_submit(view, "update-item-timer", %{
"timer_id" => timer.id,
"index" => 0,
"timer_start" => start,
"timer_stop" => "invalid"
}) =~ "Stop field has an invalid date format."
end

test "update timer timer with ongoing timer ", %{conn: conn} do
Expand Down

0 comments on commit 0e5a49e

Please sign in to comment.