<commit_before>require "spec_helper"

describe Lita::Adapters::Slack::RTMConnection, lita: true do
  def with_websocket(subject, queue)
    thread = Thread.new { subject.run(queue, ping: nil) }
    thread.abort_on_exception = true
    yield queue.pop
    subject.shut_down
    thread.join
  end

  subject { described_class.new(robot, config, rtm_start_response) }

  let(:api) { instance_double("Lita::Adapters::Slack::API") }
  let(:registry) { Lita::Registry.new }
  let(:robot) { Lita::Robot.new(registry) }
  let(:rtm_start_response) do
    Lita::Adapters::Slack::TeamData.new(
      [],
      Lita::Adapters::Slack::SlackUser.new('U12345678', 'carl', nil),
      [Lita::Adapters::Slack::SlackUser.new('U12345678', 'carl', '')],
      "wss://example.com/"
    )
  end
  let(:token) { '<KEY>' }
  let(:queue) { Queue.new }
  let(:proxy_url) { "http://foo:3128" }
  let(:config) { Lita::Adapters::Slack.configuration_builder.build }

  before do
    config.token = token
  end

  describe ".build" do
    before do
      allow(Lita::Adapters::Slack::API).to receive(:new).with(config).and_return(api)
      allow(api).to receive(:rtm_start).and_return(rtm_start_response)
    end

    it "constructs a new RTMConnection with the results of rtm.start data" do
      expect(described_class.build(robot, config)).to be_an_instance_of(described_class)
    end

    it "creates users with the results of rtm.start data" do
      expect(Lita::Adapters::Slack::UserCreator).to receive(:create_users)

      described_class.build(robot, config)
    end
  end

  describe "#im_for" do
    before do
      allow(Lita::Adapters::Slack::API).to receive(:new).with(config).and_return(api)
      allow(
        Lita::Adapters::Slack::IMMapping
      ).to receive(:new).with(api, []).and_return(im_mapping)
      allow(im_mapping).to receive(:im_for).with('U12345678').and_return('D024BFF1M')
    end

    let(:im_mapping) { instance_double('Lita::Adapters::Slack::IMMapping') }

    it "delegates to the IMMapping" do
      with_websocket(subject, queue) do |websocket|
        expect(subject.im_for('U12345678')).to eq('D024BFF1M')
      end
    end
  end

  describe "#run" do
    let(:event) { double('Event', data: '{}') }
    let(:message_handler) { instance_double('Lita::Adapters::Slack::MessageHandler') }

    it "creates the WebSocket" do
      with_websocket(subject, queue) do |websocket|
        expect(websocket).to be_an_instance_of(Faye::WebSocket::Client)
      end
    end

    context "with a proxy server specified" do
      before do
        config.proxy = proxy_url
      end

      it "creates the WebSocket" do
        with_websocket(subject, queue) do |websocket|
          expect(websocket).to be_an_instance_of(Faye::WebSocket::Client)
        end
      end
    end

    it "dispatches incoming data to MessageHandler" do
      allow(Lita::Adapters::Slack::EventLoop).to receive(:defer).and_yield
      allow(Lita::Adapters::Slack::MessageHandler).to receive(:new).with(
        robot,
        'U12345678',
        {}
      ).and_return(message_handler)

      expect(message_handler).to receive(:handle)

      with_websocket(subject, queue) do |websocket|
        websocket.emit('message', event)
      end
    end
  end

  describe "#send_messages" do
    let(:message_json) { MultiJson.dump(id: 1, type: 'message', text: 'hi', channel: channel_id) }
    let(:channel_id) { 'C024BE91L' }
    let(:websocket) { instance_double("Faye::WebSocket::Client") }

    before do
      # TODO: Don't stub what you don't own!
      allow(Faye::WebSocket::Client).to receive(:new).and_return(websocket)<commit_msg>Forego testing RTMConnection#receive_message through the public interface.<commit_after>require "spec_helper"

describe Lita::Adapters::Slack::RTMConnection, lita: true do
  def with_websocket(subject, queue)
    thread = Thread.new { subject.run(queue, ping: nil) }
    thread.abort_on_exception = true
    yield queue.pop
    subject.shut_down
    thread.join
  end

  subject { described_class.new(robot, config, rtm_start_response) }

  let(:api) { instance_double("Lita::Adapters::Slack::API") }
  let(:registry) { Lita::Registry.new }
  let(:robot) { Lita::Robot.new(registry) }
  let(:rtm_start_response) do
    Lita::Adapters::Slack::TeamData.new(
      [],
      Lita::Adapters::Slack::SlackUser.new('U12345678', 'carl', nil),
      [Lita::Adapters::Slack::SlackUser.new('U12345678', 'carl', '')],
      "wss://example.com/"
    )
  end
  let(:token) { '<KEY>' }
  let(:queue) { Queue.new }
  let(:proxy_url) { "http://foo:3128" }
  let(:config) { Lita::Adapters::Slack.configuration_builder.build }

  before do
    config.token = token
  end

  describe ".build" do
    before do
      allow(Lita::Adapters::Slack::API).to receive(:new).with(config).and_return(api)
      allow(api).to receive(:rtm_start).and_return(rtm_start_response)
    end

    it "constructs a new RTMConnection with the results of rtm.start data" do
      expect(described_class.build(robot, config)).to be_an_instance_of(described_class)
    end

    it "creates users with the results of rtm.start data" do
      expect(Lita::Adapters::Slack::UserCreator).to receive(:create_users)

      described_class.build(robot, config)
    end
  end

  describe "#im_for" do
    before do
      allow(Lita::Adapters::Slack::API).to receive(:new).with(config).and_return(api)
      allow(
        Lita::Adapters::Slack::IMMapping
      ).to receive(:new).with(api, []).and_return(im_mapping)
      allow(im_mapping).to receive(:im_for).with('U12345678').and_return('D024BFF1M')
    end

    let(:im_mapping) { instance_double('Lita::Adapters::Slack::IMMapping') }

    it "delegates to the IMMapping" do
      with_websocket(subject, queue) do |websocket|
        expect(subject.im_for('U12345678')).to eq('D024BFF1M')
      end
    end
  end

  describe "#run" do
    let(:event) { double('Event', data: '{}') }
    let(:message_handler) { instance_double('Lita::Adapters::Slack::MessageHandler') }

    it "creates the WebSocket" do
      with_websocket(subject, queue) do |websocket|
        expect(websocket).to be_an_instance_of(Faye::WebSocket::Client)
      end
    end

    context "with a proxy server specified" do
      before do
        config.proxy = proxy_url
      end

      it "creates the WebSocket" do
        with_websocket(subject, queue) do |websocket|
          expect(websocket).to be_an_instance_of(Faye::WebSocket::Client)
        end
      end
    end

    it "dispatches incoming data to MessageHandler" do
      allow(Lita::Adapters::Slack::EventLoop).to receive(:defer).and_yield
      allow(Lita::Adapters::Slack::MessageHandler).to receive(:new).with(
        robot,
        'U12345678',
        {}
      ).and_return(message_handler)

      expect(message_handler).to receive(:handle)

      # Testing private methods directly is bad, but it's difficult to get
      # the timing right when testing it by emitting the "message" event on
      # the WebSocket.
      subject.send(:receive_message, event)
    end
  end

  describe "#send_messages" do
    let(:message_json) { MultiJson.dump(id: 1, type: 'message', text: 'hi', channel: channel_id) }
    let(:channel_id) { 'C024BE91L' }
    let(:websocket) { instance_double("Faye::WebSocket::Client") }

    before do
      # TODO: Don't stub what you don't own!
      allow(Faye::WebSocket::Client).to receive(:new).and_return(websocket)
{'fraction_non_alphanumeric': 0.1366945268266379, 'fraction_numerical': 0.01563763817740631, 'mean_word_length': 3.6778058007566203, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '7241681', 'n_tokens_mistral': 2621, 'n_tokens_neox': 2438, 'n_words': 481}