fix(auth): boot AshAuthentication children under the :mv otp_app

This commit is contained in:
Moritz 2026-06-16 14:33:39 +02:00 committed by moritz
parent 39df300735
commit 7f9d9646a5
2 changed files with 59 additions and 1 deletions

View file

@ -32,7 +32,7 @@ defmodule Mv.Application do
{Task.Supervisor, name: Mv.TaskSupervisor}, {Task.Supervisor, name: Mv.TaskSupervisor},
{DNSCluster, query: Application.get_env(:mv, :dns_cluster_query) || :ignore}, {DNSCluster, query: Application.get_env(:mv, :dns_cluster_query) || :ignore},
{Phoenix.PubSub, name: Mv.PubSub}, {Phoenix.PubSub, name: Mv.PubSub},
{AshAuthentication.Supervisor, otp_app: :my}, {AshAuthentication.Supervisor, otp_app: :mv},
SystemActor, SystemActor,
# Start a worker by calling: Mv.Worker.start_link(arg) # Start a worker by calling: Mv.Worker.start_link(arg)
# {Mv.Worker, arg}, # {Mv.Worker, arg},

View file

@ -0,0 +1,58 @@
defmodule Mv.ApplicationTest do
@moduledoc """
Guards the AshAuthentication supervisor wiring in `Mv.Application`.
The auth children (token Expunger, audit-log batcher/expunger) resolve their
configuration via `Spark.sparks(otp_app, Ash.Resource)`. With the wrong
`otp_app` they silently start against an empty resource set: the token
Expunger then runs against no token resources and becomes a no-op. This test
pins the corrected `:mv` wiring against the *running* application tree: the
supervisor and all three children are present, and the token Expunger booted
live and resolved the real `:mv` token resource.
The two audit-log children legitimately report an `:undefined` pid because no
`AuditLogResource` resources exist under `:mv` (their init returns `:ignore`);
that is a successful start, not a crash, so they are only asserted present.
"""
use ExUnit.Case, async: false
alias AshAuthentication.TokenResource.Expunger
test "AshAuthentication children boot under the :mv otp_app and resolve real config" do
# Locate the running AshAuthentication.Supervisor inside the live app tree.
auth_sup =
Mv.Supervisor
|> Supervisor.which_children()
|> Enum.find_value(fn
{AshAuthentication.Supervisor, pid, _type, _mods} when is_pid(pid) -> pid
_ -> nil
end)
assert is_pid(auth_sup), "AshAuthentication.Supervisor is not running in Mv.Supervisor"
children = Supervisor.which_children(auth_sup)
child_ids = children |> Enum.map(&elem(&1, 0)) |> Enum.sort()
# All three auth children are present in the supervision tree.
assert child_ids ==
Enum.sort([
AshAuthentication.TokenResource.Expunger,
AshAuthentication.AuditLogResource.Batcher,
AshAuthentication.AuditLogResource.Expunger
])
# The token Expunger booted as a live process and resolved the real :mv
# token resource — proving the children run against non-empty :mv config
# rather than the empty set the wrong otp_app produced.
expunger_pid =
Enum.find_value(children, fn
{Expunger, pid, _, _} when is_pid(pid) -> pid
_ -> nil
end)
assert is_pid(expunger_pid), "token Expunger did not boot as a live process under :mv"
assert Process.alive?(expunger_pid)
assert %{otp_app: :mv, resources: resources} = :sys.get_state(expunger_pid)
assert Map.has_key?(resources, Mv.Accounts.Token)
end
end