Skip to content

Commit

Permalink
feat: Timers and TimerController testing. #256
Browse files Browse the repository at this point in the history
  • Loading branch information
LuchoTurtle committed Jan 12, 2023
1 parent 3d56223 commit 0355e5c
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 20 deletions.
39 changes: 34 additions & 5 deletions lib/app/timer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule App.Timer do
alias __MODULE__
require Logger

@derive {Jason.Encoder, only: [:id, :start, :stop]}
@derive {Jason.Encoder, only: [:id, :start, :stop, ]}
schema "timers" do
field :start, :naive_datetime
field :stop, :naive_datetime
Expand All @@ -20,10 +20,15 @@ defmodule App.Timer do
start = get_field(changeset, :start)
stop = get_field(changeset, :stop)

if NaiveDateTime.compare(start, stop) == :gt do
add_error(changeset, :start, "cannot be later than 'stop'")
else
changeset
# If start or stop is nil, no comparison occurs.
case is_nil(stop) or is_nil(start) do
true -> changeset
false ->
if NaiveDateTime.compare(start, stop) == :gt do
add_error(changeset, :start, "cannot be later than 'stop'")
else
changeset
end
end
end

Expand All @@ -46,6 +51,30 @@ defmodule App.Timer do
"""
def get_timer!(id), do: Repo.get!(Timer, id)

@doc """
`list_timers/1` lists all the timer objects of a given item `id`.
## Examples
iex> list_timers(1)
[
%App.Timer{
id: 7,
start: ~N[2023-01-11 17:40:44],
stop: nil,
item_id: 1,
inserted_at: ~N[2023-01-11 18:01:43],
updated_at: ~N[2023-01-11 18:01:43]
}
]
"""
def list_timers(item_id) do
Timer
|> where(item_id: ^item_id)
|> order_by(:id)
|> Repo.all()
end

@doc """
`start/1` starts a timer.
Expand Down
11 changes: 3 additions & 8 deletions lib/app_web/controllers/api/timer_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule AppWeb.API.TimerController do
def index(conn, params) do
item_id = Map.get(params, "item_id")

timers = Timer.list_timers_changesets(item_id)
timers = Timer.list_timers(item_id)
json(conn, timers)
end

Expand Down Expand Up @@ -41,7 +41,7 @@ defmodule AppWeb.API.TimerController do
stop: Map.get(params, "stop")
}

case Timer.create_timer(attrs) do
case Timer.start(attrs) do

# Successfully creates item
{:ok, timer} ->
Expand Down Expand Up @@ -91,12 +91,7 @@ defmodule AppWeb.API.TimerController do
message: "Malformed request",
}

changeset_errors = traverse_errors(changeset, fn {msg, opts} ->
Regex.replace(~r"%{(\w+)}", msg, fn _, key ->
opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string()
end)
end)

changeset_errors = traverse_errors(changeset, fn {msg, _opts} -> msg end)
Map.put(errors, :errors, changeset_errors)
end
end
7 changes: 0 additions & 7 deletions test/app_web/controllers/api/item_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,4 @@ defmodule AppWeb.API.ItemControllerTest do
assert length(json_response(conn, 400)["errors"]["text"]) > 0
end
end

test "testing error traversal", %{conn: conn} do
{:ok, item} = Item.create_item(@create_attrs)
conn = put(conn, Routes.item_path(conn, :update, item.id, @invalid_attrs))

assert conn.status == 400
end
end
115 changes: 115 additions & 0 deletions test/app_web/controllers/api/timer_controller_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
defmodule AppWeb.API.TimerControllerTest do
use AppWeb.ConnCase
alias App.Timer
alias App.Item

@create_item_attrs %{person_id: 42, status: 0, text: "some text"}

@create_attrs %{item_id: 42, start: "2022-10-27T00:00:00"}
@update_attrs %{item_id: 43, start: "2022-10-28T00:00:00"}
@invalid_attrs %{item_id: nil, start: nil}

describe "index" do
test "timers", %{conn: conn} do
# Create item
{:ok, item} = Item.create_item(@create_item_attrs)

# Create timer
started = NaiveDateTime.utc_now()
{:ok, timer} = Timer.start(%{item_id: item.id, start: started})

conn = get(conn, Routes.timer_path(conn, :index, item.id))

assert conn.status == 200
assert length(json_response(conn, 200)) == 1
end
end

describe "show" do
test "specific timer", %{conn: conn} do
# Create item
{:ok, item} = Item.create_item(@create_item_attrs)

# Create timer
started = NaiveDateTime.utc_now()
{:ok, timer} = Timer.start(%{item_id: item.id, start: started})

conn = get(conn, Routes.timer_path(conn, :show, item.id, timer.id))

assert conn.status == 200
assert json_response(conn, 200)["id"] == timer.id
end

test "not found timer", %{conn: conn} do
# Create item
{:ok, item} = Item.create_item(@create_item_attrs)

conn = get(conn, Routes.timer_path(conn, :show, item.id, -1))

assert conn.status == 404
end

test "invalid id (not being an integer)", %{conn: conn} do
# Create item
{:ok, item} = Item.create_item(@create_item_attrs)

conn = get(conn, Routes.timer_path(conn, :show, item.id, "invalid"))
assert conn.status == 400
end
end

describe "create" do
test "a valid timer", %{conn: conn} do

# Create item
{:ok, item} = Item.create_item(@create_item_attrs)

# Create timer
conn = post(conn, Routes.timer_path(conn, :create, item.id, @create_attrs))

assert conn.status == 200
assert json_response(conn, 200)["start"] == Map.get(@create_attrs, "start")
end

test "an invalid timer", %{conn: conn} do
# Create item
{:ok, item} = Item.create_item(@create_item_attrs)

conn = post(conn, Routes.timer_path(conn, :create, item.id, @invalid_attrs))

assert conn.status == 400
assert length(json_response(conn, 400)["errors"]["start"]) > 0
end
end

describe "update" do
test "timer with valid attributes", %{conn: conn} do

# Create item
{:ok, item} = Item.create_item(@create_item_attrs)

# Create timer
started = NaiveDateTime.utc_now()
{:ok, timer} = Timer.start(%{item_id: item.id, start: started})

conn = put(conn, Routes.timer_path(conn, :update, item.id, timer.id, @update_attrs))

assert conn.status == 200
assert json_response(conn, 200)["start"] == Map.get(@update_attrs, :start)
end

test "timer with invalid attributes", %{conn: conn} do
# Create item
{:ok, item} = Item.create_item(@create_item_attrs)

# Create timer
started = NaiveDateTime.utc_now()
{:ok, timer} = Timer.start(%{item_id: item.id, start: started})

conn = put(conn, Routes.timer_path(conn, :update, item.id, timer.id, @invalid_attrs))

assert conn.status == 400
assert length(json_response(conn, 400)["errors"]["start"]) > 0
end
end
end

0 comments on commit 0355e5c

Please sign in to comment.