ash/test/reactor/change_test.exs

119 lines
3.2 KiB
Elixir

defmodule Ash.Test.ReactorChangeTest do
@moduledoc false
use ExUnit.Case, async: false
defmodule Post do
@moduledoc false
use Ash.Resource, data_layer: Ash.DataLayer.Ets, domain: Ash.Test.Domain
ets do
private? true
end
attributes do
uuid_primary_key :id
attribute :title, :string, allow_nil?: false, public?: true
end
actions do
defaults [:read, :destroy, update: :*, create: :*]
end
end
test "it can create a post" do
defmodule SimpleCreatePostReactor do
@moduledoc false
use Reactor, extensions: [Ash.Reactor]
input :title
change :set_title, set_attribute(:title, arg(:title)) do
initial(Post)
argument :title, input(:title)
end
create :create_post, Post, :create do
initial(result(:set_title))
end
end
assert {:ok, post} = Reactor.run(SimpleCreatePostReactor, %{title: "Title"})
assert is_binary(post.id)
assert post.title == "Title"
end
test "it honours the `fail_if_invalid?` option" do
defmodule SimpleChangeFailReactor do
@moduledoc false
use Ash.Reactor
input :title
step :changeset do
run fn _ ->
{:ok, Ash.Changeset.for_action(Post, :create)}
end
end
change :set_title, set_attribute(:title, arg(:title)) do
initial(result(:changeset))
argument :title, input(:title)
fail_if_invalid?(true)
end
end
assert {:error, invalid} = Reactor.run(SimpleChangeFailReactor, %{title: nil})
assert Exception.message(invalid) =~ "valid?: false"
end
test "it honours the `only_when_valid?` option" do
defmodule SimpleOnlyWhenValidReactor do
@moduledoc false
use Ash.Reactor
input :changeset
input :title
change :set_title, set_attribute(:title, arg(:title)) do
initial(input(:changeset))
only_when_valid? true
end
end
valid_changeset = Ash.Changeset.new(Post)
{:ok, changeset} =
Reactor.run(SimpleOnlyWhenValidReactor, %{changeset: valid_changeset, title: "Title"})
assert Ash.Changeset.changing_attribute?(changeset, :title)
invalid_changeset = %{valid_changeset | valid?: false}
{:ok, changeset} =
Reactor.run(SimpleOnlyWhenValidReactor, %{changeset: invalid_changeset, title: "Title"})
refute Ash.Changeset.changing_attribute?(changeset, :title)
end
test "it honours the `where` option" do
defmodule SimpleWhereChangeReactor do
@moduledoc false
use Ash.Reactor
input :changeset
change :set_title, set_attribute(:title, "Default title") do
initial(input(:changeset))
where [absent(:title)]
end
end
blank_changeset = Ash.Changeset.for_create(Post, :create, %{})
{:ok, changeset} = Reactor.run(SimpleWhereChangeReactor, %{changeset: blank_changeset})
assert Ash.Changeset.get_attribute(changeset, :title) == "Default title"
with_title_changeset = Ash.Changeset.for_create(Post, :create, %{title: "Explicit title"})
{:ok, changeset} = Reactor.run(SimpleWhereChangeReactor, %{changeset: with_title_changeset})
assert Ash.Changeset.get_attribute(changeset, :title) == "Explicit title"
end
end