Add actor parameter to all tests requiring authorization

This commit adds actor: system_actor to all Ash operations in tests that
require authorization.
This commit is contained in:
Moritz 2026-01-23 20:00:24 +01:00
parent 686f69c9e9
commit 0f48a9b15a
Signed by: moritz
GPG key ID: 1020A035E5DD0824
75 changed files with 4686 additions and 2859 deletions

View file

@ -13,94 +13,99 @@ defmodule Mv.Membership.CustomFieldSlugTest do
alias Mv.Membership.CustomField
setup do
system_actor = Mv.Helpers.SystemActor.get_system_actor()
%{actor: system_actor}
end
describe "automatic slug generation on create" do
test "generates slug from name with simple ASCII text" do
test "generates slug from name with simple ASCII text", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Mobile Phone",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
assert custom_field.slug == "mobile-phone"
end
test "generates slug from name with German umlauts" do
test "generates slug from name with German umlauts", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Café Müller",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
assert custom_field.slug == "cafe-muller"
end
test "generates slug with lowercase conversion" do
test "generates slug with lowercase conversion", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "TEST NAME",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
assert custom_field.slug == "test-name"
end
test "generates slug by removing special characters" do
test "generates slug by removing special characters", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "E-Mail & Address!",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
assert custom_field.slug == "e-mail-address"
end
test "generates slug by replacing multiple spaces with single hyphen" do
test "generates slug by replacing multiple spaces with single hyphen", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Multiple Spaces",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
assert custom_field.slug == "multiple-spaces"
end
test "trims leading and trailing hyphens" do
test "trims leading and trailing hyphens", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "-Test-",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
assert custom_field.slug == "test"
end
test "handles unicode characters properly (ß becomes ss)" do
test "handles unicode characters properly (ß becomes ss)", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Straße",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
assert custom_field.slug == "strasse"
end
end
describe "slug uniqueness" do
test "prevents creating custom field with duplicate slug" do
test "prevents creating custom field with duplicate slug", %{actor: actor} do
# Create first custom field
{:ok, _custom_field} =
CustomField
@ -108,7 +113,7 @@ defmodule Mv.Membership.CustomFieldSlugTest do
name: "Test",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
# Attempt to create second custom field with same slug (different case in name)
assert {:error, %Ash.Error.Invalid{} = error} =
@ -117,19 +122,19 @@ defmodule Mv.Membership.CustomFieldSlugTest do
name: "test",
value_type: :integer
})
|> Ash.create()
|> Ash.create(actor: actor)
assert Exception.message(error) =~ "has already been taken"
end
test "allows custom fields with different slugs" do
test "allows custom fields with different slugs", %{actor: actor} do
{:ok, custom_field1} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Test One",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
{:ok, custom_field2} =
CustomField
@ -137,21 +142,21 @@ defmodule Mv.Membership.CustomFieldSlugTest do
name: "Test Two",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
assert custom_field1.slug == "test-one"
assert custom_field2.slug == "test-two"
assert custom_field1.slug != custom_field2.slug
end
test "prevents duplicate slugs when names differ only in special characters" do
test "prevents duplicate slugs when names differ only in special characters", %{actor: actor} do
{:ok, custom_field1} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Test!!!",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
assert custom_field1.slug == "test"
@ -162,7 +167,7 @@ defmodule Mv.Membership.CustomFieldSlugTest do
name: "Test???",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
# Should fail with uniqueness constraint error
assert Exception.message(error) =~ "has already been taken"
@ -170,7 +175,7 @@ defmodule Mv.Membership.CustomFieldSlugTest do
end
describe "slug immutability" do
test "slug cannot be manually set on create" do
test "slug cannot be manually set on create", %{actor: actor} do
# Attempting to set slug manually should fail because slug is not writable
result =
CustomField
@ -179,14 +184,14 @@ defmodule Mv.Membership.CustomFieldSlugTest do
value_type: :string,
slug: "custom-slug"
})
|> Ash.create()
|> Ash.create(actor: actor)
# Should fail because slug is not an accepted input
assert {:error, %Ash.Error.Invalid{}} = result
assert Exception.message(elem(result, 1)) =~ "No such input"
end
test "slug does not change when name is updated" do
test "slug does not change when name is updated", %{actor: actor} do
# Create custom field
{:ok, custom_field} =
CustomField
@ -194,7 +199,7 @@ defmodule Mv.Membership.CustomFieldSlugTest do
name: "Original Name",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
original_slug = custom_field.slug
assert original_slug == "original-name"
@ -205,7 +210,7 @@ defmodule Mv.Membership.CustomFieldSlugTest do
|> Ash.Changeset.for_update(:update, %{
name: "New Different Name"
})
|> Ash.update()
|> Ash.update(actor: actor)
# Slug should remain unchanged
assert updated_custom_field.slug == original_slug
@ -213,14 +218,14 @@ defmodule Mv.Membership.CustomFieldSlugTest do
assert updated_custom_field.name == "New Different Name"
end
test "slug cannot be manually updated" do
test "slug cannot be manually updated", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Test",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
original_slug = custom_field.slug
assert original_slug == "test"
@ -231,20 +236,20 @@ defmodule Mv.Membership.CustomFieldSlugTest do
|> Ash.Changeset.for_update(:update, %{
slug: "new-slug"
})
|> Ash.update()
|> Ash.update(actor: actor)
# Should fail because slug is not an accepted input
assert {:error, %Ash.Error.Invalid{}} = result
assert Exception.message(elem(result, 1)) =~ "No such input"
# Reload to verify slug hasn't changed
reloaded = Ash.get!(CustomField, custom_field.id)
reloaded = Ash.get!(CustomField, custom_field.id, actor: actor)
assert reloaded.slug == "test"
end
end
describe "slug edge cases" do
test "handles very long names by truncating slug" do
test "handles very long names by truncating slug", %{actor: actor} do
# Create a name at the maximum length (100 chars)
long_name = String.duplicate("abcdefghij", 10)
# 100 characters exactly
@ -255,7 +260,7 @@ defmodule Mv.Membership.CustomFieldSlugTest do
name: long_name,
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
# Slug should be truncated to maximum 100 characters
assert String.length(custom_field.slug) <= 100
@ -263,7 +268,7 @@ defmodule Mv.Membership.CustomFieldSlugTest do
assert custom_field.slug == long_name
end
test "rejects name with only special characters" do
test "rejects name with only special characters", %{actor: actor} do
# When name contains only special characters, slug would be empty
# This should fail validation
assert {:error, %Ash.Error.Invalid{} = error} =
@ -272,59 +277,59 @@ defmodule Mv.Membership.CustomFieldSlugTest do
name: "!!!",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
# Should fail because slug would be empty
error_message = Exception.message(error)
assert error_message =~ "Slug cannot be empty" or error_message =~ "is required"
end
test "handles mixed special characters and text" do
test "handles mixed special characters and text", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Test@#$%Name",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
# slugify keeps the hyphen between words
assert custom_field.slug == "test-name"
end
test "handles numbers in name" do
test "handles numbers in name", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Field 123 Test",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
assert custom_field.slug == "field-123-test"
end
test "handles consecutive hyphens in name" do
test "handles consecutive hyphens in name", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Test---Name",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
# Should reduce multiple hyphens to single hyphen
assert custom_field.slug == "test-name"
end
test "handles name with dots and underscores" do
test "handles name with dots and underscores", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "test.field_name",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
# Dots and underscores should be handled (either kept or converted)
assert custom_field.slug =~ ~r/^[a-z0-9-]+$/
@ -332,45 +337,45 @@ defmodule Mv.Membership.CustomFieldSlugTest do
end
describe "slug in queries and responses" do
test "slug is included in struct after create" do
test "slug is included in struct after create", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Test",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
# Slug should be present in the struct
assert Map.has_key?(custom_field, :slug)
assert custom_field.slug != nil
end
test "can load custom field and slug is present" do
test "can load custom field and slug is present", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Test",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
# Load it back
loaded_custom_field = Ash.get!(CustomField, custom_field.id)
loaded_custom_field = Ash.get!(CustomField, custom_field.id, actor: actor)
assert loaded_custom_field.slug == "test"
end
test "slug is returned in list queries" do
test "slug is returned in list queries", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Test",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
custom_fields = Ash.read!(CustomField)
custom_fields = Ash.read!(CustomField, actor: actor)
found = Enum.find(custom_fields, &(&1.id == custom_field.id))
assert found.slug == "test"
@ -379,18 +384,18 @@ defmodule Mv.Membership.CustomFieldSlugTest do
describe "slug-based lookup (future feature)" do
@tag :skip
test "can find custom field by slug" do
test "can find custom field by slug", %{actor: actor} do
{:ok, custom_field} =
CustomField
|> Ash.Changeset.for_create(:create, %{
name: "Test Field",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: actor)
# This test is for future implementation
# We might add a custom action like :by_slug
found = Ash.get!(CustomField, custom_field.slug, load: [:slug])
found = Ash.get!(CustomField, custom_field.slug, load: [:slug], actor: actor)
assert found.id == custom_field.id
end
end