mirror of
https://github.com/ash-project/ash_phoenix.git
synced 2024-09-08 09:30:49 +12:00
test: Nested form errors for argument attribute (#119)
This commit is contained in:
parent
6ddddf7316
commit
a098a830b1
5 changed files with 105 additions and 1 deletions
5
.gitpod.yml
Normal file
5
.gitpod.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
image: elixir:latest
|
||||
|
||||
tasks:
|
||||
- init: mix deps.get && mix compile
|
||||
command: iex -S mix
|
|
@ -4,7 +4,7 @@ defmodule AshPhoenix.FormTest do
|
|||
import ExUnit.CaptureLog
|
||||
|
||||
alias AshPhoenix.Form
|
||||
alias AshPhoenix.Test.{Api, Comment, OtherApi, Post, PostWithDefault}
|
||||
alias AshPhoenix.Test.{Api, Author, Comment, OtherApi, Post, PostWithDefault}
|
||||
alias Phoenix.HTML.FormData
|
||||
|
||||
describe "validate_opts" do
|
||||
|
@ -782,6 +782,45 @@ defmodule AshPhoenix.FormTest do
|
|||
assert [nested_form] = inputs_for(form, :post)
|
||||
assert nested_form.errors == [{:text, {"is required", []}}]
|
||||
end
|
||||
|
||||
test "errors with a path are propagated down to the appropirate nested form" do
|
||||
author = %Author{
|
||||
email: "me@example.com"
|
||||
}
|
||||
|
||||
form =
|
||||
author
|
||||
|> Form.for_update(:update_with_embedded_argument, api: Api, forms: [auto?: true])
|
||||
|> Form.add_form(:embedded_argument, params: %{})
|
||||
|> Form.validate(%{"embedded_argument" => %{"value" => "you@example.com"}})
|
||||
|> form_for("action")
|
||||
[nested_form] = inputs_for(form, :embedded_argument)
|
||||
|
||||
|
||||
# This is the top level error with a path to the nest form.
|
||||
assert [
|
||||
%Ash.Error.Changes.InvalidArgument{
|
||||
field: :value,
|
||||
message: "must match email",
|
||||
value: "you@example.com",
|
||||
path: [:embedded_argument],
|
||||
class: :invalid
|
||||
}
|
||||
] = form.source.source.errors
|
||||
assert form.errors == []
|
||||
|
||||
# This is the error on the nested form.
|
||||
assert [
|
||||
%Ash.Error.Changes.InvalidArgument{
|
||||
field: :value,
|
||||
message: "must match email",
|
||||
value: "you@example.com",
|
||||
path: [],
|
||||
class: :invalid
|
||||
}
|
||||
] = nested_form.source.source.errors
|
||||
assert nested_form.errors == [{:value, {"must match email", []}}]
|
||||
end
|
||||
end
|
||||
|
||||
describe "data" do
|
||||
|
|
|
@ -13,6 +13,14 @@ defmodule AshPhoenix.Test.Author do
|
|||
|
||||
actions do
|
||||
defaults([:create, :read, :update])
|
||||
|
||||
update :update_with_embedded_argument do
|
||||
# This an empty change, just so test how we handle errors on embedded arguments
|
||||
accept []
|
||||
argument :embedded_argument, AshPhoenix.Test.EmbeddedArgument, allow_nil?: false
|
||||
|
||||
validate { AshPhoenix.Test.ValidateEmbeddedArgument, [] }
|
||||
end
|
||||
end
|
||||
|
||||
relationships do
|
||||
|
|
8
test/support/resources/embedded_argument.ex
Normal file
8
test/support/resources/embedded_argument.ex
Normal file
|
@ -0,0 +1,8 @@
|
|||
defmodule AshPhoenix.Test.EmbeddedArgument do
|
||||
@moduledoc false
|
||||
use Ash.Resource, data_layer: :embedded
|
||||
|
||||
attributes do
|
||||
attribute :value, :string
|
||||
end
|
||||
end
|
44
test/support/validations/validate_embedded_argument.ex
Normal file
44
test/support/validations/validate_embedded_argument.ex
Normal file
|
@ -0,0 +1,44 @@
|
|||
defmodule AshPhoenix.Test.ValidateEmbeddedArgument do
|
||||
@moduledoc """
|
||||
This is a contrived example, but we want to validate one or more arguments' attributes
|
||||
against an attribute on the parent resource and then put an error on the
|
||||
changeset that will get propogated down to the nest form for the embedded argument.
|
||||
"""
|
||||
|
||||
use Ash.Resource.Validation
|
||||
|
||||
# This is the name of our embedded argument
|
||||
@embedded_argument :embedded_argument
|
||||
|
||||
# This is the name of the attribute on the embedded argument
|
||||
@embedded_attribute :value
|
||||
|
||||
@impl true
|
||||
def validate(changeset, _opts) do
|
||||
case Ash.Changeset.get_argument(changeset, @embedded_argument) do
|
||||
nil ->
|
||||
:ok
|
||||
|
||||
argument ->
|
||||
apply_validation(changeset, argument)
|
||||
end
|
||||
end
|
||||
|
||||
def apply_validation(changeset, argument) do
|
||||
email = Ash.Changeset.get_attribute(changeset, :email)
|
||||
value = Map.get(argument, @embedded_attribute)
|
||||
|
||||
if value == email do
|
||||
:ok
|
||||
else
|
||||
{:error,
|
||||
Ash.Error.Changes.InvalidArgument.exception(
|
||||
field: @embedded_attribute,
|
||||
message: "must match email",
|
||||
value: value,
|
||||
path: [@embedded_argument]
|
||||
)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue