2020-10-15 17:54:02 +13:00
|
|
|
defmodule Ash.Test.NotifierTest do
|
|
|
|
@moduledoc false
|
|
|
|
use ExUnit.Case, async: false
|
|
|
|
|
|
|
|
defmodule Notifier do
|
|
|
|
use Ash.Notifier
|
|
|
|
|
|
|
|
def notify(notification) do
|
|
|
|
send(Application.get_env(__MODULE__, :notifier_test_pid), {:notification, notification})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defmodule PostLink do
|
|
|
|
use Ash.Resource,
|
|
|
|
data_layer: Ash.DataLayer.Ets,
|
|
|
|
notifiers: [
|
|
|
|
Notifier
|
|
|
|
]
|
|
|
|
|
|
|
|
ets do
|
|
|
|
private? true
|
|
|
|
end
|
|
|
|
|
|
|
|
actions do
|
2022-04-29 10:07:06 +12:00
|
|
|
defaults [:create, :read, :update, :destroy]
|
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,
|
2022-09-14 05:52:11 +12:00
|
|
|
allow_nil?: false
|
2021-01-13 09:40:55 +13:00
|
|
|
|
|
|
|
belongs_to :destination_post, Ash.Test.NotifierTest.Post,
|
|
|
|
primary_key?: true,
|
2022-09-14 05:52:11 +12:00
|
|
|
allow_nil?: false
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defmodule Comment do
|
|
|
|
use Ash.Resource,
|
|
|
|
data_layer: Ash.DataLayer.Ets,
|
|
|
|
notifiers: [
|
|
|
|
Notifier
|
|
|
|
]
|
|
|
|
|
|
|
|
ets do
|
|
|
|
private?(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
actions do
|
2022-04-29 10:07:06 +12:00
|
|
|
defaults [:create, :read, :update, :destroy]
|
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
|
|
|
|
|
|
|
attribute :name, :string
|
|
|
|
end
|
|
|
|
|
|
|
|
relationships do
|
2023-04-13 09:35:17 +12:00
|
|
|
belongs_to :post, Ash.Test.NotifierTest.Post do
|
|
|
|
attribute_writable? true
|
|
|
|
end
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defmodule Post do
|
|
|
|
@moduledoc false
|
|
|
|
use Ash.Resource,
|
|
|
|
data_layer: Ash.DataLayer.Ets,
|
|
|
|
notifiers: [
|
|
|
|
Notifier
|
|
|
|
]
|
|
|
|
|
|
|
|
ets do
|
|
|
|
private?(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
actions do
|
2022-04-29 10:07:06 +12:00
|
|
|
defaults [:create, :read, :update, :destroy]
|
2023-04-13 09:35:17 +12:00
|
|
|
|
|
|
|
create :create_with_comment do
|
|
|
|
change fn changeset, _ ->
|
|
|
|
Ash.Changeset.after_action(changeset, fn _changeset, result ->
|
|
|
|
Comment
|
|
|
|
|> Ash.Changeset.for_create(:create, %{post_id: result.id, name: "auto"})
|
|
|
|
|> Ash.Test.NotifierTest.Api.create!()
|
|
|
|
|
|
|
|
{: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
|
|
|
|
|
|
|
attribute :name, :string
|
|
|
|
end
|
|
|
|
|
|
|
|
relationships do
|
|
|
|
many_to_many :related_posts, __MODULE__,
|
|
|
|
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
|
|
|
|
2022-08-16 06:00:02 +12:00
|
|
|
has_many :comments, Comment, destination_attribute: :post_id
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-10-07 19:41:02 +13:00
|
|
|
defmodule Registry do
|
|
|
|
@moduledoc false
|
|
|
|
use Ash.Registry
|
|
|
|
|
|
|
|
entries do
|
|
|
|
entry Post
|
|
|
|
entry PostLink
|
|
|
|
entry Comment
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-10-15 17:54:02 +13:00
|
|
|
defmodule Api do
|
|
|
|
use Ash.Api
|
|
|
|
|
|
|
|
resources do
|
2021-10-07 19:41:02 +13:00
|
|
|
registry Registry
|
2020-10-15 17:54:02 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
setup do
|
|
|
|
Application.put_env(Notifier, :notifier_test_pid, self())
|
|
|
|
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "simple creates and updates" do
|
|
|
|
test "a create notification occurs" do
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.new(%{name: "foo"})
|
|
|
|
|> Api.create!()
|
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :create}}}
|
|
|
|
end
|
|
|
|
|
|
|
|
test "an update notification occurs" do
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.new(%{name: "foo"})
|
|
|
|
|> Api.create!()
|
|
|
|
|> Ash.Changeset.new(%{name: "bar"})
|
|
|
|
|> Api.update!()
|
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :update}}}
|
|
|
|
end
|
|
|
|
|
|
|
|
test "a destroy notification occurs" do
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.new(%{name: "foo"})
|
|
|
|
|> Api.create!()
|
|
|
|
|> Api.destroy!()
|
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :destroy}}}
|
|
|
|
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
|
|
|
|
|> Ash.Changeset.new(%{})
|
|
|
|
|> Ash.Changeset.before_action(fn changeset ->
|
|
|
|
{changeset,
|
|
|
|
%{
|
|
|
|
notifications: [
|
|
|
|
%Ash.Notifier.Notification{
|
|
|
|
resource: changeset.resource,
|
|
|
|
metadata: %{custom?: true}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}}
|
|
|
|
end)
|
|
|
|
|> Api.create!()
|
|
|
|
|
|
|
|
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"})
|
|
|
|
|> Api.create!()
|
|
|
|
|
|
|
|
assert_receive {:notification, %Ash.Notifier.Notification{data: %Comment{name: "auto"}}}
|
|
|
|
end
|
|
|
|
|
2022-12-10 16:55:51 +13:00
|
|
|
test "notifications use the data before its limited by a select statement" do
|
|
|
|
Comment
|
|
|
|
|> Ash.Changeset.new(%{name: "foobar"})
|
|
|
|
|> Ash.Changeset.select([:id])
|
|
|
|
|> Api.create!()
|
|
|
|
|
|
|
|
assert_receive {:notification, %Ash.Notifier.Notification{data: %{name: "foobar"}}}
|
|
|
|
end
|
|
|
|
|
|
|
|
test "notifications use the changeset after before_action callbacks" do
|
|
|
|
Comment
|
|
|
|
|> Ash.Changeset.new(%{name: "foobar"})
|
|
|
|
|> Ash.Changeset.before_action(fn changeset ->
|
|
|
|
Ash.Changeset.set_context(changeset, %{foobar: :baz})
|
|
|
|
end)
|
|
|
|
|> Ash.Changeset.select([:id])
|
|
|
|
|> Api.create!()
|
|
|
|
|
|
|
|
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
|
|
|
|
|> Ash.Changeset.new(%{})
|
|
|
|
|> Api.create!()
|
|
|
|
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.new(%{name: "foo"})
|
2022-09-20 07:44:06 +12:00
|
|
|
|> Ash.Changeset.manage_relationship(:comments, comment, type: :append_and_remove)
|
2020-10-15 17:54:02 +13:00
|
|
|
|> Api.create!()
|
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :update}, resource: Comment}}
|
|
|
|
end
|
|
|
|
|
|
|
|
test "a create notification occurs for the join through relationship" do
|
|
|
|
post =
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.new(%{name: "foo"})
|
|
|
|
|> Api.create!()
|
|
|
|
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.new(%{name: "foo"})
|
2022-09-20 07:44:06 +12:00
|
|
|
|> Ash.Changeset.manage_relationship(:related_posts, [post], type: :append_and_remove)
|
2020-10-15 17:54:02 +13:00
|
|
|
|> Api.create!()
|
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :create}, resource: PostLink}}
|
|
|
|
end
|
|
|
|
|
|
|
|
test "a destroy notification occurs for the join through relationship" do
|
|
|
|
post =
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.new(%{name: "foo"})
|
|
|
|
|> Api.create!()
|
|
|
|
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.new(%{name: "foo"})
|
2022-09-20 07:44:06 +12:00
|
|
|
|> Ash.Changeset.manage_relationship(:related_posts, [post], type: :append_and_remove)
|
2020-10-15 17:54:02 +13:00
|
|
|
|> Api.create!()
|
|
|
|
|> Ash.Changeset.new(%{})
|
2022-09-20 07:44:06 +12:00
|
|
|
|> Ash.Changeset.manage_relationship(:related_posts, [], type: :append_and_remove)
|
2020-10-15 17:54:02 +13:00
|
|
|
|> Api.update!()
|
|
|
|
|
|
|
|
assert_receive {:notification, %{action: %{type: :destroy}, resource: PostLink}}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|