Wednesday, July 15, 2026 2:53:29 AM
> connection.rb
# frozen_string_literal: true

RSpec.shared_context("connection") do
  # When nested inside "command", inherit its community/user so the
  # channel/discord_server/community/member lineage stays consistent. Without
  # this, `Community.from_discord` first_or_initializes a fresh community with
  # the schema default `player_mode_enabled: true` and admin command checks
  # all fail with "not available in player mode".
  let!(:community) do
    super()
  rescue NoMethodError
    if respond_to?(:discord_server, true)
      create(:community, discord_server: discord_server)
    else
      create(:community)
    end
  end

  let!(:user) do
    super()
  rescue NoMethodError
    create(:user)
  end

  let!(:server) { create(:server, community_id: community.id) }
  let!(:connection_server) { ESM::Arma::Server }

  # Define this in your context and include any steam uids you'd like to be
  # added to territory admins for the server
  let(:territory_admin_uids) { [] }

  # Internal, used when spawning in players
  let(:_spawned_players) { [] }

  let(:territory_moderators) { [] }
  let(:territory_build_rights) { [] }
  let(:territory_owner) { Faker::Steam.uid }
  let(:territory) do
    owner_uid = territory_owner
    create(
      :exile_territory,
      owner_uid:,
      moderators: [owner_uid] + territory_moderators,
      build_rights: [owner_uid] + territory_moderators + territory_build_rights,
      server_id: server.id
    )
  end

  def execute_sqf!(code, **)
    server.execute_sqf!(code, **)
  end

  def spawn_player_for(user)
    net_id = user.connect_to(server)
    _spawned_players << user
    net_id
  end

  def reinitialize_server!
    server.connection.close

    wait(timeout: 5).for { server.reload.connected? }.to be(true)
  end

  before do |example|
    ESM.redis.del("server_key_set")

    next unless example.metadata[:requires_connection]

    # Store the server key so the build tool can pick it up and write it
    ESM.redis.set("server_key", server.token.to_json)

    # In order to properly bind territory_admin_uids, the UIDs must be available by
    # server initialization. However, I haven't figured out an elegant way to make this
    # data available outside storing it somewhere globally and referencing it during
    # server initialization
    ESM::Test.territory_admin_uids = territory_admin_uids

    # The server.connected? check is flakey: Arma is genuinely connected but
    # the @connections map occasionally hasn't seen the public_id yet. Pause +
    # resume forces a fresh reconnect. Up to 3 attempts before we give up.
    max_attempts = 3
    attempts = 0
    begin
      attempts += 1
      connection_server.resume

      wait_for { ESM.redis.exists?("server_key_set") }.to be(true)
      wait(timeout: 5).for { server.reload.connected? }.to be(true)
    rescue RSpec::Expectations::ExpectationNotMetError
      raise "esm_arma never connected after #{max_attempts} attempts. From the esm_arma repo, please run `bin/bot_testing`" if attempts >= max_attempts

      connection_server.pause
      retry
    end

    server.reset!
  rescue ActiveRecord::ConnectionNotEstablished
    raise "Unable to connect to the Exile MySQL server. Please ensure it is running before trying again"
  end

  after do |example|
    next unless example.metadata[:requires_connection]
    next if _spawned_players.size == 0

    users = _spawned_players.join_map("\n") do |user|
      next if user.steam_uid.blank?

      "ESM_TestUser_#{user.steam_uid} call _deleteFunction;" if user.connected
    end

    sqf = ""
    if users.present?
      sqf += <<~SQF
        private _deleteFunction = {
          if (isNil "_this") exitWith {};

          deleteVehicle _this;
        };

        #{users}
      SQF
    end

    execute_sqf!(sqf) if sqf.present?
  ensure
    connection_server.pause
  end
end
All opinions represented herein are my own
- © 2024 - 2026 itsthedevman
- build 43aa0d7