2020-10-15 17:54:02 +13:00
|
|
|
defmodule Ash.Test.NotifierTest do
|
|
|
|
@moduledoc false
|
|
|
|
use ExUnit.Case, async: false
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
alias Ash.Test.Domain, as: Domain
|
|
|
|
|
2020-10-15 17:54:02 +13:00
|
|
|
defmodule Notifier do
|
|
|
|
use Ash.Notifier
|
|
|
|
|
|
|
|
def notify(notification) do
|
|
|
|
send(Application.get_env(__MODULE__, :notifier_test_pid), {:notification, notification})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
defmodule Notifier2 do
|
|
|
|
use Ash.Notifier
|
|
|
|
|
|
|
|
def notify(notification) do
|
|
|
|
send(Application.get_env(__MODULE__, :notifier_test_pid), {:notification, notification})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-10-15 17:54:02 +13:00
|
|
|
defmodule PostLink do
|
|
|
|
use Ash.Resource,
|
2024-03-28 09:06:40 +13:00
|
|
|
domain: Domain,
|
2020-10-15 17:54:02 +13:00
|
|
|
data_layer: Ash.DataLayer.Ets,
|
|
|
|
notifiers: [
|
|
|
|
Notifier
|
|
|
|
]
|
|
|
|
|
|
|
|
ets do
|
|
|
|
private? true
|
|
|
|
end
|
|
|
|
|
|
|
|
actions do
|
2024-03-28 09:06:40 +13:00
|
|
|
default_accept :*
|
2024-04-26 14:18:38 +12:00
|
|
|
defaults [:read, :destroy, create: :*]
|
|
|
|
|
|
|
|
update :update do
|
|
|
|
primary? true
|
|
|
|
require_atomic? false
|
|
|
|
end
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
relationships do
|
2021-01-13 09:40:55 +13:00
|
|
|
belongs_to :source_post, Ash.Test.NotifierTest.Post,
|
|
|
|
primary_key?: true,
|
2024-03-28 09:06:40 +13:00
|
|
|
allow_nil?: false,
|
|
|
|
public?: true
|
2021-01-13 09:40:55 +13:00
|
|
|
|
|
|
|
belongs_to :destination_post, Ash.Test.NotifierTest.Post,
|
|
|
|
primary_key?: true,
|
2024-03-28 09:06:40 +13:00
|
|
|
allow_nil?: false,
|
|
|
|
public?: true
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defmodule Comment do
|
|
|
|
use Ash.Resource,
|
2024-03-28 09:06:40 +13:00
|
|
|
domain: Domain,
|
2020-10-15 17:54:02 +13:00
|
|
|
data_layer: Ash.DataLayer.Ets,
|
|
|
|
notifiers: [
|
|
|
|
Notifier
|
|
|
|
]
|
|
|
|
|
|
|
|
ets do
|
|
|
|
private?(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
actions do
|
2024-03-28 09:06:40 +13:00
|
|
|
default_accept :*
|
2024-04-26 14:18:38 +12:00
|
|
|
defaults [:read, :destroy, create: :*]
|
|
|
|
|
|
|
|
update :update do
|
|
|
|
primary? true
|
|
|
|
require_atomic? false
|
|
|
|
end
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
attributes do
|
2021-01-13 09:40:55 +13:00
|
|
|
uuid_primary_key :id
|
2020-10-15 17:54:02 +13:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
attribute :name, :string do
|
|
|
|
public?(true)
|
|
|
|
end
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
relationships do
|
2023-04-13 09:35:17 +12:00
|
|
|
belongs_to :post, Ash.Test.NotifierTest.Post do
|
2024-03-28 09:06:40 +13:00
|
|
|
public?(true)
|
2023-04-13 09:35:17 +12:00
|
|
|
end
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defmodule Post do
|
|
|
|
@moduledoc false
|
|
|
|
use Ash.Resource,
|
2024-03-28 09:06:40 +13:00
|
|
|
domain: Domain,
|
2020-10-15 17:54:02 +13:00
|
|
|
data_layer: Ash.DataLayer.Ets,
|
|
|
|
notifiers: [
|
|
|
|
Notifier
|
|
|
|
]
|
|
|
|
|
|
|
|
ets do
|
|
|
|
private?(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
actions do
|
2024-03-28 09:06:40 +13:00
|
|
|
default_accept :*
|
2024-04-26 14:18:38 +12:00
|
|
|
defaults [:read, create: :*]
|
|
|
|
|
|
|
|
update :update do
|
|
|
|
primary? true
|
|
|
|
require_atomic? false
|
|
|
|
end
|
2024-03-28 09:06:40 +13:00
|
|
|
|
|
|
|
destroy :destroy do
|
|
|
|
primary? true
|
|
|
|
notifiers([Notifier2])
|
|
|
|
end
|
2023-04-13 09:35:17 +12:00
|
|
|
|
|
|
|
create :create_with_comment do
|
2023-06-15 12:40:04 +12:00
|
|
|
change load(:comments)
|
|
|
|
|
2023-04-13 09:35:17 +12:00
|
|
|
change fn changeset, _ ->
|
|
|
|
Ash.Changeset.after_action(changeset, fn _changeset, result ->
|
|
|
|
Comment
|
|
|
|
|> Ash.Changeset.for_create(:create, %{post_id: result.id, name: "auto"})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2023-04-13 09:35:17 +12:00
|
|
|
|
|
|
|
{:ok, result}
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
end
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
attributes do
|
2021-01-13 09:40:55 +13:00
|
|
|
uuid_primary_key :id
|
2020-10-15 17:54:02 +13:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
attribute :name, :string do
|
|
|
|
public?(true)
|
|
|
|
end
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
relationships do
|
|
|
|
many_to_many :related_posts, __MODULE__,
|
2024-03-28 09:06:40 +13:00
|
|
|
public?: true,
|
2020-10-15 17:54:02 +13:00
|
|
|
through: PostLink,
|
2022-08-16 06:00:02 +12:00
|
|
|
source_attribute_on_join_resource: :source_post_id,
|
|
|
|
destination_attribute_on_join_resource: :destination_post_id
|
2020-10-15 17:54:02 +13:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
has_many :comments, Comment, destination_attribute: :post_id, public?: true
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
setup do
|
|
|
|
Application.put_env(Notifier, :notifier_test_pid, self())
|
2024-03-28 09:06:40 +13:00
|
|
|
Application.put_env(Notifier2, :notifier_test_pid, self())
|
2020-10-15 17:54:02 +13:00
|
|
|
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "simple creates and updates" do
|
|
|
|
test "a create notification occurs" do
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "foo"})
|
|
|
|
|> Ash.create!()
|
2020-10-15 17:54:02 +13:00
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :create}}}
|
|
|
|
end
|
|
|
|
|
|
|
|
test "an update notification occurs" do
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "foo"})
|
|
|
|
|> Ash.create!()
|
|
|
|
|> Ash.Changeset.for_update(:update, %{name: "bar"})
|
|
|
|
|> Ash.update!()
|
2020-10-15 17:54:02 +13:00
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :update}}}
|
|
|
|
end
|
|
|
|
|
|
|
|
test "a destroy notification occurs" do
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "foo"})
|
|
|
|
|> Ash.create!()
|
|
|
|
|> Ash.destroy!()
|
2020-10-15 17:54:02 +13:00
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :destroy}}}
|
2024-03-28 09:06:40 +13:00
|
|
|
assert_receive {:notification, %{action: %{type: :destroy}}}
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-12-10 16:55:51 +13:00
|
|
|
describe "custom notifications" do
|
|
|
|
test "a custom notification can be returned in a before or after action hook" do
|
|
|
|
Comment
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{})
|
2022-12-10 16:55:51 +13:00
|
|
|
|> Ash.Changeset.before_action(fn changeset ->
|
|
|
|
{changeset,
|
|
|
|
%{
|
|
|
|
notifications: [
|
|
|
|
%Ash.Notifier.Notification{
|
|
|
|
resource: changeset.resource,
|
|
|
|
metadata: %{custom?: true}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}}
|
|
|
|
end)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2022-12-10 16:55:51 +13:00
|
|
|
|
|
|
|
assert_receive {:notification, %Ash.Notifier.Notification{metadata: %{custom?: true}}}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-04-13 09:35:17 +12:00
|
|
|
test "a nested notification is sent automatically" do
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.for_create(:create_with_comment, %{name: "foobar"})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2023-04-13 09:35:17 +12:00
|
|
|
|
|
|
|
assert_receive {:notification, %Ash.Notifier.Notification{data: %Comment{name: "auto"}}}
|
|
|
|
end
|
|
|
|
|
2023-06-15 12:40:04 +12:00
|
|
|
test "the `load/1` change puts the loaded data into the notification" do
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.for_create(:create_with_comment, %{name: "foobar"})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2023-06-15 12:40:04 +12:00
|
|
|
|
|
|
|
assert_receive {:notification, %Ash.Notifier.Notification{data: %Post{comments: [_]}}}
|
|
|
|
end
|
|
|
|
|
2022-12-10 16:55:51 +13:00
|
|
|
test "notifications use the data before its limited by a select statement" do
|
|
|
|
Comment
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "foobar"})
|
2022-12-10 16:55:51 +13:00
|
|
|
|> Ash.Changeset.select([:id])
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2022-12-10 16:55:51 +13:00
|
|
|
|
|
|
|
assert_receive {:notification, %Ash.Notifier.Notification{data: %{name: "foobar"}}}
|
|
|
|
end
|
|
|
|
|
|
|
|
test "notifications use the changeset after before_action callbacks" do
|
|
|
|
Comment
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "foobar"})
|
2022-12-10 16:55:51 +13:00
|
|
|
|> Ash.Changeset.before_action(fn changeset ->
|
|
|
|
Ash.Changeset.set_context(changeset, %{foobar: :baz})
|
|
|
|
end)
|
|
|
|
|> Ash.Changeset.select([:id])
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2022-12-10 16:55:51 +13:00
|
|
|
|
|
|
|
assert_receive {:notification,
|
|
|
|
%Ash.Notifier.Notification{changeset: %{context: %{foobar: :baz}}}}
|
|
|
|
end
|
|
|
|
|
2020-10-15 17:54:02 +13:00
|
|
|
describe "related notifications" do
|
|
|
|
test "an update notification occurs when relating many to many" do
|
|
|
|
comment =
|
|
|
|
Comment
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{})
|
|
|
|
|> Ash.create!()
|
2020-10-15 17:54:02 +13:00
|
|
|
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "foo"})
|
2022-09-20 07:44:06 +12:00
|
|
|
|> Ash.Changeset.manage_relationship(:comments, comment, type: :append_and_remove)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2020-10-15 17:54:02 +13:00
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :update}, resource: Comment}}
|
|
|
|
end
|
|
|
|
|
|
|
|
test "a create notification occurs for the join through relationship" do
|
|
|
|
post =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "foo"})
|
|
|
|
|> Ash.create!()
|
2020-10-15 17:54:02 +13:00
|
|
|
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "foo"})
|
2022-09-20 07:44:06 +12:00
|
|
|
|> Ash.Changeset.manage_relationship(:related_posts, [post], type: :append_and_remove)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2020-10-15 17:54:02 +13:00
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :create}, resource: PostLink}}
|
|
|
|
end
|
|
|
|
|
|
|
|
test "a destroy notification occurs for the join through relationship" do
|
|
|
|
post =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "foo"})
|
|
|
|
|> Ash.create!()
|
2020-10-15 17:54:02 +13:00
|
|
|
|
2023-07-27 08:46:22 +12:00
|
|
|
assert %{related_posts: [_]} =
|
|
|
|
post =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "foo"})
|
2023-07-27 08:46:22 +12:00
|
|
|
|> Ash.Changeset.manage_relationship(:related_posts, [post],
|
|
|
|
type: :append_and_remove
|
|
|
|
)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
|
|
|
|> Ash.load!(:related_posts)
|
2023-07-27 08:46:22 +12:00
|
|
|
|
|
|
|
assert %{related_posts: []} =
|
|
|
|
post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_update(:update, %{})
|
2023-07-27 08:46:22 +12:00
|
|
|
|> Ash.Changeset.manage_relationship(:related_posts, [], type: :append_and_remove)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.update!()
|
2020-10-15 17:54:02 +13:00
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :destroy}, resource: PostLink}}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|