aboutsummaryrefslogblamecommitdiffstats
path: root/actioncable/test/connection/test_case_test.rb
blob: 76cfb2c07c3d008c103685f931caca4b960bcb42 (plain) (tree)































































































































































































                                                                                
# frozen_string_literal: true

require "test_helper"

class SimpleConnection < ActionCable::Connection::Base
  identified_by :user_id

  class << self
    attr_accessor :disconnected_user_id
  end

  def connect
    self.user_id = request.params[:user_id] || cookies[:user_id]
  end

  def disconnect
    self.class.disconnected_user_id = user_id
  end
end

class ConnectionSimpleTest < ActionCable::Connection::TestCase
  tests SimpleConnection

  def test_connected
    connect

    assert_nil connection.user_id
  end

  def test_url_params
    connect "/cable?user_id=323"

    assert_equal "323", connection.user_id
  end

  def test_params
    connect params: { user_id: 323 }

    assert_equal "323", connection.user_id
  end

  def test_plain_cookie
    cookies["user_id"] = "456"

    connect

    assert_equal "456", connection.user_id
  end

  def test_disconnect
    cookies["user_id"] = "456"

    connect

    assert_equal "456", connection.user_id

    disconnect

    assert_equal "456", SimpleConnection.disconnected_user_id
  end
end

class Connection < ActionCable::Connection::Base
  identified_by :current_user_id
  identified_by :token

  class << self
    attr_accessor :disconnected_user_id
  end

  def connect
    self.current_user_id = verify_user
    self.token = request.headers["X-API-TOKEN"]
    logger.add_tags("ActionCable")
  end

  private

    def verify_user
      reject_unauthorized_connection unless cookies.signed[:user_id].present?
      cookies.signed[:user_id]
    end
end

class ConnectionTest < ActionCable::Connection::TestCase
  def test_connected_with_signed_cookies_and_headers
    cookies.signed["user_id"] = "456"

    connect headers: { "X-API-TOKEN" => "abc" }

    assert_equal "abc", connection.token
    assert_equal "456", connection.current_user_id
  end

  def test_connected_when_no_signed_cookies_set
    cookies["user_id"] = "456"

    assert_reject_connection { connect }
  end

  def test_connection_rejected
    assert_reject_connection { connect }
  end
end

class EncryptedCookiesConnection < ActionCable::Connection::Base
  identified_by :user_id

  def connect
    self.user_id = verify_user
  end

  private

    def verify_user
      reject_unauthorized_connection unless cookies.encrypted[:user_id].present?
      cookies.encrypted[:user_id]
    end
end

class EncryptedCookiesConnectionTest < ActionCable::Connection::TestCase
  tests EncryptedCookiesConnection

  def test_connected_with_encrypted_cookies
    cookies.encrypted["user_id"] = "456"

    connect

    assert_equal "456", connection.user_id
  end

  def test_connection_rejected
    assert_reject_connection { connect }
  end
end

class SessionConnection < ActionCable::Connection::Base
  identified_by :user_id

  def connect
    self.user_id = verify_user
  end

  private

    def verify_user
      reject_unauthorized_connection unless request.session[:user_id].present?
      request.session[:user_id]
    end
end

class SessionConnectionTest < ActionCable::Connection::TestCase
  tests SessionConnection

  def test_connected_with_encrypted_cookies
    connect session: { user_id: "789" }
    assert_equal "789", connection.user_id
  end

  def test_connection_rejected
    assert_reject_connection { connect }
  end
end

class EnvConnection < ActionCable::Connection::Base
  identified_by :user

  def connect
    self.user = verify_user
  end

  private

    def verify_user
      # Warden-like authentication
      reject_unauthorized_connection unless env["authenticator"]&.user.present?
      env["authenticator"].user
    end
end

class EnvConnectionTest < ActionCable::Connection::TestCase
  tests EnvConnection

  def test_connected_with_env
    connect env: { "authenticator" => OpenStruct.new(user: "David") }
    assert_equal "David", connection.user
  end

  def test_connection_rejected
    assert_reject_connection { connect }
  end
end