mailcannon 0.0.8.pre.1 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/Gemfile +2 -1
- data/Rakefile +1 -1
- data/Readme.md +4 -39
- data/env.sample.sh +4 -5
- data/lib/mailcannon/adapters/sendgrid_web.rb +12 -48
- data/lib/mailcannon/airbrake.rb +18 -0
- data/lib/mailcannon/envelope.rb +3 -12
- data/lib/mailcannon/envelope_bag.rb +0 -9
- data/lib/mailcannon/librato.rb +15 -0
- data/lib/mailcannon/version.rb +1 -2
- data/lib/mailcannon/workers/barrel.rb +16 -2
- data/lib/mailcannon.rb +5 -5
- data/mailcannon.gemspec +2 -0
- data/spec/integration/1k_spec.rb +2 -16
- data/spec/integration/xsmtpapi_spec.rb +1 -4
- data/spec/mailcannon/adapters/sendgrid_spec.rb +4 -17
- data/spec/mailcannon/airbrake_spec.rb +23 -0
- data/spec/mailcannon/envelope_spec.rb +0 -5
- data/spec/mailcannon/librato_spec.rb +24 -0
- data/templates/config/mailcannon.yml +1 -10
- metadata +38 -18
- data/lib/mailcannon/envelope_bag_map_reduce.rb +0 -106
- data/lib/mailcannon/envelope_bag_statistic.rb +0 -5
- data/lib/mailcannon/reduces/envelope_bag_map.js +0 -3
- data/lib/mailcannon/reduces/envelope_bag_reduce.js +0 -116
- data/lib/mailcannon/sendgrid_event.rb +0 -18
- data/lib/mailcannon/workers/envelope_bag_reduce_job.rb +0 -11
- data/spec/integration/full_stack_stats_spec.rb +0 -118
- data/spec/mailcannon/envelope_bag_map_reduce_spec.rb +0 -211
- data/spec/mailcannon/envelope_bag_statistic_spec.rb +0 -41
- data/spec/mailcannon/workers/envelope_bag_reduce_job_spec.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16aeff734b9badfd24d471a07fc5a750f6a799a1
|
4
|
+
data.tar.gz: 05bf51210743215b43333d337f9f3cfd88e0079f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41bd9d22235bbb8fcbece0a246b3821487f0bf2c4e5fadedf1a03b22567d8fb499443900ebe014b1e66e8ffaae49cad4a309820727dd4737a4ffe0f30c9318d5
|
7
|
+
data.tar.gz: b08f2360e0901a2d3d9a2c5b73a02fed45182e5ed1b2a0bbe7a9429601bd5bfca017d0bc56354b2c89ff94b7d3f05244e0d74355e731ae66c2517aaa9270b6cf
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -3,9 +3,10 @@ source 'https://rubygems.org'
|
|
3
3
|
gem 'redis'
|
4
4
|
gem 'activemodel'
|
5
5
|
gem 'mongoid', '>=3.1.6'
|
6
|
-
gem 'sidekiq'
|
6
|
+
gem 'sidekiq'
|
7
7
|
gem 'sendgrid_webapi', '0.0.3'
|
8
8
|
gem 'librato-metrics'
|
9
|
+
gem 'airbrake'
|
9
10
|
gem 'rubysl', platform: :rbx
|
10
11
|
gem 'jruby-openssl', platform: :jruby
|
11
12
|
gem 'yajl-ruby', :platforms=>[:rbx,:ruby]
|
data/Rakefile
CHANGED
data/Readme.md
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
MailCannon
|
6
6
|
==========
|
7
7
|
|
8
|
-
Although this is a **WORK IN PROGRESS**, we're
|
8
|
+
Although this is a **WORK IN PROGRESS**, we're rolling it out to **production** with no issues for now at [Resultados Digitais](http://resultadosdigitais.com.br/).
|
9
9
|
|
10
10
|
This Gem relies heavily on both [Sidekiq](https://github.com/mperham/sidekiq) and Celluloid Gems, you are encouraged to use it anywhere with Ruby (a http interface is on the Roadmap ).
|
11
11
|
|
12
12
|
This Gem provides a worker ready for deploy cooked with [MongoDB](http://www.mongodb.org/) + [Mongoid](https://github.com/mongoid/mongoid) + [Sidekiq](https://github.com/mperham/sidekiq) + [Rubinius](http://rubini.us/) (feel free to use on MRI and jRuby as well).
|
13
13
|
|
14
|
-
For production deployment, you should take a
|
14
|
+
For production deployment, you should take a loot at both [MailCannon Outpost](https://github.com/lucasmartins/mailcannon-outpost) and [MailCannon Monitor](https://github.com/lucasmartins/mailcannon-monitor) projects.
|
15
15
|
|
16
16
|
Install
|
17
17
|
=======
|
@@ -68,7 +68,7 @@ envelope = MailCannon::Envelope.create(
|
|
68
68
|
subject: 'Test',
|
69
69
|
mail: MailCannon::Mail.new(text: 'you will see this when no HTML reader is available', html: 'this should be an HTML'))
|
70
70
|
envelope_bag.push envelope
|
71
|
-
envelope_bag.post! # this will
|
71
|
+
envelope_bag.post! # this will sent using the 'hot-account'.
|
72
72
|
```
|
73
73
|
|
74
74
|
### Configuration file
|
@@ -87,52 +87,17 @@ Edit the file to meet your environemnt needs.
|
|
87
87
|
|
88
88
|
Check the [specs](https://github.com/lucasmartins/mailcannon/tree/master/spec) to see the testing example, it will surely make it clearer.
|
89
89
|
|
90
|
-
### Statistics & MapReduce
|
91
|
-
|
92
|
-
MailCannon provides statistics calculation/reduce for the events related to an `Envelope`, like `open`,`click`,`spam`, etc. Assuming you have your Outpost running properly (running reduce jobs), you can access the data through the `envelope.stats` method to get the following hash:
|
93
|
-
|
94
|
-
```ruby
|
95
|
-
{
|
96
|
-
"posted"=>{"count"=>0.0, "targets"=>[]},
|
97
|
-
"processed"=>{"count"=>0.0, "targets"=>[]},
|
98
|
-
"delivered"=>{"count"=>1.0, "targets"=>["1"]},
|
99
|
-
"open"=>{"count"=>1.0, "targets"=>["2"]},
|
100
|
-
"click"=>{"count"=>0.0, "targets"=>[]},
|
101
|
-
"deferred"=>{"count"=>0.0, "targets"=>[]},
|
102
|
-
"spam_report"=>{"count"=>0.0, "targets"=>[]},
|
103
|
-
"spam"=>{"count"=>0.0, "targets"=>[]},
|
104
|
-
"unsubscribe"=>{"count"=>0.0, "targets"=>[]},
|
105
|
-
"drop"=>{"count"=>0.0, "targets"=>[]},
|
106
|
-
"bounce"=>{"count"=>1.0, "targets"=>["3"]}
|
107
|
-
}
|
108
|
-
```
|
109
|
-
|
110
|
-
You can trigger the reduce operation directly with `envelope.reduce_statistics`.
|
111
|
-
|
112
|
-
**Targets** are your __glue_id__ to link this data inside your own application, we use it as the "Contact#id" so we can show witch `Contact` has received, read, or clicked the email.
|
113
|
-
|
114
|
-
Repeating events on the same target will increase the array: `"click"=>{"count"=>3.0, "targets"=>["3","3","3"]}`
|
115
|
-
|
116
|
-
|
117
90
|
Docs
|
118
91
|
====
|
119
92
|
You should check the [factories](https://github.com/lucasmartins/mailcannon/tree/master/spec/factories) to learn what you need to build your objects, and the [tests](https://github.com/lucasmartins/mailcannon/tree/master/spec/mailcannon) to learn how to use them. But hey, we have docs [right here](http://rdoc.info/github/lucasmartins/mailcannon/master/frames).
|
120
93
|
|
121
|
-
Roadmap
|
122
|
-
=======
|
123
|
-
|
124
|
-
- Statistics (Map&Reduce awesomeness);
|
125
|
-
- Memory optimization (focused on MailCannon Outpost);
|
126
|
-
- HTTP (webservice) interface - so you don't need to be coding Ruby to use it!;
|
127
|
-
- New service adapter (Mandrill?);
|
128
|
-
|
129
94
|
Contribute
|
130
95
|
==========
|
131
96
|
|
132
97
|
Just fork [MailCannon](https://github.com/lucasmartins/mailcannon), add your feature+spec, and make a pull request. Do not mess up with the version file though.
|
133
98
|
|
134
99
|
**NOTICE**: The project is at embrionary stage, breaking changes will apply.
|
135
|
-
|
100
|
+
|
136
101
|
Support
|
137
102
|
=======
|
138
103
|
|
data/env.sample.sh
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
export REDIS_URL='redis://localhost:6379'
|
2
2
|
export SENDGRID_USERNAME=''
|
3
3
|
export SENDGRID_PASSWORD=''
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
export AIRBRAKE_TOKEN=''
|
5
|
+
export LIBRATO_SOURCE='staging'
|
6
|
+
export LIBRATO_USER=''
|
7
|
+
export LIBRATO_TOKEN=''
|
8
8
|
export MONGODB_URL=mongodb://localhost:27017:mailcannon_development
|
9
|
-
export MONGODB_PORT=27017
|
@@ -29,7 +29,7 @@ module MailCannon::Adapter::SendgridWeb
|
|
29
29
|
rescue Exception => e
|
30
30
|
logger.error "Unable to read auth config from Envelope or Bag, using default auth options from ENV"
|
31
31
|
return default_auth
|
32
|
-
end
|
32
|
+
end
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -55,61 +55,25 @@ module MailCannon::Adapter::SendgridWeb
|
|
55
55
|
self.save!
|
56
56
|
end
|
57
57
|
|
58
|
-
def build_to_subs(placeholder, to_key)
|
59
|
-
selected_hash_array = []
|
60
|
-
self.to.map {|h| selected_hash_array.push h[to_key]||h[to_key.to_sym]||''}
|
61
|
-
{'sub'=>{"#{placeholder}"=>selected_hash_array}}
|
62
|
-
end
|
63
|
-
|
64
58
|
def build_name_subs
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
def build_email_subs
|
70
|
-
placeholder = MailCannon.config['default_email_placeholder'] || '%email%'
|
71
|
-
build_to_subs(placeholder, 'email')
|
72
|
-
end
|
73
|
-
|
74
|
-
|
75
|
-
def build_unique_args
|
76
|
-
unique_args = {}
|
77
|
-
if MailCannon.config['add_envelope_id_to_unique_args']
|
78
|
-
unique_args.merge!({'envelope_id'=>self.id})
|
79
|
-
end
|
80
|
-
if MailCannon.config['add_envelope_bag_id_to_unique_args'] && self.envelope_bag
|
81
|
-
unique_args.merge!({'envelope_bag_id'=>self.envelope_bag.id})
|
82
|
-
end
|
83
|
-
unique_args
|
59
|
+
name_placeholder = MailCannon.config['default_name_placeholder'] || '%name%'
|
60
|
+
selected_hash_array = []
|
61
|
+
self.to.map {|h| selected_hash_array.push h['name']||h[:name]||''}
|
62
|
+
{'sub'=>{"#{name_placeholder}"=>selected_hash_array}}
|
84
63
|
end
|
85
64
|
|
86
65
|
def build_xsmtpapi(recipients,subs)
|
87
66
|
xsmtpapi = self.xsmtpapi || {}
|
67
|
+
to = []
|
88
68
|
recipients.symbolize_keys!
|
89
|
-
|
90
|
-
xsmtpapi.merge!({'to' => to}) if to
|
91
|
-
xsmtpapi = merge_subs_hash(xsmtpapi,subs)
|
92
|
-
xsmtpapi = merge_subs_hash(xsmtpapi,build_name_subs)
|
93
|
-
xsmtpapi = merge_subs_hash(xsmtpapi,build_email_subs)
|
94
|
-
xsmtpapi.merge!({'unique_args' => build_unique_args })
|
95
|
-
return xsmtpapi
|
96
|
-
end
|
97
|
-
|
98
|
-
def extract_values(values,key)
|
99
|
-
extract=[]
|
100
|
-
values.each do |h|
|
69
|
+
recipients[:to].each do |h|
|
101
70
|
h.symbolize_keys!
|
102
|
-
|
103
|
-
end
|
104
|
-
extract
|
105
|
-
end
|
106
|
-
|
107
|
-
def merge_subs_hash(xsmtpapi,subs)
|
108
|
-
if subs!=nil && subs.is_a?(Hash)
|
109
|
-
xsmtpapi.deep_merge(subs)
|
110
|
-
else
|
111
|
-
xsmtpapi
|
71
|
+
to.push h[:email]
|
112
72
|
end
|
73
|
+
xsmtpapi.merge!({'to' => to}) if to
|
74
|
+
xsmtpapi = xsmtpapi.deep_merge(subs) if subs!=nil && subs['sub']!=nil
|
75
|
+
xsmtpapi = xsmtpapi.deep_merge(build_name_subs) if build_name_subs!=nil && build_name_subs.is_a?(Hash)
|
76
|
+
return xsmtpapi
|
113
77
|
end
|
114
78
|
|
115
79
|
def validate_xsmtpapi!
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module MailCannon::Airbrake
|
2
|
+
extend self
|
3
|
+
|
4
|
+
def available?
|
5
|
+
if ENV['AIRBRAKE_TOKEN']
|
6
|
+
true
|
7
|
+
else
|
8
|
+
false
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def authenticate
|
13
|
+
Airbrake.configure do |config|
|
14
|
+
config.api_key = ENV['AIRBRAKE_TOKEN']
|
15
|
+
config.host = 'api.airbrake.io'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/mailcannon/envelope.rb
CHANGED
@@ -4,12 +4,10 @@ class MailCannon::Envelope
|
|
4
4
|
include Mongoid::Timestamps
|
5
5
|
include MailCannon::Adapter::SendgridWeb
|
6
6
|
|
7
|
-
belongs_to :envelope_bag
|
8
|
-
|
9
7
|
embeds_one :mail
|
10
8
|
embeds_many :stamps
|
11
|
-
|
12
|
-
|
9
|
+
belongs_to :envelope_bag
|
10
|
+
|
13
11
|
field :from, type: String
|
14
12
|
field :from_name, type: String
|
15
13
|
field :to, type: Array # of hashes. [{email: '', name: ''},...]
|
@@ -21,6 +19,7 @@ class MailCannon::Envelope
|
|
21
19
|
field :xsmtpapi, type: Hash # this will mostly be used by MailCannon itself. http://sendgrid.com/docs/API_Reference/SMTP_API/index.html
|
22
20
|
field :auth, type: Hash # {user: 'foo', password: 'bar'}, some Adapters might need an token:secret pair, which you can translete into user:password pair.
|
23
21
|
field :jid, type: String
|
22
|
+
|
24
23
|
|
25
24
|
validates :from, :to, :subject, presence: true
|
26
25
|
validates_associated :mail
|
@@ -66,14 +65,6 @@ class MailCannon::Envelope
|
|
66
65
|
false
|
67
66
|
end
|
68
67
|
end
|
69
|
-
|
70
|
-
def processed?
|
71
|
-
if self.stamps.where(code: 1).count > 0
|
72
|
-
true
|
73
|
-
else
|
74
|
-
false
|
75
|
-
end
|
76
|
-
end
|
77
68
|
|
78
69
|
private
|
79
70
|
def schedule_send_job
|
@@ -2,20 +2,11 @@
|
|
2
2
|
class MailCannon::EnvelopeBag
|
3
3
|
include Mongoid::Document
|
4
4
|
include Mongoid::Timestamps
|
5
|
-
include MailCannon::EnvelopeBagMapReduce
|
6
5
|
|
7
6
|
has_many :envelopes, autosave: true
|
8
7
|
field :integration_code, type: String # Used to link your own app models to the Bag.
|
9
8
|
field :auth, type: Hash # {user: 'foo', password: 'bar'}, some Adapters might need an token:secret pair, which you can translete into user:password pair. This config will be overriden by the Envelope.auth if present.
|
10
9
|
|
11
|
-
def stats
|
12
|
-
begin
|
13
|
-
MailCannon::EnvelopeBagStatistic.find(self.id).value
|
14
|
-
rescue Mongoid::Errors::DocumentNotFound => e
|
15
|
-
raise "You haven't run envelope.reduce_statistics yet, no data available!"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
10
|
def push(envelope)
|
20
11
|
self.envelopes.push envelope
|
21
12
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module MailCannon::Librato
|
2
|
+
extend self
|
3
|
+
|
4
|
+
def available?
|
5
|
+
if ENV['LIBRATO_USER'] && ENV['LIBRATO_TOKEN']
|
6
|
+
true
|
7
|
+
else
|
8
|
+
false
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def authenticate
|
13
|
+
Librato::Metrics.authenticate(ENV['LIBRATO_USER'], ENV['LIBRATO_TOKEN']) if available?
|
14
|
+
end
|
15
|
+
end
|
data/lib/mailcannon/version.rb
CHANGED
@@ -4,10 +4,23 @@ class MailCannon::Barrel
|
|
4
4
|
|
5
5
|
def perform(envelope_id)
|
6
6
|
envelope_id = envelope_id['$oid'] if envelope_id['$oid']
|
7
|
-
|
7
|
+
if MailCannon::Librato.available?
|
8
|
+
shoot_with_librato!(envelope_id)
|
9
|
+
else
|
10
|
+
shoot!(envelope_id)
|
11
|
+
end
|
8
12
|
end
|
9
13
|
|
10
14
|
private
|
15
|
+
def shoot_with_librato!(envelope_id)
|
16
|
+
MailCannon::Librato.authenticate
|
17
|
+
aggregator = Librato::Metrics::Aggregator.new
|
18
|
+
aggregator.time 'mailcannon.shoot' do
|
19
|
+
shoot!(envelope_id)
|
20
|
+
end
|
21
|
+
aggregator.submit
|
22
|
+
end
|
23
|
+
|
11
24
|
def shoot!(envelope_id)
|
12
25
|
logger.info "sending MailCannon::Envelope.find('#{envelope_id}')"
|
13
26
|
begin
|
@@ -21,7 +34,8 @@ class MailCannon::Barrel
|
|
21
34
|
rescue Mongoid::Errors::DocumentNotFound
|
22
35
|
logger.error "unable to find the document MailCannon::Envelope.find('#{envelope_id}')"
|
23
36
|
rescue Exception => e
|
24
|
-
logger.error "unable to send MailCannon::Envelope.find('#{envelope_id}')
|
37
|
+
logger.error "unable to send MailCannon::Envelope.find('#{envelope_id}')\n#{e.backtrace}"
|
38
|
+
Airbrake.notify(e, parameters: {'envelope_id'=>envelope_id}, cgi_data: ENV.to_hash) if MailCannon::Airbrake.available?
|
25
39
|
end
|
26
40
|
end
|
27
41
|
end
|
data/lib/mailcannon.rb
CHANGED
@@ -7,6 +7,8 @@ require 'sidekiq'
|
|
7
7
|
require 'sendgrid_webapi'
|
8
8
|
require 'yajl-ruby' if RUBY_PLATFORM=='ruby'
|
9
9
|
require 'jruby-openssl' if RUBY_PLATFORM=='jruby'
|
10
|
+
require 'librato/metrics'
|
11
|
+
require 'airbrake'
|
10
12
|
|
11
13
|
Encoding.default_internal = "utf-8"
|
12
14
|
Encoding.default_external = "utf-8"
|
@@ -14,16 +16,14 @@ Encoding.default_external = "utf-8"
|
|
14
16
|
module MailCannon
|
15
17
|
require_relative 'mailcannon/adapter'
|
16
18
|
require_relative 'mailcannon/adapters/sendgrid_web'
|
17
|
-
require_relative 'mailcannon/envelope_bag_map_reduce'
|
18
|
-
require_relative 'mailcannon/envelope_bag_statistic'
|
19
19
|
require_relative 'mailcannon/envelope_bag'
|
20
|
-
require_relative 'mailcannon/envelope'
|
20
|
+
require_relative 'mailcannon/envelope'
|
21
21
|
require_relative 'mailcannon/mail'
|
22
22
|
require_relative 'mailcannon/stamp'
|
23
23
|
require_relative 'mailcannon/event'
|
24
|
-
require_relative 'mailcannon/sendgrid_event'
|
25
24
|
require_relative 'mailcannon/workers/barrel'
|
26
|
-
require_relative 'mailcannon/
|
25
|
+
require_relative 'mailcannon/librato'
|
26
|
+
require_relative 'mailcannon/airbrake'
|
27
27
|
require_relative 'mailcannon/version'
|
28
28
|
|
29
29
|
# To be used with caution
|
data/mailcannon.gemspec
CHANGED
@@ -36,6 +36,8 @@ Gem::Specification.new do |s|
|
|
36
36
|
s.add_dependency 'sidekiq'
|
37
37
|
s.add_dependency 'sendgrid_webapi'
|
38
38
|
s.add_dependency 'json-schema'
|
39
|
+
s.add_dependency 'librato-metrics'
|
40
|
+
s.add_dependency 'airbrake'
|
39
41
|
|
40
42
|
s.add_development_dependency "vcr"
|
41
43
|
s.add_development_dependency "rspec"
|
data/spec/integration/1k_spec.rb
CHANGED
@@ -1,24 +1,10 @@
|
|
1
1
|
require "spec_helper"
|
2
|
-
require 'benchmark'
|
3
|
-
|
4
2
|
|
5
3
|
describe "shoot 1k emails!" do
|
6
|
-
let
|
4
|
+
let(:envelope) { build(:envelope_multi_1k) }
|
7
5
|
it "sends http request for Sendgrid web API" do
|
8
6
|
VCR.use_cassette('mailcannon_integration_1k') do
|
9
|
-
|
10
|
-
bm = Benchmark.measure do
|
11
|
-
envelope_a.post!
|
12
|
-
end
|
13
|
-
puts "1k test real time: #{bm.real}"
|
14
|
-
expect(envelope_a.reload.processed?).to be_true
|
15
|
-
|
16
|
-
# Travis has been showing unstable performance, not feasible to include performance tests.
|
17
|
-
# The performance varies from machine to machine, specially when using dedicated servers for each service.
|
18
|
-
if ENV['PERFORMANCE_TEST']
|
19
|
-
expect(bm.real<0.2).to be_true
|
20
|
-
end
|
21
|
-
end
|
7
|
+
expect(envelope.send_bulk!).to be_true
|
22
8
|
end
|
23
9
|
end
|
24
10
|
end
|
@@ -5,13 +5,10 @@ describe 'X-SMTPAPI compatibility' do
|
|
5
5
|
# This should guarantee the expected behavior for the following api:
|
6
6
|
# http://sendgrid.com/docs/API_Reference/SMTP_API/unique_arguments.html
|
7
7
|
context "generates expected xsmtpapi for #post!" do
|
8
|
-
let(:envelope_bag) { build(:empty_envelope_bag)}
|
9
8
|
let(:envelope) { build(:envelope_multi, xsmtpapi: { "sub" => { "-email-id-" => ["314159","271828"] }, "unique_args" => { "email_id" => "-email-id-"} }) }
|
10
|
-
let(:expectated_hash) { {"sub"=>{"-email-id-"=>["314159", "271828"], "*|NAME|*"=>["Mail Cannon", "Lucas Martins", "Contact"]
|
9
|
+
let(:expectated_hash) { {"sub"=>{"-email-id-"=>["314159", "271828"], "*|NAME|*"=>["Mail Cannon", "Lucas Martins", "Contact"]}, "unique_args"=>{"email_id"=>"-email-id-"}, "to"=>["mailcannon@railsnapraia.com", "lucasmartins@railsnapraia.com", "contact@railsonthebeach.com"]} }
|
11
10
|
|
12
11
|
it "returns true" do
|
13
|
-
envelope_bag.save
|
14
|
-
envelope_bag.envelopes << envelope
|
15
12
|
VCR.use_cassette('mailcannon_adapter_sendgrid_send_bulk') do
|
16
13
|
Sidekiq::Testing.inline! do
|
17
14
|
envelope.post!
|
@@ -21,19 +21,13 @@ describe MailCannon::Adapter::SendgridWeb do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
describe "#send!" do
|
24
|
-
let(:envelope_bag) { build(:empty_envelope_bag) }
|
25
24
|
let(:envelope) { build(:envelope) }
|
26
|
-
|
27
25
|
it "sends http request for Sendgrid web API" do
|
28
|
-
envelope_bag.save
|
29
|
-
envelope_bag.envelopes << envelope
|
30
26
|
VCR.use_cassette('mailcannon_adapter_sendgrid_send') do
|
31
27
|
expect(envelope.send!).to be_true
|
32
28
|
end
|
33
29
|
end
|
34
30
|
it "calls after_sent callback" do
|
35
|
-
envelope_bag.save
|
36
|
-
envelope_bag.envelopes << envelope
|
37
31
|
VCR.use_cassette('mailcannon_adapter_sendgrid_send') do
|
38
32
|
envelope.should_receive(:after_sent)
|
39
33
|
envelope.send!
|
@@ -42,11 +36,8 @@ describe MailCannon::Adapter::SendgridWeb do
|
|
42
36
|
end
|
43
37
|
|
44
38
|
describe "#send_bulk!" do
|
45
|
-
let(:envelope_bag) { build(:empty_envelope_bag) }
|
46
39
|
let(:envelope) { build(:envelope_multi) }
|
47
40
|
it "sends http request for Sendgrid web API" do
|
48
|
-
envelope_bag.save
|
49
|
-
envelope_bag.envelopes << envelope
|
50
41
|
VCR.use_cassette('mailcannon_adapter_sendgrid_send_bulk') do
|
51
42
|
expect(envelope.send_bulk!).to be_true
|
52
43
|
end
|
@@ -55,16 +46,12 @@ describe MailCannon::Adapter::SendgridWeb do
|
|
55
46
|
|
56
47
|
context "grab auth exception" do
|
57
48
|
describe "#send!" do
|
58
|
-
let(:envelope_bag) { build(:empty_envelope_bag) }
|
59
49
|
let(:envelope) { build(:envelope_wrong_auth) }
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
Sidekiq::Testing.inline! do
|
64
|
-
expect{envelope.send!}.to raise_error(MailCannon::Adapter::AuthException)
|
65
|
-
end
|
50
|
+
it "sends http request for Sendgrid web API with a wrong user/passwd combination" do
|
51
|
+
Sidekiq::Testing.inline! do
|
52
|
+
expect{envelope.send!}.to raise_error(MailCannon::Adapter::AuthException)
|
66
53
|
end
|
67
54
|
end
|
68
55
|
end
|
69
|
-
|
56
|
+
end
|
70
57
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe MailCannon::Airbrake do
|
4
|
+
before(:each) do
|
5
|
+
ENV['AIRBRAKE_TOKEN']=nil
|
6
|
+
end
|
7
|
+
after(:each) do
|
8
|
+
ENV['AIRBRAKE_TOKEN']=nil
|
9
|
+
end
|
10
|
+
describe "#available?" do
|
11
|
+
context 'when Airbrake token is NOT in the ENV' do
|
12
|
+
it "returns false" do
|
13
|
+
expect(MailCannon::Airbrake.available?).to be_false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
context 'when Airbrake token IS in the ENV' do
|
17
|
+
it "returns false" do
|
18
|
+
ENV['AIRBRAKE_TOKEN']='a.token'
|
19
|
+
expect(MailCannon::Airbrake.available?).to be_true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -73,13 +73,10 @@ describe MailCannon::Envelope do
|
|
73
73
|
|
74
74
|
describe "xsmtpapi" do
|
75
75
|
context "keep xsmtpapi arguments after #post!" do
|
76
|
-
let(:envelope_bag) { build(:empty_envelope_bag)}
|
77
76
|
let(:envelope) { build(:envelope_multi, xsmtpapi: { "unique_args" => { "userid" => "1123", "template" => "welcome" }}) }
|
78
77
|
let(:name_placeholder) { MailCannon.config['default_name_placeholder'].to_s }
|
79
78
|
|
80
79
|
it "returns true" do
|
81
|
-
envelope_bag.save
|
82
|
-
envelope_bag.envelopes << envelope
|
83
80
|
VCR.use_cassette('mailcannon_adapter_sendgrid_send_bulk') do
|
84
81
|
Sidekiq::Testing.inline! do
|
85
82
|
envelope.post!
|
@@ -87,8 +84,6 @@ describe MailCannon::Envelope do
|
|
87
84
|
end
|
88
85
|
envelope.reload # content is changed inside the Adapter module
|
89
86
|
expect(envelope.xsmtpapi).to have_key("unique_args")
|
90
|
-
expect(envelope.xsmtpapi["unique_args"]).to have_key("envelope_id") if MailCannon.config['add_envelope_id_to_unique_args']
|
91
|
-
expect(envelope.xsmtpapi["unique_args"]).to have_key("envelope_bag_id") if MailCannon.config['add_envelope_bag_id_to_unique_args']
|
92
87
|
expect(envelope.xsmtpapi).to have_key("to")
|
93
88
|
expect(envelope.xsmtpapi).to have_key("sub")
|
94
89
|
expect(envelope.xsmtpapi['sub']).to have_key("*|NAME|*")
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe MailCannon::Librato do
|
4
|
+
after(:each) do
|
5
|
+
ENV['LIBRATO_USER']=nil
|
6
|
+
ENV['LIBRATO_TOKEN']=nil
|
7
|
+
end
|
8
|
+
describe "#available?" do
|
9
|
+
context 'when Librato info is NOT in the ENV' do
|
10
|
+
it "returns false" do
|
11
|
+
ENV['LIBRATO_USER']=nil
|
12
|
+
ENV['LIBRATO_TOKEN']=''
|
13
|
+
expect(MailCannon::Librato.available?).to be_false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
context 'when Librato info IS in the ENV' do
|
17
|
+
it "returns false" do
|
18
|
+
ENV['LIBRATO_USER']='tha.user'
|
19
|
+
ENV['LIBRATO_TOKEN']='tha.password'
|
20
|
+
expect(MailCannon::Librato.available?).to be_true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -11,13 +11,4 @@ waiting_time: 0
|
|
11
11
|
auto_destroy: true
|
12
12
|
|
13
13
|
# MailCannon builds the 'name' substitution Array for convenience, using the name from Envelope.to: [{email: 'foo', name: 'bar'}]
|
14
|
-
default_name_placeholder: "*|NAME|*"
|
15
|
-
|
16
|
-
# MailCannon builds the 'email' substitution Array for convenience, using the email from Envelope.to: [{email: 'foo', name: 'bar'}]
|
17
|
-
default_email_placeholder: "*|EMAIL|*"
|
18
|
-
|
19
|
-
# Pretty self explanatory. This is intended to be used by your event consuming service.
|
20
|
-
add_envelope_id_to_unique_args: true
|
21
|
-
|
22
|
-
# Pretty self explanatory. This is intended to be used by your event consuming service.
|
23
|
-
add_envelope_bag_id_to_unique_args: true
|
14
|
+
default_name_placeholder: "*|NAME|*"
|