ash_archival/test/archival_with_policy_test.exs
2024-03-29 10:19:24 -04:00

263 lines
5.5 KiB
Elixir

defmodule ArchivalWithPolicyTest do
use ExUnit.Case
defmodule Author do
use Ash.Resource,
domain: ArchivalWithPolicyTest.Domain,
data_layer: Ash.DataLayer.Ets,
extensions: [AshArchival.Resource],
authorizers: [Ash.Policy.Authorizer]
ets do
table(:authors)
private?(true)
end
archive do
archive_related([:posts])
end
actions do
default_accept(:*)
defaults([:create, :read, :update, :destroy])
end
attributes do
uuid_primary_key(:id)
end
relationships do
has_many(:posts, ArchivalWithPolicyTest.Post) do
public?(true)
end
end
policies do
policy always() do
authorize_if(action_type(:create))
authorize_if(action_type(:read))
authorize_if(actor_attribute_equals(:admin, true))
end
end
end
defmodule AuthorWithArchive do
use Ash.Resource,
domain: ArchivalWithPolicyTest.Domain,
data_layer: Ash.DataLayer.Ets
ets do
table(:authors)
private?(true)
end
actions do
default_accept(:*)
defaults([:create, :read, :update, :destroy])
end
attributes do
uuid_primary_key(:id)
attribute(:archived_at, :utc_datetime_usec, public?: true)
end
end
defmodule Post do
use Ash.Resource,
domain: ArchivalWithPolicyTest.Domain,
data_layer: Ash.DataLayer.Ets,
extensions: [AshArchival.Resource],
authorizers: [Ash.Policy.Authorizer]
ets do
table(:posts)
private?(true)
end
archive do
archive_related([:comments])
end
actions do
default_accept(:*)
defaults([:create, :read, :update, :destroy])
end
attributes do
uuid_primary_key(:id)
end
relationships do
belongs_to :author, Author do
public?(true)
attribute_writable?(true)
end
has_many(:comments, ArchivalWithPolicyTest.Comment) do
public?(true)
end
end
policies do
policy always() do
authorize_if(action_type(:create))
authorize_if(action_type(:read))
authorize_if(actor_attribute_equals(:admin, true))
end
end
end
defmodule PostWithArchive do
use Ash.Resource,
domain: ArchivalWithPolicyTest.Domain,
data_layer: Ash.DataLayer.Ets
ets do
table(:posts)
private?(true)
end
actions do
default_accept(:*)
defaults([:create, :read, :update, :destroy])
end
attributes do
uuid_primary_key(:id)
attribute(:archived_at, :utc_datetime_usec, public?: true)
end
end
defmodule Comment do
use Ash.Resource,
domain: ArchivalWithPolicyTest.Domain,
data_layer: Ash.DataLayer.Ets,
extensions: [AshArchival.Resource],
authorizers: [Ash.Policy.Authorizer]
ets do
table(:comments)
private?(true)
end
actions do
default_accept(:*)
defaults([:create, :read, :update, :destroy])
end
attributes do
uuid_primary_key(:id)
end
relationships do
belongs_to :post, Post do
public?(true)
attribute_writable?(true)
end
end
policies do
policy always() do
authorize_if(action_type(:create))
authorize_if(action_type(:read))
authorize_if(actor_attribute_equals(:admin, true))
end
end
end
defmodule CommentWithArchive do
use Ash.Resource,
domain: ArchivalWithPolicyTest.Domain,
data_layer: Ash.DataLayer.Ets
ets do
table(:comments)
private?(true)
end
actions do
default_accept(:*)
defaults([:create, :read, :update, :destroy])
end
attributes do
uuid_primary_key(:id)
attribute(:archived_at, :utc_datetime_usec, public?: true)
end
end
defmodule Domain do
use Ash.Domain
authorization do
authorize(:always)
end
resources do
resource(Author)
resource(AuthorWithArchive)
resource(Post)
resource(PostWithArchive)
resource(Comment)
resource(CommentWithArchive)
end
end
test "destroying a record archives it" do
comment =
Comment
|> Ash.Changeset.for_create(:create)
|> Ash.create!()
assert :ok = comment |> Ash.destroy!(actor: %{admin: true})
[archived] = Ash.read!(CommentWithArchive)
assert archived.id == comment.id
assert archived.archived_at
end
test "destroying a record archives any `archive_related` it has configured" do
post =
Post
|> Ash.Changeset.for_create(:create)
|> Ash.create!()
comment =
Comment
|> Ash.Changeset.for_create(:create, %{post_id: post.id})
|> Ash.create!()
assert :ok = post |> Ash.destroy!(actor: %{admin: true})
[archived] = Ash.read!(CommentWithArchive)
assert archived.id == comment.id
assert archived.archived_at
end
test "destroying a record triggers a cascading archive." do
author =
Author
|> Ash.Changeset.for_create(:create)
|> Ash.create!()
post =
Post
|> Ash.Changeset.for_create(:create, %{author_id: author.id})
|> Ash.create!()
comment =
Comment
|> Ash.Changeset.for_create(:create, %{post_id: post.id})
|> Ash.create!()
assert :ok = author |> Ash.destroy!(actor: %{admin: true})
[archived_post] = Ash.read!(PostWithArchive)
assert archived_post.id == post.id
assert archived_post.archived_at
[archived_comment] = Ash.read!(CommentWithArchive)
assert archived_comment.id == comment.id
assert archived_comment.archived_at
end
end