Commit 635ea0e2 authored by Frank Rousseau's avatar Frank Rousseau
Browse files

Allow to set entries (values + date) for a given tracker

Add tracker entries routes
parent c96fe2bc
defmodule Gaja.TrackerEntries do
@moduledoc false
import Ecto
import Ecto.Query, warn: false
alias Gaja.{Tracker, TrackerEntry, Repo}
def create_tracker_entry(tracker, attrs) do
tracker
|> build_assoc(:tracker_entries)
|> TrackerEntry.changeset(attrs)
|> Repo.insert()
end
def list_tracker_entries(tracker) do
Repo.all(Ecto.assoc(tracker, :tracker_entries))
end
def get_tracker_entry(%Tracker{id: tracker_id}, id) do
TrackerEntry
|> where([t], t.id == ^id and t.tracker_id == ^tracker_id)
|> Repo.one()
end
def get_by(attrs) do
Repo.get_by(TrackerEntry, attrs)
end
def update_tracker_entry(%TrackerEntry{} = tracker_entry, attrs) do
tracker_entry
|> TrackerEntry.changeset(attrs)
|> Repo.update()
end
def delete_tracker_entry(%TrackerEntry{} = tracker_entry) do
Repo.delete(tracker_entry)
end
end
......@@ -2,6 +2,7 @@ defmodule Gaja.TrackerEntry do
@moduledoc false
use Ecto.Schema
use Gaja.Web, :model
import Ecto.Changeset
schema "tracker_entries" do
......@@ -17,6 +18,6 @@ defmodule Gaja.TrackerEntry do
def changeset(tracker, attrs) do
tracker
|> cast(attrs, [:date, :value, :value_string])
|> validate_required([:date, :value, :value_string])
|> validate_required([:date])
end
end
......@@ -18,8 +18,8 @@ defmodule Gaja.Trackers do
def get_tracker(%User{id: user_id}, id) do
Tracker
|> where([t], t.id == ^id and t.user_id == ^user_id)
|> Repo.one()
|> where([t], t.id == ^id and t.user_id == ^user_id)
|> Repo.one()
end
def update_tracker(%Tracker{} = tracker, attrs) do
......
......@@ -3,7 +3,7 @@ defmodule Gaja.Repo.Migrations.CleanTrackerRelation do
def change do
alter table(:trackers) do
add :user_id, references(:users, type: :uuid), null: false
add :user_id, references(:users, type: :binary_id), null: false
end
end
end
defmodule Gaja.Repo.Migrations.AddTrackerEntryTable do
use Ecto.Migration
def change do
create table(:tracker_entries, primary_key: false) do
add(:id, :binary_id, primary_key: true)
add(:value, :float)
add(:value_string, :string)
add(:date, :utc_datetime, default: fragment("now()"))
add(:tracker_id, references(:trackers, type: :binary_id), null: false)
timestamps()
end
create index(:tracker_entries, [:date])
end
end
......@@ -76,7 +76,7 @@ defmodule Gaja.Web.TrackerControllerTest do
test "401 for unauthorized user", %{conn: conn, user: user} do
attrs = %{
user: user,
user: user,
name: "New tracker"
}
conn = post(conn, Routes.tracker_path(conn, :create), tracker: attrs)
......
defmodule Gaja.Web.TrackerEntryControllerTest do
use Gaja.ConnCase
import Gaja.AuthCase
alias Gaja.{Trackers, TrackerEntries}
setup %{conn: conn} = config do
email = config[:login] || "default@example.com"
user = add_user(email)
tracker_attrs = %{
name: "My tracker"
}
attrs = %{
value: 8,
date: "2019-08-01T00:00:00"
}
{:ok, tracker} = Trackers.create_tracker(user, tracker_attrs)
{:ok, tracker_entry} = TrackerEntries.create_tracker_entry(tracker, attrs)
if config[:login] do
conn = conn |> add_token_conn(user)
{:ok, %{conn: conn, user: user, tracker: tracker, tracker_entry: tracker_entry}}
else
{:ok, %{conn: conn, user: user, tracker: tracker, tracker_entry: tracker_entry}}
end
end
describe "index |" do
@tag login: "bill@example.com"
test "lists all tracker entries", %{conn: conn, tracker: tracker} do
conn = get(conn, Routes.tracker_tracker_entry_path(conn, :index, tracker))
assert json_response(conn, 200)
end
test "401 for unauthorized user", %{conn: conn, tracker: tracker} do
conn = get(conn, Routes.tracker_tracker_entry_path(conn, :index, tracker))
assert json_response(conn, 401)
end
end
describe "create |" do
@tag login: "bill@example.com"
test "data is valid", %{conn: conn, tracker: tracker} do
attrs = %{
value: 8,
date: "2019-08-01T00:00:00"
}
conn = post(
conn,
Routes.tracker_tracker_entry_path(conn, :create, tracker),
attrs
)
assert json_response(conn, 201)["data"]["uuid"]
# assert TrackerEntries.get_by date: "New tracker"
assert length(TrackerEntries.list_tracker_entries(tracker)) == 2
end
@tag login: "bill@example.com"
test "data is invalid", %{conn: conn, tracker: tracker} do
attrs = %{
value: nil,
date: "2019-08-01T00:00:00"
}
conn = post(conn, Routes.tracker_tracker_entry_path(conn, :create, tracker), tracker: attrs)
assert json_response(conn, 422)["errors"] != %{}
end
test "401 for unauthorized user", %{conn: conn, tracker: tracker} do
attrs = %{
value: 8,
date: "2019-08-01T00:00:00"
}
conn = post(conn, Routes.tracker_tracker_entry_path(conn, :create, tracker), tracker: attrs)
assert json_response(conn, 401)
end
end
describe "show |" do
@tag login: "bill@example.com"
test "show tracker entry info", %{conn: conn, tracker: tracker, tracker_entry: tracker_entry} do
conn = get(conn, Routes.tracker_tracker_entry_path(conn, :show, tracker, tracker_entry))
assert json_response(conn, 200)["data"]["uuid"] == tracker_entry.id
end
test "401 for unauthorized user", %{conn: conn, tracker: tracker, tracker_entry: tracker_entry} do
conn = get(conn, Routes.tracker_tracker_entry_path(conn, :show, tracker, tracker_entry))
assert json_response(conn, 401)
end
end
describe "update |" do
@tag login: "reg@example.com"
test "data is valid", %{conn: conn, tracker: tracker, tracker_entry: tracker_entry} do
attrs = %{
value: 6.0
}
conn = put(conn, Routes.tracker_tracker_entry_path(conn, :update, tracker, tracker_entry), tracker_entry: attrs)
assert json_response(conn, 200)
updated_tracker_entry = TrackerEntries.get_tracker_entry(tracker, tracker_entry.id)
assert updated_tracker_entry.value == 6.0
end
@tag login: "reg@example.com"
test "data is invalid", %{conn: conn, tracker: tracker, tracker_entry: tracker_entry} do
invalid_attrs = %{
value: "test"
}
conn = put(conn, Routes.tracker_tracker_entry_path(conn, :update, tracker, tracker_entry), tracker_entry: invalid_attrs)
assert json_response(conn, 422)["errors"] != %{}
end
end
describe "delete |" do
@tag login: "reg@example.com"
test(
"success",
%{conn: conn, tracker: tracker, tracker_entry: tracker_entry}
) do
conn = delete(
conn,
Routes.tracker_tracker_entry_path(
conn, :delete, tracker, tracker_entry
)
)
assert response(conn, 204)
refute TrackerEntries.get_tracker_entry(tracker, tracker_entry.id)
end
test "401 for unauthorized user", %{conn: conn, tracker: tracker, tracker_entry: tracker_entry} do
conn = delete(conn, Routes.tracker_tracker_entry_path(conn, :delete, tracker, tracker_entry))
assert json_response(conn, 401)
end
end
end
defmodule Gaja.TrackerEntryController do
use Gaja.Web, :controller
import Gaja.Web.Authorize
alias Gaja.{TrackerEntry, TrackerEntries, Trackers}
action_fallback Gaja.Web.FallbackController
plug :user_check when action in [
:index, :show, :create, :update, :delete
]
def index(
%Plug.Conn{assigns: %{current_user: user}} = conn,
%{"tracker_id" => tracker_id}
) do
tracker = Trackers.get_tracker(user, tracker_id)
tracker_entries = TrackerEntries.list_tracker_entries(tracker)
render(conn, "index.json", tracker_entries: tracker_entries)
end
def show(
%Plug.Conn{assigns: %{current_user: user}} = conn,
%{"tracker_id" => tracker_id, "id" => uuid}
) do
tracker = Trackers.get_tracker(user, tracker_id)
with tracker_entry = %TrackerEntry{} <- TrackerEntries.get_tracker_entry(tracker, uuid) do
render(conn, "show.json", tracker_entry: tracker_entry)
end
end
def create(%Plug.Conn{assigns: %{current_user: user}} = conn, params) do
tracker = Trackers.get_tracker(user, params["tracker_id"])
with {:ok, tracker_entry} <- TrackerEntries.create_tracker_entry(tracker, params) do
conn
|> put_status(201)
|> render("show.json", tracker_entry: tracker_entry)
end
end
def update(%Plug.Conn{assigns: %{current_user: user}} = conn, params) do
tracker = Trackers.get_tracker(user, params["tracker_id"])
with tracker_entry = %TrackerEntry{} <- TrackerEntries.get_tracker_entry(tracker, params["id"]) do
changeset = TrackerEntries.update_tracker_entry(tracker_entry, params["tracker_entry"])
case changeset do
{:ok, tracker_entry} -> render(conn, "show.json", tracker_entry: tracker_entry)
{:error, _} -> changeset
end
end
end
def delete(%Plug.Conn{assigns: %{current_user: user}} = conn, params) do
tracker = Trackers.get_tracker(user, params["tracker_id"])
with tracker_entry = %TrackerEntry{} <- TrackerEntries.get_tracker_entry(tracker, params["id"]) do
TrackerEntries.delete_tracker_entry(tracker_entry)
conn
|> put_status(204)
|> send_resp(:no_content, "")
end
end
end
......@@ -18,13 +18,15 @@ defmodule Gaja.Router do
scope "/api", Gaja do
pipe_through [
:api,
:api,
:authenticated
]
get "/authenticated", SessionController, :index
post "/sessions", SessionController, :create
resources "/users", UserController, except: [:new, :edit]
resources "/trackers", TrackerController, except: [:new, :edit]
resources "/trackers", TrackerController, except: [:new, :edit] do
resources "/entries", TrackerEntryController, except: [:new, :edit]
end
end
end
defmodule Gaja.TrackerEntryView do
use Gaja.Web, :view
def render("index.json", %{tracker_entries: tracker_entries}) do
%{data: render_many(tracker_entries, Gaja.TrackerEntryView, "tracker_entry.json")}
end
def render("show.json", %{tracker_entry: tracker_entry}) do
%{data: render_one(tracker_entry, Gaja.TrackerEntryView, "tracker_entry.json")}
end
def render("tracker_entry.json", %{tracker_entry: tracker_entry}) do
%{
uuid: tracker_entry.id,
date: tracker_entry.date,
value: tracker_entry.value,
value_string: tracker_entry.value_string
}
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment