defmodule Mv.Authorization.ActorTest do @moduledoc """ Tests for the Actor helper module. """ use Mv.DataCase, async: false alias Mv.Accounts alias Mv.Authorization.Actor setup do system_actor = Mv.Helpers.SystemActor.get_system_actor() %{actor: system_actor} end 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", %{actor: actor} 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(actor: actor) # Load role {:ok, user_with_role} = Ash.load(user, :role, domain: Mv.Accounts, actor: actor) # 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", %{actor: actor} 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(actor: actor) # 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(actor: actor) # 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(actor: actor) # 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, actor: actor) # 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 "returns non-User actors as-is (no-op)" do # Create a plain map (not Mv.Accounts.User) other_actor = %{id: "fake", role: %Ash.NotLoaded{field: :role}} # Should return as-is (pattern match doesn't apply to non-User) result = Actor.ensure_loaded(other_actor) assert result == other_actor end end end