130 lines
4.7 KiB
Elixir
130 lines
4.7 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
|
|
|
|
describe "User-Member Linking with Email Sync" do
|
|
test "link user to member with different email syncs member email" do
|
|
# Create user with one email
|
|
{:ok, user} = Accounts.create_user(%{email: "user@example.com"})
|
|
|
|
# Create member with different email
|
|
{:ok, member} =
|
|
Membership.create_member(%{
|
|
first_name: "John",
|
|
last_name: "Doe",
|
|
email: "member@example.com"
|
|
})
|
|
|
|
# Link user to member
|
|
{:ok, updated_user} = Accounts.update_user(user, %{member: %{id: member.id}})
|
|
|
|
# Verify link exists
|
|
user_with_member = Ash.get!(Mv.Accounts.User, updated_user.id, 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)
|
|
assert synced_member.email == "user@example.com"
|
|
end
|
|
|
|
test "unlink member from user sets member to nil" do
|
|
# Create and link user and member
|
|
{:ok, user} = Accounts.create_user(%{email: "user@example.com"})
|
|
|
|
{:ok, member} =
|
|
Membership.create_member(%{
|
|
first_name: "Jane",
|
|
last_name: "Smith",
|
|
email: "jane@example.com"
|
|
})
|
|
|
|
{:ok, linked_user} = Accounts.update_user(user, %{member: %{id: member.id}})
|
|
|
|
# Verify link exists
|
|
user_with_member = Ash.get!(Mv.Accounts.User, linked_user.id, 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})
|
|
|
|
# Verify link is removed
|
|
user_without_member = Ash.get!(Mv.Accounts.User, unlinked_user.id, load: [:member])
|
|
assert is_nil(user_without_member.member)
|
|
|
|
# Verify member still exists independently
|
|
member_still_exists = Ash.get!(Mv.Membership.Member, member.id)
|
|
assert member_still_exists.id == member.id
|
|
end
|
|
|
|
test "cannot link member already linked to another user" do
|
|
# Create first user and link to member
|
|
{:ok, user1} = Accounts.create_user(%{email: "user1@example.com"})
|
|
|
|
{:ok, member} =
|
|
Membership.create_member(%{
|
|
first_name: "Bob",
|
|
last_name: "Wilson",
|
|
email: "bob@example.com"
|
|
})
|
|
|
|
{:ok, _linked_user1} = Accounts.update_user(user1, %{member: %{id: member.id}})
|
|
|
|
# Create second user and try to link to same member
|
|
{:ok, user2} = Accounts.create_user(%{email: "user2@example.com"})
|
|
|
|
# Should fail because member is already linked
|
|
assert {:error, %Ash.Error.Invalid{}} =
|
|
Accounts.update_user(user2, %{member: %{id: member.id}})
|
|
end
|
|
|
|
test "cannot change member link directly, must unlink first" do
|
|
# Create user and link to first member
|
|
{:ok, user} = Accounts.create_user(%{email: "user@example.com"})
|
|
|
|
{:ok, member1} =
|
|
Membership.create_member(%{
|
|
first_name: "Alice",
|
|
last_name: "Johnson",
|
|
email: "alice@example.com"
|
|
})
|
|
|
|
{:ok, linked_user} = Accounts.update_user(user, %{member: %{id: member1.id}})
|
|
|
|
# Create second member
|
|
{:ok, member2} =
|
|
Membership.create_member(%{
|
|
first_name: "Charlie",
|
|
last_name: "Brown",
|
|
email: "charlie@example.com"
|
|
})
|
|
|
|
# Try to directly change member link (should fail)
|
|
assert {:error, %Ash.Error.Invalid{errors: errors}} =
|
|
Accounts.update_user(linked_user, %{member: %{id: member2.id}})
|
|
|
|
# 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})
|
|
|
|
# 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"})
|
|
|
|
{:ok, relinked_user} = Accounts.update_user(unlinked_user, %{member: %{id: member2.id}})
|
|
|
|
# Verify new link is established
|
|
user_with_new_member = Ash.get!(Mv.Accounts.User, relinked_user.id, load: [:member])
|
|
assert user_with_new_member.member.id == member2.id
|
|
end
|
|
end
|
|
end
|