mandrill-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .rvmrc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,11 @@
1
+ # These are specific configuration settings required for travis-ci
2
+ # see http://travis-ci.org/evendis/mandrill-rails
3
+ language: ruby
4
+ rvm:
5
+ - 1.8.7
6
+ - 1.9.2
7
+ - 1.9.3
8
+ - rbx-18mode
9
+ - rbx-19mode
10
+ - jruby-18mode
11
+ - jruby-19mode
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mandrill-rails.gemspec
4
+ gemspec
5
+
@@ -0,0 +1,10 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ end
10
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Paul Gallagher
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,128 @@
1
+ = Mandrill::Rails {<img src="https://secure.travis-ci.org/evendis/mandrill-rails.png" />}[http://travis-ci.org/evendis/mandrill-rails]
2
+
3
+ Mandrill::Rails extends the capabilities of the
4
+ {Mandrill}[https://github.com/tatemae-consultancy/mandrill] gem to provide tighter integration for Rails projects.
5
+
6
+ The primary goal of Mandrill::Rails is to make supporting Mandrill web hooks as easy and Rails-native as possible. As other opportunities for better Rails integration of the Mandrill API are discovered, these may be rolled in too.
7
+
8
+ FYI, {Mandrill}[http://mandrill.com/] is the transactional email service by the same folks who do MailChimp.
9
+
10
+ == Requirements and Known Limitations
11
+
12
+ * Tested with MRI 1.9.3
13
+ * Requires Rails >= 3.0.3 (including 3.1 and 3.2)
14
+ * Includes {Mandrill}[https://github.com/tatemae-consultancy/mandrill] ~> 0.0.2 as a dependency
15
+
16
+ Food for thought (upcoming features maybe)..
17
+ * some generators may be handy to avoid the manual coding to hook up web hooks
18
+ * I thought about implementing this as an engine, but the overhead did not seem appropriate. Maybe that view will change..
19
+
20
+ == The Mandrill::Rails Cookbook
21
+
22
+ === How do I install it for normal use?
23
+
24
+ Add this line to your application's Gemfile:
25
+
26
+ gem 'mandrill-rails'
27
+
28
+ And then execute:
29
+
30
+ $ bundle
31
+
32
+ Or install it yourself as:
33
+
34
+ $ gem install mandrill-rails
35
+
36
+ === How do I install it for gem development?
37
+
38
+ If you want to work on enhancements of fix bugs in Mandrill::Rails, fork and clone the github repository. If you are using bundler (recommended), run <tt>bundle</tt> to install development dependencies.
39
+
40
+ See the section below on 'Contributing to Mandrill::Rails' for more information.
41
+
42
+ === How do I configure my app for incoming Mandrill WebHooks?
43
+
44
+ Say we have configured Mandrill to send requests to /inbox at our site (see the next recipes for how you do that).
45
+
46
+ Once we have Mandrill::Rails in our project, we just need to do two things. There's no generator to help you do this at the moment, but it is pretty simple:
47
+
48
+ First, configure a resource route:
49
+
50
+ resource :inbox, :controller => 'inbox', :only => [:show,:create]
51
+
52
+ Next, create the corresponding controller:
53
+
54
+ class InboxController < ApplicationController
55
+ include Mandrill::Rails::WebHookProcessor
56
+ end
57
+
58
+ That's all for the basic do-nothing endpoint setup. Note that we need both the GET and POST routes (Mandrill sends data to the POST route, but it uses GET to test the availability of the endpoint).
59
+
60
+ You can setup as many of these controllers as you need, if you wish different types of events to be handled by different routes.
61
+
62
+ === How do I configure Mandrill to send inbound email to my app?
63
+
64
+ See {Mandrill Inbound Domains}[https://mandrillapp.com/inbound]
65
+ * enter the mail route you want to match on e.g. *@app.mydomain.com
66
+ * set the WebHook enpoint to match e.g. http://mydomain.com/inbox
67
+
68
+ === How do I configure Mandrill to send WebHook requests to my app?
69
+
70
+ See {Mandrill WebHooks}[https://mandrillapp.com/settings/webhooks]
71
+ * select the events you want to trigger on
72
+ * set the "Post to URL" to point to your controller e.g. http://mydomain.com/inbox
73
+
74
+ === How do I handle a specific Mandrill event payload in my app?
75
+
76
+ Once you have configured Mandrill and setup your routes and controllers, we can successfully
77
+ receive WebHook event notifications from Mandrill. But we are not doing anything with the payload yet.
78
+
79
+ To handle specific Mandrill event payloads, we just need to implement a handler for each event type
80
+ we are interested in.
81
+
82
+ The list of available event types includes: inbound, send, hard_bounce, soft_bounce, open,
83
+ click, spam, unsub, and reject.
84
+
85
+ In our controller, we simply write a method called handle_<event-type> and it will be called
86
+ for each event payload received. The event payload will be passed to this method
87
+ as an Mandrill::WebHook::EventDecorator - basically a Hash with some additional methods to
88
+ help extract payload-specific elements.
89
+
90
+ For example, to handle inbound email:
91
+
92
+ class InboxController < ApplicationController
93
+ include Mandrill::Rails::WebHookProcessor
94
+
95
+ def handle_inbound(event_payload)
96
+ Item.save_inbound_mail(event_payload)
97
+ end
98
+
99
+ end
100
+
101
+ If the handling of the payload may be time-consuming, you could throw it onto a background
102
+ queue at this point instead.
103
+
104
+ Note that Mandrill may send multiple event payloads in a single request, but you don't need
105
+ to worry about that. Each event payload will be unpacked from the request and dispatched to
106
+ your handler individually.
107
+
108
+ And if you don't care to handle a specific payload type - then just don't implement the associated handler.
109
+
110
+ === How do I use Mandrill gem features with Mandrill::Rails?
111
+
112
+ {Mandrill}[https://github.com/tatemae-consultancy/mandrill] is included with Mandrill::Rails
113
+ and its behaviour is unchanged. You can use all the features of the Mandrill gem as normal.
114
+
115
+ == Contributing to Mandrill::Rails
116
+
117
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
118
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
119
+ * Fork the project
120
+ * Start a feature/bugfix branch
121
+ * Commit and push until you are happy with your contribution
122
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
123
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
124
+
125
+ == Copyright
126
+
127
+ Copyright (c) 2012 Paul Gallagher. See LICENSE for further details.
128
+
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rspec'
5
+ require 'rspec/core/rake_task'
6
+
7
+ desc "Run all RSpec test examples"
8
+ RSpec::Core::RakeTask.new do |spec|
9
+ spec.rspec_opts = ["-c", "-f progress"]
10
+ spec.pattern = 'spec/**/*_spec.rb'
11
+ end
12
+
13
+ task :default => :spec
14
+
15
+ require 'rdoc/task'
16
+ RDoc::Task.new do |rdoc|
17
+ rdoc.main = "README.rdoc"
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = "mandrill-rails"
20
+ rdoc.rdoc_files.include('README*', 'lib/**/*.rb')
21
+ end
@@ -0,0 +1,7 @@
1
+ require 'json'
2
+ require 'active_support/concern'
3
+ require 'active_support/dependencies'
4
+
5
+ require "mandrill-rails/version"
6
+ require 'mandrill/web_hook'
7
+ require 'mandrill-rails/web_hook_processor'
@@ -0,0 +1,5 @@
1
+ module Mandrill
2
+ module Rails
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,54 @@
1
+ # WebHookProcessor is a module that mixes in Mandrill web hook processing support
2
+ # to a controller in your application.
3
+ #
4
+ # The controller is expected to be a singlular resource controller.
5
+ # WebHookProcessor provides the :show and :create method implementation.
6
+ #
7
+ # 1. Create a controller that includes Mandrill::Rails::WebHookProcessor
8
+ # 2. Direct a GET :show and POST :create route to the controller
9
+ # 3. Define handlers for each of the event types you want to handle
10
+ #
11
+ # e.g. in routes.rb:
12
+ #
13
+ # resource :webhook, :controller => 'webhook', :only => [:show,:create]
14
+ #
15
+ # e.g. a Webhook controller:
16
+ #
17
+ # class WebhookController < ApplicationController
18
+ # include Mandrill::Rails::WebHookProcessor
19
+ #
20
+ # # Command: handle each 'inbound' +event_payload+ from Mandrill
21
+ # def handle_inbound(event_payload)
22
+ # # do some stuff
23
+ # end
24
+ #
25
+ # # Define other handlers for each event type required.
26
+ # # Possible event types: inbound, send, hard_bounce, soft_bounce, open, click, spam, unsub, or reject
27
+ # # def handle_<event_type>(event_payload)
28
+ # # # do some stuff
29
+ # # end
30
+ #
31
+ # end
32
+ #
33
+ module Mandrill::Rails::WebHookProcessor
34
+ extend ActiveSupport::Concern
35
+
36
+ included do
37
+ skip_before_filter :verify_authenticity_token
38
+ end
39
+
40
+ # Returns 200 and does nothing else (this is a test done by the mandrill service)
41
+ def show
42
+ head(:ok)
43
+ end
44
+
45
+ def create
46
+ if processor = Mandrill::WebHook::Processor.new(params)
47
+ processor.callback_host = self
48
+ processor.run!
49
+ end
50
+ head(:ok)
51
+ end
52
+
53
+
54
+ end
@@ -0,0 +1,7 @@
1
+ module Mandrill
2
+ module WebHook
3
+ end
4
+ end
5
+
6
+ require 'mandrill/web_hook/event_decorator'
7
+ require 'mandrill/web_hook/processor'
@@ -0,0 +1,77 @@
1
+ # Wraps an individual Mandrill web hook event payload,
2
+ # providing some convenience methods handling the payload.
3
+ #
4
+ # Given a raw event payload Hash, wrap it thus:
5
+ #
6
+ # JSON.parse(params['mandrill_events']).each do |raw_event|
7
+ # event = Mandrill::WebHook::EventDecorator[raw_event]
8
+ # ..
9
+ # end
10
+ #
11
+ class Mandrill::WebHook::EventDecorator < Hash
12
+
13
+ # Returns the event type
14
+ def event_type
15
+ self['event']
16
+ end
17
+
18
+ # Returns the subject
19
+ def subject
20
+ self['subject'] || msg['subject']
21
+ end
22
+
23
+ # Returns the msg Hash (as used for inbound messages )
24
+ def msg
25
+ self['msg']||{}
26
+ end
27
+
28
+ # Returns the message_id (as used for inbound messages )
29
+ def message_id
30
+ headers['Message-Id']
31
+ end
32
+
33
+ # Returns the reply-to ID (as used for inbound messages )
34
+ def in_reply_to
35
+ headers['In-Reply-To']
36
+ end
37
+
38
+ # Returns an array of reference IDs (as used for inbound messages )
39
+ def references
40
+ (headers['References']||'').scan(/(<[^<]+?>)/).flatten
41
+ end
42
+
43
+ # Returns the headers Hash (as used for inbound messages )
44
+ def headers
45
+ msg['headers']||{}
46
+ end
47
+
48
+ # Returns the email (String) of the sender
49
+ def sender_email
50
+ msg['from_email']
51
+ end
52
+
53
+ # Returns an array of all unique recipient emails (to/cc)
54
+ # [ email, email, .. ]
55
+ def recipients
56
+ (Array(msg['to']) | Array(msg['cc'])).compact
57
+ end
58
+
59
+ # Returns an array of all unique recipients (to/cc)
60
+ # [ [email,name], [email,name], .. ]
61
+ def recipient_emails
62
+ recipients.map(&:first)
63
+ end
64
+
65
+ # Returns the +format+ (:text,:html,:raw) message body
66
+ def message_body(format=:text)
67
+ case format
68
+ when :text
69
+ msg['text']
70
+ when :html
71
+ msg['html']
72
+ when :raw
73
+ msg['raw_msg']
74
+ end
75
+ end
76
+
77
+ end
@@ -0,0 +1,31 @@
1
+ class Mandrill::WebHook::Processor
2
+
3
+ attr_accessor :mandrill_events, :callback_host
4
+
5
+ # Command initialise the processor with +params+ Hash.
6
+ # +params+ is expected to contain an array of mandrill_events
7
+ def initialize(params={})
8
+ @mandrill_events = JSON.parse(params['mandrill_events'] || '[]')
9
+ end
10
+
11
+ # Command: processes all +mandrill_events+
12
+ def run!
13
+ mandrill_events.each do |raw_payload|
14
+ event_payload = wrap_payload(raw_payload)
15
+ handler = "handle_#{event_payload.event_type}".to_sym
16
+ if callback_host && callback_host.respond_to?(handler)
17
+ callback_host.send(handler,event_payload)
18
+ elsif self.respond_to?(handler)
19
+ self.send(handler,event_payload)
20
+ else
21
+ # TODO raise an error
22
+ end
23
+ end
24
+ end
25
+
26
+ # Returns a suitably ecapsulated +raw_event_payload+
27
+ def wrap_payload(raw_event_payload)
28
+ Mandrill::WebHook::EventDecorator[raw_event_payload]
29
+ end
30
+
31
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/mandrill-rails/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Paul Gallagher"]
6
+ gem.email = ["gallagher.paul@gmail.com"]
7
+ gem.description = %q{Rails integration for working with Mandrill}
8
+ gem.summary = %q{Rails integration for working with Mandrill}
9
+ gem.homepage = "https://github.com/evendis/mandrill-rails"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "mandrill-rails"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Mandrill::Rails::VERSION
17
+
18
+ gem.add_runtime_dependency(%q<mandrill>, ["~> 0.0.2"])
19
+ gem.add_runtime_dependency(%q<activesupport>, [">= 3.0.3"])
20
+ gem.add_development_dependency(%q<bundler>, ["~> 1.1.0"])
21
+ gem.add_development_dependency(%q<rake>, ["~> 0.9.2.2"])
22
+ gem.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
23
+ gem.add_development_dependency(%q<rdoc>, ["~> 3.11"])
24
+ gem.add_development_dependency(%q<guard-rspec>, ["~> 1.2.0"])
25
+
26
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ class WebHookProcessorTestHarness
4
+ def self.skip_before_filter(*args) ; end
5
+ def head(*args) ; end
6
+ attr_accessor :params
7
+
8
+ include Mandrill::Rails::WebHookProcessor
9
+ end
10
+
11
+ describe Mandrill::Rails::WebHookProcessor do
12
+ let(:processor_instance) { WebHookProcessorTestHarness.new }
13
+ let(:params) { {} }
14
+ before { processor_instance.params = params}
15
+
16
+ subject { processor_instance }
17
+
18
+ describe "#show" do
19
+ it "should return head(:ok)" do
20
+ processor_instance.should_receive(:head).with(:ok)
21
+ processor_instance.show
22
+ end
23
+ end
24
+
25
+ describe "#create" do
26
+ it "should return head(:ok)" do
27
+ Mandrill::WebHook::Processor.any_instance.should_receive(:run!)
28
+ processor_instance.should_receive(:head).with(:ok)
29
+ processor_instance.create
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mandrill::WebHook::EventDecorator do
4
+
5
+
6
+ let(:event_payload) { Mandrill::WebHook::EventDecorator[raw_event] }
7
+ subject { event_payload }
8
+
9
+ context "with 'inbound' event_type" do
10
+
11
+ let(:event_type) { 'inbound' }
12
+ let(:subject_line) { 'a subject line' }
13
+ let(:sender_email) { 'test@example.com' }
14
+ let(:message_text) { "raw message text\n\n" }
15
+ let(:message_html) { "<div>some content</div>" }
16
+ let(:message_raw) { "the raw message text" }
17
+ let(:message_id) { "<111111>" }
18
+ let(:in_reply_to) { "<222222>" }
19
+ let(:references) { "<222222> <333333>" }
20
+ let(:references_array) { ["<222222>","<333333>"] }
21
+
22
+ let(:raw_event) { {
23
+ 'event' => event_type,
24
+ 'msg' => {
25
+ 'from_email' => sender_email,
26
+ 'subject' => subject_line,
27
+ 'headers' => {
28
+ 'Cc' => "c@example.com,b@example.com",
29
+ 'Message-Id' => message_id,
30
+ 'In-Reply-To' => in_reply_to,
31
+ 'References' => references
32
+ },
33
+ 'html' => message_html,
34
+ 'raw_msg' => message_raw,
35
+ 'text' => message_text,
36
+ 'cc' => [ [ "c@example.com", "C"],[ "b@example.com", nil] ],
37
+ 'to' => [ [ "a@example.com", "A"],[ "b@example.com", nil] ]
38
+ }
39
+ } }
40
+
41
+ its(:event_type) { should eql(event_type) }
42
+ its(:subject) { should eql(subject_line) }
43
+ its(:sender_email) { should eql(sender_email) }
44
+ its(:recipients) { should eql([["a@example.com", "A"], ["b@example.com", nil], ["c@example.com", "C"]]) }
45
+ its(:message_id) { should eql(message_id) }
46
+ its(:in_reply_to) { should eql(in_reply_to) }
47
+
48
+ describe "#references" do
49
+ its(:references) { should eql(references_array) }
50
+ context "when no references element" do
51
+ let(:raw_event) { {} }
52
+ its(:references) { should eql([]) }
53
+ end
54
+ end
55
+
56
+ describe "#recipient_emails" do
57
+ its(:recipient_emails) { should eql(["a@example.com", "b@example.com", "c@example.com"]) }
58
+ context "when no to or Cc elements" do
59
+ let(:raw_event) { {} }
60
+ its(:recipient_emails) { should eql([]) }
61
+ end
62
+ end
63
+
64
+ describe "#message_body" do
65
+ subject { event_payload.message_body(format) }
66
+ describe ":text" do
67
+ let(:format) { :text }
68
+ it { should eql(message_text) }
69
+ end
70
+ describe ":html" do
71
+ let(:format) { :html }
72
+ it { should eql(message_html) }
73
+ end
74
+ describe ":raw" do
75
+ let(:format) { :raw }
76
+ it { should eql(message_raw) }
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+
83
+ # TODO: elaborate specs for send web hook (need some real payload examples)
84
+ context "with 'send' event_type" do
85
+ let(:event_type) { 'send' }
86
+ let(:subject_line) { 'a subject line' }
87
+ let(:raw_event) { {
88
+ 'event' => event_type,
89
+ 'subject' => subject_line
90
+ } }
91
+
92
+ its(:event_type) { should eql(event_type) }
93
+ its(:subject) { should eql(subject_line) }
94
+ end
95
+
96
+ # TODO: other web hook types
97
+ # send - message has been sent
98
+ # hard_bounce - message has hard bounced
99
+ # soft_bounce - message has soft bounced
100
+ # open - recipient opened a message; will only occur when open tracking is enabled
101
+ # click - recipient clicked a link in a message; will only occur when click tracking is enabled
102
+ # spam - recipient marked a message as spam
103
+ # unsub - recipient unsubscribed
104
+ # reject - message was rejected
105
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mandrill::WebHook::Processor do
4
+
5
+ let(:params) { {} }
6
+ let(:processor) { Mandrill::WebHook::Processor.new(params) }
7
+
8
+ describe "#run!" do
9
+ context "with inbound events" do
10
+ before do
11
+ Mandrill::WebHook::Processor.stub(:handle_inbound)
12
+ end
13
+ let(:event1) { { "event" => "inbound" } }
14
+ let(:event2) { { "event" => "inbound" } }
15
+ let(:params) { { "mandrill_events" => [event1,event2].to_json } }
16
+ it "should pass event payload to the handler" do
17
+ processor.should_receive(:handle_inbound).twice
18
+ processor.run!
19
+ end
20
+ end
21
+ end
22
+
23
+ describe "#wrap_payload" do
24
+ let(:raw_payload) { {} }
25
+ subject { processor.wrap_payload(raw_payload) }
26
+ its(:class) { should eql(Mandrill::WebHook::EventDecorator) }
27
+ end
28
+
29
+ end
@@ -0,0 +1,24 @@
1
+ require 'mandrill-rails'
2
+
3
+ # Requires supporting files with custom matchers and macros, etc,
4
+ # in ./support/ and its subdirectories.
5
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
6
+
7
+ RSpec.configure do |config|
8
+ # == Mock Framework
9
+ #
10
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
11
+ #
12
+ # config.mock_with :mocha
13
+ # config.mock_with :flexmock
14
+ # config.mock_with :rr
15
+ config.mock_with :rspec
16
+
17
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
18
+ # config.fixture_path = "#{::Rails.root}/spec/fixtures"
19
+
20
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
21
+ # examples within a transaction, remove the following line or assign false
22
+ # instead of true.
23
+ # config.use_transactional_fixtures = true
24
+ end
metadata ADDED
@@ -0,0 +1,186 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mandrill-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Paul Gallagher
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mandrill
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.0.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.0.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 3.0.3
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 3.0.3
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.1.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.9.2.2
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.9.2.2
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 2.8.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 2.8.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: rdoc
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '3.11'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '3.11'
110
+ - !ruby/object:Gem::Dependency
111
+ name: guard-rspec
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 1.2.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 1.2.0
126
+ description: Rails integration for working with Mandrill
127
+ email:
128
+ - gallagher.paul@gmail.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - .rspec
135
+ - .travis.yml
136
+ - Gemfile
137
+ - Guardfile
138
+ - LICENSE
139
+ - README.rdoc
140
+ - Rakefile
141
+ - lib/mandrill-rails.rb
142
+ - lib/mandrill-rails/version.rb
143
+ - lib/mandrill-rails/web_hook_processor.rb
144
+ - lib/mandrill/web_hook.rb
145
+ - lib/mandrill/web_hook/event_decorator.rb
146
+ - lib/mandrill/web_hook/processor.rb
147
+ - mandrill-rails.gemspec
148
+ - spec/mandrill-rails/web_hook_processor_spec.rb
149
+ - spec/mandrill/web_hook/event_decorator_spec.rb
150
+ - spec/mandrill/web_hook/processor_spec.rb
151
+ - spec/spec_helper.rb
152
+ homepage: https://github.com/evendis/mandrill-rails
153
+ licenses: []
154
+ post_install_message:
155
+ rdoc_options: []
156
+ require_paths:
157
+ - lib
158
+ required_ruby_version: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ segments:
165
+ - 0
166
+ hash: 1652128042679890864
167
+ required_rubygems_version: !ruby/object:Gem::Requirement
168
+ none: false
169
+ requirements:
170
+ - - ! '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ segments:
174
+ - 0
175
+ hash: 1652128042679890864
176
+ requirements: []
177
+ rubyforge_project:
178
+ rubygems_version: 1.8.24
179
+ signing_key:
180
+ specification_version: 3
181
+ summary: Rails integration for working with Mandrill
182
+ test_files:
183
+ - spec/mandrill-rails/web_hook_processor_spec.rb
184
+ - spec/mandrill/web_hook/event_decorator_spec.rb
185
+ - spec/mandrill/web_hook/processor_spec.rb
186
+ - spec/spec_helper.rb