diff --git a/test/aprsme/cluster/leader_election_test.exs b/test/aprsme/cluster/leader_election_test.exs index 7660d76..52fb2f2 100644 --- a/test/aprsme/cluster/leader_election_test.exs +++ b/test/aprsme/cluster/leader_election_test.exs @@ -492,6 +492,34 @@ defmodule Aprsme.Cluster.LeaderElectionTest do end end + describe "handle_info(:attempt_election) with another pid holding the global key" do + test "becomes non-leader when another process holds the registration (:no path)" do + # Pre-register a different pid (not the test process) so attempt_election + # sees a foreign pid and returns :no via check_own_registration. + other = spawn(fn -> Process.sleep(:infinity) end) + :global.unregister_name(@election_key) + :global.register_name(@election_key, other) + + try do + state = %LeaderElection{ + cluster_enabled: false, + is_leader: false, + leader_node: nil + } + + assert {:noreply, new_state} = + LeaderElection.handle_info(:attempt_election, state) + + # We got the :no path. leader_node should be the foreign pid's node. + assert new_state.is_leader == false + assert new_state.leader_node == node(other) + after + Process.exit(other, :kill) + :global.unregister_name(@election_key) + end + end + end + describe "init/1 in clustered mode (schedule_initial_election(true) path)" do test "schedules :check_cluster_and_elect and :force_election_timeout" do # Capture the test process — init/1 runs in this process and sends