Skip to content

Commit

Permalink
add test and code to stop a timer dwyl/app#265 #89
Browse files Browse the repository at this point in the history
  • Loading branch information
nelsonic committed Jul 11, 2022
1 parent 32bce85 commit c47f811
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 20 deletions.
32 changes: 28 additions & 4 deletions lib/app/timer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,46 @@ defmodule App.Timer do
|> validate_required([:item_id, :start])
end

@doc """
`get_timer/1` gets a single Timer.
Raises `Ecto.NoResultsError` if the Timer does not exist.
## Examples
iex> get_timer!(123)
%Timer{}
"""
def get_timer!(id), do: Repo.get!(Timer, id)


@doc """
`start/1` starts a timer.
## Examples
iex> start(%{item_id: 1, })
{:ok, %Timer{}}
iex> create_item(%{item_id: nil})
{:error, %Ecto.Changeset{}}
{:ok, %Timer{start: ~N[2022-07-11 04:20:42]}}
"""
def start(attrs \\ %{}) do
%Timer{}
|> changeset(attrs)
|> Repo.insert()
end

@doc """
`stop/1` stops a timer.
## Examples
iex> stop(%{id: 1})
{:ok, %Timer{end: ~N[2022-07-11 05:15:31], etc.}}
"""
def stop(attrs \\ %{}) do
get_timer!(attrs.id)
|> changeset(%{end: NaiveDateTime.utc_now})
|> Repo.update()
end
end
47 changes: 42 additions & 5 deletions lib/app_web/live/app_live.ex
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
defmodule AppWeb.AppLive do
use AppWeb, :live_view
alias App.Item
alias App.{Item, Timer}

@topic "live"

@impl true
def mount(_params, _session, socket) do
# subscribe to the channel
if connected?(socket), do: AppWeb.Endpoint.subscribe(@topic)
{:ok, assign(socket, items: Item.list_items(), editing: nil)}
{:ok, assign(socket, items: Item.list_items(), editing: nil, timer: %Timer{})}
end

@impl true
def handle_event("create", %{"text" => text}, socket) do
Item.create_item(%{text: text, person_id: 1, status_code: 2})
socket = assign(socket, items: Item.list_items(), active: %Item{})
socket = assign(socket, items: Item.list_items(), active: %Item{}, timer: %Timer{})
AppWeb.Endpoint.broadcast_from(self(), @topic, "update", socket.assigns)
{:noreply, socket}
end
Expand All @@ -25,21 +25,58 @@ defmodule AppWeb.AppLive do
status = if Map.has_key?(data, "value"), do: 4, else: 3
item = Item.get_item!(Map.get(data, "id"))
Item.update_item(item, %{id: item.id, status_code: status})
socket = assign(socket, items: Item.list_items(), active: %Item{})
socket = assign(socket, items: Item.list_items(), active: %Item{}, timer: %Timer{})
AppWeb.Endpoint.broadcast_from(self(), @topic, "update", socket.assigns)
{:noreply, socket}
end

@impl true
def handle_event("delete", data, socket) do
Item.delete_item(Map.get(data, "id"))
socket = assign(socket, items: Item.list_items(), active: %Item{})
socket = assign(socket, items: Item.list_items(), active: %Item{}, timer: %Timer{})
AppWeb.Endpoint.broadcast_from(self(), @topic, "delete", socket.assigns)
{:noreply, socket}
end

@impl true
def handle_event("start", data, socket) do
# Toggle the status of the item between 3 (:active) and 4 (:done)
# status = if Map.has_key?(data, "value"), do: 4, else: 3
item = Item.get_item!(Map.get(data, "id"))
# Item.update_item(item, %{id: item.id, status_code: status})
{:ok, timer} = Timer.start(%{item_id: item.id, person_id: 1, start: NaiveDateTime.utc_now})
IO.inspect(timer)

socket = assign(socket, items: Item.list_items(), active: %Item{}, timer: timer)
AppWeb.Endpoint.broadcast_from(self(), @topic, "start", socket.assigns)
{:noreply, socket}
end

@impl true
def handle_event("stop", data, socket) do
# Toggle the status of the item between 3 (:active) and 4 (:done)
# status = if Map.has_key?(data, "value"), do: 4, else: 3
# item = Item.get_item!(Map.get(data, "id"))
# IO.inspect(data, label: "data")
timer_id = Map.get(data, "timerid")
# IO.inspect(timer_id, label: "timer_id")
# Item.update_item(item, %{id: item.id, status_code: status})
{:ok, timer} = Timer.stop(%{id: timer_id})
# IO.inspect(timer)

socket = assign(socket, items: Item.list_items(), active: %Item{}, timer: timer)
AppWeb.Endpoint.broadcast_from(self(), @topic, "start", socket.assigns)
{:noreply, socket}
end

# helper function that checks for status 4 (:done)
def done?(item) do
not is_nil(item.status_code) and item.status_code == 4
end

def started?(item, timer) do
# IO.inspect(item, label: "item")
# IO.inspect(timer, label: "timer")
item.id == timer.item_id
end
end
31 changes: 24 additions & 7 deletions lib/app_web/live/app_live.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class="w-full py-2 px-2 text-slate-800 text-3xl
bg-white bg-clip-padding
transition ease-in-out
border border-b border-slate-200
focus:border-none focus:outline-none"
name="text"
placeholder="What is on your mind?"
Expand All @@ -21,25 +22,41 @@
<ul class="w-full">
<%= for item <- @items do %>
<li data-id={item.id}
class="mt-2 flex w-full border-t border-slate-200 py-2">
class="mt-2 flex w-full border-t border-slate-200 py-2">

<%= if done?(item) do %>
<input type="checkbox" phx-value-id={item.id} phx-click="toggle"
class="flex-none p-4 m-2 form-checkbox text-slate-400"
checked
/>
checked />
<label class="w-full text-slate-400 m-2 line-through">
<%= item.text %>
</label>
<button class="bg-red-600 text-white rounded-xl px-2 py-2 mr-2 mt-2 h-10"
phx-click="delete" phx-value-id={item.id}>
Delete
</button>
<% else %>
<input type="checkbox" phx-value-id={item.id} phx-click="toggle"
class="flex-none p-4 m-2 form-checkbox hover:text-slate-600"
/>
class="flex-none p-4 m-2 form-checkbox hover:text-slate-600" />
<label class="w-full flex-auto text-slate-800 m-2">
<%= item.text %>
</label>

<%= if started?(item, @timer) do %>
<!-- render the counting timer! -->


<button class="bg-blue-600 text-white rounded-xl px-2 py-2 mr-2 mt-2 h-10"
phx-click="stop" phx-value-id={item.id} phx-value-timerid={@timer.id}>
Stop
</button>
<% else %>
<button class="bg-green-600 text-white rounded-xl px-2 py-2 mr-2 mt-2 h-10"
phx-click="start" phx-value-id={item.id}>
Start
</button>
<% end %>
<% end %>
<button class="bg-green-600 text-white rounded-xl px-2 py-2 mr-2 mt-2 h-10"
phx-click="delete" phx-value-id={item.id}>Start</button>
</li>
<% end %>
</ul>
Expand Down
5 changes: 3 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,15 @@ defmodule App.MixProject do
{:jason, "~> 1.2"},
{:plug_cowboy, "~> 2.5"},

# Easily Encrypt Senstive Data: github.com/dwyl/fields
{:fields, "~> 2.9"},
# Auth with ONE Environment Variable™: github.com/dwyl/auth_plug
{:auth_plug, "~> 1.4"},
# Easily Encrypt Senstive Data: github.com/dwyl/fields
{:fields, "~> 2.9"},
# Useful functions: github.com/dwyl/useful
{:useful, "~> 1.0.8"},
# Statuses: github.com/dwyl/statuses
{:statuses, "~> 1.1.1"},

# create docs on localhost by running "mix docs"
{:ex_doc, "~> 0.22.6", only: :dev, runtime: false},
# Track test coverage
Expand Down
17 changes: 16 additions & 1 deletion test/app/timer_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,28 @@ defmodule App.TimerTest do
item
end

test "Timer.start!/1 returns timer that has been started" do
test "Timer.start/1 returns timer that has been started" do
item = item_fixture(@valid_item_attrs)
assert Item.get_item!(item.id) == item

started = NaiveDateTime.utc_now
{:ok, timer} = Timer.start(%{item_id: item.id, person_id: 1, start: started})
assert NaiveDateTime.diff(timer.start, started) == 0
end

test "Timer.stop/1 stops the timer that had been started" do
item = item_fixture(@valid_item_attrs)
assert Item.get_item!(item.id) == item

started = NaiveDateTime.utc_now
{:ok, timer} = Timer.start(%{item_id: item.id, person_id: 1, start: started})
assert NaiveDateTime.diff(timer.start, started) == 0

IO.puts "waiting 1 second ... " ; :timer.sleep(1000); IO.puts "done"

ended = NaiveDateTime.utc_now
{:ok, timer} = Timer.stop(%{id: timer.id, end: ended})
assert NaiveDateTime.diff(timer.end, timer.start) == 1
end
end
end
20 changes: 19 additions & 1 deletion test/app_web/live/app_live_test.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
defmodule AppWeb.AppLiveTest do
use AppWeb.ConnCase
alias App.Item
alias App.{Item, Timer}
import Phoenix.LiveViewTest

test "disconnected and connected render", %{conn: conn} do
Expand Down Expand Up @@ -35,4 +35,22 @@ defmodule AppWeb.AppLiveTest do
updated_item = Item.get_item!(item.id)
assert updated_item.status_code == 6
end

test "start a timer", %{conn: conn} do
{:ok, item} = Item.create_item(%{text: "Get Fancy!", person_id: 1, status_code: 2})
assert item.status_code == 2

{:ok, view, _html} = live(conn, "/")
assert render_click(view, :start, %{"id" => item.id}) =~ "stop"
end

test "stop a timer", %{conn: conn} do
{:ok, item} = Item.create_item(%{text: "Get Fancy!", person_id: 1, status_code: 2})
assert item.status_code == 2
started = NaiveDateTime.utc_now
{:ok, timer} = Timer.start(%{item_id: item.id, start: started})

{:ok, view, _html} = live(conn, "/")
assert render_click(view, :stop, %{"id" => item.id, "timerid" => timer.id}) =~ "mind"
end
end

0 comments on commit c47f811

Please sign in to comment.