96 lines
3.1 KiB
Elixir
96 lines
3.1 KiB
Elixir
defmodule Mv.Authorization.Checks.HasPermissionIntegrationTest do
|
|
@moduledoc """
|
|
Integration tests for HasPermission policy check.
|
|
|
|
These tests verify that the filter expressions generated by HasPermission
|
|
have the correct structure for relationship-based filtering.
|
|
|
|
Note: Full integration tests with real queries require resources to have
|
|
policies that use HasPermission. These tests validate filter expression
|
|
structure and ensure the relationship paths are correct.
|
|
"""
|
|
use ExUnit.Case, async: true
|
|
|
|
alias Mv.Authorization.Checks.HasPermission
|
|
|
|
# Helper to create mock actor with role
|
|
defp create_actor_with_role(permission_set_name, opts \\ []) do
|
|
actor = %{
|
|
id: "user-#{System.unique_integer([:positive])}",
|
|
role: %{permission_set_name: permission_set_name}
|
|
}
|
|
|
|
# Add member_id if provided (needed for :linked scope tests)
|
|
case Keyword.get(opts, :member_id) do
|
|
nil -> actor
|
|
member_id -> Map.put(actor, :member_id, member_id)
|
|
end
|
|
end
|
|
|
|
describe "Filter Expression Structure - :linked scope" do
|
|
test "Member filter uses user.id relationship path" do
|
|
actor = create_actor_with_role("own_data", member_id: "member-123")
|
|
authorizer = create_authorizer(Mv.Membership.Member, :read)
|
|
|
|
filter = HasPermission.auto_filter(actor, authorizer, [])
|
|
|
|
# Verify filter is not nil (should return a filter for :linked scope)
|
|
assert not is_nil(filter)
|
|
|
|
# The filter should be a valid expression (keyword list or Ash.Expr)
|
|
# We verify it's not nil and can be used in queries
|
|
assert is_list(filter) or is_map(filter)
|
|
end
|
|
|
|
test "CustomFieldValue filter uses member.user.id relationship path" do
|
|
actor = create_actor_with_role("own_data", member_id: "member-123")
|
|
authorizer = create_authorizer(Mv.Membership.CustomFieldValue, :read)
|
|
|
|
filter = HasPermission.auto_filter(actor, authorizer, [])
|
|
|
|
# Verify filter is not nil
|
|
assert not is_nil(filter)
|
|
|
|
# The filter should be a valid expression
|
|
assert is_list(filter) or is_map(filter)
|
|
end
|
|
end
|
|
|
|
describe "Filter Expression Structure - :own scope" do
|
|
test "User filter uses id == actor.id" do
|
|
actor = create_actor_with_role("own_data")
|
|
authorizer = create_authorizer(Mv.Accounts.User, :read)
|
|
|
|
filter = HasPermission.auto_filter(actor, authorizer, [])
|
|
|
|
# Verify filter is not nil (should return a filter for :own scope)
|
|
assert not is_nil(filter)
|
|
|
|
# The filter should be a valid expression
|
|
assert is_list(filter) or is_map(filter)
|
|
end
|
|
end
|
|
|
|
describe "Filter Expression Structure - :all scope" do
|
|
test "Admin can read all members without filter" do
|
|
actor = create_actor_with_role("admin")
|
|
authorizer = create_authorizer(Mv.Membership.Member, :read)
|
|
|
|
filter = HasPermission.auto_filter(actor, authorizer, [])
|
|
|
|
# :all scope should return nil (no filter needed)
|
|
assert is_nil(filter)
|
|
end
|
|
end
|
|
|
|
# Helper to create a mock authorizer
|
|
defp create_authorizer(resource, action) do
|
|
%Ash.Policy.Authorizer{
|
|
resource: resource,
|
|
subject: %{
|
|
action: %{type: action},
|
|
data: nil
|
|
}
|
|
}
|
|
end
|
|
end
|