mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 21:43:02 +12:00
145 lines
3.2 KiB
Elixir
145 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
|