Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard tests and changes found in QA #6

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

GPATH
GRTAGS
GTAGS
10 changes: 10 additions & 0 deletions apps/api/lib/api_web/controllers/api/v1/fallback_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ defmodule ApiWeb.Api.V1.FallbackController do
|> render_errors(%{status: "401", detail: "Unauthorized"})
end

def call(conn, {:error, %Ecto.Changeset{errors: errors}}) do
conn
|> put_status(:bad_request)
|> render_errors(%{status: "400", detail: format_changest_errors(errors)})
end

def call(conn, {:error, reason}) do
conn
|> put_status(:bad_request)
Expand All @@ -44,4 +50,8 @@ defmodule ApiWeb.Api.V1.FallbackController do
|> render("errors.json-api", data: data)
end

defp format_changest_errors(errors) do
Enum.map(errors, fn({key, {val, _}}) -> "#{key} #{val}" end)
end

end
1 change: 0 additions & 1 deletion apps/api/lib/api_web/views/dashboard_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ defmodule ApiWeb.Api.V1.DashboardView do
has_many :widgets,
serializer: ApiWeb.Api.V1.WidgetView,
include: true

end
4 changes: 3 additions & 1 deletion apps/core/lib/core/data/dashboard.ex
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
defmodule Core.Data.Dashboard do
use Core.Data.Query, schema: Core.Schemas.Dashboard
use Core.Data.Query,
schema: Core.Schemas.Dashboard,
preloads: [:author, [widgets: [:author, :data_sources]]]
end
38 changes: 32 additions & 6 deletions apps/core/lib/core/data/query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,43 @@ defmodule Core.Data.Query do

defmacro __using__(opts \\ []) do
schema = opts[:schema] || __CALLER__.module
preloads = opts[:preloads] || []
quote do
alias Core.Repo
alias unquote(schema)

import Ecto.Query, only: [from: 2]

@type t :: %unquote(schema){}
@behaviour Core.Data.Query

def all(repo \\ Repo) do
unquote(schema)
from(m in unquote(schema), where: m.deleted == false)
|> repo.all()
|> repo.preload(unquote(preloads))
end

def get(id, repo \\ Repo)
def get(id, repo) when is_binary(id) do
repo.get_by(unquote(schema), %{id: id})
try do
result = unquote(schema)
|> repo.get_by(%{id: id})
|> repo.preload(unquote(preloads))

{:ok, result}
rescue
error ->
{:error, "Invalid #{inspect error.type} with value #{inspect error.value}"}
end
end
def get(_id, _repo), do: nil
def get(_id, _repo), do: {:ok, nil}

def upsert(params, repo \\ Repo) do
with %unquote(schema){} = model <- get(params["id"], repo),
with {:ok, %unquote(schema){} = model} <- get(params["id"], repo),
{:ok, %unquote(schema){}} = result <- update(model, params, repo) do
result
else
nil ->
{:ok, nil} ->
create(params, repo)
{:error, %Ecto.Changeset{}} = changeset_error ->
changeset_error
Expand All @@ -53,23 +66,36 @@ defmodule Core.Data.Query do
"id" => id,
"deleted" => true,
"deleted_at" => DateTime.utc_now()
} |> upsert(repo)
}
|> upsert(repo)
|> case do
{:ok, %unquote(schema){}} -> :ok
error -> error
end
end

defp update(%unquote(schema){} = author, params, repo) do
author
|> unquote(schema).changeset(params)
|> repo.update()
|> preload(repo)
end
defoverridable [update: 3]

defp create(params, repo) do
%unquote(schema){}
|> unquote(schema).changeset(params)
|> repo.insert()
|> preload(repo)
end
defoverridable [create: 2]

defp preload({:ok, model}, repo) do
{:ok, repo.preload(model, unquote(preloads))}
end

defp preload(error, _repo), do: error

end
end
end
4 changes: 3 additions & 1 deletion apps/core/lib/core/data/widget.ex
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
defmodule Core.Data.Widget do
use Core.Data.Query, schema: Core.Schemas.Widget
use Core.Data.Query,
schema: Core.Schemas.Widget,
preloads: [:author, :data_sources]
end
3 changes: 1 addition & 2 deletions apps/core/lib/core/schemas/author.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ defmodule Core.Schemas.Author do
"""

@unique_index :index_unique_active_authors_idx
@unique_error "already exists"

@primary_key {:id, :binary_id, autogenerate: true}

Expand All @@ -29,6 +28,6 @@ defmodule Core.Schemas.Author do
model
|> cast(params, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
|> unique_constraint(:author, name: @unique_index, message: @unique_error)
|> unique_constraint(:username, name: @unique_index)
end
end
6 changes: 3 additions & 3 deletions apps/core/lib/core/schemas/dashboard.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ defmodule Core.Schemas.Dashboard do
belongs_to :author, Author, type: Ecto.UUID

has_many :dashboard_widgets, DashboardWidget, on_delete: :delete_all, on_replace: :delete
has_many :widgets, through: [:dashboard_widgets, :widgets]
has_many :widgets, through: [:dashboard_widgets, :widget]

timestamps type: :utc_datetime
end
Expand All @@ -40,13 +40,13 @@ defmodule Core.Schemas.Dashboard do

def changeset(model, params \\ %{})

def changeset(model, %{"dashboard_widgets" => widgets} = params) when is_list(widgets) do
def changeset(model, %{"dashboard_widgets" => dashboard_widgets} = params) when is_list(dashboard_widgets) do
model
|> cast(params, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
|> foreign_key_constraint(:author_id)
|> unique_constraint(:dashboard, name: @unique_index, message: @unique_error)
|> put_assoc(:dashboard_widgets, params["dashboard_widgets"])
|> cast_assoc(:dashboard_widgets, dashboard_widgets)
end

def changeset(model, params) do
Expand Down
2 changes: 1 addition & 1 deletion apps/core/lib/core/schemas/widget.ex
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ defmodule Core.Schemas.Widget do
|> validate_required(@required_fields)
|> foreign_key_constraint(:author_id)
|> unique_constraint(:widget, name: @unique_index, message: @unique_error)
|> put_assoc(:widget_data_sources, params["widget_data_sources"])
|> cast_assoc(:widget_data_sources, data_sources)
end

def changeset(model, params) do
Expand Down
18 changes: 14 additions & 4 deletions apps/core/test/core/data/author_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ defmodule Core.Data.AuthorTest do

alias Core.Data.Author

test "get an author by id" do
assert {:ok, author} = Author.upsert(%{"username" => "bob-dobbs"})
assert {:ok, author} == Author.get(author.id)
end

test "create a new author with valid params" do
assert [] = Author.all()
assert {:ok, author} = Author.upsert(%{"username" => "bob-dobbs"})
Expand All @@ -28,10 +33,15 @@ defmodule Core.Data.AuthorTest do
{:ok, author} = Author.upsert(%{"username" => "bob-dobbs"})
refute author.deleted
refute author.deleted_at
assert {:ok, deleted} = Author.delete(author.id)
assert deleted.deleted
assert deleted.deleted_at
assert [deleted] == Author.all()
assert :ok = Author.delete(author.id)
assert [] = Author.all()
end

test "get an author with bad id" do
assert {:error, "Invalid :binary_id with value \"1\""} = Author.delete("1")
end

test "delete an author with bad id" do
assert {:error, "Invalid :binary_id with value \"1\""} = Author.delete("1")
end
end
56 changes: 56 additions & 0 deletions apps/core/test/core/data/dashboard_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
defmodule Core.Data.DashboardTest do
use Core.DataCase

@valid_attrs %{"name" => "Dashboard 1", "slug" => "dashboard-1"}

import Core.DataHelper, only: [generate_author: 0, generate_widget: 1]

setup do
author = generate_author()
widget = generate_widget(author)
{:ok, [author: author, widget: widget]}
end

alias Core.Data.Dashboard

test "get an dashboard by id", %{author: author, widget: widget} do
attrs = Map.merge(@valid_attrs, %{"author_id" => author.id, "dashboard_widgets" => [%{"widget_id" => widget.id}]} )
assert {:ok, dashboard} = Dashboard.upsert(attrs)
assert {:ok, dashboard} == Dashboard.get(dashboard.id)
end

test "create a new dashboard with valid params", %{author: author, widget: widget} do
assert [] = Dashboard.all()
attrs = Map.merge(@valid_attrs, %{"author_id" => author.id, "dashboard_widgets" => [%{"widget_id" => widget.id}]} )
assert {:ok, dashboard} = Dashboard.upsert(attrs)
assert dashboard.widgets
assert [dashboard] == Dashboard.all()
end

test "edit an existing dashboard with valid params", %{author: author, widget: widget} do
assert [] = Dashboard.all()
attrs = Map.merge(@valid_attrs, %{"author_id" => author.id})
assert {:ok, dashboard} = Dashboard.upsert(attrs)
refute dashboard.image_src
assert {:ok, updated} = Dashboard.upsert(%{"id" => dashboard.id, "description" => "Updated description"})
assert updated.id == dashboard.id
assert updated.description == "Updated description"
assert [updated] == Dashboard.all()
end

test "delete an existing dashboard" do
{:ok, dashboard} = Dashboard.upsert(%{"username" => "bob-dobbs"})
refute dashboard.deleted
refute dashboard.deleted_at
assert :ok = Dashboard.delete(dashboard.id)
assert [] = Dashboard.all()
end

test "get an dashboard with bad id" do
assert {:error, "Invalid :binary_id with value \"1\""} = Dashboard.delete("1")
end

test "delete an dashboard with bad id" do
assert {:error, "Invalid :binary_id with value \"1\""} = Dashboard.delete("1")
end
end
2 changes: 1 addition & 1 deletion apps/core/test/core/schemas/author_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ defmodule Core.Schemas.AuthorTest do
|> Author.changeset(@valid_attrs)
|> Repo.insert

assert changeset.errors == [author: {"already exists", []}]
assert changeset.errors == [username: {"has already been taken", []}]
end
end