Merge branch 'master' into omniauth

Conflicts:
	Gemfile.lock
This commit is contained in:
Dominik Sander 2014-08-21 22:26:31 +02:00
commit 00663c153c
21 changed files with 332 additions and 91 deletions

View file

@ -99,13 +99,17 @@ AWS_SANDBOX=false
# Various Settings #
########################
# Specify the HTTP backend library for Faraday, used in WebsiteAgent.
# You can change this depending on the performance and stability you
# need for your service. Any choice other than "typhoeus",
# "net_http", or "em_http" should require you to bundle a corresponding
# gem via Gemfile.
# Specify the HTTP backend library for Faraday, commonly used by
# WebsiteAgent, RssAgent and PostAgent. You can change this depending
# on the performance and stability you need for your service. Any
# choice other than "typhoeus", "net_http", or "em_http" should
# require you to bundle a corresponding gem via Gemfile.
FARADAY_HTTP_BACKEND=typhoeus
# Specify the default User-Agent header value for HTTP requests made
# by Agents that allow overriding the User-Agent header value.
DEFAULT_HTTP_USER_AGENT="Huginn - https://github.com/cantino/huginn"
# Allow JSONPath eval expresions. i.e., $..price[?(@ < 20)]
# You should not allow this on a shared Huginn box because it is not secure.
ALLOW_JSONPATH_EVAL=false

56
Dockerfile Normal file
View file

@ -0,0 +1,56 @@
FROM ubuntu
# MAINTAINER Someone <someone@example.com>
# Update package list
RUN apt-get update
# Set environmental variables
ENV HOME /root
ENV RBENV_ROOT $HOME/.rbenv
ENV RUBY_VERSION 1.9.3-p545
ENV RUBYGEMS_VERSION 2.2.2
ENV PATH $HOME/.rbenv/shims:$HOME/.rbenv/bin:$RBENV_ROOT/versions/$RUBY_VERSION/bin:$PATH
# Install OS packages
RUN apt-get install -y build-essential curl zlib1g-dev libreadline-dev libssl-dev libcurl4-openssl-dev git libmysqlclient-dev
RUN git clone https://github.com/sstephenson/rbenv.git $HOME/.rbenv
RUN git clone https://github.com/sstephenson/ruby-build.git $HOME/.rbenv/plugins/ruby-build
# install & set global ruby version
RUN rbenv install $RUBY_VERSION
RUN rbenv global $RUBY_VERSION
WORKDIR /usr/local/src
RUN curl -O http://production.cf.rubygems.org/rubygems/rubygems-$RUBYGEMS_VERSION.tgz
RUN tar -xvf rubygems-$RUBYGEMS_VERSION.tgz
RUN cd rubygems-$RUBYGEMS_VERSION ; ruby setup.rb
RUN gem install bundle
RUN mkdir huginn
WORKDIR huginn
# Add Gemfiles and run bundle ahead of time
# This way bundle does not have to rerun unless the Gemfile changes
# It drastically speeds up rebuilds
ADD Gemfile /usr/local/src/huginn/
ADD Procfile /usr/local/src/huginn/
ADD Gemfile.lock /usr/local/src/huginn/
RUN bundle
# Now add the rest of the source
ADD . /usr/local/src/huginn/
RUN rm -rf /usr/local/src/huginn/.env
# Add the environmental variables this way so that the -e option can override them
ENV DATABASE_HOST db
ENV DATABASE_NAME huginn
ENV DATABASE_USERNAME huginn
# Expose the Rails port to the rest of the world
EXPOSE 3000
# Default command - optimized for upgradability
CMD ["foreman", "start"]

23
Gemfile
View file

@ -11,17 +11,25 @@ gem 'bundler', '>= 1.5.0'
gem 'protected_attributes', '~>1.0.8'
gem 'rails' , '4.1.4'
gem 'rails' , '4.1.5'
case RUBY_PLATFORM
when /freebsd/
# Seems FreeBSD's zoneinfo is not exactly what tzinfo expects
gem 'tzinfo-data'
else
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]
when /freebsd|netbsd|openbsd/
# ffi (required by typhoeus via ethon) merged fixes for bugs fatal
# on these platforms after 1.9.3; no following release as yet.
gem 'ffi', github: 'ffi/ffi', branch: 'master'
# tzinfo 1.2.0 has added support for reading zoneinfo on these
# platforms.
gem 'tzinfo', '>= 1.2.0'
when /solaris/
# ditto
gem 'tzinfo', '>= 1.2.0'
end
# Windows does not have zoneinfo files, so bundle the tzinfo-data gem.
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]
gem 'mysql2', '~> 0.3.16'
gem 'devise', '~> 3.2.4'
gem 'kaminari', '~> 0.16.1'
@ -120,4 +128,3 @@ else
gem 'unicorn', platform: :ruby_18
gem 'rails_12factor', platform: :ruby_18
end

View file

@ -12,27 +12,27 @@ GEM
remote: https://rubygems.org/
specs:
ace-rails-ap (2.0.1)
actionmailer (4.1.4)
actionpack (= 4.1.4)
actionview (= 4.1.4)
actionmailer (4.1.5)
actionpack (= 4.1.5)
actionview (= 4.1.5)
mail (~> 2.5.4)
actionpack (4.1.4)
actionview (= 4.1.4)
activesupport (= 4.1.4)
actionpack (4.1.5)
actionview (= 4.1.5)
activesupport (= 4.1.5)
rack (~> 1.5.2)
rack-test (~> 0.6.2)
actionview (4.1.4)
activesupport (= 4.1.4)
actionview (4.1.5)
activesupport (= 4.1.5)
builder (~> 3.1)
erubis (~> 2.7.0)
activemodel (4.1.4)
activesupport (= 4.1.4)
activemodel (4.1.5)
activesupport (= 4.1.5)
builder (~> 3.1)
activerecord (4.1.4)
activemodel (= 4.1.4)
activesupport (= 4.1.4)
activerecord (4.1.5)
activemodel (= 4.1.5)
activesupport (= 4.1.5)
arel (~> 5.0.0)
activesupport (4.1.4)
activesupport (4.1.5)
i18n (~> 0.6, >= 0.6.9)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
@ -65,7 +65,7 @@ GEM
execjs
coffee-script-source (1.7.1)
cookiejar (0.3.2)
coveralls (0.7.0)
coveralls (0.7.1)
multi_json (~> 1.3)
rest-client
simplecov (>= 0.7)
@ -77,7 +77,7 @@ GEM
debug_inspector (0.0.2)
delayed_job (4.0.2)
activesupport (>= 3.0, < 4.2)
delayed_job_active_record (4.0.1)
delayed_job_active_record (4.0.2)
activerecord (>= 3.0, < 4.2)
delayed_job (>= 3.0, < 4.1)
delorean (2.1.0)
@ -223,7 +223,7 @@ GEM
polyglot (0.3.5)
protected_attributes (1.0.8)
activemodel (>= 4.0.1, < 5.0)
pry (0.10.0)
pry (0.10.1)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
@ -232,24 +232,24 @@ GEM
rack (1.5.2)
rack-test (0.6.2)
rack (>= 1.0)
rails (4.1.4)
actionmailer (= 4.1.4)
actionpack (= 4.1.4)
actionview (= 4.1.4)
activemodel (= 4.1.4)
activerecord (= 4.1.4)
activesupport (= 4.1.4)
rails (4.1.5)
actionmailer (= 4.1.5)
actionpack (= 4.1.5)
actionview (= 4.1.5)
activemodel (= 4.1.5)
activerecord (= 4.1.5)
activesupport (= 4.1.5)
bundler (>= 1.3.0, < 2.0)
railties (= 4.1.4)
railties (= 4.1.5)
sprockets-rails (~> 2.0)
rails_12factor (0.0.2)
rails_serve_static_assets
rails_stdout_logging
rails_serve_static_assets (0.0.2)
rails_stdout_logging (0.0.3)
railties (4.1.4)
actionpack (= 4.1.4)
activesupport (= 4.1.4)
railties (4.1.5)
actionpack (= 4.1.5)
activesupport (= 4.1.5)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
raindrops (0.13.0)
@ -268,7 +268,7 @@ GEM
rspec-mocks (~> 2.99.0)
rspec-collection_matchers (1.0.0)
rspec-expectations (>= 2.99.0.beta1)
rspec-core (2.99.1)
rspec-core (2.99.2)
rspec-expectations (2.99.2)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.99.2)
@ -296,7 +296,7 @@ GEM
sass (~> 3.2.0)
sprockets (~> 2.8, <= 2.11.0)
sprockets-rails (~> 2.0)
select2-rails (3.5.9)
select2-rails (3.5.9.1)
thor (~> 0.14)
shoulda-matchers (2.6.2)
activesupport (>= 3.0.0)
@ -332,7 +332,7 @@ GEM
thor (0.19.1)
thread_safe (0.3.4)
tilt (1.4.1)
tins (1.3.0)
tins (1.3.2)
treetop (1.4.15)
polyglot
polyglot (>= 0.3.1)
@ -353,7 +353,7 @@ GEM
simple_oauth (~> 0.2.0)
typhoeus (0.6.9)
ethon (>= 0.7.1)
tzinfo (1.2.1)
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (2.5.3)
execjs (>= 0.3.0)
@ -364,7 +364,7 @@ GEM
raindrops (~> 0.7)
uuid (2.3.7)
macaddr (~> 1.0)
uuidtools (2.1.4)
uuidtools (2.1.5)
vcr (2.9.2)
warden (1.2.3)
rack (>= 1.0)
@ -430,7 +430,7 @@ DEPENDENCIES
pry
quiet_assets
rack
rails (= 4.1.4)
rails (= 4.1.5)
rails_12factor
rr
rspec (~> 2.99)

View file

@ -60,6 +60,10 @@ showEventDescriptions = ->
$(".event-descriptions").html("").hide()
$(document).ready ->
$('.navbar .dropdown.dropdown-hover').hover \
-> $(this).addClass('open'),
-> $(this).removeClass('open')
# JSON Editor
window.jsonEditor = setupJsonEditor()[0]

View file

@ -98,6 +98,12 @@ span.not-applicable:after {
right: 1px;
}
.navbar {
.dropdown.dropdown-hover:hover .dropdown-menu {
display: block;
}
}
// Flash
.flash {

View file

@ -1,3 +1,6 @@
require 'faraday'
require 'faraday_middleware'
module WebRequestConcern
extend ActiveSupport::Concern
@ -21,9 +24,7 @@ module WebRequestConcern
@faraday ||= Faraday.new { |builder|
builder.headers = headers if headers.length > 0
if (user_agent = interpolated['user_agent']).present?
builder.headers[:user_agent] = user_agent
end
builder.headers[:user_agent] = user_agent
builder.use FaradayMiddleware::FollowRedirects
builder.request :url_encoded
@ -58,4 +59,14 @@ module WebRequestConcern
def faraday_backend
ENV.fetch('FARADAY_HTTP_BACKEND', 'typhoeus').to_sym
end
end
def user_agent
interpolated['user_agent'].presence || self.class.default_user_agent
end
module ClassMethods
def default_user_agent
ENV.fetch('DEFAULT_HTTP_USER_AGENT', Faraday.new.headers[:user_agent])
end
end
end

View file

@ -1,27 +1,41 @@
module ApplicationHelper
def nav_link(name, path, options = {})
(<<-HTML).html_safe
<li class='#{(current_page?(path) ? "active" : "")}'>
#{link_to name, path}
</li>
HTML
def nav_link(name, path, options = {}, &block)
if glyphicon = options.delete(:glyphicon)
name = "<span class='glyphicon glyphicon-#{glyphicon}'></span> ".html_safe + name
end
content = link_to(name, path, options)
active = current_page?(path)
if block
# Passing a block signifies that the link is a header of a hover
# menu which contains what's in the block.
begin
@nav_in_menu = true
@nav_link_active = active
content += capture(&block)
class_name = "dropdown dropdown-hover #{@nav_link_active ? 'active' : ''}"
ensure
@nav_in_menu = @nav_link_active = false
end
else
# Mark the menu header active if it contains the current page
@nav_link_active ||= active if @nav_in_menu
# An "active" menu item may be an eyesore, hence `!@nav_in_menu &&`.
class_name = !@nav_in_menu && active ? 'active' : ''
end
content_tag :li, content, class: class_name
end
def yes_no(bool)
if bool
'<span class="label label-info">Yes</span>'.html_safe
else
'<span class="label label-default">No</span>'.html_safe
end
content_tag :span, bool ? 'Yes' : 'No', class: "label #{bool ? 'label-info' : 'label-default' }"
end
def working(agent)
if agent.disabled?
link_to 'Disabled', agent_path(agent), :class => 'label label-warning'
link_to 'Disabled', agent_path(agent), class: 'label label-warning'
elsif agent.working?
'<span class="label label-success">Yes</span>'.html_safe
content_tag :span, 'Yes', class: 'label label-success'
else
link_to 'No', agent_path(agent, :tab => (agent.recent_error_logs? ? 'logs' : 'details')), :class => 'label label-danger'
link_to 'No', agent_path(agent, tab: (agent.recent_error_logs? ? 'logs' : 'details')), class: 'label label-danger'
end
end
end

View file

@ -0,0 +1,7 @@
module MarkdownHelper
def markdown(text)
Kramdown::Document.new(text, :auto_ids => false).to_html.html_safe
end
end

View file

@ -56,6 +56,8 @@ class Agent < ActiveRecord::Base
has_many :scenario_memberships, :dependent => :destroy, :inverse_of => :agent
has_many :scenarios, :through => :scenario_memberships, :inverse_of => :agents
scope :active, -> { where(disabled: false) }
scope :of_type, lambda { |type|
type = case type
when String, Symbol, Class

View file

@ -43,7 +43,7 @@ module Agents
client = HipChat::Client.new(interpolated[:auth_token] || credential('hipchat_auth_token'))
incoming_events.each do |event|
mo = interpolated(event)
client[mo[:room_name]].send(mo[:username], mo[:message], :notify => boolify(mo[:notify]) ? 1 : 0, :color => mo[:color])
client[mo[:room_name]].send(mo[:username], mo[:message], :notify => boolify(mo[:notify]), :color => mo[:color])
end
end
end

View file

@ -1,6 +1,4 @@
require 'nokogiri'
require 'faraday'
require 'faraday_middleware'
require 'date'
module Agents
@ -19,7 +17,7 @@ module Agents
`url` can be a single url, or an array of urls (for example, for multiple pages with the exact same structure but different content to scrape)
The `type` value can be `xml`, `html`, or `json`.
The `type` value can be `xml`, `html`, `json`, or `text`.
To tell the Agent how to parse the content, specify `extract` as a hash with keys naming the extractions and values of hashes.
@ -40,6 +38,28 @@ module Agents
"description": { "path": "results.data[*].description" }
}
When parsing text, each sub-hash should contain a `regexp` and `index`. Output text is matched against the regular expression repeatedly from the beginning through to the end, collecting a captured group specified by `index` in each match. Each index should be either an integer or a string name which corresponds to `(?<_name_>...)`. For example, to parse lines of `_word_: _definition_`, the following should work:
"extract": {
"word": { "regexp": "^(.+?): (.+)$", index: 1 },
"definition": { "regexp": "^(.+?): (.+)$", index: 2 },
}
Or if you prefer names to numbers for index:
"extract": {
"word": { "regexp": "^(?<word>.+?): (?<definition>.+)$", index: 'word' },
"definition": { "regexp": "^(?<word>.+?): (?<definition>.+)$", index: 'definition' },
}
To extract the whole content as one event:
"extract": {
"content": { "regexp": "\A(?m:.)*\z", index: 0 },
}
Beware that `.` does not match the newline character (LF) unless the `m` flag is in effect, and `^`/`$` basically match every line beginning/end. See [this document](http://ruby-doc.org/core-#{RUBY_VERSION}/doc/regexp_rdoc.html) to learn the regular expression variant used in this service.
Note that for all of the formats, whatever you extract MUST have the same number of matches for each extractor. E.g., if you're extracting rows, all extractors must match all rows. For generating CSS selectors, something like [SelectorGadget](http://selectorgadget.com) may be helpful.
Can be configured to use HTTP basic auth by including the `basic_auth` parameter with `"username:password"`, or `["username", "password"]`.
@ -50,7 +70,7 @@ module Agents
Set `force_encoding` to an encoding name if the website does not return a Content-Type header with a proper charset.
Set `user_agent` to a custom User-Agent name if the website does not like the default value ("Faraday v#{Faraday::VERSION}").
Set `user_agent` to a custom User-Agent name if the website does not like the default value (`#{default_user_agent}`).
The `headers` field is optional. When present, it should be a hash of headers to send with the request.
@ -140,7 +160,15 @@ module Agents
else
output = {}
interpolated['extract'].each do |name, extraction_details|
if extraction_type == "json"
case extraction_type
when "text"
regexp = Regexp.new(extraction_details['regexp'])
result = []
doc.scan(regexp) {
result << Regexp.last_match[extraction_details['index']]
}
log "Extracting #{extraction_type} at #{regexp}: #{result}"
when "json"
result = Utils.values_at(doc, extraction_details['path'])
log "Extracting #{extraction_type} at #{extraction_details['path']}: #{result}"
else
@ -253,10 +281,13 @@ module Agents
def extraction_type
(interpolated['type'] || begin
if interpolated['url'] =~ /\.(rss|xml)$/i
case interpolated['url']
when /\.(rss|xml)$/i
"xml"
elsif interpolated['url'] =~ /\.json$/i
when /\.json$/i
"json"
when /\.(txt|text)$/i
"text"
else
"html"
end
@ -271,6 +302,8 @@ module Agents
JSON.parse(data)
when "html"
Nokogiri::HTML(data)
when "text"
data
else
raise "Unknown extraction type #{extraction_type}"
end

View file

@ -110,8 +110,8 @@
<% if @agent.can_receive_events? %>
<p>
<b>Event sources:</b>
<% if @agent.sources.length %>
<%= @agent.sources.map { |source_agent| link_to(source_agent.name, agent_path(source_agent)) }.to_sentence.html_safe %>
<% if (agents = @agent.sources).length > 0 %>
<%= agents.map { |agent| link_to(agent.name, agent_path(agent)) }.to_sentence.html_safe %>
<% else %>
None
<% end %>
@ -126,8 +126,8 @@
<% if @agent.can_create_events? %>
<p>
<b>Event receivers:</b>
<% if @agent.receivers.length %>
<%= @agent.receivers.map { |receiver_agent| link_to(receiver_agent.name, agent_path(receiver_agent)) }.to_sentence.html_safe %>
<% if (agents = @agent.receivers).length > 0 %>
<%= agents.map { |agent| link_to(agent.name, agent_path(agent)) }.to_sentence.html_safe %>
<% else %>
None
<% end %>

View file

@ -12,7 +12,13 @@
<% if user_signed_in? %>
<ul class='nav navbar-nav'>
<%= nav_link "Agents", agents_path %>
<%= nav_link "Agents", agents_path do %>
<ul class='dropdown-menu' role='menu'>
<%= nav_link "New Agent", new_agent_path, glyphicon: "plus" %>
<%= nav_link "Run event propagation", propagate_agents_path, method: 'post', glyphicon: "refresh" %>
<%= nav_link "View Diagram", diagram_path, glyphicon: 'random' %>
</ul>
<% end %>
<%= nav_link "Scenarios", scenarios_path %>
<%= nav_link "Events", events_path %>
<%= nav_link "Credentials", user_credentials_path %>

View file

@ -30,7 +30,7 @@
</div>
<% if @scenario_import.parsed_data["description"].present? %>
<blockquote><%= @scenario_import.parsed_data["description"] %></blockquote>
<blockquote><%= markdown(@scenario_import.parsed_data["description"]) %></blockquote>
<% end %>
</div>

View file

@ -6,7 +6,7 @@
</div>
<% if @scenario.description.present? %>
<blockquote><%= @scenario.description %></blockquote>
<blockquote><%= markdown(@scenario.description) %></blockquote>
<% end %>
<%= render 'agents/table', :returnTo => scenario_path(@scenario) %>

View file

@ -11,7 +11,6 @@ class TwitterStream
def stop
@running = false
EventMachine::stop_event_loop if EventMachine.reactor_running?
end
def stream!(filters, agent, &block)
@ -91,9 +90,13 @@ class TwitterStream
def run
while @running
begin
agents = Agents::TwitterStreamAgent.all
agents = Agents::TwitterStreamAgent.active.all
EventMachine::run do
EventMachine.add_periodic_timer(1) {
EventMachine::stop_event_loop if !@running
}
EventMachine.add_periodic_timer(RELOAD_TIMEOUT) {
puts "Reloading EventMachine and all Agents..."
EventMachine::stop_event_loop
@ -101,17 +104,14 @@ class TwitterStream
if agents.length == 0
puts "No agents found. Will look again in a minute."
sleep 60
EventMachine::stop_event_loop
EventMachine.add_timer(60) {
EventMachine::stop_event_loop
}
else
puts "Found #{agents.length} agent(s). Loading them now..."
load_and_run agents
end
end
print "Pausing..."; STDOUT.flush
sleep 1
puts "done."
rescue SignalException, SystemExit
@running = false
EventMachine::stop_event_loop if EventMachine.reactor_running?

View file

@ -0,0 +1,14 @@
require 'spec_helper'
describe MarkdownHelper do
describe '#markdown' do
it 'renders HTML from a markdown text' do
markdown('# Header').should =~ /<h1>Header<\/h1>/
markdown('## Header 2').should =~ /<h2>Header 2<\/h2>/
end
end
end

View file

@ -7,7 +7,7 @@ describe Agents::HipchatAgent do
'room_name' => 'test',
'username' => "{{username}}",
'message' => "{{message}}",
'notify' => false,
'notify' => 'false',
'color' => 'yellow',
}
@ -53,7 +53,7 @@ describe Agents::HipchatAgent do
describe "#receive" do
it "send a message to the hipchat" do
any_instance_of(HipChat::Room) do |obj|
mock(obj).send(@event.payload[:username], @event.payload[:message], {:notify => 0, :color => 'yellow'})
mock(obj).send(@event.payload[:username], @event.payload[:message], {:notify => false, :color => 'yellow'})
end
@checker.receive([@event])
end

View file

@ -398,6 +398,58 @@ describe Agents::WebsiteAgent do
event.payload['response']['title'].should == "hello!"
end
end
describe "text parsing" do
before do
stub_request(:any, /text-site/).to_return(body: <<-EOF, status: 200)
water: wet
fire: hot
EOF
site = {
'name' => 'Some Text Response',
'expected_update_period_in_days' => '2',
'type' => 'text',
'url' => 'http://text-site.com',
'mode' => 'on_change',
'extract' => {
'word' => { 'regexp' => '^(.+?): (.+)$', index: 1 },
'property' => { 'regexp' => '^(.+?): (.+)$', index: 2 },
}
}
@checker = Agents::WebsiteAgent.new(name: 'Text Site', options: site)
@checker.user = users(:bob)
@checker.save!
end
it "works with regexp" do
@checker.options = @checker.options.merge('extract' => {
'word' => { 'regexp' => '^(?<word>.+?): (?<property>.+)$', index: 'word' },
'property' => { 'regexp' => '^(?<word>.+?): (?<property>.+)$', index: 'property' },
})
lambda {
@checker.check
}.should change { Event.count }.by(2)
event1, event2 = Event.last(2)
event1.payload['word'].should == 'water'
event1.payload['property'].should == 'wet'
event2.payload['word'].should == 'fire'
event2.payload['property'].should == 'hot'
end
it "works with regexp with named capture" do
lambda {
@checker.check
}.should change { Event.count }.by(2)
event1, event2 = Event.last(2)
event1.payload['word'].should == 'water'
event1.payload['property'].should == 'wet'
event2.payload['word'].should == 'fire'
event2.payload['property'].should == 'hot'
end
end
end
describe "#receive" do

View file

@ -63,4 +63,29 @@ shared_examples_for WebRequestConcern do
agent.should_not be_valid
end
end
end
describe "User-Agent" do
before do
@default_http_user_agent = ENV['DEFAULT_HTTP_USER_AGENT']
ENV['DEFAULT_HTTP_USER_AGENT'] = nil
end
after do
ENV['DEFAULT_HTTP_USER_AGENT'] = @default_http_user_agent
end
it "should have the default value set by Faraday" do
agent.user_agent.should == Faraday.new.headers[:user_agent]
end
it "should be overridden by the environment variable if present" do
ENV['DEFAULT_HTTP_USER_AGENT'] = 'Huginn - https://github.com/cantino/huginn'
agent.user_agent.should == 'Huginn - https://github.com/cantino/huginn'
end
it "should be overriden by the value in options if present" do
agent.options['user_agent'] = 'Override'
agent.user_agent.should == 'Override'
end
end
end