mirror of
https://github.com/ash-project/ash.git
synced 2024-09-21 05:53:06 +12:00
8cbd766172
improvement: add more ergonomic manual action definitions. The old method will likely be deprecated some time in the future (there is no rush really, they both work).
211 lines
4.5 KiB
Elixir
211 lines
4.5 KiB
Elixir
defmodule Ash.Test.Actions.DestroyTest do
|
|
@moduledoc false
|
|
use ExUnit.Case, async: true
|
|
|
|
import Ash.Changeset
|
|
require Ash.Query
|
|
|
|
defmodule Profile do
|
|
@moduledoc false
|
|
use Ash.Resource, data_layer: Ash.DataLayer.Ets
|
|
|
|
ets do
|
|
private?(true)
|
|
end
|
|
|
|
actions do
|
|
defaults [:create, :read, :update, :destroy]
|
|
end
|
|
|
|
attributes do
|
|
uuid_primary_key :id
|
|
attribute :bio, :string
|
|
end
|
|
|
|
relationships do
|
|
belongs_to :author, Ash.Test.Actions.DestroyTest.Author
|
|
end
|
|
end
|
|
|
|
defmodule ManualDestroyAuthor do
|
|
@moduledoc false
|
|
use Ash.Resource.Change
|
|
|
|
def change(changeset, _, _) do
|
|
Ash.Changeset.after_action(changeset, fn _changeset, data ->
|
|
Ash.Test.Actions.DestroyTest.Api.destroy!(data)
|
|
|
|
{:ok, data}
|
|
end)
|
|
end
|
|
end
|
|
|
|
defmodule Author do
|
|
@moduledoc false
|
|
use Ash.Resource, data_layer: Ash.DataLayer.Ets, authorizers: [Ash.Test.Authorizer]
|
|
|
|
ets do
|
|
private?(true)
|
|
end
|
|
|
|
actions do
|
|
defaults [:create, :read, :update, :destroy]
|
|
|
|
destroy :old_manual do
|
|
accept []
|
|
manual? true
|
|
change ManualDestroyAuthor
|
|
end
|
|
|
|
destroy :manual do
|
|
accept []
|
|
|
|
manual fn changeset, _ ->
|
|
Ash.Test.Actions.DestroyTest.Api.destroy(changeset.data, return_destroyed?: true)
|
|
end
|
|
end
|
|
end
|
|
|
|
attributes do
|
|
uuid_primary_key :id
|
|
attribute :name, :string
|
|
end
|
|
|
|
relationships do
|
|
has_one :profile, Profile, destination_attribute: :author_id
|
|
|
|
has_many :posts, Ash.Test.Actions.DestroyTest.Post, destination_attribute: :author_id
|
|
end
|
|
end
|
|
|
|
defmodule PostDefaults do
|
|
@moduledoc false
|
|
def garbage2, do: "garbage2"
|
|
def garbage3, do: "garbage3"
|
|
end
|
|
|
|
defmodule Post do
|
|
@moduledoc false
|
|
use Ash.Resource, data_layer: Ash.DataLayer.Ets
|
|
|
|
ets do
|
|
private?(true)
|
|
end
|
|
|
|
actions do
|
|
defaults [:create, :read, :update, :destroy]
|
|
end
|
|
|
|
attributes do
|
|
uuid_primary_key :id
|
|
attribute :title, :string
|
|
attribute :contents, :string
|
|
attribute :tag, :string, default: "garbage"
|
|
attribute :tag2, :string, default: &PostDefaults.garbage2/0
|
|
attribute :tag3, :string, default: {PostDefaults, :garbage3, []}
|
|
end
|
|
|
|
relationships do
|
|
belongs_to :author, Author
|
|
end
|
|
end
|
|
|
|
defmodule Registry do
|
|
@moduledoc false
|
|
use Ash.Registry
|
|
|
|
entries do
|
|
entry(Author)
|
|
entry(Post)
|
|
entry(Profile)
|
|
end
|
|
end
|
|
|
|
defmodule Api do
|
|
@moduledoc false
|
|
use Ash.Api
|
|
|
|
resources do
|
|
registry Registry
|
|
end
|
|
end
|
|
|
|
describe "simple destroy" do
|
|
test "allows destroying a record" do
|
|
post =
|
|
Post
|
|
|> new(%{title: "foo", contents: "bar"})
|
|
|> Api.create!()
|
|
|
|
assert Api.destroy!(post) == :ok
|
|
|
|
refute Api.read_one!(Ash.Query.filter(Post, id == ^post.id))
|
|
end
|
|
|
|
test "returns the record if requested" do
|
|
post =
|
|
Post
|
|
|> new(%{title: "foo", contents: "bar"})
|
|
|> Api.create!()
|
|
|
|
post_id = post.id
|
|
|
|
assert {:ok, %{id: ^post_id}} = Api.destroy(post, return_destroyed?: true)
|
|
|
|
refute Api.read_one!(Ash.Query.filter(Post, id == ^post.id))
|
|
end
|
|
|
|
test "returns the record and notifications if requested" do
|
|
post =
|
|
Post
|
|
|> new(%{title: "foo", contents: "bar"})
|
|
|> Api.create!()
|
|
|
|
post_id = post.id
|
|
|
|
assert {:ok, %{id: ^post_id}, [_]} =
|
|
Api.destroy(post, return_destroyed?: true, return_notifications?: true)
|
|
|
|
refute Api.read_one!(Ash.Query.filter(Post, id == ^post.id))
|
|
end
|
|
|
|
test "the destroy does not happen if it is unauthorized" do
|
|
author =
|
|
Author
|
|
|> new(%{name: "foobar"})
|
|
|> Api.create!()
|
|
|
|
start_supervised({Ash.Test.Authorizer, strict_check: :continue, check: :forbidden})
|
|
|
|
assert_raise(Ash.Error.Forbidden, fn ->
|
|
Api.destroy!(author, authorize?: true)
|
|
end)
|
|
|
|
assert Api.get!(Author, author.id)
|
|
end
|
|
end
|
|
|
|
describe "manual destroy" do
|
|
test "old: allows destroying a record" do
|
|
author =
|
|
Author
|
|
|> new(%{name: "foo"})
|
|
|> Api.create!()
|
|
|
|
assert Api.destroy!(author, action: :old_manual) == :ok
|
|
|
|
refute Api.read_one!(Ash.Query.filter(Author, id == ^author.id))
|
|
end
|
|
|
|
test "new: allows destroying a record" do
|
|
author =
|
|
Author
|
|
|> new(%{name: "foo"})
|
|
|> Api.create!()
|
|
|
|
assert Api.destroy!(author, action: :manual) == :ok
|
|
|
|
refute Api.read_one!(Ash.Query.filter(Author, id == ^author.id))
|
|
end
|
|
end
|
|
end
|