ash/test/reactor/notifications_test.exs
James Harton 86d74ed789
feat(Ash.Reactor): Add a Reactor extension that makes working with resources easy. (#683)
* feat: Add `Ash.Reactor` with create support.

* improvement: Add `Ash.Reactor` update support.

* improvement: Add `Ash.Reactor` destroy support.

* improvement(Ash.Reactor): Support for transactional handling of notifications.

* improvement(Ash.Reactor): Add `read` and `get` steps.

* docs: Add the beginnings of a Reactor topic.

* improvement(Ash.Reactor): add support for generic actions.

* improvement: Add `undo` capability to `create` step.

* improvement: transaction and undo working.

* docs: Start documenting undo behaviour.

* chore: Update to Reactor 0.6.

* improvement: Automatically thread Ash tracers through Reactor.

* improvement(Ash.Reactor): Add undo to generic actions.

* docs: Improve reactor documentation.

* fix: Mimic copying `Ash.Notifier` seems to break the compiler for some reason.
2024-03-02 10:26:25 +13:00

116 lines
3.4 KiB
Elixir

defmodule Ash.Test.Reactor.NotificationsTest do
@moduledoc false
use ExUnit.Case, async: true
use Mimic
import ExUnit.CaptureLog
alias Ash.Reactor.Notifications
describe "init/1" do
test "it starts an agent" do
{:ok, context} = Notifications.init(%{})
assert [] == agent_get(context.__ash_notification_agent__)
end
test "when there are already notifications in the context it stores them in the agent" do
notifications = build_notifications()
{:ok, context} =
Notifications.init(%{__unpublished_ash_notifications__: notifications})
enqueued = agent_get(context.__ash_notification_agent__)
assert enqueued == notifications
end
test "when there are already notifications in the context it removes them" do
notifications = build_notifications()
{:ok, context} =
Notifications.init(%{__unpublished_ash_notifications__: notifications})
refute is_map_key(context, :__unpublished_ash_notifications__)
end
end
describe "halt/1" do
setup do
{:ok, context} = Notifications.init(%{})
{:ok, context: context}
end
test "it stops the agent", %{context: context} do
agent = context.__ash_notification_agent__
{:ok, context} = Notifications.halt(context)
refute is_map_key(context, :__ash_notification_agent__)
refute Process.alive?(agent)
end
test "it moves any queued notifications into the context", %{context: context} do
notifications = build_notifications()
:ok = Notifications.enqueue_notifications(context, notifications)
{:ok, context} = Notifications.halt(context)
assert context.__unpublished_ash_notifications__ == notifications
end
end
describe "complete/2" do
setup do
{:ok, context} = Notifications.init(%{})
{:ok, context: context}
end
test "it publishes any queued notifications", %{context: context} do
notifications = build_notifications()
:ok = Notifications.enqueue_notifications(context, notifications)
expect(Notifications, :publish, fn actual ->
assert actual == notifications
[]
end)
assert {:ok, :result} = Notifications.complete(:result, context)
end
test "it logs a warning when there are unpublished notifications", %{context: context} do
notifications = build_notifications()
:ok = Notifications.enqueue_notifications(context, notifications)
expect(Notifications, :publish, & &1)
assert capture_log(fn ->
assert {:ok, :result} = Notifications.complete(:result, context)
end) =~ "Missed 3 notifications"
end
test "it stops the agent", %{context: context} do
agent = context.__ash_notification_agent__
{:ok, :result} = Notifications.complete(:result, context)
refute Process.alive?(agent)
end
end
describe "error/2" do
setup do
{:ok, context} = Notifications.init(%{})
{:ok, context: context}
end
test "it stops the agent", %{context: context} do
agent = context.__ash_notification_agent__
:ok = Notifications.error([:errors], context)
refute Process.alive?(agent)
end
end
defp build_notifications(how_many \\ 3) do
for i <- 1..how_many do
Ash.Notifier.Notification.new(__MODULE__.FakeResource, data: %{count: i})
end
end
defp agent_get(agent), do: Agent.get(agent, & &1)
end