<file_sep>require 'spec_helper'

describe FlowdockRails::Configuration do
  describe 'retive configuration' do
    before(:all) do
      sources = { test1: '123', test2: '456' }
      @config = FlowdockRails::Configuration.new(sources)
    end

    it 'should return flow token by source' do
      expect(@config.test1).to eq('123')
    end

    it 'should return nil if source does not exist' do
      expect(@config.test3).to be_nil
    end

    it 'should be invalid for development env' do
      expect(@config.valid_env?).to be false
    end

    it 'should invalid for development env' do
      config = FlowdockRails::Configuration.new
      config.environments = %w(test development)
      expect(config.valid_env?).to be true
    end

    it 'should deactivate using env var' do
      ClimateControl.modify FLOWDOCK_ENABLED: 'false' do
        config = FlowdockRails::Configuration.new
        expect(config.active?).to be false
      end
    end

    it 'should be active by default' do
      expect(@config.active?).to be true
    end
  end
end
<file_sep>$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
require 'flowdock_rails'
require 'webmock/rspec'
require 'byebug'
require 'climate_control'
<file_sep>require 'flowdock_rails/version'
require 'active_support'

module FlowdockRails
  extend ActiveSupport::Autoload
  autoload :Configuration

  autoload_under 'models' do
    autoload :Flowdock
    autoload :Message
  end

  module Utils
    extend ActiveSupport::Autoload
    autoload :Network
  end

  def self.configure
    yield configuration
  end

  def self.configuration
    @configuration ||= Configuration.new
  end
end
<file_sep>require 'flowdock_rails'

FlowdockRails.configure do |config|
  # You can configure more than one source.
  # https://www.flowdock.com/api/sources
  #
  # config.sources = { main: 'token', bugs: 'token' }

  # Configure env allowed to post messages
  # default: production
  #
  # config.environments = %w(production)
end
<file_sep>module FlowdockRails
  class Configuration
    attr_accessor :sources, :environments

    def initialize(sources = {})
      @sources = sources
      @environments = %w(production)
    end

    def valid_env?
      @environments.include?(ENV['RAILS_ENV'] || 'development')
    end

    def active?
      !(ENV['FLOWDOCK_ENABLED']&.downcase == 'false')
    end

    def method_missing(m)
      return unless @sources[m]
      @sources[m]
    end
  end
end
<file_sep>require 'spec_helper'

describe FlowdockRails::Message do
  before(:all) do
    attributes = { thread_id: '123', text: 'Ok', tags: %w(a b) }
    @instance = FlowdockRails::Message.new(attributes)
  end

  it 'should initialize attributes' do
    expect(@instance.thread_id).to eq('123')
    expect(@instance.text).to eq('Ok')
    expect(@instance.tags).to eq(%w(a b))
  end

  it 'should format tags' do
    expected_tags = '#a,#b'
    expect(@instance.format_tags).to eq(expected_tags)
  end

  it 'should check if message is from a thread' do
    expect(@instance.thread?).to be true
  end

  it 'should have sent flag false' do
    expect(@instance.sent?).to be false
  end

  it 'should have sent flag true' do
    instance = FlowdockRails::Message.new
    instance.sent
    expect(instance.sent?).to be true
  end

  it 'should create bullet message' do
    lines = ['**Title**', 'bullet 1', 'time: today']
    instance = FlowdockRails::Message.new(lines: lines)
    expected = "**Title**\nbullet 1\ntime: today"
    expect(instance.text).to eq(expected)
  end
end
<file_sep>require 'faraday_middleware'

module FlowdockRails
  module Utils
    module Network
      def connection
        @conn ||= Faraday.new(url: 'https://api.flowdock.com') do |conn|
          conn.request  :url_encoded
          conn.response :logger
          conn.response :json
          conn.adapter  Faraday.default_adapter
        end
      end

      def post(url, params = {})
        connection.post do |req|
          req.url url
          req.headers['Content-Type'] = 'application/json'
          req.headers['X-flowdock-wait-for-message'] = 'true'
          req.body = params.to_json
        end
      end
    end
  end
end
<file_sep>require 'spec_helper'

describe FlowdockRails do
  it 'has a version number' do
    expect(FlowdockRails::VERSION).not_to be nil
  end
end
<file_sep># Flowdock Rails

Simple to post message to flowdock

## Installation

Add this line to your application's Gemfile:
```rb
gem 'flowdock_rails'
```

## Usage

* Add initializer to use yor config
```sh
rails g flowdock_rails:config
```

Configure
* sources
* environments
```rb
# config/initializers/flowdock_rails.rb
require 'flowdock_rails'

FlowdockRails.configure do |config|
  # You can configure more than one source.
  # https://www.flowdock.com/api/sources
  #
  config.sources = { source_name: 'flowdock_token' }

  # Configure env allowed to post messages
  # default: production
  #
  config.environments = %w(production development)
end
```

Sample
```ruby
# Message
attributes = { text: 'Ok', tags: %w(a b) }
message = FlowdockRails::Message.new(attributes)

flow = FlowdockRails::Flowdock.new(:source_name)
flow.post_message(message)
```

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/aaroalan/flowdock_rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.


## License

The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
<file_sep>require 'spec_helper'

describe FlowdockRails::Flowdock do
  before(:each) do
    sources = { test1: '123' }
    configuration = FlowdockRails::Configuration.new(sources)
    configuration.environments = %w(development test)
    allow(FlowdockRails).to receive(:configuration).and_return(configuration)
  end

  it 'is initialized with a source' do
    instance = FlowdockRails::Flowdock.new(:test1)
    expect(instance.source).to eq(:test1)
  end

  it 'should not be ready if source is invalid' do
    instance = FlowdockRails::Flowdock.new(:test2)
    expect(instance.ready?).to be false
  end

  it 'should be ready if source is valid' do
    instance = FlowdockRails::Flowdock.new(:test1)
    expect(instance.ready?).to be true
  end

  it 'should format params' do
    attributes = { thread_id: '456', text: 'Ok', tags: %w(a b) }
    message = FlowdockRails::Message.new(attributes)
    instance = FlowdockRails::Flowdock.new(:test1)
    params = instance.send(:format_params, message)
    expected = { thread_id: '456', content: 'Ok', tags: '#a,#b',
                 flow_token: '123', event: 'message' }
    expect(params).to eq(expected)
  end

  it 'should raise error if is not ready' do
    instance = FlowdockRails::Flowdock.new(:ok)
    expected = 'Instance is not ready'
    expect { instance.post_message(1) }.to raise_error(expected)
  end

  it 'should update message' do
    json_response = { thread_id: 'aaazzz' }
    stub_request(:any, /.*flowdock.*/)
      .to_return(body: json_response.to_json, status: 200)
    attributes = { text: 'Ok', tags: %w(a b) }
    message = FlowdockRails::Message.new(attributes)
    instance = FlowdockRails::Flowdock.new(:test1)
    new_message = instance.post_message(message)

    expect(new_message.thread_id).to eq('aaazzz')
    expect(new_message.sent?).to be true
  end

  it 'should return nil if environments is not allowed' do
    sources = { test1: '123' }
    configuration = FlowdockRails::Configuration.new(sources)
    configuration.environments = %w(production)
    allow(FlowdockRails).to receive(:configuration).and_return(configuration)
    instance = FlowdockRails::Flowdock.new(:test1)

    expect(instance.post_message(1)).to be_nil
  end

  it 'should not post message if flowdock is not enabled' do
    ClimateControl.modify FLOWDOCK_ENABLED: 'false' do
      instance = FlowdockRails::Flowdock.new(:test1)
      expect(instance.post_message(nil)).to be_nil
    end
  end
end
<file_sep>module FlowdockRails
  class Flowdock
    include FlowdockRails::Utils::Network

    attr_reader :source

    def initialize(source)
      @source = source
      @flow_token = FlowdockRails.configuration.send(source)
    end

    def ready?
      !@flow_token.nil?
    end

    def post_message(message)
      return unless enabled?
      raise 'Instance is not ready' unless ready?
      params = format_params(message)
      response = post('/messages', params)
      message.thread_id = response.body['thread_id']
      message.sent
      message
    end

    def enabled?
      FlowdockRails.configuration.valid_env? &&
        FlowdockRails.configuration.active?
    end

    private

    def format_params(message)
      {
        thread_id: message.thread_id, content: message.text.to_s,
        tags: message.format_tags, flow_token: @flow_token, event: 'message'
      }.reject { |_, v| v.nil? }
    end
  end
end
<file_sep>module FlowdockRails
  # Create a message you can apply markdown to text multile line
  # text
  class Message
    attr_accessor :thread_id, :text, :tags, :lines
    def initialize(attributes = {})
      @thread_id = attributes[:thread_id]
      @text = attributes[:text]
      @tags = attributes[:tags] || []
      @lines = attributes[:lines] || []
      @sent = false
    end

    def format_tags
      @tags.map { |e| '#' + e.to_s }.join(',')
    end

    def thread?
      !@thread_id.nil?
    end

    def sent?
      @sent
    end

    def sent
      @sent = true
    end

    def text
      return lines.join("\n") if @lines.any?
      @text
    end
  end
end
