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.
159 lines
5.4 KiB
Elixir
159 lines
5.4 KiB
Elixir
defmodule Mv.Accounts.UserMemberLinkingTest do
|
|
@moduledoc """
|
|
Integration tests for User-Member linking functionality.
|
|
|
|
Tests the complete workflow of linking and unlinking members to users,
|
|
including email synchronization and validation rules.
|
|
"""
|
|
use Mv.DataCase, async: false
|
|
alias Mv.Accounts
|
|
alias Mv.Membership
|
|
|
|
setup do
|
|
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
|
%{actor: system_actor}
|
|
end
|
|
|
|
describe "User-Member Linking with Email Sync" do
|
|
test "link user to member with different email syncs member email", %{actor: actor} do
|
|
# Create user with one email
|
|
{:ok, user} = Accounts.create_user(%{email: "user@example.com"}, actor: actor)
|
|
|
|
# Create member with different email
|
|
{:ok, member} =
|
|
Membership.create_member(
|
|
%{
|
|
first_name: "John",
|
|
last_name: "Doe",
|
|
email: "member@example.com"
|
|
},
|
|
actor: actor
|
|
)
|
|
|
|
# Link user to member
|
|
{:ok, updated_user} = Accounts.update_user(user, %{member: %{id: member.id}}, actor: actor)
|
|
|
|
# Verify link exists
|
|
user_with_member =
|
|
Ash.get!(Mv.Accounts.User, updated_user.id, actor: actor, load: [:member])
|
|
|
|
assert user_with_member.member.id == member.id
|
|
|
|
# Verify member email was synced to match user email
|
|
synced_member = Ash.get!(Mv.Membership.Member, member.id, actor: actor)
|
|
assert synced_member.email == "user@example.com"
|
|
end
|
|
|
|
test "unlink member from user sets member to nil", %{actor: actor} do
|
|
# Create and link user and member
|
|
{:ok, user} = Accounts.create_user(%{email: "user@example.com"}, actor: actor)
|
|
|
|
{:ok, member} =
|
|
Membership.create_member(
|
|
%{
|
|
first_name: "Jane",
|
|
last_name: "Smith",
|
|
email: "jane@example.com"
|
|
},
|
|
actor: actor
|
|
)
|
|
|
|
{:ok, linked_user} = Accounts.update_user(user, %{member: %{id: member.id}}, actor: actor)
|
|
|
|
# Verify link exists
|
|
user_with_member = Ash.get!(Mv.Accounts.User, linked_user.id, actor: actor, load: [:member])
|
|
assert user_with_member.member.id == member.id
|
|
|
|
# Unlink by setting member to nil
|
|
{:ok, unlinked_user} = Accounts.update_user(linked_user, %{member: nil}, actor: actor)
|
|
|
|
# Verify link is removed
|
|
user_without_member =
|
|
Ash.get!(Mv.Accounts.User, unlinked_user.id, actor: actor, load: [:member])
|
|
|
|
assert is_nil(user_without_member.member)
|
|
|
|
# Verify member still exists independently
|
|
member_still_exists = Ash.get!(Mv.Membership.Member, member.id, actor: actor)
|
|
assert member_still_exists.id == member.id
|
|
end
|
|
|
|
test "cannot link member already linked to another user", %{actor: actor} do
|
|
# Create first user and link to member
|
|
{:ok, user1} = Accounts.create_user(%{email: "user1@example.com"}, actor: actor)
|
|
|
|
{:ok, member} =
|
|
Membership.create_member(
|
|
%{
|
|
first_name: "Bob",
|
|
last_name: "Wilson",
|
|
email: "bob@example.com"
|
|
},
|
|
actor: actor
|
|
)
|
|
|
|
{:ok, _linked_user1} =
|
|
Accounts.update_user(user1, %{member: %{id: member.id}}, actor: actor)
|
|
|
|
# Create second user and try to link to same member
|
|
{:ok, user2} = Accounts.create_user(%{email: "user2@example.com"}, actor: actor)
|
|
|
|
# Should fail because member is already linked
|
|
assert {:error, %Ash.Error.Invalid{}} =
|
|
Accounts.update_user(user2, %{member: %{id: member.id}}, actor: actor)
|
|
end
|
|
|
|
test "cannot change member link directly, must unlink first", %{actor: actor} do
|
|
# Create user and link to first member
|
|
{:ok, user} = Accounts.create_user(%{email: "user@example.com"}, actor: actor)
|
|
|
|
{:ok, member1} =
|
|
Membership.create_member(
|
|
%{
|
|
first_name: "Alice",
|
|
last_name: "Johnson",
|
|
email: "alice@example.com"
|
|
},
|
|
actor: actor
|
|
)
|
|
|
|
{:ok, linked_user} = Accounts.update_user(user, %{member: %{id: member1.id}}, actor: actor)
|
|
|
|
# Create second member
|
|
{:ok, member2} =
|
|
Membership.create_member(
|
|
%{
|
|
first_name: "Charlie",
|
|
last_name: "Brown",
|
|
email: "charlie@example.com"
|
|
},
|
|
actor: actor
|
|
)
|
|
|
|
# Try to directly change member link (should fail)
|
|
assert {:error, %Ash.Error.Invalid{errors: errors}} =
|
|
Accounts.update_user(linked_user, %{member: %{id: member2.id}}, actor: actor)
|
|
|
|
# Verify error message mentions "Remove existing member first"
|
|
error_messages = Enum.map(errors, & &1.message)
|
|
assert Enum.any?(error_messages, &String.contains?(&1, "Remove existing member first"))
|
|
|
|
# Two-step process: first unlink, then link new member
|
|
{:ok, unlinked_user} = Accounts.update_user(linked_user, %{member: nil}, actor: actor)
|
|
|
|
# After unlinking, member1 still has the user's email
|
|
# Change member1's email to avoid conflict when relinking to member2
|
|
{:ok, _} =
|
|
Membership.update_member(member1, %{email: "alice_changed@example.com"}, actor: actor)
|
|
|
|
{:ok, relinked_user} =
|
|
Accounts.update_user(unlinked_user, %{member: %{id: member2.id}}, actor: actor)
|
|
|
|
# Verify new link is established
|
|
user_with_new_member =
|
|
Ash.get!(Mv.Accounts.User, relinked_user.id, actor: actor, load: [:member])
|
|
|
|
assert user_with_new_member.member.id == member2.id
|
|
end
|
|
end
|
|
end
|