2024-03-02 10:26:25 +13:00
|
|
|
defmodule Ash.Test.Reactor.TransactionTest do
|
|
|
|
@moduledoc false
|
|
|
|
use ExUnit.Case, async: false
|
|
|
|
use Mimic
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
alias Ash.Test.Domain
|
|
|
|
|
2024-03-02 10:26:25 +13:00
|
|
|
defmodule Post do
|
|
|
|
@moduledoc false
|
2024-03-28 09:06:40 +13:00
|
|
|
use Ash.Resource, data_layer: Ash.DataLayer.Mnesia, domain: Domain
|
2024-03-02 10:26:25 +13:00
|
|
|
|
|
|
|
attributes do
|
|
|
|
uuid_primary_key :id
|
2024-03-28 09:06:40 +13:00
|
|
|
attribute :title, :string, allow_nil?: false, public?: true
|
2024-03-02 10:26:25 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
actions do
|
2024-03-28 09:06:40 +13:00
|
|
|
default_accept :*
|
|
|
|
defaults [:destroy, create: :*]
|
2024-03-02 10:26:25 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
setup do
|
|
|
|
ExUnit.CaptureLog.capture_log(fn ->
|
2024-03-28 09:06:40 +13:00
|
|
|
Ash.DataLayer.Mnesia.start(Domain, [Post])
|
2024-03-02 10:26:25 +13:00
|
|
|
end)
|
|
|
|
|
|
|
|
on_exit(fn ->
|
|
|
|
ExUnit.CaptureLog.capture_log(fn ->
|
|
|
|
:mnesia.stop()
|
|
|
|
:mnesia.delete_schema([node()])
|
|
|
|
end)
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "when the transaction completes successfully it returns the last result" do
|
|
|
|
defmodule SuccessfulNoReturnTransactionReactor do
|
|
|
|
@moduledoc false
|
|
|
|
use Ash.Reactor
|
|
|
|
|
|
|
|
ash do
|
2024-03-28 09:06:40 +13:00
|
|
|
default_domain(Domain)
|
2024-03-02 10:26:25 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
transaction :create_posts, Post do
|
|
|
|
create :post_1, Post, :create do
|
|
|
|
inputs(%{title: value("About Marty McFly")})
|
|
|
|
end
|
|
|
|
|
|
|
|
create :post_2, Post, :create do
|
|
|
|
inputs(%{title: value("About Doc Brown")})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
assert {:ok, %{title: "About Doc Brown"}} = Reactor.run(SuccessfulNoReturnTransactionReactor)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "when the transaction completes successfully it returns the specified result" do
|
|
|
|
defmodule SuccessfulNamedReturnTransactionReactor do
|
|
|
|
@moduledoc false
|
|
|
|
use Ash.Reactor
|
|
|
|
|
|
|
|
ash do
|
2024-03-28 09:06:40 +13:00
|
|
|
default_domain(Domain)
|
2024-03-02 10:26:25 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
transaction :create_posts, Post do
|
|
|
|
create :post_1, Post, :create do
|
|
|
|
inputs(%{title: value("About Marty McFly")})
|
|
|
|
end
|
|
|
|
|
|
|
|
create :post_2, Post, :create do
|
|
|
|
inputs(%{title: value("About Doc Brown")})
|
|
|
|
end
|
|
|
|
|
|
|
|
return :post_1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
assert {:ok, %{title: "About Marty McFly"}} =
|
2024-04-09 14:46:11 +12:00
|
|
|
Reactor.run!(SuccessfulNamedReturnTransactionReactor)
|
2024-03-02 10:26:25 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
test "when the transaction fails it is rolled back" do
|
|
|
|
defmodule FailAndRollBackTransactionReactor do
|
|
|
|
@moduledoc false
|
|
|
|
use Ash.Reactor
|
|
|
|
|
|
|
|
ash do
|
2024-03-28 09:06:40 +13:00
|
|
|
default_domain(Domain)
|
2024-03-02 10:26:25 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
transaction :create_posts, Post do
|
|
|
|
create :post_1, Post, :create do
|
|
|
|
inputs(%{title: value("About Marty McFly")})
|
|
|
|
end
|
|
|
|
|
|
|
|
step :fail do
|
|
|
|
run fn _, _ ->
|
|
|
|
raise "hell"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return :post_1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
Ash.DataLayer
|
|
|
|
|> expect(:rollback, fn resources, reason ->
|
|
|
|
assert resources == [Post]
|
|
|
|
assert Exception.message(reason) == "hell"
|
|
|
|
|
|
|
|
raise reason
|
|
|
|
end)
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
FailAndRollBackTransactionReactor
|
|
|
|
|> Reactor.run(%{}, %{}, async?: false)
|
|
|
|
|> Ash.Test.assert_has_error(fn
|
|
|
|
%Reactor.Error.Invalid.RunStepError{error: error} ->
|
|
|
|
Exception.message(error) =~ "hell"
|
2024-03-02 10:26:25 +13:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
_ ->
|
|
|
|
false
|
|
|
|
end)
|
2024-03-02 10:26:25 +13:00
|
|
|
end
|
|
|
|
end
|