mailcannon 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +1 -1
- data/Gemfile +6 -7
- data/Rakefile +1 -0
- data/Readme.md +20 -3
- data/lib/mailcannon/adapters/sendgrid_web.rb +12 -7
- data/lib/mailcannon/envelope.rb +24 -10
- data/lib/mailcannon/envelope_bag.rb +27 -0
- data/lib/mailcannon/event.rb +1 -1
- data/lib/mailcannon/hash.rb +10 -0
- data/lib/mailcannon/mail.rb +1 -1
- data/lib/mailcannon/stamp.rb +2 -2
- data/lib/mailcannon/version.rb +1 -1
- data/lib/mailcannon/workers/barrel.rb +13 -17
- data/lib/mailcannon.rb +33 -13
- data/mailcannon.gemspec +19 -0
- data/spec/factories/envelope_bag.rb +13 -0
- data/spec/integration/1k_spec.rb +1 -1
- data/spec/integration/xsmtpapi_spec.rb +20 -0
- data/spec/mailcannon/adapters/sendgrid_spec.rb +2 -2
- data/spec/mailcannon/envelope_bag_spec.rb +37 -0
- data/spec/mailcannon/envelope_spec.rb +40 -3
- data/spec/mailcannon/workers/barrel_spec.rb +40 -0
- data/spec/mailcannon_spec.rb +1 -1
- data/spec/spec_helper.rb +3 -1
- data/templates/config/mailcannon.yml +6 -2
- metadata +98 -5
- data/Gemfile.lock +0 -322
- /data/lib/generators/{highrise_mapper → mailcannon}/USAGE +0 -0
- /data/lib/generators/{highrise_mapper → mailcannon}/config_generator.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3959f5796552901e917b0be3bb6fb9aa24764385
|
4
|
+
data.tar.gz: d7e17ded5d4953acb0f5f1120d4f0ed3b5f70a07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 677148b0354d35fa556dd58890ea96b7991b28057fcc7dadf1df893805fb1db242d02b2eca74552dcb29fc40b9cb7005e8433479dbf58496214c7a0461d3204c
|
7
|
+
data.tar.gz: d6308cd543f6f44779d90d5ec62c4a799189ceebc4e4f653ffd4b368e62db775bd0b656c7192b7ecf7a5373bdf0f75aa2caad1edc4580bc98616d9b267a794e7
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
gem 'redis'
|
4
|
-
gem '
|
4
|
+
gem 'activemodel'
|
5
|
+
gem 'mongoid', '3.1.6'
|
5
6
|
gem 'sidekiq'
|
6
7
|
gem 'sendgrid_webapi'
|
7
|
-
#gem '
|
8
|
-
gem 'librato-metrics'
|
8
|
+
#gem 'librato-metrics'
|
9
9
|
gem 'rubysl', platform: :rbx
|
10
10
|
gem 'jruby-openssl', platform: :jruby
|
11
|
-
|
12
|
-
gem
|
13
|
-
gem "json-schema"
|
11
|
+
gem 'yajl-ruby', :platforms=>[:rbx,:ruby]
|
12
|
+
gem 'json-schema'
|
14
13
|
|
15
14
|
group :development do
|
16
15
|
gem 'rake'
|
@@ -24,7 +23,7 @@ group :test do
|
|
24
23
|
gem 'rspec-mocks'
|
25
24
|
gem 'rspec-expectations'
|
26
25
|
gem 'database_cleaner'
|
27
|
-
gem 'factory_girl'
|
26
|
+
gem 'factory_girl', '4.2.0'
|
28
27
|
gem 'vcr'
|
29
28
|
gem 'webmock', '>= 1.8.0', '< 1.16'
|
30
29
|
gem 'coveralls', platform: :ruby, require: false
|
data/Rakefile
CHANGED
data/Readme.md
CHANGED
@@ -29,11 +29,28 @@ Create a `MailCannon::Envelope`:
|
|
29
29
|
```ruby
|
30
30
|
envelope = MailCannon::Envelope.create(
|
31
31
|
from: 'test@mailcannon.com',
|
32
|
-
to: 'lucasmartins@railsnapraia.com',
|
32
|
+
to: [{email: 'lucasmartins@railsnapraia.com', name: 'Lucas Martins'}],
|
33
33
|
subject: 'Test',
|
34
|
-
mail: MailCannon::Mail.
|
35
|
-
|
34
|
+
mail: MailCannon::Mail.new(text: 'you will see this when no HTML reader is available', html: 'this should be an HTML'))
|
35
|
+
|
36
|
+
envelope.post!
|
37
|
+
```
|
38
|
+
|
39
|
+
### Campaign abstraction
|
40
|
+
|
41
|
+
Create a `MailCannon::Envelope`:
|
42
|
+
```ruby
|
43
|
+
envelope_bag = MailCannon::EnvelopeBag.new(integration_code: 'my-cool-campaign')
|
44
|
+
envelope = MailCannon::Envelope.create(
|
45
|
+
from: 'test@mailcannon.com',
|
46
|
+
to: [{email: 'lucasmartins@railsnapraia.com', name: 'Lucas Martins'}],
|
47
|
+
subject: 'Test',
|
48
|
+
mail: MailCannon::Mail.new(text: 'you will see this when no HTML reader is available', html: 'this should be an HTML'))
|
49
|
+
envelope_bag.push envelope
|
50
|
+
# envelope_bag.push ...
|
51
|
+
envelope_bag.post!
|
36
52
|
```
|
53
|
+
|
37
54
|
### Configuration file
|
38
55
|
If you are on Rails, run the following command to generate a config file:
|
39
56
|
|
@@ -11,7 +11,7 @@ module MailCannon::Adapter::SendgridWeb
|
|
11
11
|
response = send_single_email
|
12
12
|
end
|
13
13
|
self.after_sent(successfully_sent?(response))
|
14
|
-
return response
|
14
|
+
return successfully_sent?(response)
|
15
15
|
end
|
16
16
|
|
17
17
|
def send_bulk!
|
@@ -34,14 +34,18 @@ module MailCannon::Adapter::SendgridWeb
|
|
34
34
|
|
35
35
|
def prepare_xsmtpapi!
|
36
36
|
validate_envelope!
|
37
|
-
self.xsmtpapi =
|
37
|
+
self.xsmtpapi = {} if self.xsmtpapi.nil?
|
38
|
+
self.xsmtpapi = self.xsmtpapi.merge(build_xsmtpapi({'to'=>self.to},{'sub'=>self.substitutions}))
|
38
39
|
validate_xsmtpapi!
|
40
|
+
self.save!
|
39
41
|
end
|
40
42
|
|
41
43
|
def build_xsmtpapi(recipients,subs)
|
42
44
|
xsmtpapi = {}
|
43
45
|
to = []
|
44
|
-
recipients
|
46
|
+
recipients.symbolize_keys!
|
47
|
+
recipients[:to].each do |h|
|
48
|
+
h.symbolize_keys!
|
45
49
|
to.push h[:email]
|
46
50
|
end
|
47
51
|
xsmtpapi.merge!({'to' => to})
|
@@ -71,9 +75,12 @@ module MailCannon::Adapter::SendgridWeb
|
|
71
75
|
end
|
72
76
|
|
73
77
|
def send_single_email
|
78
|
+
if self.xsmtpapi!=nil
|
79
|
+
logger.warn "Single emails do not support X-SMTPAPI! #{self.id}"
|
80
|
+
end
|
74
81
|
api_client.mail.send(
|
75
|
-
:to => self.to.first[
|
76
|
-
:toname => self.to.first[
|
82
|
+
:to => self.to.first['email'],
|
83
|
+
:toname => self.to.first['name'],
|
77
84
|
:subject => self.subject,
|
78
85
|
:text => self.mail.text,
|
79
86
|
:html => self.mail.html,
|
@@ -86,10 +93,8 @@ module MailCannon::Adapter::SendgridWeb
|
|
86
93
|
|
87
94
|
def send_multiple_emails
|
88
95
|
prepare_xsmtpapi!
|
89
|
-
|
90
96
|
api_client.mail.send(
|
91
97
|
:to => self.from,
|
92
|
-
#:toname => self.to.first[:name],
|
93
98
|
:subject => self.subject,
|
94
99
|
:text => self.mail.text,
|
95
100
|
:html => self.mail.html,
|
data/lib/mailcannon/envelope.rb
CHANGED
@@ -6,12 +6,11 @@ class MailCannon::Envelope
|
|
6
6
|
|
7
7
|
embeds_one :mail
|
8
8
|
embeds_many :stamps
|
9
|
-
|
10
|
-
|
9
|
+
belongs_to :envelope_bag
|
10
|
+
|
11
11
|
field :from, type: String
|
12
12
|
field :from_name, type: String
|
13
|
-
field :to, type: Array # of hashes
|
14
|
-
field :to_name, type: Array # strings
|
13
|
+
field :to, type: Array # of hashes. [{email: '', name: ''},...]
|
15
14
|
field :substitutions, type: Hash # of hashes
|
16
15
|
field :subject, type: String
|
17
16
|
field :bcc, type: String
|
@@ -21,24 +20,31 @@ class MailCannon::Envelope
|
|
21
20
|
|
22
21
|
validates :from, :to, :subject, :mail, presence: true
|
23
22
|
validates_associated :mail
|
24
|
-
|
25
|
-
after_create :post_envelope!
|
26
23
|
|
27
24
|
# Post this Envelope!
|
28
25
|
def post_envelope!
|
29
26
|
self.save if self.changed?
|
30
|
-
self.stamp! MailCannon::Event::
|
27
|
+
self.stamp! MailCannon::Event::Posted.stamp
|
31
28
|
if validate_xsmtpapi(self.xsmtpapi)
|
32
|
-
MailCannon
|
29
|
+
if MailCannon.config['waiting_time'] && MailCannon.config['waiting_time'].to_i>0
|
30
|
+
MailCannon::Barrel.perform_in(MailCannon.config['waiting_time'].seconds,self.id)
|
31
|
+
else
|
32
|
+
MailCannon::Barrel.perform_async(self.id)
|
33
|
+
end
|
33
34
|
else
|
34
35
|
raise 'Invalid xsmtpapi hash!'
|
35
36
|
end
|
36
37
|
end
|
38
|
+
alias_method :"post!",:"post_envelope!"
|
37
39
|
|
38
40
|
# Stamp this Envelope with code.
|
39
|
-
def stamp!(code)
|
41
|
+
def stamp!(code,recipient=nil)
|
40
42
|
self.class.valid_code_kind?(code)
|
41
|
-
self.
|
43
|
+
unless self.persisted?
|
44
|
+
logger.warn "You're trying to save the Stamp with an unsaved Envelope! Auto-saving Envelope."
|
45
|
+
self.save
|
46
|
+
end
|
47
|
+
self.stamps.create(code: MailCannon::Stamp.from_code(code).code, recipient: recipient)
|
42
48
|
end
|
43
49
|
|
44
50
|
# Callback to be run after the Envelope has been processed.
|
@@ -49,6 +55,14 @@ class MailCannon::Envelope
|
|
49
55
|
self.mail=nil # to avoid reload
|
50
56
|
end
|
51
57
|
end
|
58
|
+
|
59
|
+
def posted?
|
60
|
+
if self.stamps.where(code: 0).count > 0
|
61
|
+
true
|
62
|
+
else
|
63
|
+
false
|
64
|
+
end
|
65
|
+
end
|
52
66
|
|
53
67
|
private
|
54
68
|
def self.valid_code_kind?(code)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Where the magic happens, the Envelope is responsible for keeping the information necessary to send the email(s) and holding the Stamps related to mailing Events.
|
2
|
+
class MailCannon::EnvelopeBag
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
|
6
|
+
has_many :envelopes, autosave: true
|
7
|
+
field :integration_code, type: String # Used to link your own app models to the Bag.
|
8
|
+
|
9
|
+
def push(envelope)
|
10
|
+
self.envelopes.push envelope
|
11
|
+
end
|
12
|
+
alias_method :"add",:"push"
|
13
|
+
|
14
|
+
# Post this Envelope!
|
15
|
+
def post_envelopes!
|
16
|
+
return false if envelopes.size==0
|
17
|
+
self.save if self.changed?
|
18
|
+
envelopes.each do |e|
|
19
|
+
unless e.posted?
|
20
|
+
e.post!
|
21
|
+
end
|
22
|
+
end
|
23
|
+
true
|
24
|
+
end
|
25
|
+
alias_method :"post!",:"post_envelopes!"
|
26
|
+
|
27
|
+
end
|
data/lib/mailcannon/event.rb
CHANGED
data/lib/mailcannon/mail.rb
CHANGED
data/lib/mailcannon/stamp.rb
CHANGED
@@ -3,11 +3,11 @@ class MailCannon::Stamp
|
|
3
3
|
include Mongoid::Document
|
4
4
|
include Mongoid::Timestamps
|
5
5
|
|
6
|
-
|
6
|
+
embedded_in :envelope
|
7
7
|
|
8
8
|
field :code, type: Integer, default: 0
|
9
9
|
field :recipient # email address for this "notification"
|
10
|
-
validates :code,
|
10
|
+
validates :code, presence: true
|
11
11
|
|
12
12
|
# Returns the Event for this Stamp.
|
13
13
|
def event
|
data/lib/mailcannon/version.rb
CHANGED
@@ -3,24 +3,20 @@ class MailCannon::Barrel
|
|
3
3
|
include Sidekiq::Worker
|
4
4
|
|
5
5
|
def perform(envelope_id)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
unless response==true
|
16
|
-
raise response
|
17
|
-
end
|
18
|
-
end
|
19
|
-
rescue Exception => e
|
20
|
-
puts "unable to send MailCannon::Envelope.find(#{envelope_id})"
|
21
|
-
puts e.backtrace
|
6
|
+
envelope_id = envelope_id['$oid'] if envelope_id['$oid']
|
7
|
+
logger.info "sending MailCannon::Envelope.find('#{envelope_id}')"
|
8
|
+
begin
|
9
|
+
envelope = MailCannon::Envelope.find(envelope_id.to_s)
|
10
|
+
if envelope.valid?
|
11
|
+
response = envelope.send!
|
12
|
+
unless response==true
|
13
|
+
raise response
|
14
|
+
end
|
22
15
|
end
|
16
|
+
rescue Mongoid::Errors::DocumentNotFound
|
17
|
+
logger.error "unable to find the document MailCannon::Envelope.find('#{envelope_id}')"
|
18
|
+
rescue Exception => e
|
19
|
+
logger.error "unable to send MailCannon::Envelope.find('#{envelope_id}')\n#{e.backtrace}"
|
23
20
|
end
|
24
|
-
aggregator.submit
|
25
21
|
end
|
26
22
|
end
|
data/lib/mailcannon.rb
CHANGED
@@ -2,14 +2,13 @@ require 'yaml'
|
|
2
2
|
require 'openssl'
|
3
3
|
require 'bundler'
|
4
4
|
require 'json'
|
5
|
+
#should use Bundler
|
5
6
|
require 'mongoid'
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
Bundler.require(:default,:development)
|
12
|
-
end
|
7
|
+
require 'sidekiq'
|
8
|
+
require 'sendgrid_webapi'
|
9
|
+
require 'yajl-ruby' if RUBY_PLATFORM=='ruby'
|
10
|
+
require 'jruby-openssl' if RUBY_PLATFORM=='jruby'
|
11
|
+
#require 'librato-metrics'
|
13
12
|
|
14
13
|
Encoding.default_internal = "utf-8"
|
15
14
|
Encoding.default_external = "utf-8"
|
@@ -17,6 +16,7 @@ Encoding.default_external = "utf-8"
|
|
17
16
|
module MailCannon
|
18
17
|
require_relative 'mailcannon/adapter'
|
19
18
|
require_relative 'mailcannon/adapters/sendgrid_web'
|
19
|
+
require_relative 'mailcannon/envelope_bag'
|
20
20
|
require_relative 'mailcannon/envelope'
|
21
21
|
require_relative 'mailcannon/mail'
|
22
22
|
require_relative 'mailcannon/stamp'
|
@@ -24,16 +24,16 @@ module MailCannon
|
|
24
24
|
require_relative 'mailcannon/workers/barrel'
|
25
25
|
require_relative 'mailcannon/version'
|
26
26
|
|
27
|
-
|
27
|
+
#Librato::Metrics.authenticate(ENV['LIBRATO_USER'], ENV['LIBRATO_TOKEN']) if ENV['LIBRATO_TOKEN'] && ENV['LIBRATO_USER'] # change to initializer
|
28
28
|
|
29
29
|
# To be used with caution
|
30
30
|
def self.warmode
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
$redis = Redis.new(host: redis_uri.host, port: redis_uri.port)
|
31
|
+
#Mongoid.load!("config/mongoid.yml", ENV['RACK_ENV']||'development') # change to env URL
|
32
|
+
Sidekiq.configure_client do |config|
|
33
|
+
config.redis = { :namespace => 'mailcannon', :size => 1, :url => ENV['REDIS_URL'] }
|
34
|
+
end
|
36
35
|
end
|
36
|
+
self.warmode if ENV['MAILCANNON_MODE']=='war'
|
37
37
|
|
38
38
|
# Returns the config Hash
|
39
39
|
def self.config(root_dir=nil)
|
@@ -52,4 +52,24 @@ module MailCannon
|
|
52
52
|
YAML.load(erb)
|
53
53
|
end
|
54
54
|
|
55
|
+
# alias method
|
56
|
+
def logger
|
57
|
+
MailCannon.logger
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the lib logger object
|
61
|
+
def self.logger
|
62
|
+
@logger || initialize_logger
|
63
|
+
end
|
64
|
+
|
65
|
+
# Initializes logger with mailcannon setup
|
66
|
+
def self.initialize_logger(log_target = STDOUT)
|
67
|
+
oldlogger = @logger
|
68
|
+
@logger = Logger.new(log_target)
|
69
|
+
@logger.level = Logger::INFO
|
70
|
+
@logger.progname = 'mailcannon'
|
71
|
+
oldlogger.close if oldlogger && !$TESTING # don't want to close testing's STDOUT logging
|
72
|
+
@logger
|
73
|
+
end
|
74
|
+
|
55
75
|
end
|
data/mailcannon.gemspec
CHANGED
@@ -18,6 +18,25 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
if RUBY_ENGINE=='rbx'
|
23
|
+
s.add_dependency 'rubysl'
|
24
|
+
end
|
25
|
+
if RUBY_PLATFORM=='ruby'
|
26
|
+
s.add_dependency 'yajl-ruby'
|
27
|
+
end
|
28
|
+
if RUBY_PLATFORM=='jruby'
|
29
|
+
s.add_dependency 'jruby-openssl'
|
30
|
+
end
|
31
|
+
|
32
|
+
s.add_runtime_dependency 'activemodel', '>= 3.0.0'
|
33
|
+
|
34
|
+
#s.add_dependency 'librato-metrics'
|
35
|
+
s.add_dependency 'redis'
|
36
|
+
s.add_dependency 'mongoid'
|
37
|
+
s.add_dependency 'sidekiq'
|
38
|
+
s.add_dependency 'sendgrid_webapi'
|
39
|
+
s.add_dependency 'json-schema'
|
21
40
|
|
22
41
|
s.add_development_dependency "vcr"
|
23
42
|
s.add_development_dependency "rspec"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :empty_envelope_bag, class: MailCannon::EnvelopeBag do
|
3
|
+
envelopes []
|
4
|
+
|
5
|
+
factory :filled_envelope_bag, class: MailCannon::EnvelopeBag do
|
6
|
+
# This factories will be inconsistent on tests running post! at the same spec
|
7
|
+
envelope_a = FactoryGirl.build(:envelope)
|
8
|
+
envelope_b = FactoryGirl.build(:envelope_multi)
|
9
|
+
envelopes [envelope_a,envelope_b]
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
data/spec/integration/1k_spec.rb
CHANGED
@@ -4,7 +4,7 @@ describe "shoot 1k emails!" do
|
|
4
4
|
let(:envelope) { build(:envelope_multi_1k) }
|
5
5
|
it "sends http request for Sendgrid web API" do
|
6
6
|
VCR.use_cassette('mailcannon_integration_1k') do
|
7
|
-
expect(envelope.send_bulk!).to
|
7
|
+
expect(envelope.send_bulk!).to be_true
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe 'X-SMTPAPI compatibility' do
|
4
|
+
describe "xsmtpapi for bulk" do
|
5
|
+
context "generates expected xsmtpapi for #post!" do
|
6
|
+
let(:envelope) { build(:envelope_multi, xsmtpapi: { "unique_args" => { "userid" => "1123", "template" => "welcome" }}) }
|
7
|
+
|
8
|
+
it "returns true" do
|
9
|
+
VCR.use_cassette('mailcannon_adapter_sendgrid_send_bulk') do
|
10
|
+
Sidekiq::Testing.inline! do
|
11
|
+
envelope.post!
|
12
|
+
end
|
13
|
+
end
|
14
|
+
envelope.reload # content is changed inside the Adapter module
|
15
|
+
#binding.pry
|
16
|
+
expect(envelope.xsmtpapi['to']).to match_array ['mailcannon@railsnapraia.com', 'contact@railsonthebeach.com', 'lucasmartins@railsnapraia.com']
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -5,7 +5,7 @@ describe MailCannon::Adapter::SendgridWeb do
|
|
5
5
|
let(:envelope) { build(:envelope) }
|
6
6
|
it "sends http request for Sendgrid web API" do
|
7
7
|
VCR.use_cassette('mailcannon_adapter_sendgrid_send') do
|
8
|
-
expect(envelope.send!).to
|
8
|
+
expect(envelope.send!).to be_true
|
9
9
|
end
|
10
10
|
end
|
11
11
|
it "calls after_sent callback" do
|
@@ -20,7 +20,7 @@ describe MailCannon::Adapter::SendgridWeb do
|
|
20
20
|
let(:envelope) { build(:envelope_multi) }
|
21
21
|
it "sends http request for Sendgrid web API" do
|
22
22
|
VCR.use_cassette('mailcannon_adapter_sendgrid_send_bulk') do
|
23
|
-
expect(envelope.send_bulk!).to
|
23
|
+
expect(envelope.send_bulk!).to be_true
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe MailCannon::EnvelopeBag do
|
4
|
+
describe "#post!" do
|
5
|
+
context "when it has no Envelopes" do
|
6
|
+
let(:envelope_bag) { build(:empty_envelope_bag) }
|
7
|
+
it "does not raise error" do
|
8
|
+
expect{envelope_bag.post!}.not_to raise_error
|
9
|
+
end
|
10
|
+
it "returns false" do
|
11
|
+
expect(envelope_bag.post!).to be_false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
context "when it has Envelopes" do
|
15
|
+
let(:envelope_bag) { build(:filled_envelope_bag) }
|
16
|
+
it "does not raise error" do
|
17
|
+
expect{envelope_bag.post!}.not_to raise_error
|
18
|
+
end
|
19
|
+
it "returns true" do
|
20
|
+
expect(envelope_bag.post!).to be_true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
context "when it has Envelopes (isolating Bag)" do
|
24
|
+
let(:envelope_bag) { MailCannon::EnvelopeBag.new }
|
25
|
+
it "posts Envelopes in the bag" do
|
26
|
+
envelope_bag.envelopes.push build(:envelope)
|
27
|
+
envelope_bag.envelopes.push build(:envelope_multi)
|
28
|
+
expect(envelope_bag.envelopes.size).to eq(2)
|
29
|
+
# Rspec can't do 'any_instance.should_receive' twice.
|
30
|
+
envelope_bag.envelopes.each do |envelope|
|
31
|
+
expect(envelope).to receive(:post!)
|
32
|
+
end
|
33
|
+
envelope_bag.post!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe MailCannon::Envelope do
|
4
|
-
describe "
|
4
|
+
describe "initialization" do
|
5
5
|
let(:envelope) { build(:envelope) }
|
6
|
-
it "
|
7
|
-
|
6
|
+
it "has no Stamps" do
|
7
|
+
envelope.save
|
8
|
+
expect(envelope.stamps.size).to eq(0)
|
8
9
|
end
|
9
10
|
context "check for expected adapter behavior" do
|
10
11
|
it "implements send! behavior" do
|
@@ -52,6 +53,42 @@ describe MailCannon::Envelope do
|
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
56
|
+
describe "#posted?" do
|
57
|
+
context "when already posted" do
|
58
|
+
let(:envelope) { build(:envelope) }
|
59
|
+
it "returns true" do
|
60
|
+
VCR.use_cassette('mailcannon_adapter_sendgrid_send') do
|
61
|
+
envelope.post!
|
62
|
+
end
|
63
|
+
expect(envelope.posted?).to be_true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
context "when not yet posted" do
|
67
|
+
let(:envelope) { build(:envelope) }
|
68
|
+
it "returns false" do
|
69
|
+
expect(envelope.posted?).to be_false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "xsmtpapi" do
|
75
|
+
context "keep xsmtpapi arguments after #post!" do
|
76
|
+
let(:envelope) { build(:envelope_multi, xsmtpapi: { "unique_args" => { "userid" => "1123", "template" => "welcome" }}) }
|
77
|
+
|
78
|
+
it "returns true" do
|
79
|
+
VCR.use_cassette('mailcannon_adapter_sendgrid_send_bulk') do
|
80
|
+
Sidekiq::Testing.inline! do
|
81
|
+
envelope.post!
|
82
|
+
end
|
83
|
+
end
|
84
|
+
envelope.reload # content is changed inside the Adapter module
|
85
|
+
expect(envelope.xsmtpapi).to have_key("unique_args")
|
86
|
+
expect(envelope.xsmtpapi).to have_key("to")
|
87
|
+
expect(envelope.xsmtpapi).to have_key("sub")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
55
92
|
describe "#after_sent" do
|
56
93
|
let(:envelope) { create(:envelope) }
|
57
94
|
it "creates a Processed Stamp" do
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe MailCannon::Barrel do
|
4
|
+
describe "perform" do
|
5
|
+
let(:envelope) { create(:envelope) }
|
6
|
+
it "creates a new Stamp" do
|
7
|
+
VCR.use_cassette('mailcannon_barrel_envelope_post') do
|
8
|
+
expect{ envelope.post! }.to change{envelope.stamps.size}.by(1)
|
9
|
+
end
|
10
|
+
expect(envelope.stamps.first.code).to eq(0) # 0=posted
|
11
|
+
end
|
12
|
+
it "looks for an existing MongoDB document" do
|
13
|
+
VCR.use_cassette('mailcannon_barrel_envelope_post') do
|
14
|
+
Sidekiq::Testing.inline! do
|
15
|
+
expect{envelope.post!}.not_to raise_error(Mongoid::Errors::DocumentNotFound)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
it "runs the job without errors" do
|
20
|
+
VCR.use_cassette('mailcannon_barrel_envelope_post') do
|
21
|
+
Sidekiq::Testing.inline! do
|
22
|
+
expect{envelope.post!}.not_to raise_error
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
pending "calls Envelope#send!" do
|
27
|
+
Sidekiq::Testing.inline! do
|
28
|
+
MailCannon::Adapter::SendgridWeb.any_instance.should_receive('send!')
|
29
|
+
VCR.use_cassette('mailcannon_barrel_envelope_post') do
|
30
|
+
envelope.post!
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
context "check for expected adapter behavior" do
|
35
|
+
it "implements send! behavior" do
|
36
|
+
expect(envelope.respond_to?(:send!)).to be_true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/spec/mailcannon_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -10,6 +10,7 @@ require 'factory_girl'
|
|
10
10
|
require 'vcr'
|
11
11
|
require 'webmock'
|
12
12
|
require 'webmock/rspec'
|
13
|
+
require 'sidekiq/testing'
|
13
14
|
|
14
15
|
if ENV['TRAVIS']==true
|
15
16
|
begin
|
@@ -54,4 +55,5 @@ VCR.configure do |c|
|
|
54
55
|
c.allow_http_connections_when_no_cassette = true
|
55
56
|
end
|
56
57
|
|
57
|
-
Mongoid.load!("spec/support/mongoid.yml", 'test')
|
58
|
+
Mongoid.load!("spec/support/mongoid.yml", 'test')
|
59
|
+
MailCannon.config('templates')
|
@@ -1,3 +1,7 @@
|
|
1
1
|
# This file will hold any hard configurations MailCannon may need. Customizations included.
|
2
|
-
|
3
|
-
|
2
|
+
|
3
|
+
# When creating a MailCannon::Envelope the default behavior is to auto-post the Job to send it.
|
4
|
+
auto_post: true
|
5
|
+
|
6
|
+
# This is will schedule a delay for the Job execution, useful if you want to be able to Cancel the Job.
|
7
|
+
waiting_time: 0
|
metadata
CHANGED
@@ -1,15 +1,99 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mailcannon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Martins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activemodel
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: redis
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mongoid
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sidekiq
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sendgrid_webapi
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: json-schema
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
13
97
|
- !ruby/object:Gem::Dependency
|
14
98
|
name: vcr
|
15
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -183,35 +267,40 @@ files:
|
|
183
267
|
- .travis.yml
|
184
268
|
- .yardopts
|
185
269
|
- Gemfile
|
186
|
-
- Gemfile.lock
|
187
270
|
- Rakefile
|
188
271
|
- Readme.md
|
189
272
|
- ReadmeContributors.md
|
190
273
|
- config/locales/en.yml
|
191
274
|
- config/locales/pt-BR.yml
|
192
275
|
- env.sample.sh
|
193
|
-
- lib/generators/
|
194
|
-
- lib/generators/
|
276
|
+
- lib/generators/mailcannon/USAGE
|
277
|
+
- lib/generators/mailcannon/config_generator.rb
|
195
278
|
- lib/mailcannon.rb
|
196
279
|
- lib/mailcannon/adapter.rb
|
197
280
|
- lib/mailcannon/adapters/sendgrid_web.rb
|
198
281
|
- lib/mailcannon/envelope.rb
|
282
|
+
- lib/mailcannon/envelope_bag.rb
|
199
283
|
- lib/mailcannon/event.rb
|
284
|
+
- lib/mailcannon/hash.rb
|
200
285
|
- lib/mailcannon/mail.rb
|
201
286
|
- lib/mailcannon/stamp.rb
|
202
287
|
- lib/mailcannon/version.rb
|
203
288
|
- lib/mailcannon/workers/barrel.rb
|
204
289
|
- mailcannon.gemspec
|
205
290
|
- spec/factories/envelope.rb
|
291
|
+
- spec/factories/envelope_bag.rb
|
206
292
|
- spec/factories/stamp.rb
|
207
293
|
- spec/fixtures/cassettes/mailcannon_adapter_sendgrid.send.yml
|
208
294
|
- spec/fixtures/cassettes/mailcannon_adapter_sendgrid_send.yml
|
209
295
|
- spec/fixtures/cassettes/mailcannon_adapter_sendgrid_send_bulk.yml
|
210
296
|
- spec/fixtures/cassettes/mailcannon_integration_1k.yml
|
211
297
|
- spec/integration/1k_spec.rb
|
298
|
+
- spec/integration/xsmtpapi_spec.rb
|
212
299
|
- spec/mailcannon/adapters/sendgrid_spec.rb
|
300
|
+
- spec/mailcannon/envelope_bag_spec.rb
|
213
301
|
- spec/mailcannon/envelope_spec.rb
|
214
302
|
- spec/mailcannon/stamp_spec.rb
|
303
|
+
- spec/mailcannon/workers/barrel_spec.rb
|
215
304
|
- spec/mailcannon_spec.rb
|
216
305
|
- spec/spec_helper.rb
|
217
306
|
- spec/support/mongoid.yml
|
@@ -243,15 +332,19 @@ specification_version: 4
|
|
243
332
|
summary: A mass mailing tool for real threads aficionados
|
244
333
|
test_files:
|
245
334
|
- spec/factories/envelope.rb
|
335
|
+
- spec/factories/envelope_bag.rb
|
246
336
|
- spec/factories/stamp.rb
|
247
337
|
- spec/fixtures/cassettes/mailcannon_adapter_sendgrid.send.yml
|
248
338
|
- spec/fixtures/cassettes/mailcannon_adapter_sendgrid_send.yml
|
249
339
|
- spec/fixtures/cassettes/mailcannon_adapter_sendgrid_send_bulk.yml
|
250
340
|
- spec/fixtures/cassettes/mailcannon_integration_1k.yml
|
251
341
|
- spec/integration/1k_spec.rb
|
342
|
+
- spec/integration/xsmtpapi_spec.rb
|
252
343
|
- spec/mailcannon/adapters/sendgrid_spec.rb
|
344
|
+
- spec/mailcannon/envelope_bag_spec.rb
|
253
345
|
- spec/mailcannon/envelope_spec.rb
|
254
346
|
- spec/mailcannon/stamp_spec.rb
|
347
|
+
- spec/mailcannon/workers/barrel_spec.rb
|
255
348
|
- spec/mailcannon_spec.rb
|
256
349
|
- spec/spec_helper.rb
|
257
350
|
- spec/support/mongoid.yml
|
data/Gemfile.lock
DELETED
@@ -1,322 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: https://rubygems.org/
|
3
|
-
specs:
|
4
|
-
activemodel (3.2.16)
|
5
|
-
activesupport (= 3.2.16)
|
6
|
-
builder (~> 3.0.0)
|
7
|
-
activesupport (3.2.16)
|
8
|
-
i18n (~> 0.6, >= 0.6.4)
|
9
|
-
multi_json (~> 1.0)
|
10
|
-
addressable (2.3.5)
|
11
|
-
aggregate (0.2.2)
|
12
|
-
builder (3.0.4)
|
13
|
-
celluloid (0.15.2)
|
14
|
-
timers (~> 1.1.0)
|
15
|
-
coderay (1.0.9)
|
16
|
-
colorize (0.5.8)
|
17
|
-
connection_pool (1.2.0)
|
18
|
-
coveralls (0.6.7)
|
19
|
-
colorize
|
20
|
-
multi_json (~> 1.3)
|
21
|
-
rest-client
|
22
|
-
simplecov (>= 0.7)
|
23
|
-
thor
|
24
|
-
crack (0.4.1)
|
25
|
-
safe_yaml (~> 0.9.0)
|
26
|
-
database_cleaner (1.2.0)
|
27
|
-
diff-lcs (1.2.4)
|
28
|
-
factory_girl (4.3.0)
|
29
|
-
activesupport (>= 3.0.0)
|
30
|
-
faraday (0.8.8)
|
31
|
-
multipart-post (~> 1.2.0)
|
32
|
-
ffi2-generators (0.1.1)
|
33
|
-
i18n (0.6.9)
|
34
|
-
json (1.8.1)
|
35
|
-
json-schema (2.1.8)
|
36
|
-
librato-metrics (1.3.0)
|
37
|
-
aggregate (~> 0.2.2)
|
38
|
-
faraday (~> 0.7)
|
39
|
-
multi_json
|
40
|
-
method_source (0.8.1)
|
41
|
-
mime-types (1.23)
|
42
|
-
mongoid (3.1.6)
|
43
|
-
activemodel (~> 3.2)
|
44
|
-
moped (~> 1.4)
|
45
|
-
origin (~> 1.0)
|
46
|
-
tzinfo (~> 0.3.29)
|
47
|
-
moped (1.5.1)
|
48
|
-
multi_json (1.8.2)
|
49
|
-
multipart-post (1.2.0)
|
50
|
-
origin (1.1.0)
|
51
|
-
pry (0.9.12.2)
|
52
|
-
coderay (~> 1.0.5)
|
53
|
-
method_source (~> 0.8)
|
54
|
-
slop (~> 3.4)
|
55
|
-
pry-nav (0.2.3)
|
56
|
-
pry (~> 0.9.10)
|
57
|
-
rake (10.0.4)
|
58
|
-
redis (3.0.6)
|
59
|
-
redis-namespace (1.4.1)
|
60
|
-
redis (~> 3.0.4)
|
61
|
-
rest-client (1.6.7)
|
62
|
-
mime-types (>= 1.16)
|
63
|
-
rspec (2.13.0)
|
64
|
-
rspec-core (~> 2.13.0)
|
65
|
-
rspec-expectations (~> 2.13.0)
|
66
|
-
rspec-mocks (~> 2.13.0)
|
67
|
-
rspec-core (2.13.1)
|
68
|
-
rspec-expectations (2.13.0)
|
69
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
70
|
-
rspec-mocks (2.13.1)
|
71
|
-
rubysl (2.0.15)
|
72
|
-
rubysl-abbrev (~> 2.0)
|
73
|
-
rubysl-base64 (~> 2.0)
|
74
|
-
rubysl-benchmark (~> 2.0)
|
75
|
-
rubysl-bigdecimal (~> 2.0)
|
76
|
-
rubysl-cgi (~> 2.0)
|
77
|
-
rubysl-cgi-session (~> 2.0)
|
78
|
-
rubysl-cmath (~> 2.0)
|
79
|
-
rubysl-complex (~> 2.0)
|
80
|
-
rubysl-continuation (~> 2.0)
|
81
|
-
rubysl-coverage (~> 2.0)
|
82
|
-
rubysl-csv (~> 2.0)
|
83
|
-
rubysl-curses (~> 2.0)
|
84
|
-
rubysl-date (~> 2.0)
|
85
|
-
rubysl-delegate (~> 2.0)
|
86
|
-
rubysl-digest (~> 2.0)
|
87
|
-
rubysl-drb (~> 2.0)
|
88
|
-
rubysl-e2mmap (~> 2.0)
|
89
|
-
rubysl-english (~> 2.0)
|
90
|
-
rubysl-enumerator (~> 2.0)
|
91
|
-
rubysl-erb (~> 2.0)
|
92
|
-
rubysl-etc (~> 2.0)
|
93
|
-
rubysl-expect (~> 2.0)
|
94
|
-
rubysl-fcntl (~> 2.0)
|
95
|
-
rubysl-fiber (~> 2.0)
|
96
|
-
rubysl-fileutils (~> 2.0)
|
97
|
-
rubysl-find (~> 2.0)
|
98
|
-
rubysl-forwardable (~> 2.0)
|
99
|
-
rubysl-getoptlong (~> 2.0)
|
100
|
-
rubysl-gserver (~> 2.0)
|
101
|
-
rubysl-io-console (~> 2.0)
|
102
|
-
rubysl-io-nonblock (~> 2.0)
|
103
|
-
rubysl-io-wait (~> 2.0)
|
104
|
-
rubysl-ipaddr (~> 2.0)
|
105
|
-
rubysl-irb (~> 2.0)
|
106
|
-
rubysl-logger (~> 2.0)
|
107
|
-
rubysl-mathn (~> 2.0)
|
108
|
-
rubysl-matrix (~> 2.0)
|
109
|
-
rubysl-mkmf (~> 2.0)
|
110
|
-
rubysl-monitor (~> 2.0)
|
111
|
-
rubysl-mutex_m (~> 2.0)
|
112
|
-
rubysl-net-ftp (~> 2.0)
|
113
|
-
rubysl-net-http (~> 2.0)
|
114
|
-
rubysl-net-imap (~> 2.0)
|
115
|
-
rubysl-net-pop (~> 2.0)
|
116
|
-
rubysl-net-protocol (~> 2.0)
|
117
|
-
rubysl-net-smtp (~> 2.0)
|
118
|
-
rubysl-net-telnet (~> 2.0)
|
119
|
-
rubysl-nkf (~> 2.0)
|
120
|
-
rubysl-observer (~> 2.0)
|
121
|
-
rubysl-open-uri (~> 2.0)
|
122
|
-
rubysl-open3 (~> 2.0)
|
123
|
-
rubysl-openssl (~> 2.0)
|
124
|
-
rubysl-optparse (~> 2.0)
|
125
|
-
rubysl-ostruct (~> 2.0)
|
126
|
-
rubysl-pathname (~> 2.0)
|
127
|
-
rubysl-prettyprint (~> 2.0)
|
128
|
-
rubysl-prime (~> 2.0)
|
129
|
-
rubysl-profile (~> 2.0)
|
130
|
-
rubysl-profiler (~> 2.0)
|
131
|
-
rubysl-pstore (~> 2.0)
|
132
|
-
rubysl-pty (~> 2.0)
|
133
|
-
rubysl-rational (~> 2.0)
|
134
|
-
rubysl-readline (~> 2.0)
|
135
|
-
rubysl-resolv (~> 2.0)
|
136
|
-
rubysl-rexml (~> 2.0)
|
137
|
-
rubysl-rinda (~> 2.0)
|
138
|
-
rubysl-rss (~> 2.0)
|
139
|
-
rubysl-scanf (~> 2.0)
|
140
|
-
rubysl-securerandom (~> 2.0)
|
141
|
-
rubysl-set (~> 2.0)
|
142
|
-
rubysl-shellwords (~> 2.0)
|
143
|
-
rubysl-singleton (~> 2.0)
|
144
|
-
rubysl-socket (~> 2.0)
|
145
|
-
rubysl-stringio (~> 2.0)
|
146
|
-
rubysl-strscan (~> 2.0)
|
147
|
-
rubysl-sync (~> 2.0)
|
148
|
-
rubysl-syslog (~> 2.0)
|
149
|
-
rubysl-tempfile (~> 2.0)
|
150
|
-
rubysl-thread (~> 2.0)
|
151
|
-
rubysl-thwait (~> 2.0)
|
152
|
-
rubysl-time (~> 2.0)
|
153
|
-
rubysl-timeout (~> 2.0)
|
154
|
-
rubysl-tmpdir (~> 2.0)
|
155
|
-
rubysl-tsort (~> 2.0)
|
156
|
-
rubysl-un (~> 2.0)
|
157
|
-
rubysl-uri (~> 2.0)
|
158
|
-
rubysl-weakref (~> 2.0)
|
159
|
-
rubysl-webrick (~> 2.0)
|
160
|
-
rubysl-xmlrpc (~> 2.0)
|
161
|
-
rubysl-yaml (~> 2.0)
|
162
|
-
rubysl-zlib (~> 2.0)
|
163
|
-
rubysl-abbrev (2.0.4)
|
164
|
-
rubysl-base64 (2.0.0)
|
165
|
-
rubysl-benchmark (2.0.1)
|
166
|
-
rubysl-bigdecimal (2.0.2)
|
167
|
-
rubysl-cgi (2.0.1)
|
168
|
-
rubysl-cgi-session (2.0.1)
|
169
|
-
rubysl-cmath (2.0.0)
|
170
|
-
rubysl-complex (2.0.0)
|
171
|
-
rubysl-continuation (2.0.0)
|
172
|
-
rubysl-coverage (2.0.3)
|
173
|
-
rubysl-csv (2.0.2)
|
174
|
-
rubysl-english (~> 2.0)
|
175
|
-
rubysl-curses (2.0.0)
|
176
|
-
rubysl-date (2.0.6)
|
177
|
-
rubysl-delegate (2.0.1)
|
178
|
-
rubysl-digest (2.0.3)
|
179
|
-
rubysl-drb (2.0.1)
|
180
|
-
rubysl-e2mmap (2.0.0)
|
181
|
-
rubysl-english (2.0.0)
|
182
|
-
rubysl-enumerator (2.0.0)
|
183
|
-
rubysl-erb (2.0.1)
|
184
|
-
rubysl-etc (2.0.3)
|
185
|
-
ffi2-generators (~> 0.1)
|
186
|
-
rubysl-expect (2.0.0)
|
187
|
-
rubysl-fcntl (2.0.4)
|
188
|
-
ffi2-generators (~> 0.1)
|
189
|
-
rubysl-fiber (2.0.0)
|
190
|
-
rubysl-fileutils (2.0.3)
|
191
|
-
rubysl-find (2.0.1)
|
192
|
-
rubysl-forwardable (2.0.1)
|
193
|
-
rubysl-getoptlong (2.0.0)
|
194
|
-
rubysl-gserver (2.0.0)
|
195
|
-
rubysl-socket (~> 2.0)
|
196
|
-
rubysl-thread (~> 2.0)
|
197
|
-
rubysl-io-console (2.0.0)
|
198
|
-
rubysl-io-nonblock (2.0.0)
|
199
|
-
rubysl-io-wait (2.0.0)
|
200
|
-
rubysl-ipaddr (2.0.0)
|
201
|
-
rubysl-irb (2.0.4)
|
202
|
-
rubysl-e2mmap (~> 2.0)
|
203
|
-
rubysl-mathn (~> 2.0)
|
204
|
-
rubysl-readline (~> 2.0)
|
205
|
-
rubysl-thread (~> 2.0)
|
206
|
-
rubysl-logger (2.0.0)
|
207
|
-
rubysl-mathn (2.0.0)
|
208
|
-
rubysl-matrix (2.1.0)
|
209
|
-
rubysl-e2mmap (~> 2.0)
|
210
|
-
rubysl-mkmf (2.0.1)
|
211
|
-
rubysl-fileutils (~> 2.0)
|
212
|
-
rubysl-shellwords (~> 2.0)
|
213
|
-
rubysl-monitor (2.0.0)
|
214
|
-
rubysl-mutex_m (2.0.0)
|
215
|
-
rubysl-net-ftp (2.0.1)
|
216
|
-
rubysl-net-http (2.0.4)
|
217
|
-
rubysl-cgi (~> 2.0)
|
218
|
-
rubysl-erb (~> 2.0)
|
219
|
-
rubysl-singleton (~> 2.0)
|
220
|
-
rubysl-net-imap (2.0.1)
|
221
|
-
rubysl-net-pop (2.0.1)
|
222
|
-
rubysl-net-protocol (2.0.1)
|
223
|
-
rubysl-net-smtp (2.0.1)
|
224
|
-
rubysl-net-telnet (2.0.0)
|
225
|
-
rubysl-nkf (2.0.1)
|
226
|
-
rubysl-observer (2.0.0)
|
227
|
-
rubysl-open-uri (2.0.0)
|
228
|
-
rubysl-open3 (2.0.0)
|
229
|
-
rubysl-openssl (2.0.5)
|
230
|
-
rubysl-optparse (2.0.1)
|
231
|
-
rubysl-shellwords (~> 2.0)
|
232
|
-
rubysl-ostruct (2.0.4)
|
233
|
-
rubysl-pathname (2.0.0)
|
234
|
-
rubysl-prettyprint (2.0.2)
|
235
|
-
rubysl-prime (2.0.1)
|
236
|
-
rubysl-profile (2.0.0)
|
237
|
-
rubysl-profiler (2.0.1)
|
238
|
-
rubysl-pstore (2.0.0)
|
239
|
-
rubysl-pty (2.0.2)
|
240
|
-
rubysl-rational (2.0.1)
|
241
|
-
rubysl-readline (2.0.2)
|
242
|
-
rubysl-resolv (2.0.0)
|
243
|
-
rubysl-rexml (2.0.2)
|
244
|
-
rubysl-rinda (2.0.0)
|
245
|
-
rubysl-rss (2.0.0)
|
246
|
-
rubysl-scanf (2.0.0)
|
247
|
-
rubysl-securerandom (2.0.0)
|
248
|
-
rubysl-set (2.0.1)
|
249
|
-
rubysl-shellwords (2.0.0)
|
250
|
-
rubysl-singleton (2.0.0)
|
251
|
-
rubysl-socket (2.0.1)
|
252
|
-
rubysl-stringio (2.0.0)
|
253
|
-
rubysl-strscan (2.0.0)
|
254
|
-
rubysl-sync (2.0.0)
|
255
|
-
rubysl-syslog (2.0.1)
|
256
|
-
ffi2-generators (~> 0.1)
|
257
|
-
rubysl-tempfile (2.0.1)
|
258
|
-
rubysl-thread (2.0.2)
|
259
|
-
rubysl-thwait (2.0.0)
|
260
|
-
rubysl-time (2.0.3)
|
261
|
-
rubysl-timeout (2.0.0)
|
262
|
-
rubysl-tmpdir (2.0.0)
|
263
|
-
rubysl-tsort (2.0.1)
|
264
|
-
rubysl-un (2.0.0)
|
265
|
-
rubysl-fileutils (~> 2.0)
|
266
|
-
rubysl-optparse (~> 2.0)
|
267
|
-
rubysl-uri (2.0.0)
|
268
|
-
rubysl-weakref (2.0.0)
|
269
|
-
rubysl-webrick (2.0.0)
|
270
|
-
rubysl-xmlrpc (2.0.0)
|
271
|
-
rubysl-yaml (2.0.4)
|
272
|
-
rubysl-zlib (2.0.1)
|
273
|
-
safe_yaml (0.9.7)
|
274
|
-
sendgrid_webapi (0.0.2)
|
275
|
-
faraday (~> 0.8.0)
|
276
|
-
json (~> 1.8.0)
|
277
|
-
sidekiq (2.17.0)
|
278
|
-
celluloid (>= 0.15.2)
|
279
|
-
connection_pool (>= 1.0.0)
|
280
|
-
json
|
281
|
-
redis (>= 3.0.4)
|
282
|
-
redis-namespace (>= 1.3.1)
|
283
|
-
simplecov (0.7.1)
|
284
|
-
multi_json (~> 1.0)
|
285
|
-
simplecov-html (~> 0.7.1)
|
286
|
-
simplecov-html (0.7.1)
|
287
|
-
slop (3.4.5)
|
288
|
-
thor (0.18.1)
|
289
|
-
timers (1.1.0)
|
290
|
-
tzinfo (0.3.38)
|
291
|
-
vcr (2.8.0)
|
292
|
-
webmock (1.15.2)
|
293
|
-
addressable (>= 2.2.7)
|
294
|
-
crack (>= 0.3.2)
|
295
|
-
yajl-ruby (1.2.0)
|
296
|
-
yard (0.8.6.2)
|
297
|
-
|
298
|
-
PLATFORMS
|
299
|
-
ruby
|
300
|
-
|
301
|
-
DEPENDENCIES
|
302
|
-
coveralls
|
303
|
-
database_cleaner
|
304
|
-
factory_girl
|
305
|
-
jruby-openssl
|
306
|
-
json-schema
|
307
|
-
librato-metrics
|
308
|
-
mongoid
|
309
|
-
pry
|
310
|
-
pry-nav
|
311
|
-
rake
|
312
|
-
redis
|
313
|
-
rspec
|
314
|
-
rspec-expectations
|
315
|
-
rspec-mocks
|
316
|
-
rubysl
|
317
|
-
sendgrid_webapi
|
318
|
-
sidekiq
|
319
|
-
vcr
|
320
|
-
webmock (>= 1.8.0, < 1.16)
|
321
|
-
yajl-ruby
|
322
|
-
yard
|
File without changes
|
File without changes
|