Add actor parameter to all tests requiring authorization
All checks were successful
continuous-integration/drone/push Build is passing

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 4c846f8bba
commit a6cdeaa18d
Signed by: moritz
GPG key ID: 1020A035E5DD0824
75 changed files with 4649 additions and 2865 deletions

View file

@ -4,121 +4,177 @@ defmodule Mv.Accounts.EmailUniquenessTest do
alias Mv.Accounts
alias Mv.Membership
setup do
system_actor = Mv.Helpers.SystemActor.get_system_actor()
%{actor: system_actor}
end
describe "Email uniqueness validation - Creation" do
test "CAN create member with existing unlinked user email" do
test "CAN create member with existing unlinked user email", %{actor: actor} do
# Create a user with email
{:ok, _user} =
Accounts.create_user(%{
email: "existing@example.com"
})
Accounts.create_user(
%{
email: "existing@example.com"
},
actor: actor
)
# Create member with same email - should succeed
{:ok, member} =
Membership.create_member(%{
first_name: "John",
last_name: "Doe",
email: "existing@example.com"
})
Membership.create_member(
%{
first_name: "John",
last_name: "Doe",
email: "existing@example.com"
},
actor: actor
)
assert to_string(member.email) == "existing@example.com"
end
test "CAN create user with existing unlinked member email" do
test "CAN create user with existing unlinked member email", %{actor: actor} do
# Create a member with email
{:ok, _member} =
Membership.create_member(%{
first_name: "John",
last_name: "Doe",
email: "existing@example.com"
})
Membership.create_member(
%{
first_name: "John",
last_name: "Doe",
email: "existing@example.com"
},
actor: actor
)
# Create user with same email - should succeed
{:ok, user} =
Accounts.create_user(%{
email: "existing@example.com"
})
Accounts.create_user(
%{
email: "existing@example.com"
},
actor: actor
)
assert to_string(user.email) == "existing@example.com"
end
end
describe "Email uniqueness validation - Updating unlinked entities" do
test "unlinked member email CAN be changed to an existing unlinked user email" do
test "unlinked member email CAN be changed to an existing unlinked user email", %{
actor: actor
} do
# Create a user with email
{:ok, _user} =
Accounts.create_user(%{
email: "existing_user@example.com"
})
Accounts.create_user(
%{
email: "existing_user@example.com"
},
actor: actor
)
# Create an unlinked member with different email
{:ok, member} =
Membership.create_member(%{
first_name: "John",
last_name: "Doe",
email: "member@example.com"
})
Membership.create_member(
%{
first_name: "John",
last_name: "Doe",
email: "member@example.com"
},
actor: actor
)
# Change member email to existing user email - should succeed (member is unlinked)
{:ok, updated_member} =
Membership.update_member(member, %{
email: "existing_user@example.com"
})
Membership.update_member(
member,
%{
email: "existing_user@example.com"
},
actor: actor
)
assert to_string(updated_member.email) == "existing_user@example.com"
end
test "unlinked user email CAN be changed to an existing unlinked member email" do
test "unlinked user email CAN be changed to an existing unlinked member email", %{
actor: actor
} do
# Create a member with email
{:ok, _member} =
Membership.create_member(%{
first_name: "John",
last_name: "Doe",
email: "existing_member@example.com"
})
Membership.create_member(
%{
first_name: "John",
last_name: "Doe",
email: "existing_member@example.com"
},
actor: actor
)
# Create an unlinked user with different email
{:ok, user} =
Accounts.create_user(%{
email: "user@example.com"
})
Accounts.create_user(
%{
email: "user@example.com"
},
actor: actor
)
# Change user email to existing member email - should succeed (user is unlinked)
{:ok, updated_user} =
Accounts.update_user(user, %{
email: "existing_member@example.com"
})
Accounts.update_user(
user,
%{
email: "existing_member@example.com"
},
actor: actor
)
assert to_string(updated_user.email) == "existing_member@example.com"
end
test "unlinked member email CANNOT be changed to an existing linked user email" do
test "unlinked member email CANNOT be changed to an existing linked user email", %{
actor: actor
} do
# Create a user and link it to a member - this makes the user "linked"
{:ok, user} =
Accounts.create_user(%{
email: "linked_user@example.com"
})
Accounts.create_user(
%{
email: "linked_user@example.com"
},
actor: actor
)
{:ok, _member_a} =
Membership.create_member(%{
first_name: "Member",
last_name: "A",
email: "temp@example.com",
user: %{id: user.id}
})
Membership.create_member(
%{
first_name: "Member",
last_name: "A",
email: "temp@example.com",
user: %{id: user.id}
},
actor: actor
)
# Create an unlinked member with different email
{:ok, member_b} =
Membership.create_member(%{
first_name: "Member",
last_name: "B",
email: "member_b@example.com"
})
Membership.create_member(
%{
first_name: "Member",
last_name: "B",
email: "member_b@example.com"
},
actor: actor
)
# Try to change unlinked member's email to linked user's email - should fail
result =
Membership.update_member(member_b, %{
email: "linked_user@example.com"
})
Membership.update_member(
member_b,
%{
email: "linked_user@example.com"
},
actor: actor
)
assert {:error, %Ash.Error.Invalid{} = error} = result
@ -129,37 +185,52 @@ defmodule Mv.Accounts.EmailUniquenessTest do
end)
end
test "unlinked user email CANNOT be changed to an existing linked member email" do
test "unlinked user email CANNOT be changed to an existing linked member email", %{
actor: actor
} do
# Create a user and link it to a member - this makes the member "linked"
{:ok, user_a} =
Accounts.create_user(%{
email: "user_a@example.com"
})
Accounts.create_user(
%{
email: "user_a@example.com"
},
actor: actor
)
{:ok, _member_a} =
Membership.create_member(%{
first_name: "Member",
last_name: "A",
email: "temp@example.com",
user: %{id: user_a.id}
})
Membership.create_member(
%{
first_name: "Member",
last_name: "A",
email: "temp@example.com",
user: %{id: user_a.id}
},
actor: actor
)
# Reload user to get updated member_id and linked member email
{:ok, user_a_reloaded} = Ash.get(Mv.Accounts.User, user_a.id)
{:ok, user_a_with_member} = Ash.load(user_a_reloaded, :member)
{:ok, user_a_reloaded} = Ash.get(Mv.Accounts.User, user_a.id, actor: actor)
{:ok, user_a_with_member} = Ash.load(user_a_reloaded, :member, actor: actor)
linked_member_email = to_string(user_a_with_member.member.email)
# Create an unlinked user with different email
{:ok, user_b} =
Accounts.create_user(%{
email: "user_b@example.com"
})
Accounts.create_user(
%{
email: "user_b@example.com"
},
actor: actor
)
# Try to change unlinked user's email to linked member's email - should fail
result =
Accounts.update_user(user_b, %{
email: linked_member_email
})
Accounts.update_user(
user_b,
%{
email: linked_member_email
},
actor: actor
)
assert {:error, %Ash.Error.Invalid{} = error} = result
@ -172,28 +243,37 @@ defmodule Mv.Accounts.EmailUniquenessTest do
end
describe "Email uniqueness validation - Creating with linked emails" do
test "CANNOT create member with existing linked user email" do
test "CANNOT create member with existing linked user email", %{actor: actor} do
# Create a user and link it to a member
{:ok, user} =
Accounts.create_user(%{
email: "linked@example.com"
})
Accounts.create_user(
%{
email: "linked@example.com"
},
actor: actor
)
{:ok, _member} =
Membership.create_member(%{
first_name: "First",
last_name: "Member",
email: "temp@example.com",
user: %{id: user.id}
})
Membership.create_member(
%{
first_name: "First",
last_name: "Member",
email: "temp@example.com",
user: %{id: user.id}
},
actor: actor
)
# Try to create a new member with the linked user's email - should fail
result =
Membership.create_member(%{
first_name: "Second",
last_name: "Member",
email: "linked@example.com"
})
Membership.create_member(
%{
first_name: "Second",
last_name: "Member",
email: "linked@example.com"
},
actor: actor
)
assert {:error, %Ash.Error.Invalid{} = error} = result
@ -204,31 +284,40 @@ defmodule Mv.Accounts.EmailUniquenessTest do
end)
end
test "CANNOT create user with existing linked member email" do
test "CANNOT create user with existing linked member email", %{actor: actor} do
# Create a user and link it to a member
{:ok, user} =
Accounts.create_user(%{
email: "user@example.com"
})
Accounts.create_user(
%{
email: "user@example.com"
},
actor: actor
)
{:ok, _member} =
Membership.create_member(%{
first_name: "Member",
last_name: "One",
email: "temp@example.com",
user: %{id: user.id}
})
Membership.create_member(
%{
first_name: "Member",
last_name: "One",
email: "temp@example.com",
user: %{id: user.id}
},
actor: actor
)
# Reload user to get the linked member's email
{:ok, user_reloaded} = Ash.get(Mv.Accounts.User, user.id)
{:ok, user_with_member} = Ash.load(user_reloaded, :member)
{:ok, user_reloaded} = Ash.get(Mv.Accounts.User, user.id, actor: actor)
{:ok, user_with_member} = Ash.load(user_reloaded, :member, actor: actor)
linked_member_email = to_string(user_with_member.member.email)
# Try to create a new user with the linked member's email - should fail
result =
Accounts.create_user(%{
email: linked_member_email
})
Accounts.create_user(
%{
email: linked_member_email
},
actor: actor
)
assert {:error, %Ash.Error.Invalid{} = error} = result
@ -241,32 +330,45 @@ defmodule Mv.Accounts.EmailUniquenessTest do
end
describe "Email uniqueness validation - Updating linked entities" do
test "linked member email CANNOT be changed to an existing user email" do
test "linked member email CANNOT be changed to an existing user email", %{actor: actor} do
# Create a user with email
{:ok, _other_user} =
Accounts.create_user(%{
email: "other_user@example.com"
})
Accounts.create_user(
%{
email: "other_user@example.com"
},
actor: actor
)
# Create a user and link it to a member
{:ok, user} =
Accounts.create_user(%{
email: "user@example.com"
})
Accounts.create_user(
%{
email: "user@example.com"
},
actor: actor
)
{:ok, member} =
Membership.create_member(%{
first_name: "John",
last_name: "Doe",
email: "temp@example.com",
user: %{id: user.id}
})
Membership.create_member(
%{
first_name: "John",
last_name: "Doe",
email: "temp@example.com",
user: %{id: user.id}
},
actor: actor
)
# Try to change linked member's email to other user's email - should fail
result =
Membership.update_member(member, %{
email: "other_user@example.com"
})
Membership.update_member(
member,
%{
email: "other_user@example.com"
},
actor: actor
)
assert {:error, %Ash.Error.Invalid{} = error} = result
@ -277,37 +379,50 @@ defmodule Mv.Accounts.EmailUniquenessTest do
end)
end
test "linked user email CANNOT be changed to an existing member email" do
test "linked user email CANNOT be changed to an existing member email", %{actor: actor} do
# Create a member with email
{:ok, _other_member} =
Membership.create_member(%{
first_name: "Jane",
last_name: "Doe",
email: "other_member@example.com"
})
Membership.create_member(
%{
first_name: "Jane",
last_name: "Doe",
email: "other_member@example.com"
},
actor: actor
)
# Create a user and link it to a member
{:ok, user} =
Accounts.create_user(%{
email: "user@example.com"
})
Accounts.create_user(
%{
email: "user@example.com"
},
actor: actor
)
{:ok, _member} =
Membership.create_member(%{
first_name: "John",
last_name: "Doe",
email: "temp@example.com",
user: %{id: user.id}
})
Membership.create_member(
%{
first_name: "John",
last_name: "Doe",
email: "temp@example.com",
user: %{id: user.id}
},
actor: actor
)
# Reload user to get updated member_id
{:ok, user_reloaded} = Ash.get(Mv.Accounts.User, user.id)
{:ok, user_reloaded} = Ash.get(Mv.Accounts.User, user.id, actor: actor)
# Try to change linked user's email to other member's email - should fail
result =
Accounts.update_user(user_reloaded, %{
email: "other_member@example.com"
})
Accounts.update_user(
user_reloaded,
%{
email: "other_member@example.com"
},
actor: actor
)
assert {:error, %Ash.Error.Invalid{} = error} = result
@ -320,34 +435,49 @@ defmodule Mv.Accounts.EmailUniquenessTest do
end
describe "Email uniqueness validation - Linking" do
test "CANNOT link user to member if user email is already used by another unlinked member" do
test "CANNOT link user to member if user email is already used by another unlinked member", %{
actor: actor
} do
# Create a member with email
{:ok, _other_member} =
Membership.create_member(%{
first_name: "Jane",
last_name: "Doe",
email: "duplicate@example.com"
})
Membership.create_member(
%{
first_name: "Jane",
last_name: "Doe",
email: "duplicate@example.com"
},
actor: actor
)
# Create a user with same email
{:ok, user} =
Accounts.create_user(%{
email: "duplicate@example.com"
})
Accounts.create_user(
%{
email: "duplicate@example.com"
},
actor: actor
)
# Create a member to link with the user
{:ok, member} =
Membership.create_member(%{
first_name: "John",
last_name: "Smith",
email: "john@example.com"
})
Membership.create_member(
%{
first_name: "John",
last_name: "Smith",
email: "john@example.com"
},
actor: actor
)
# Try to link user to member - should fail because user.email is already used by other_member
result =
Accounts.update_user(user, %{
member: %{id: member.id}
})
Accounts.update_user(
user,
%{
member: %{id: member.id}
},
actor: actor
)
assert {:error, %Ash.Error.Invalid{} = error} = result
@ -358,120 +488,160 @@ defmodule Mv.Accounts.EmailUniquenessTest do
end)
end
test "CAN link member to user even if member email is used by another user (member email gets overridden)" do
test "CAN link member to user even if member email is used by another user (member email gets overridden)",
%{actor: actor} do
# Create a user with email
{:ok, _other_user} =
Accounts.create_user(%{
email: "duplicate@example.com"
})
Accounts.create_user(
%{
email: "duplicate@example.com"
},
actor: actor
)
# Create a member with same email
{:ok, member} =
Membership.create_member(%{
first_name: "John",
last_name: "Doe",
email: "duplicate@example.com"
})
Membership.create_member(
%{
first_name: "John",
last_name: "Doe",
email: "duplicate@example.com"
},
actor: actor
)
# Create a user to link with the member
{:ok, user} =
Accounts.create_user(%{
email: "user@example.com"
})
Accounts.create_user(
%{
email: "user@example.com"
},
actor: actor
)
# Link member to user - should succeed because member.email will be overridden
{:ok, updated_member} =
Membership.update_member(member, %{
user: %{id: user.id}
})
Membership.update_member(
member,
%{
user: %{id: user.id}
},
actor: actor
)
# Member email should now be the same as user email
{:ok, member_reloaded} = Ash.get(Mv.Membership.Member, updated_member.id)
{:ok, member_reloaded} = Ash.get(Mv.Membership.Member, updated_member.id, actor: actor)
assert to_string(member_reloaded.email) == "user@example.com"
end
end
describe "Email syncing" do
test "member email syncs to linked user email without validation error" do
test "member email syncs to linked user email without validation error", %{actor: actor} do
# Create a user
{:ok, user} =
Accounts.create_user(%{
email: "user@example.com"
})
Accounts.create_user(
%{
email: "user@example.com"
},
actor: actor
)
# Create a member linked to this user
# The override change will set member.email = user.email automatically
{:ok, member} =
Membership.create_member(%{
first_name: "John",
last_name: "Doe",
email: "member@example.com",
user: %{id: user.id}
})
Membership.create_member(
%{
first_name: "John",
last_name: "Doe",
email: "member@example.com",
user: %{id: user.id}
},
actor: actor
)
# Member email should have been overridden to user email
# This happens through our sync mechanism, which should NOT trigger
# the "email already used" validation because it's the same user
{:ok, member_after_link} = Ash.get(Mv.Membership.Member, member.id)
{:ok, member_after_link} = Ash.get(Mv.Membership.Member, member.id, actor: actor)
assert member_after_link.email == "user@example.com"
end
test "user email syncs to linked member without validation error" do
test "user email syncs to linked member without validation error", %{actor: actor} do
# Create a member
{:ok, member} =
Membership.create_member(%{
first_name: "John",
last_name: "Doe",
email: "member@example.com"
})
Membership.create_member(
%{
first_name: "John",
last_name: "Doe",
email: "member@example.com"
},
actor: actor
)
# Create a user linked to this member
# The override change will set member.email = user.email automatically
{:ok, _user} =
Accounts.create_user(%{
email: "user@example.com",
member: %{id: member.id}
})
Accounts.create_user(
%{
email: "user@example.com",
member: %{id: member.id}
},
actor: actor
)
# Member email should have been overridden to user email
# This happens through our sync mechanism, which should NOT trigger
# the "email already used" validation because it's the same member
{:ok, member_after_link} = Ash.get(Mv.Membership.Member, member.id)
{:ok, member_after_link} = Ash.get(Mv.Membership.Member, member.id, actor: actor)
assert member_after_link.email == "user@example.com"
end
test "two unlinked users cannot have the same email" do
test "two unlinked users cannot have the same email", %{actor: actor} do
# Create first user
{:ok, _user1} =
Accounts.create_user(%{
email: "duplicate@example.com"
})
Accounts.create_user(
%{
email: "duplicate@example.com"
},
actor: actor
)
# Try to create second user with same email
result =
Accounts.create_user(%{
email: "duplicate@example.com"
})
Accounts.create_user(
%{
email: "duplicate@example.com"
},
actor: actor
)
assert {:error, %Ash.Error.Invalid{}} = result
end
test "two unlinked members cannot have the same email (members have unique constraint)" do
test "two unlinked members cannot have the same email (members have unique constraint)", %{
actor: actor
} do
# Create first member
{:ok, _member1} =
Membership.create_member(%{
first_name: "John",
last_name: "Doe",
email: "duplicate@example.com"
})
Membership.create_member(
%{
first_name: "John",
last_name: "Doe",
email: "duplicate@example.com"
},
actor: actor
)
# Try to create second member with same email - should fail
result =
Membership.create_member(%{
first_name: "Jane",
last_name: "Smith",
email: "duplicate@example.com"
})
Membership.create_member(
%{
first_name: "Jane",
last_name: "Smith",
email: "duplicate@example.com"
},
actor: actor
)
assert {:error, %Ash.Error.Invalid{}} = result
# Members DO have a unique email constraint at database level