This commit adds actor: system_actor to all Ash operations in tests that require authorization.
143 lines
5.2 KiB
Elixir
143 lines
5.2 KiB
Elixir
defmodule Mv.Membership.MemberEmailSyncTest do
|
|
@moduledoc """
|
|
Tests for email synchronization from Member to User.
|
|
When a member and user are linked, email changes should sync bidirectionally.
|
|
User.email is the source of truth when linking occurs.
|
|
"""
|
|
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 "Member email synchronization to linked User" do
|
|
@valid_user_attrs %{
|
|
email: "user@example.com"
|
|
}
|
|
|
|
@valid_member_attrs %{
|
|
first_name: "John",
|
|
last_name: "Doe",
|
|
email: "member@example.com"
|
|
}
|
|
|
|
test "updating member email syncs to linked user", %{actor: actor} do
|
|
# Create a user
|
|
{:ok, user} = Accounts.create_user(@valid_user_attrs, actor: actor)
|
|
assert to_string(user.email) == "user@example.com"
|
|
|
|
# Create a member linked to the user
|
|
{:ok, member} =
|
|
Membership.create_member(Map.put(@valid_member_attrs, :user, %{id: user.id}),
|
|
actor: actor
|
|
)
|
|
|
|
# Verify initial state - member email should be overridden by user email
|
|
{:ok, member_after_create} = Ash.get(Mv.Membership.Member, member.id, actor: actor)
|
|
assert member_after_create.email == "user@example.com"
|
|
|
|
# Update member email
|
|
{:ok, updated_member} =
|
|
Membership.update_member(member, %{email: "newmember@example.com"}, actor: actor)
|
|
|
|
assert updated_member.email == "newmember@example.com"
|
|
|
|
# Verify user email was also updated
|
|
{:ok, synced_user} = Ash.get(Mv.Accounts.User, user.id, actor: actor)
|
|
assert to_string(synced_user.email) == "newmember@example.com"
|
|
end
|
|
|
|
test "creating member linked to user syncs user email to member", %{actor: actor} do
|
|
# Create a user with their own email
|
|
{:ok, user} = Accounts.create_user(@valid_user_attrs, actor: actor)
|
|
assert to_string(user.email) == "user@example.com"
|
|
|
|
# Create a member linked to this user
|
|
{:ok, member} =
|
|
Membership.create_member(Map.put(@valid_member_attrs, :user, %{id: user.id}),
|
|
actor: actor
|
|
)
|
|
|
|
# Member should have been created with user's email (user is source of truth)
|
|
assert member.email == "user@example.com"
|
|
|
|
# Verify the link
|
|
{:ok, loaded_member} = Ash.get(Mv.Membership.Member, member.id, load: [:user], actor: actor)
|
|
assert loaded_member.user.id == user.id
|
|
end
|
|
|
|
test "linking member to existing user syncs user email to member", %{actor: actor} do
|
|
# Create a standalone user
|
|
{:ok, user} = Accounts.create_user(@valid_user_attrs, actor: actor)
|
|
assert to_string(user.email) == "user@example.com"
|
|
|
|
# Create a standalone member
|
|
{:ok, member} = Membership.create_member(@valid_member_attrs, actor: actor)
|
|
assert member.email == "member@example.com"
|
|
|
|
# Link the member to the user
|
|
{:ok, linked_member} =
|
|
Membership.update_member(member, %{user: %{id: user.id}}, actor: actor)
|
|
|
|
# Verify the link
|
|
{:ok, loaded_member} =
|
|
Ash.get(Mv.Membership.Member, linked_member.id, load: [:user], actor: actor)
|
|
|
|
assert loaded_member.user.id == user.id
|
|
|
|
# Verify member email was overridden with user email
|
|
assert loaded_member.email == "user@example.com"
|
|
end
|
|
|
|
test "updating member email when no user linked does not error", %{actor: actor} do
|
|
# Create a standalone member without user link
|
|
{:ok, member} = Membership.create_member(@valid_member_attrs, actor: actor)
|
|
assert member.email == "member@example.com"
|
|
|
|
# Load to verify no user link
|
|
{:ok, loaded_member} = Ash.get(Mv.Membership.Member, member.id, load: [:user], actor: actor)
|
|
assert loaded_member.user == nil
|
|
|
|
# Update member email - should work fine without error
|
|
{:ok, updated_member} =
|
|
Membership.update_member(member, %{email: "newemail@example.com"}, actor: actor)
|
|
|
|
assert updated_member.email == "newemail@example.com"
|
|
end
|
|
|
|
test "unlinking member from user does not sync email", %{actor: actor} do
|
|
# Create user
|
|
{:ok, user} = Accounts.create_user(@valid_user_attrs, actor: actor)
|
|
|
|
# Create member linked to user
|
|
{:ok, member} =
|
|
Membership.create_member(Map.put(@valid_member_attrs, :user, %{id: user.id}),
|
|
actor: actor
|
|
)
|
|
|
|
# Verify member email was synced to user email
|
|
{:ok, synced_member} = Ash.get(Mv.Membership.Member, member.id, actor: actor)
|
|
assert synced_member.email == "user@example.com"
|
|
|
|
# Verify link exists
|
|
{:ok, loaded_member} = Ash.get(Mv.Membership.Member, member.id, load: [:user], actor: actor)
|
|
assert loaded_member.user != nil
|
|
|
|
# Unlink member from user
|
|
{:ok, unlinked_member} = Membership.update_member(member, %{user: nil}, actor: actor)
|
|
|
|
# Verify unlink
|
|
{:ok, loaded_unlinked} =
|
|
Ash.get(Mv.Membership.Member, unlinked_member.id, load: [:user], actor: actor)
|
|
|
|
assert loaded_unlinked.user == nil
|
|
|
|
# User email should remain unchanged after unlinking
|
|
{:ok, user_after_unlink} = Ash.get(Mv.Accounts.User, user.id, actor: actor)
|
|
assert to_string(user_after_unlink.email) == "user@example.com"
|
|
end
|
|
end
|
|
end
|