defmodule Mv.Accounts.UserMemberDeletionTest do @moduledoc """ Tests for ON DELETE SET NULL constraint on users.member_id. When a member is deleted, the linked user should remain but with member_id set to NULL. """ use Mv.DataCase, async: true alias Mv.Accounts alias Mv.Membership describe "User remains when linked Member is deleted (ON DELETE SET NULL)" do @valid_user_attrs %{ email: "test@example.com" } @valid_member_attrs %{ first_name: "John", last_name: "Doe", email: "john@example.com" } setup do system_actor = Mv.Helpers.SystemActor.get_system_actor() %{actor: system_actor} end test "deleting a member sets the user's member_id to NULL", %{actor: actor} do # Create a member {:ok, member} = Membership.create_member(@valid_member_attrs, actor: actor) # Create a user linked to the member {:ok, user} = Accounts.create_user(Map.put(@valid_user_attrs, :member, %{id: member.id}), actor: actor) # Verify the relationship is established {:ok, user_before_delete} = Ash.get(Mv.Accounts.User, user.id, actor: actor, load: [:member]) assert user_before_delete.member_id == member.id assert user_before_delete.member.id == member.id # Delete the member :ok = Membership.destroy_member(member, actor: actor) # Verify the user still exists but member_id is NULL {:ok, user_after_delete} = Ash.get(Mv.Accounts.User, user.id, actor: actor, load: [:member]) assert user_after_delete.id == user.id assert user_after_delete.member_id == nil assert user_after_delete.member == nil end test "user can be linked to a new member after old member is deleted", %{actor: actor} do # Create first member {:ok, member1} = Membership.create_member(@valid_member_attrs, actor: actor) # Create user linked to first member {:ok, user} = Accounts.create_user(Map.put(@valid_user_attrs, :member, %{id: member1.id}), actor: actor) assert user.member_id == member1.id # Delete first member :ok = Membership.destroy_member(member1, actor: actor) # Reload user from database to get updated member_id (should be NULL) {:ok, user_after_delete} = Ash.get(Mv.Accounts.User, user.id, actor: actor) assert user_after_delete.member_id == nil # Create second member {:ok, member2} = Membership.create_member( %{ first_name: "Jane", last_name: "Smith", email: "jane@example.com" }, actor: actor ) # Link user to second member (use reloaded user) {:ok, updated_user} = Accounts.update_user(user_after_delete, %{member: %{id: member2.id}}, actor: actor) # Verify new relationship {:ok, final_user} = Ash.get(Mv.Accounts.User, updated_user.id, actor: actor, load: [:member]) assert final_user.member_id == member2.id assert final_user.member.id == member2.id end test "member without linked user can be deleted normally", %{actor: actor} do {:ok, member} = Membership.create_member(@valid_member_attrs, actor: actor) # Delete member (no users linked) assert :ok = Membership.destroy_member(member, actor: actor) # Verify member is deleted assert {:error, _} = Ash.get(Mv.Membership.Member, member.id, actor: actor) end end end