Skip to content

Commit

Permalink
add test to reproduce errors
Browse files Browse the repository at this point in the history
  • Loading branch information
rgraff committed Nov 27, 2023
1 parent f39031c commit 2aa9930
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 1 deletion.
41 changes: 40 additions & 1 deletion test/form_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -772,6 +772,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

Check failure on line 776 in test/form_test.exs

View workflow job for this annotation

GitHub Actions / ash-ci / mix test

test errors errors with a path are propagated down to the appropirate nested form (AshPhoenix.FormTest)
author = %Author{
email: "[email protected]"
}

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" => "[email protected]"}})
|> 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: "[email protected]",
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: "[email protected]",
path: [],
class: :invalid
}
] = nested_form.source.source.errors
assert nested_form.errors == [{:value, {"must match email", []}}]
end
end

describe "data" do
Expand Down
8 changes: 8 additions & 0 deletions test/support/resources/author.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions test/support/resources/embedded_argument.ex
Original file line number Diff line number Diff line change
@@ -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 changes: 44 additions & 0 deletions test/support/validations/validate_embedded_argument.ex
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 2aa9930

Please sign in to comment.