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

@ -10,6 +10,8 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
alias Mv.Membership.{CustomField, CustomFieldValue, Member}
setup do
system_actor = Mv.Helpers.SystemActor.get_system_actor()
# Create test members
{:ok, member1} =
Member
@ -18,7 +20,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
last_name: "Anderson",
email: "alice@example.com"
})
|> Ash.create()
|> Ash.create(actor: system_actor)
{:ok, member2} =
Member
@ -27,7 +29,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
last_name: "Brown",
email: "bob@example.com"
})
|> Ash.create()
|> Ash.create(actor: system_actor)
{:ok, member3} =
Member
@ -36,7 +38,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
last_name: "Clark",
email: "charlie@example.com"
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Create custom fields for different types
{:ok, string_field} =
@ -45,7 +47,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
name: "membership_number",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: system_actor)
{:ok, integer_field} =
CustomField
@ -53,7 +55,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
name: "member_id_number",
value_type: :integer
})
|> Ash.create()
|> Ash.create(actor: system_actor)
{:ok, email_field} =
CustomField
@ -61,7 +63,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
name: "secondary_email",
value_type: :email
})
|> Ash.create()
|> Ash.create(actor: system_actor)
{:ok, date_field} =
CustomField
@ -69,7 +71,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
name: "birthday",
value_type: :date
})
|> Ash.create()
|> Ash.create(actor: system_actor)
{:ok, boolean_field} =
CustomField
@ -77,7 +79,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
name: "newsletter",
value_type: :boolean
})
|> Ash.create()
|> Ash.create(actor: system_actor)
%{
member1: member1,
@ -87,12 +89,14 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
integer_field: integer_field,
email_field: email_field,
date_field: date_field,
boolean_field: boolean_field
boolean_field: boolean_field,
system_actor: system_actor
}
end
describe "search with custom field values" do
test "finds member by string custom field value", %{
system_actor: system_actor,
member1: member1,
string_field: string_field
} do
@ -104,25 +108,26 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "MEMBER12345"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Force search_vector update by reloading member
{:ok, _updated_member} =
member1
|> Ash.Changeset.for_update(:update_member, %{})
|> Ash.update()
|> Ash.update(actor: system_actor)
# Search for the custom field value
results =
Member
|> Member.fuzzy_search(%{query: "MEMBER12345"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results) == 1
assert List.first(results).id == member1.id
end
test "finds member by integer custom field value", %{
system_actor: system_actor,
member1: member1,
integer_field: integer_field
} do
@ -134,25 +139,26 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: integer_field.id,
value: %{"_union_type" => "integer", "_union_value" => 42_424}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Force search_vector update
{:ok, _updated_member} =
member1
|> Ash.Changeset.for_update(:update_member, %{})
|> Ash.update()
|> Ash.update(actor: system_actor)
# Search for the custom field value
results =
Member
|> Member.fuzzy_search(%{query: "42424"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results) == 1
assert List.first(results).id == member1.id
end
test "finds member by email custom field value", %{
system_actor: system_actor,
member1: member1,
email_field: email_field
} do
@ -164,19 +170,19 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: email_field.id,
value: %{"_union_type" => "email", "_union_value" => "alice.secondary@example.com"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Force search_vector update
{:ok, _updated_member} =
member1
|> Ash.Changeset.for_update(:update_member, %{})
|> Ash.update()
|> Ash.update(actor: system_actor)
# Search for partial custom field value (should work via FTS or custom field filter)
results =
Member
|> Member.fuzzy_search(%{query: "alice.secondary"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results) == 1
assert List.first(results).id == member1.id
@ -185,7 +191,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
results_full =
Member
|> Member.fuzzy_search(%{query: "alice.secondary@example.com"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results_full) == 1
assert List.first(results_full).id == member1.id
@ -195,7 +201,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
results_domain =
Member
|> Member.fuzzy_search(%{query: "example.com"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
# Verify that member1 is in the results (may have other members too)
ids = Enum.map(results_domain, & &1.id)
@ -203,6 +209,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
end
test "finds member by date custom field value", %{
system_actor: system_actor,
member1: member1,
date_field: date_field
} do
@ -214,25 +221,26 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: date_field.id,
value: %{"_union_type" => "date", "_union_value" => ~D[1990-05-15]}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Force search_vector update
{:ok, _updated_member} =
member1
|> Ash.Changeset.for_update(:update_member, %{})
|> Ash.update()
|> Ash.update(actor: system_actor)
# Search for the custom field value (date is stored as text in search_vector)
results =
Member
|> Member.fuzzy_search(%{query: "1990-05-15"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results) == 1
assert List.first(results).id == member1.id
end
test "finds member by boolean custom field value", %{
system_actor: system_actor,
member1: member1,
boolean_field: boolean_field
} do
@ -244,25 +252,26 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: boolean_field.id,
value: %{"_union_type" => "boolean", "_union_value" => true}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Force search_vector update
{:ok, _updated_member} =
member1
|> Ash.Changeset.for_update(:update_member, %{})
|> Ash.update()
|> Ash.update(actor: system_actor)
# Search for the custom field value (boolean is stored as "true" or "false" text)
results =
Member
|> Member.fuzzy_search(%{query: "true"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
# Note: "true" might match other things, so we check that member1 is in results
assert Enum.any?(results, fn m -> m.id == member1.id end)
end
test "custom field value update triggers search_vector update", %{
system_actor: system_actor,
member1: member1,
string_field: string_field
} do
@ -274,13 +283,13 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "OLDVALUE"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Force search_vector update
{:ok, _updated_member} =
member1
|> Ash.Changeset.for_update(:update_member, %{})
|> Ash.update()
|> Ash.update(actor: system_actor)
# Update custom field value
{:ok, _updated_cfv} =
@ -288,13 +297,13 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
|> Ash.Changeset.for_update(:update, %{
value: %{"_union_type" => "string", "_union_value" => "NEWVALUE123"}
})
|> Ash.update()
|> Ash.update(actor: system_actor)
# Search for the new value
results =
Member
|> Member.fuzzy_search(%{query: "NEWVALUE123"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results) == 1
assert List.first(results).id == member1.id
@ -303,12 +312,13 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
old_results =
Member
|> Member.fuzzy_search(%{query: "OLDVALUE"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
refute Enum.any?(old_results, fn m -> m.id == member1.id end)
end
test "custom field value delete triggers search_vector update", %{
system_actor: system_actor,
member1: member1,
string_field: string_field
} do
@ -320,19 +330,19 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "TOBEDELETED"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Force search_vector update
{:ok, _updated_member} =
member1
|> Ash.Changeset.for_update(:update_member, %{})
|> Ash.update()
|> Ash.update(actor: system_actor)
# Verify it's searchable
results =
Member
|> Member.fuzzy_search(%{query: "TOBEDELETED"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results) == 1
assert List.first(results).id == member1.id
@ -344,12 +354,13 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
deleted_results =
Member
|> Member.fuzzy_search(%{query: "TOBEDELETED"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
refute Enum.any?(deleted_results, fn m -> m.id == member1.id end)
end
test "custom field value create triggers search_vector update", %{
system_actor: system_actor,
member1: member1,
string_field: string_field
} do
@ -361,19 +372,20 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "AUTOUPDATE"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Search should find it immediately (trigger should have updated search_vector)
results =
Member
|> Member.fuzzy_search(%{query: "AUTOUPDATE"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results) == 1
assert List.first(results).id == member1.id
end
test "member update includes custom field values in search_vector", %{
system_actor: system_actor,
member1: member1,
string_field: string_field
} do
@ -385,25 +397,26 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "MEMBERUPDATE"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Update member (should trigger search_vector update including custom fields)
{:ok, _updated_member} =
member1
|> Ash.Changeset.for_update(:update_member, %{notes: "Updated notes"})
|> Ash.update()
|> Ash.update(actor: system_actor)
# Search should find the custom field value
results =
Member
|> Member.fuzzy_search(%{query: "MEMBERUPDATE"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results) == 1
assert List.first(results).id == member1.id
end
test "multiple custom field values are all searchable", %{
system_actor: system_actor,
member1: member1,
string_field: string_field,
integer_field: integer_field,
@ -417,7 +430,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "MULTI1"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
{:ok, _cfv2} =
CustomFieldValue
@ -426,7 +439,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: integer_field.id,
value: %{"_union_type" => "integer", "_union_value" => 99_999}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
{:ok, _cfv3} =
CustomFieldValue
@ -435,38 +448,39 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: email_field.id,
value: %{"_union_type" => "email", "_union_value" => "multi@test.com"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Force search_vector update
{:ok, _updated_member} =
member1
|> Ash.Changeset.for_update(:update_member, %{})
|> Ash.update()
|> Ash.update(actor: system_actor)
# All values should be searchable
results1 =
Member
|> Member.fuzzy_search(%{query: "MULTI1"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert Enum.any?(results1, fn m -> m.id == member1.id end)
results2 =
Member
|> Member.fuzzy_search(%{query: "99999"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert Enum.any?(results2, fn m -> m.id == member1.id end)
results3 =
Member
|> Member.fuzzy_search(%{query: "multi@test.com"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert Enum.any?(results3, fn m -> m.id == member1.id end)
end
test "finds member by custom field value with numbers in text field (e.g. phone number)", %{
system_actor: system_actor,
member1: member1,
string_field: string_field
} do
@ -478,19 +492,19 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "M-123-456"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Force search_vector update
{:ok, _updated_member} =
member1
|> Ash.Changeset.for_update(:update_member, %{})
|> Ash.update()
|> Ash.update(actor: system_actor)
# Search for full value (should work via search_vector)
results_full =
Member
|> Member.fuzzy_search(%{query: "M-123-456"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert Enum.any?(results_full, fn m -> m.id == member1.id end),
"Full value search should find member via search_vector"
@ -501,6 +515,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
end
test "finds member by phone number in Emergency Contact custom field", %{
system_actor: system_actor,
member1: member1
} do
# Create Emergency Contact custom field
@ -510,7 +525,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
name: "Emergency Contact",
value_type: :string
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Create custom field value with phone number
phone_number = "+49 123 456789"
@ -522,19 +537,19 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: emergency_contact_field.id,
value: %{"_union_type" => "string", "_union_value" => phone_number}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Force search_vector update
{:ok, _updated_member} =
member1
|> Ash.Changeset.for_update(:update_member, %{})
|> Ash.update()
|> Ash.update(actor: system_actor)
# Search for full phone number (should work via search_vector)
results_full =
Member
|> Member.fuzzy_search(%{query: phone_number})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert Enum.any?(results_full, fn m -> m.id == member1.id end),
"Full phone number search should find member via search_vector"
@ -547,6 +562,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
describe "custom field substring search (ILIKE)" do
test "finds member by prefix of custom field value", %{
system_actor: system_actor,
member1: member1,
string_field: string_field
} do
@ -558,14 +574,14 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "Premium"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Test prefix searches - should all find the member
for prefix <- ["Premium", "Premiu", "Premi", "Prem", "Pre"] do
results =
Member
|> Member.fuzzy_search(%{query: prefix})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert Enum.any?(results, fn m -> m.id == member1.id end),
"Prefix '#{prefix}' should find member with custom field 'Premium'"
@ -573,6 +589,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
end
test "custom field search is case-insensitive", %{
system_actor: system_actor,
member1: member1,
string_field: string_field
} do
@ -584,7 +601,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "GoldMember"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Test case variations - should all find the member
for variant <- [
@ -599,7 +616,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
results =
Member
|> Member.fuzzy_search(%{query: variant})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert Enum.any?(results, fn m -> m.id == member1.id end),
"Case variant '#{variant}' should find member with custom field 'GoldMember'"
@ -607,6 +624,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
end
test "finds member by suffix/middle of custom field value", %{
system_actor: system_actor,
member1: member1,
string_field: string_field
} do
@ -618,14 +636,14 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "ActiveMember"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Test suffix and middle substring searches
for substring <- ["Member", "ember", "tiveMem", "ctive"] do
results =
Member
|> Member.fuzzy_search(%{query: substring})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert Enum.any?(results, fn m -> m.id == member1.id end),
"Substring '#{substring}' should find member with custom field 'ActiveMember'"
@ -633,6 +651,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
end
test "finds correct member among multiple with different custom field values", %{
system_actor: system_actor,
member1: member1,
member2: member2,
member3: member3,
@ -646,7 +665,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "Beginner"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
{:ok, _cfv2} =
CustomFieldValue
@ -655,7 +674,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "Advanced"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
{:ok, _cfv3} =
CustomFieldValue
@ -664,13 +683,13 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
custom_field_id: string_field.id,
value: %{"_union_type" => "string", "_union_value" => "Expert"}
})
|> Ash.create()
|> Ash.create(actor: system_actor)
# Search for "Begin" - should only find member1
results_begin =
Member
|> Member.fuzzy_search(%{query: "Begin"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results_begin) == 1
assert List.first(results_begin).id == member1.id
@ -679,7 +698,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
results_advan =
Member
|> Member.fuzzy_search(%{query: "Advan"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results_advan) == 1
assert List.first(results_advan).id == member2.id
@ -688,7 +707,7 @@ defmodule Mv.Membership.MemberSearchWithCustomFieldsTest do
results_exper =
Member
|> Member.fuzzy_search(%{query: "Exper"})
|> Ash.read!()
|> Ash.read!(actor: system_actor)
assert length(results_exper) == 1
assert List.first(results_exper).id == member3.id