- Policy tests: use Fixtures where applicable; create_custom_field() fix in custom_field_value. - Replace unused actor with _actor, remove unused alias Accounts in policy tests. - profile_navigation_test: disable Credo for intentional TODO comment.
151 lines
5.3 KiB
Elixir
151 lines
5.3 KiB
Elixir
defmodule Mv.Membership.CustomFieldPoliciesTest do
|
|
@moduledoc """
|
|
Tests for CustomField resource authorization policies.
|
|
|
|
Verifies that all authenticated users with a valid role can read custom fields,
|
|
and only admin can create/update/destroy custom fields.
|
|
"""
|
|
use Mv.DataCase, async: false
|
|
|
|
alias Mv.Membership.CustomField
|
|
|
|
setup do
|
|
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
|
%{actor: system_actor}
|
|
end
|
|
|
|
defp create_custom_field do
|
|
admin = Mv.Fixtures.user_with_role_fixture("admin")
|
|
|
|
{:ok, field} =
|
|
CustomField
|
|
|> Ash.Changeset.for_create(:create, %{
|
|
name: "test_field_#{System.unique_integer([:positive])}",
|
|
value_type: :string
|
|
})
|
|
|> Ash.create(actor: admin, domain: Mv.Membership)
|
|
|
|
field
|
|
end
|
|
|
|
describe "read access (all roles)" do
|
|
test "user with own_data can read all custom fields", %{actor: _actor} do
|
|
custom_field = create_custom_field()
|
|
user = Mv.Fixtures.user_with_role_fixture("own_data")
|
|
|
|
{:ok, fields} = Ash.read(CustomField, actor: user, domain: Mv.Membership)
|
|
ids = Enum.map(fields, & &1.id)
|
|
assert custom_field.id in ids
|
|
|
|
{:ok, fetched} = Ash.get(CustomField, custom_field.id, actor: user, domain: Mv.Membership)
|
|
assert fetched.id == custom_field.id
|
|
end
|
|
|
|
test "user with read_only can read all custom fields", %{actor: _actor} do
|
|
custom_field = create_custom_field()
|
|
user = Mv.Fixtures.user_with_role_fixture("read_only")
|
|
|
|
{:ok, fields} = Ash.read(CustomField, actor: user, domain: Mv.Membership)
|
|
ids = Enum.map(fields, & &1.id)
|
|
assert custom_field.id in ids
|
|
|
|
{:ok, fetched} = Ash.get(CustomField, custom_field.id, actor: user, domain: Mv.Membership)
|
|
assert fetched.id == custom_field.id
|
|
end
|
|
|
|
test "user with normal_user can read all custom fields", %{actor: _actor} do
|
|
custom_field = create_custom_field()
|
|
user = Mv.Fixtures.user_with_role_fixture("normal_user")
|
|
|
|
{:ok, fields} = Ash.read(CustomField, actor: user, domain: Mv.Membership)
|
|
ids = Enum.map(fields, & &1.id)
|
|
assert custom_field.id in ids
|
|
|
|
{:ok, fetched} = Ash.get(CustomField, custom_field.id, actor: user, domain: Mv.Membership)
|
|
assert fetched.id == custom_field.id
|
|
end
|
|
|
|
test "user with admin can read all custom fields", %{actor: _actor} do
|
|
custom_field = create_custom_field()
|
|
user = Mv.Fixtures.user_with_role_fixture("admin")
|
|
|
|
{:ok, fields} = Ash.read(CustomField, actor: user, domain: Mv.Membership)
|
|
ids = Enum.map(fields, & &1.id)
|
|
assert custom_field.id in ids
|
|
|
|
{:ok, fetched} = Ash.get(CustomField, custom_field.id, actor: user, domain: Mv.Membership)
|
|
assert fetched.id == custom_field.id
|
|
end
|
|
end
|
|
|
|
describe "write access - non-admin cannot create/update/destroy" do
|
|
setup %{actor: _actor} do
|
|
user = Mv.Fixtures.user_with_role_fixture("normal_user")
|
|
custom_field = create_custom_field()
|
|
%{user: user, custom_field: custom_field}
|
|
end
|
|
|
|
test "non-admin cannot create custom field (forbidden)", %{user: user} do
|
|
assert {:error, %Ash.Error.Forbidden{}} =
|
|
CustomField
|
|
|> Ash.Changeset.for_create(:create, %{
|
|
name: "forbidden_field_#{System.unique_integer([:positive])}",
|
|
value_type: :string
|
|
})
|
|
|> Ash.create(actor: user, domain: Mv.Membership)
|
|
end
|
|
|
|
test "non-admin cannot update custom field (forbidden)", %{
|
|
user: user,
|
|
custom_field: custom_field
|
|
} do
|
|
assert {:error, %Ash.Error.Forbidden{}} =
|
|
custom_field
|
|
|> Ash.Changeset.for_update(:update, %{description: "Updated"})
|
|
|> Ash.update(actor: user, domain: Mv.Membership)
|
|
end
|
|
|
|
test "non-admin cannot destroy custom field (forbidden)", %{
|
|
user: user,
|
|
custom_field: custom_field
|
|
} do
|
|
assert {:error, %Ash.Error.Forbidden{}} =
|
|
Ash.destroy(custom_field, actor: user, domain: Mv.Membership)
|
|
end
|
|
end
|
|
|
|
describe "write access - admin can create/update/destroy" do
|
|
setup %{actor: _actor} do
|
|
user = Mv.Fixtures.user_with_role_fixture("admin")
|
|
custom_field = create_custom_field()
|
|
%{user: user, custom_field: custom_field}
|
|
end
|
|
|
|
test "admin can create custom field", %{user: user} do
|
|
name = "admin_field_#{System.unique_integer([:positive])}"
|
|
|
|
assert {:ok, %CustomField{} = field} =
|
|
CustomField
|
|
|> Ash.Changeset.for_create(:create, %{name: name, value_type: :string})
|
|
|> Ash.create(actor: user, domain: Mv.Membership)
|
|
|
|
assert field.name == name
|
|
end
|
|
|
|
test "admin can update custom field", %{user: user, custom_field: custom_field} do
|
|
assert {:ok, updated} =
|
|
custom_field
|
|
|> Ash.Changeset.for_update(:update, %{description: "Admin updated"})
|
|
|> Ash.update(actor: user, domain: Mv.Membership)
|
|
|
|
assert updated.description == "Admin updated"
|
|
end
|
|
|
|
test "admin can destroy custom field", %{user: user, custom_field: custom_field} do
|
|
assert :ok = Ash.destroy(custom_field, actor: user, domain: Mv.Membership)
|
|
|
|
assert {:error, _} =
|
|
Ash.get(CustomField, custom_field.id, domain: Mv.Membership, actor: user)
|
|
end
|
|
end
|
|
end
|