Add centralized Actor.ensure_loaded helper
Consolidate role loading logic from HasPermission and LiveHelpers. Use Ash.Resource.Info.resource? for reliable Ash detection.
This commit is contained in:
parent
05c71132e4
commit
f2def20fce
4 changed files with 181 additions and 51 deletions
84
test/mv/authorization/actor_test.exs
Normal file
84
test/mv/authorization/actor_test.exs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
defmodule Mv.Authorization.ActorTest do
|
||||
@moduledoc """
|
||||
Tests for the Actor helper module.
|
||||
"""
|
||||
use Mv.DataCase, async: false
|
||||
|
||||
alias Mv.Accounts
|
||||
alias Mv.Authorization.Actor
|
||||
|
||||
describe "ensure_loaded/1" do
|
||||
test "returns nil when actor is nil" do
|
||||
assert Actor.ensure_loaded(nil) == nil
|
||||
end
|
||||
|
||||
test "returns actor as-is when role is already loaded" do
|
||||
# Create user with role
|
||||
{:ok, user} =
|
||||
Accounts.User
|
||||
|> Ash.Changeset.for_create(:register_with_password, %{
|
||||
email: "test#{System.unique_integer([:positive])}@example.com",
|
||||
password: "testpassword123"
|
||||
})
|
||||
|> Ash.create()
|
||||
|
||||
# Load role
|
||||
{:ok, user_with_role} = Ash.load(user, :role, domain: Mv.Accounts)
|
||||
|
||||
# Should return as-is (no additional load)
|
||||
result = Actor.ensure_loaded(user_with_role)
|
||||
assert result.id == user.id
|
||||
assert result.role != %Ash.NotLoaded{}
|
||||
end
|
||||
|
||||
test "loads role when it's NotLoaded" do
|
||||
# Create a role first
|
||||
{:ok, role} =
|
||||
Mv.Authorization.Role
|
||||
|> Ash.Changeset.for_create(:create_role, %{
|
||||
name: "Test Role #{System.unique_integer([:positive])}",
|
||||
description: "Test role",
|
||||
permission_set_name: "own_data"
|
||||
})
|
||||
|> Ash.create()
|
||||
|
||||
# Create user with role
|
||||
{:ok, user} =
|
||||
Accounts.User
|
||||
|> Ash.Changeset.for_create(:register_with_password, %{
|
||||
email: "test#{System.unique_integer([:positive])}@example.com",
|
||||
password: "testpassword123"
|
||||
})
|
||||
|> Ash.create()
|
||||
|
||||
# Assign role to user
|
||||
{:ok, user_with_role} =
|
||||
user
|
||||
|> Ash.Changeset.for_update(:update, %{})
|
||||
|> Ash.Changeset.manage_relationship(:role, role, type: :append_and_remove)
|
||||
|> Ash.update()
|
||||
|
||||
# Fetch user again WITHOUT loading role (simulates "role not preloaded" scenario)
|
||||
{:ok, user_without_role_loaded} =
|
||||
Ash.get(Accounts.User, user_with_role.id, domain: Mv.Accounts)
|
||||
|
||||
# User has role as NotLoaded (relationship not preloaded)
|
||||
assert match?(%Ash.NotLoaded{}, user_without_role_loaded.role)
|
||||
|
||||
# ensure_loaded should load it
|
||||
result = Actor.ensure_loaded(user_without_role_loaded)
|
||||
assert result.id == user.id
|
||||
refute match?(%Ash.NotLoaded{}, result.role)
|
||||
assert result.role.id == role.id
|
||||
end
|
||||
|
||||
test "handles load errors gracefully (returns original actor)" do
|
||||
# Create a plain map (not a real Ash resource)
|
||||
fake_actor = %{id: "fake", role: %Ash.NotLoaded{field: :role}}
|
||||
|
||||
# Should not crash, returns original
|
||||
result = Actor.ensure_loaded(fake_actor)
|
||||
assert result == fake_actor
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue