write first test and let changeset errors return error json in controller
This commit is contained in:
parent
89c2a99283
commit
d32dc8c2cb
|
@ -0,0 +1,67 @@
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [{
|
||||||
|
"label": "mix test",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mix",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--exclude",
|
||||||
|
"integration",
|
||||||
|
"--exclude",
|
||||||
|
"feature",
|
||||||
|
"--color"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"requireFiles": [
|
||||||
|
"test/**/test_helper.exs",
|
||||||
|
"test/**/*_test.exs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"problemMatcher": "$mixTestFailure"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "mix test file",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mix",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"${relativeFile}",
|
||||||
|
"--color",
|
||||||
|
"--trace"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"requireFiles": [
|
||||||
|
"test/**/test_helper.exs",
|
||||||
|
"test/**/*_test.exs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"problemMatcher": "$mixTestFailure"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "mix test focused",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mix",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"${relativeFile}:${lineNumber}",
|
||||||
|
"--color",
|
||||||
|
"--trace"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"requireFiles": [
|
||||||
|
"test/**/test_helper.exs",
|
||||||
|
"test/**/*_test.exs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"problemMatcher": "$mixTestFailure",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -10,6 +10,8 @@ use Mix.Config
|
||||||
config :entendu,
|
config :entendu,
|
||||||
ecto_repos: [Entendu.Repo]
|
ecto_repos: [Entendu.Repo]
|
||||||
|
|
||||||
|
config :entendu, Entendu.Repo, migration_primary_key: [type: :uuid]
|
||||||
|
|
||||||
# Configures the endpoint
|
# Configures the endpoint
|
||||||
config :entendu, EntenduWeb.Endpoint,
|
config :entendu, EntenduWeb.Endpoint,
|
||||||
url: [host: "dev.intended.link"],
|
url: [host: "dev.intended.link"],
|
||||||
|
|
|
@ -2,6 +2,8 @@ defmodule Entendu.Links.Link do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
@primary_key {:id, Ecto.UUID, autogenerate: true}
|
||||||
|
|
||||||
schema "links" do
|
schema "links" do
|
||||||
field :burn_after_reading, :boolean, default: false
|
field :burn_after_reading, :boolean, default: false
|
||||||
field :expires, :utc_datetime
|
field :expires, :utc_datetime
|
||||||
|
@ -16,7 +18,13 @@ defmodule Entendu.Links.Link do
|
||||||
@doc false
|
@doc false
|
||||||
def changeset(link, attrs) do
|
def changeset(link, attrs) do
|
||||||
link
|
link
|
||||||
|> cast(attrs, [:expires, :burn_after_reading, :filename, :filetype, :text_content, :file_content])
|
|> cast(attrs, [
|
||||||
|> validate_required([:expires, :burn_after_reading, :filename, :filetype])
|
:expires,
|
||||||
|
:burn_after_reading,
|
||||||
|
:filename,
|
||||||
|
:filetype,
|
||||||
|
:text_content,
|
||||||
|
:file_content
|
||||||
|
])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
defmodule EntenduWeb.FallbackController do
|
||||||
|
use EntenduWeb, :controller
|
||||||
|
|
||||||
|
def call(conn, {:error, %Ecto.Changeset{} = changeset}) do
|
||||||
|
conn
|
||||||
|
|> put_status(:unprocessable_entity)
|
||||||
|
|> put_view(EntenduWeb.ChangesetView)
|
||||||
|
|> render("error.json", changeset: changeset)
|
||||||
|
end
|
||||||
|
end
|
|
@ -9,27 +9,33 @@ defmodule EntenduWeb.LinkController do
|
||||||
alias Entendu.Links
|
alias Entendu.Links
|
||||||
alias Links.Link
|
alias Links.Link
|
||||||
alias Ecto.Changeset
|
alias Ecto.Changeset
|
||||||
|
alias EntenduWeb.FallbackController
|
||||||
|
|
||||||
|
action_fallback(FallbackController)
|
||||||
|
|
||||||
def just_page(conn, _params) do
|
def just_page(conn, _params) do
|
||||||
render(conn, "just.html")
|
render(conn, "just.html")
|
||||||
end
|
end
|
||||||
|
|
||||||
defparams first_step %{
|
defparams(
|
||||||
|
first_step(%{
|
||||||
burn_after_reading: [field: :boolean, default: false],
|
burn_after_reading: [field: :boolean, default: false],
|
||||||
expires: :utc_datetime,
|
expires: :utc_datetime,
|
||||||
filename: :string,
|
filename: :string,
|
||||||
filetype: :string,
|
filetype: :string,
|
||||||
text_content: :string,
|
text_content: :string,
|
||||||
file_content: :string
|
file_content: :string
|
||||||
}
|
})
|
||||||
|
)
|
||||||
|
|
||||||
def just(conn, params) do
|
def just(conn, params) do
|
||||||
with %Changeset{valid?: true} = changeset <- first_step(params),
|
with %Changeset{valid?: true} = changeset <- first_step(params),
|
||||||
link_params <- Params.to_map(changeset),
|
link_params <- Params.to_map(changeset),
|
||||||
{:ok, %Link{} = link} <- Links.create_link(link_params) do
|
{:ok, %Link{} = link} <- Links.create_link(link_params) do
|
||||||
conn
|
conn
|
||||||
|
|> put_status(:created)
|
||||||
|> assign(:link, link)
|
|> assign(:link, link)
|
||||||
|> render("show_authorized", link: link)
|
|> render("show_authorized.json", %{link: link})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
defmodule EntenduWeb.ChangesetView do
|
||||||
|
use EntenduWeb, :view
|
||||||
|
|
||||||
|
def translate_errors(%Ecto.Changeset{} = changeset) do
|
||||||
|
Ecto.Changeset.traverse_errors(changeset, &translate_error/1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def translate_errors(errors = %{}), do: errors
|
||||||
|
|
||||||
|
def render("error.json", %{changeset: changeset}) do
|
||||||
|
# When encoded, the changeset returns its errors
|
||||||
|
# as a JSON object. So we just pass it forward.
|
||||||
|
%{errors: translate_errors(changeset)}
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,27 @@
|
||||||
|
defmodule EntenduWeb.ErrorViewTest do
|
||||||
|
use EntenduWeb.ConnCase, async: true
|
||||||
|
|
||||||
|
# Bring render/3 and render_to_string/3 for testing custom views
|
||||||
|
import Phoenix.View
|
||||||
|
|
||||||
|
test "renders 404.html" do
|
||||||
|
assert render_to_string(EntenduWeb.ErrorView, "404.html", []) == "Not Found"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "just endpoint creates a link with valid attrs", %{conn: conn} do
|
||||||
|
params = %{
|
||||||
|
"text_content" => "some gibberish",
|
||||||
|
"filename" => "more gibberish"
|
||||||
|
}
|
||||||
|
|
||||||
|
conn = post(conn, Routes.link_path(conn, :just), params)
|
||||||
|
|
||||||
|
response = json_response(conn, 201)
|
||||||
|
|
||||||
|
assert %{
|
||||||
|
"id" => _link_id,
|
||||||
|
"text_content" => "some gibberish",
|
||||||
|
"filename" => "more gibberish"
|
||||||
|
} = response
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue