<commit_before>describe Appsignal::Hooks::ActionCableHook do
  if DependencyHelper.action_cable_present?
    context "with ActionCable" do
      require "action_cable/engine"

      describe ".dependencies_present?" do
        subject { described_class.new.dependencies_present? }

        it "returns true" do
          is_expected.to be_truthy
        end
      end

      describe ActionCable::Channel::Base do
        let(:transaction) do
          Appsignal::Transaction.new(
            request_id,
            Appsignal::Transaction::ACTION_CABLE,
            ActionDispatch::Request.new(env)
          )
        end
        let(:channel) do
          Class.new(ActionCable::Channel::Base) do
            def speak(_data)
            end

            def self.to_s
              "MyChannel"
            end
          end
        end
        let(:log) { StringIO.new }
        let(:server) do
          ActionCable::Server::Base.new.tap do |s|
            s.config.logger = ActiveSupport::Logger.new(log)
          end
        end
        let(:connection) { ActionCable::Connection::Base.new(server, env) }
        let(:identifier) { { :channel => "MyChannel" }.to_json }
        let(:params) { {} }
        let(:request_id) { SecureRandom.uuid }
        let(:env) do
          http_request_env_with_data("action_dispatch.request_id" => request_id, :params => params)
        end
        let(:instance) { channel.new(connection, identifier, params) }
        subject { transaction.to_h }
        before do
          start_agent
          expect(Appsignal.active?).to be_truthy
          transaction

          expect(Appsignal::Transaction).to receive(:create)
            .with(request_id, Appsignal::Transaction::ACTION_CABLE, kind_of(ActionDispatch::Request))
            .and_return(transaction)
          allow(Appsignal::Transaction).to receive(:current).and_return(transaction)
          expect(transaction.ext).to receive(:complete) # and do nothing

          # Stub transmit call for subscribe/unsubscribe tests
          allow(connection).to receive(:websocket).and_return(double(:transmit => nil))
        end

        describe "#perform_action" do
          it "creates a transaction for an action" do
            instance.perform_action("message" => "foo", "action" => "speak")

            expect(subject).to include(
              "action" => "MyChannel#speak",
              "error" => nil,
              "id" => request_id,
              "namespace" => Appsignal::Transaction::ACTION_CABLE,
              "metadata" => {
                "method" => "websocket",<commit_msg>Use `instance_double` for stubbed websocket<commit_after>describe Appsignal::Hooks::ActionCableHook do
  if DependencyHelper.action_cable_present?
    context "with ActionCable" do
      require "action_cable/engine"

      describe ".dependencies_present?" do
        subject { described_class.new.dependencies_present? }

        it "returns true" do
          is_expected.to be_truthy
        end
      end

      describe ActionCable::Channel::Base do
        let(:transaction) do
          Appsignal::Transaction.new(
            request_id,
            Appsignal::Transaction::ACTION_CABLE,
            ActionDispatch::Request.new(env)
          )
        end
        let(:channel) do
          Class.new(ActionCable::Channel::Base) do
            def speak(_data)
            end

            def self.to_s
              "MyChannel"
            end
          end
        end
        let(:log) { StringIO.new }
        let(:server) do
          ActionCable::Server::Base.new.tap do |s|
            s.config.logger = ActiveSupport::Logger.new(log)
          end
        end
        let(:connection) { ActionCable::Connection::Base.new(server, env) }
        let(:identifier) { { :channel => "MyChannel" }.to_json }
        let(:params) { {} }
        let(:request_id) { SecureRandom.uuid }
        let(:env) do
          http_request_env_with_data("action_dispatch.request_id" => request_id, :params => params)
        end
        let(:instance) { channel.new(connection, identifier, params) }
        subject { transaction.to_h }
        before do
          start_agent
          expect(Appsignal.active?).to be_truthy
          transaction

          expect(Appsignal::Transaction).to receive(:create)
            .with(request_id, Appsignal::Transaction::ACTION_CABLE, kind_of(ActionDispatch::Request))
            .and_return(transaction)
          allow(Appsignal::Transaction).to receive(:current).and_return(transaction)
          expect(transaction.ext).to receive(:complete) # and do nothing

          # Stub transmit call for subscribe/unsubscribe tests
          allow(connection).to receive(:websocket)
            .and_return(instance_double("ActionCable::Connection::WebSocket", :transmit => nil))
        end

        describe "#perform_action" do
          it "creates a transaction for an action" do
            instance.perform_action("message" => "foo", "action" => "speak")

            expect(subject).to include(
              "action" => "MyChannel#speak",
              "error" => nil,
              "id" => request_id,
              "namespace" => Appsignal::Transaction::ACTION_CABLE,
              "metadata" => {
                "method" => "websocket",
{'fraction_non_alphanumeric': 0.10881907645722937, 'fraction_numerical': 0.0, 'mean_word_length': 2.1552238805970148, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '816125', 'n_tokens_mistral': 1436, 'n_tokens_neox': 1397, 'n_words': 281}