Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agent for Boxcar.io #1323

Merged
merged 5 commits into from
Mar 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
82 changes: 82 additions & 0 deletions app/models/agents/boxcar_agent.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
module Agents
class BoxcarAgent < Agent

cannot_be_scheduled!
cannot_create_events!

API_URL = 'https://new.boxcar.io/api/notifications'

description <<-MD
The Boxcar agent sends push notifications to iPhone.

To be able to use the Boxcar end-user API, you need your `Access Token`.
The access token is available on general "Settings" screen of Boxcar iOS
app or from Boxcar Web Inbox settings page.

Please provide your access token in the `user_credentials` option. If
you'd like to use a credential, set the `user_credentials` option to `{%
credential CREDENTIAL_NAME %}`.

Options:

* `user_credentials` - Boxcar access token.
* `title` - Title of the message.
* `body` - Body of the message.
* `source_name` - Name of the source of the message. Set to `Huginn` by default.
* `icon_url` - URL to the icon.
* `sound` - Sound to be played for the notification. Set to 'bird-1' by default.
MD

def default_options
{
'user_credentials' => '',
'title' => "{{title}}",
'body' => "{{body}}",
'source_name' => "Huginn",
'icon_url' => "",
'sound' => "bird-1"
}
end

def working?
received_event_without_error?
end

def strip(string)
(string || '').strip
end

def validate_options
errors.add(:base, "you need to specify a boxcar api key") if options['user_credentials'].blank?
end

def receive(incoming_events)
incoming_events.each do |event|
payload_interpolated = interpolated(event)
user_credentials = payload_interpolated['user_credentials']
post_params = {
'user_credentials' => user_credentials,
'notification' => {
'title' => strip(payload_interpolated['title']),
'long_message' => strip(payload_interpolated['body']),
'source_name' => payload_interpolated['source_name'],
'sound' => payload_interpolated['sound'],
'icon_url' => payload_interpolated['icon_url']
}
}
send_notification(post_params)
end
end

def send_notification(post_params)
response = HTTParty.post(API_URL, :query => post_params)
raise StandardError, response['error']['message'] if response['error'].present?
if response['Response'].present? && response['Response'] == "Not authorized"
raise StandardError, response['Response']
end
if !response['id'].present?
raise StandardError, "Invalid response from Boxcar: #{response}"
end
end
end
end
60 changes: 60 additions & 0 deletions spec/models/agents/boxcar_agent_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require 'rails_helper'

describe Agents::BoxcarAgent do
before(:each) do
@valid_params = {
'user_credentials' => 'access_token',
'title' => 'Sample Title',
'body' => 'Sample Body'
}
@checker = Agents::BoxcarAgent.new(:name => "boxcartest", :options => @valid_params)
@checker.user = users(:bob)
@checker.save!

@event = Event.new
@event.agent = agents(:bob_weather_agent)
@event.payload = { :body => 'Sample message' }
@event.save!
end

describe 'validating' do
before do
expect(@checker).to be_valid
end

it "should require access token" do
@checker.options['user_credentials'] = nil
expect(@checker).not_to be_valid
end
end

describe '#working?' do
it "should not be working until the first event was received" do
expect(@checker).not_to be_working
@checker.last_receive_at = Time.now
expect(@checker).to be_working
end
end

describe "#receive" do
it "sends a message" do
stub(HTTParty).post { {"id" => 1, "message" => "blah", "title" => "blah","source_name" => "Custom Notification"} }
@checker.receive([@event])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this spec fail if you break the code? I think you may need mock here so that an expectation is set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it fails. I even found a bug (typo) when I first ran this.

end

it "should raise error when invalid response arrives" do
stub(HTTParty).post { {"blah" => "blah"} }
expect{@checker.send_notification}.to raise_error
end

it "should raise error when response says unauthorized" do
stub(HTTParty).post '{"Response":"Not authorized"}'
expect{@checker.send_notification}.to raise_error
end

it "should raise error when response has an error" do
stub(HTTParty).post '{"error": {"message": "Sample error"}}'
expect{@checker.send_notification}.to raise_error
end
end
end