fix: CustomField policies, no system-actor fallback, guidelines

- Tests and UI pass actor for CustomField create/read/destroy; seeds use actor
- Member required-custom-fields validation uses context.actor only (no fallback)
- CODE_GUIDELINES: add rule forbidding system-actor fallbacks
This commit is contained in:
Moritz 2026-01-29 13:53:55 +01:00 committed by moritz
parent 36b5d5880b
commit 1d17c4f2dd
10 changed files with 116 additions and 43 deletions

View file

@ -20,8 +20,9 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
setup do
system_actor = Mv.Helpers.SystemActor.get_system_actor()
admin_role = Mv.Fixtures.role_fixture("admin")
# Create admin user for testing
# Create admin user for testing (must have admin role to read/manage CustomField)
{:ok, user} =
Mv.Accounts.User
|> Ash.Changeset.for_create(:register_with_password, %{
@ -30,8 +31,17 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
})
|> Ash.create(actor: system_actor)
conn = log_in_user(build_conn(), user)
%{conn: conn, user: user}
{:ok, user} =
user
|> Ash.Changeset.for_update(:update, %{})
|> Ash.Changeset.manage_relationship(:role, admin_role, type: :append_and_remove)
|> Ash.update(actor: system_actor)
user_with_role = Ash.load!(user, :role, domain: Mv.Accounts, actor: system_actor)
conn = log_in_user(build_conn(), user_with_role)
# Use English locale so "Delete" link text matches in assertions
conn = Plug.Test.init_test_session(conn, Map.put(conn.private.plug_session, "locale", "en"))
%{conn: conn, user: user_with_role}
end
describe "delete button and modal" do
@ -107,9 +117,8 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|> element("#delete-custom-field-modal form")
|> render_change(%{"slug" => custom_field.slug})
# Confirm button should be enabled now (no disabled attribute)
html = render(view)
refute html =~ ~r/disabled(?:=""|(?!\w))/
# Confirm button should be enabled now (no disabled attribute on the confirm button)
refute has_element?(view, "#delete-custom-field-modal button.btn-error[disabled]")
end
test "delete button is disabled when slug doesn't match", %{conn: conn} do
@ -126,9 +135,8 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|> element("#delete-custom-field-modal form")
|> render_change(%{"slug" => "wrong-slug"})
# Button should be disabled
html = render(view)
assert html =~ ~r/disabled(?:=""|(?!\w))/
# Confirm button should be disabled
assert has_element?(view, "#delete-custom-field-modal button.btn-error[disabled]")
end
end
@ -186,10 +194,8 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|> element("#delete-custom-field-modal form")
|> render_change(%{"slug" => "wrong-slug"})
# Button should be disabled and we cannot click it
# The test verifies that the button is properly disabled in the UI
html = render(view)
assert html =~ ~r/disabled(?:=""|(?!\w))/
# Confirm button should be disabled and we cannot click it
assert has_element?(view, "#delete-custom-field-modal button.btn-error[disabled]")
# Custom field should still exist since deletion couldn't proceed
system_actor = Mv.Helpers.SystemActor.get_system_actor()