mailcannon 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|