ash/test/flow_test/transaction_test.exs
Zach Daniel 022708c6b5 improvement: add api option to relationships
improvement: make default actions and primary actions far more explicit

this begins the official 2.0.0 work
2022-04-04 01:48:37 -04:00

144 lines
3.2 KiB
Elixir

defmodule Ash.FlowTest.TransactionTest do
@moduledoc false
use ExUnit.Case, async: false
alias Ash.Test.Support.Flow.{Api, Org, User}
setup do
ExUnit.CaptureLog.capture_log(fn ->
Ash.DataLayer.Mnesia.start(Api)
end)
on_exit(fn ->
ExUnit.CaptureLog.capture_log(fn ->
:mnesia.stop()
:mnesia.delete_schema([node()])
end)
end)
end
defmodule CountValue do
use Ash.Flow.Step
def run(input, opts, _context) do
field = opts[:field] || :value
{:ok, input |> Map.get(field) |> List.wrap() |> Enum.count()}
end
end
defmodule Error do
use Ash.Flow.Step
def run(%{error: :raise}, _opts, _context) do
raise "uh oh!"
end
def run(%{error: :return}, _opts, _context) do
{:error, "uh oh!"}
end
def run(_input, _opts, _context) do
{:ok, nil}
end
end
defmodule UnapproveAllUsers do
@moduledoc "Foo"
use Ash.Flow
flow do
api Api
argument :org_name, :string do
allow_nil? false
end
argument :error, :atom do
constraints one_of: [:raise, :return]
end
returns :count_unapproved_users
end
steps do
transaction :get_org_and_unapprove_users do
read :get_org, Org, :by_name do
input(%{
name: arg(:org_name)
})
end
read :list_users, User, :for_org do
input %{
org: path(result(:get_org), :id)
}
end
map :unapprove_users, result(:list_users) do
update :unapprove_user, User, :unapprove do
record element(:unapprove_users)
end
end
custom :count_unapproved_users, {CountValue, field: :users} do
input %{
users: result(:list_users)
}
end
custom :error, Error do
input %{
error: arg(:error)
}
end
end
end
end
test "a flow in a transaction can be run" do
org =
Org
|> Ash.Changeset.for_create(:create, %{name: "Org 1"})
|> Api.create!()
User
|> Ash.Changeset.for_create(:create, %{first_name: "abc", org: org.id})
|> Api.create!()
|> Ash.Changeset.for_update(:approve, %{})
|> Api.update!()
User
|> Ash.Changeset.for_create(:create, %{first_name: "def", org: org.id})
|> Api.create!()
|> Ash.Changeset.for_update(:approve, %{})
|> Api.update!()
UnapproveAllUsers.run!("Org 1")
end
test "a flow in a transaction will be rolled back if an error is raised" do
org =
Org
|> Ash.Changeset.for_create(:create, %{name: "Org 1"})
|> Api.create!()
User
|> Ash.Changeset.for_create(:create, %{first_name: "abc", org: org.id})
|> Api.create!()
|> Ash.Changeset.for_update(:approve, %{})
|> Api.update!()
User
|> Ash.Changeset.for_create(:create, %{first_name: "def", org: org.id})
|> Api.create!()
|> Ash.Changeset.for_update(:approve, %{})
|> Api.update!()
assert_raise(Ash.Error.Unknown, ~r/uh oh!/, fn ->
UnapproveAllUsers.run!("Org 1", %{error: :raise})
end)
assert User |> Api.read!() |> Enum.all?(& &1.approved)
end
end