improvement: tests and better behavior for union forms

This commit is contained in:
Zach Daniel 2023-08-12 21:29:37 -07:00
parent f4f8897e9f
commit e295fb72f7
4 changed files with 100 additions and 8 deletions

View file

@ -177,8 +177,12 @@ defmodule AshPhoenix.Form.Auto do
transform_params =
if fake_embedded? do
fn form, _params, _type ->
AshPhoenix.Form.value(form, :value)
fn form, params, type ->
if type == :nested do
AshPhoenix.Form.value(form, :value)
else
params
end
end
end
@ -244,11 +248,11 @@ defmodule AshPhoenix.Form.Auto do
Params:
#{inspect(params)}
#{inspect(params, pretty: true)}
Available types:
#{inspect(constraints[:types])}
#{inspect(constraints[:types], pretty: true)}
"""
{_key, config} ->
@ -266,13 +270,16 @@ defmodule AshPhoenix.Form.Auto do
raise """
Got no "_union_type" parameter, and no union type had a tag & tag_value pair matching the params.
If you are adding a form, select a type using `params: %{"_union_type" => "type_name"}`, or if one
or more of your types is using a tag you can set that tag with `params: %{"tag" => "tag_value"}`.
Params:
#{inspect(params)}
#{inspect(params, pretty: true)}
Available types:
#{inspect(constraints[:types])}
#{inspect(constraints[:types], pretty: true)}
"""
{_key, config} ->
@ -823,6 +830,8 @@ defmodule AshPhoenix.Form.Auto do
|> Keyword.new()
end
defp union?({:array, type}), do: union?(type)
defp union?(type) do
if Ash.Type.NewType.new_type?(type) do
union?(Ash.Type.NewType.subtype_of(type))

View file

@ -1182,7 +1182,7 @@ defmodule AshPhoenix.Form do
Map.update(forms, key, [new_form], &(&1 ++ [new_form]))
matching_form ->
opts = update_opts(opts, matching_form.data, form_params)
opts = update_opts(opts, matching_form.data, params)
validated =
validate(matching_form, params,
@ -2889,6 +2889,13 @@ defmodule AshPhoenix.Form do
fields -> Keyword.put(hidden, :_touched, fields)
end
hidden =
if form.params["_union_type"] do
Keyword.put(hidden, :_union_type, form.params["_union_type"])
else
hidden
end
if form.params["_index"] && form.params["_index"] != "" do
Keyword.put(hidden, :_index, form.params["_index"])
else

View file

@ -2,7 +2,8 @@ defmodule AshPhoenix.AutoFormTest do
use ExUnit.Case
alias AshPhoenix.Form.Auto
alias AshPhoenix.Test.Post
alias AshPhoenix.Test.{Api, Post}
import Phoenix.HTML.Form, only: [form_for: 2]
import AshPhoenix.Form, only: [update_opts: 2]
test "it works for simple relationships" do
@ -53,6 +54,80 @@ defmodule AshPhoenix.AutoFormTest do
assert validated.source.arguments[:comment_ids] == [1]
end
describe "single unions" do
test "a form can be added for a union" do
Post
|> AshPhoenix.Form.for_create(:create,
api: Api,
forms: [
auto?: true
]
)
|> AshPhoenix.Form.add_form(:union, params: %{"type" => "foo"})
|> form_for("action")
end
test "a form can be removed from a union" do
form =
Post
|> AshPhoenix.Form.for_create(:create,
api: Api,
forms: [
auto?: true
]
)
|> AshPhoenix.Form.add_form(:union, params: %{"type" => "foo"})
|> form_for("action")
AshPhoenix.Form.remove_form(form, [:union])
end
test "a form can be added for a non-embedded type" do
Post
|> AshPhoenix.Form.for_create(:create,
api: Api,
forms: [
auto?: true
],
params: %{
"text" => "foobar"
}
)
|> AshPhoenix.Form.add_form(:union, params: %{"_union_type" => "bar", "value" => 10})
|> AshPhoenix.Form.submit!()
end
end
describe "list unions" do
test "a form can be added for a union" do
Post
|> AshPhoenix.Form.for_create(:create,
api: Api,
forms: [
auto?: true
]
)
|> AshPhoenix.Form.add_form(:union_array, params: %{"type" => "foo"})
|> form_for("action")
end
test "a form can be removed from a union" do
form =
Post
|> AshPhoenix.Form.for_create(:create,
api: Api,
forms: [
auto?: true
]
)
|> AshPhoenix.Form.add_form(:union_array, params: %{"type" => "foo"})
|> form_for("action")
AshPhoenix.Form.remove_form(form, [:union_array, 0])
end
end
defp auto_forms(resource, action) do
[forms: Auto.auto(resource, action)]
end

View file

@ -10,6 +10,7 @@ defmodule AshPhoenix.Test.Post do
uuid_primary_key(:id)
attribute(:text, :string, allow_nil?: false)
attribute(:union, AshPhoenix.Test.UnionValue)
attribute(:union_array, {:array, AshPhoenix.Test.UnionValue})
attribute(:title, :string)
end