mimi_mailer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjQxOTk1ZTgxMDM4ZDU5NTdlNmNjMzk1MDVkZDhkYmVmMTY0Y2JmNQ==
5
+ data.tar.gz: !binary |-
6
+ M2NmNzZkNTkzYTBjNzFmODcwNGZlNDliNzg5MjljYzIxM2E2YmY3Yg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZjMwZjliODEzZDNkYmZjYWZhMTE0MDVhNDhlNjkyNDc4OTA4ZThmZGY4YjI1
10
+ MjEwMjgzMmFmY2NhNGFkNWE1MDc3YTYxYTg0M2VlMTBlYTk5ZDRlMWE0ZTZk
11
+ OGJkYTcwY2RkOGNlOWUyZjA1Zjk5NjUzZTY0NDRhZGRkYjI4NmQ=
12
+ data.tar.gz: !binary |-
13
+ Mjc5MDBjNjVlZWYwYTMxZGQxMmZlNGJhZDBhMDk5NmY2NGZlMzFmYzA3OWRi
14
+ NmQzMThhYmMyNGE3MDc5YzY0YjNlZGExN2YxZTE1OGFlMWU3OGYzMmMyYWFh
15
+ NjNjN2E1NzFjNWY3MWQ5N2Q2NjU1ZTRkY2Y0YTgyOWVkMWQ2OTI=
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .ruby-*
4
+ *.sublime-*
5
+ .bundle
6
+ .config
7
+ .yardoc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ ## 0.1.0
2
+
3
+ * Added `bulk_mail`
4
+
5
+ ## 0.0.1
6
+
7
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mimi_mailer.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Jeff Browning
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # MimiMailer
2
+
3
+ This gem provides a simple low-frills way to send transactional emails using the [Mad Mimi Mailer API](https://madmimi.com/developer/mailer/methods). If you need more, please check out our full-sized [madmimi gem](http://rubygems.org/gems/madmimi).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'mimi_mailer'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install mimi_mailer
18
+
19
+ ## Usage
20
+
21
+ If you aren't using bundler,
22
+
23
+ ```ruby
24
+ require "mimi_mailer"
25
+ ```
26
+
27
+ and then configure the mailer to use your Mad Mimi API settings.
28
+
29
+ ```ruby
30
+ MimiMailer.configure do |config|
31
+ config.username = "you@example.com"
32
+ config.api_key = "your_api_key"
33
+ config.default_from_address = "your default from address" # optional -- will use your username if not configured
34
+ end
35
+ ```
36
+
37
+ Then, create a mailer class that subclasses `MimiMailer::Base` and implements a delivery method like so:
38
+
39
+ ```ruby
40
+ class UserWelcomeMailer < MimiMailer::Base
41
+ from_address 'someone@example.com' # A class-specific from address
42
+
43
+ def self.deliver(user)
44
+ mail(promotion_name: 'promotion_name', to: user.email, subject: "subject", body: { name: user.name })
45
+ end
46
+ end
47
+
48
+ ```
49
+
50
+ ### MimiMailer::Base.mail
51
+
52
+ `MimiMailer::Base.mail` accepts the following options:
53
+
54
+ ```ruby
55
+ {
56
+ # Required. The name of the Mad Mimi promotion you want to send
57
+ promotion_name: 'promotion_name',
58
+
59
+ # Required. Who you want to send the email to. Also may be specified with :recipient.
60
+ to: 'someone@example.com',
61
+
62
+ # Who you want the email to be from. If not specified, this will fall back to the
63
+ # class-specific from address or the configured default_from_address
64
+ from: 'you@example.com',
65
+
66
+ # The subject of the email
67
+ subject: 'A nice email',
68
+
69
+ # Placeholders that will be merged into a composed promotion on Mad Mimi. :raw_html
70
+ # and/or :raw_plain_text may be specified instead (see below)
71
+ body: {
72
+ first_name: user.first_name,
73
+ last_name: user.last_name
74
+ }
75
+ }
76
+ ```
77
+
78
+ ### MimiMailer::Base.bulk_mail
79
+
80
+ `MimiMailer::Base.bulk_mail` accepts the following options:
81
+
82
+ ```ruby
83
+ {
84
+ # Required. The name of the Mad Mimi promotion you want to send
85
+ promotion_name: 'promotion_name',
86
+
87
+ # Required. The name of the audience list to import into and send to.
88
+ audience_list: 'audience_list',
89
+
90
+ # Required. The email recipients list in CSV format. Also may be specified with :csv_file.
91
+ to: "email,first name,last name,car\ndave@example.com,Dave,Hoover,Ford\ncolin@example.com,Colin,Harris,Chevy",
92
+
93
+ # Who you want the email to be from. If not specified, this will fall back to the
94
+ # class-specific from address or the configured default_from_address
95
+ from: 'you@example.com',
96
+
97
+ # The subject of the email
98
+ subject: 'A nice email',
99
+
100
+ # Placeholders that will be merged into a composed promotion on Mad Mimi. :raw_html
101
+ # and/or :raw_plain_text may be specified instead (see below)
102
+ body: {
103
+ first_name: user.first_name,
104
+ last_name: user.last_name
105
+ }
106
+ }
107
+ ```
108
+
109
+ ### Email body
110
+
111
+ The email contents can be specified using **either**:
112
+
113
+ `:body`
114
+
115
+ The body hash contains keys and values that will be substituted into correspoding promotion placeholders.
116
+
117
+ **or**
118
+
119
+ `:raw_html`
120
+
121
+ The raw HTML body of the email. May be used in conjunction with `:raw_plain_text`.
122
+
123
+ `:raw_plain_text`
124
+
125
+ The raw plain text body of the email. May be used in conjunction with `:raw_html`.
126
+
127
+ Please take a look at our [transactional email API guide](https://madmimi.com/developer/mailer/transactional) for more information about these and other options.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,31 @@
1
+ require 'httparty'
2
+ require "mimi_mailer/version"
3
+ require 'mimi_mailer/base'
4
+ require 'mimi_mailer/configuration'
5
+
6
+ module MimiMailer
7
+ class InvalidConfigurationError < StandardError;end
8
+
9
+ extend self
10
+
11
+ def configure
12
+ raise ArgumentError.new("A block must be supplied") unless block_given?
13
+ yield config
14
+ end
15
+
16
+ def config
17
+ @config ||= MimiMailer::Configuration.new
18
+ end
19
+
20
+ def enable_deliveries!
21
+ config.deliveries_enabled = true
22
+ end
23
+
24
+ def disable_deliveries!
25
+ config.deliveries_enabled = false
26
+ end
27
+
28
+ def deliveries_enabled?
29
+ config.deliveries_enabled
30
+ end
31
+ end
@@ -0,0 +1,74 @@
1
+ module MimiMailer
2
+ class Base
3
+ include HTTParty
4
+ base_uri 'https://api.madmimi.com'
5
+
6
+ def self.from_address(new_address = nil)
7
+ if new_address.nil?
8
+ @from_address || MimiMailer.config.default_from_address || MimiMailer.config.username
9
+ else
10
+ @from_address = new_address
11
+ end
12
+ end
13
+
14
+ def self.deliver(*args)
15
+ raise NotImplementedError.new("#{self.class.name}.deliver must be overridden")
16
+ end
17
+
18
+ def self.mail(options = {})
19
+ if MimiMailer.deliveries_enabled?
20
+ check_config!
21
+
22
+ options = default_options.merge(options)
23
+ options[:recipient] = options.delete(:to) if options[:recipient].nil?
24
+ options[:body] = options[:body].to_yaml unless options[:body].nil?
25
+
26
+ mail_options_sanity_check! options
27
+
28
+ response = post('/mailer', body: options)
29
+
30
+ response.body.to_i
31
+ end
32
+ end
33
+
34
+ def self.bulk_mail(options = {})
35
+ if MimiMailer.deliveries_enabled?
36
+ check_config!
37
+
38
+ options = default_options.merge(options)
39
+ options[:csv_file] = options.delete(:to) if options[:csv_file].nil?
40
+ options[:body] = options[:body].to_yaml unless options[:body].nil?
41
+
42
+ bulk_mail_options_sanity_check! options
43
+
44
+ response = post('/mailer/to_imported_list', body: options)
45
+
46
+ response.body.to_i
47
+ end
48
+ end
49
+
50
+ def self.default_options
51
+ @default_options.merge(
52
+ username: MimiMailer.config.username,
53
+ api_key: MimiMailer.config.api_key,
54
+ from: from_address
55
+ )
56
+ end
57
+
58
+ protected
59
+ def self.check_config!
60
+ raise MimiMailer::InvalidConfigurationError unless MimiMailer.config.valid?
61
+ end
62
+
63
+ def self.mail_options_sanity_check!(options)
64
+ raise ArgumentError.new(":recipient or :to must be specified") if options[:recipient].nil?
65
+ raise ArgumentError.new(":promotion_name must be specified") if options[:promotion_name].nil?
66
+ end
67
+
68
+ def self.bulk_mail_options_sanity_check!(options)
69
+ raise ArgumentError.new(":csv_file or :to must be specified") if options[:csv_file].nil?
70
+ raise ArgumentError.new(":audience_list must be specified") if options[:audience_list].nil?
71
+ raise ArgumentError.new(":promotion_name must be specified") if options[:promotion_name].nil?
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,24 @@
1
+ module MimiMailer
2
+ class Configuration < OpenStruct
3
+
4
+ REQUIRED_KEYS = %w(username api_key default_from_address deliveries_enabled)
5
+
6
+ def initialize(config = {})
7
+ default_config = {
8
+ username: nil,
9
+ api_key: nil,
10
+ default_from_address: nil,
11
+ deliveries_enabled: true
12
+ }
13
+
14
+ config = default_config.merge(config)
15
+
16
+ super config
17
+ end
18
+
19
+ def valid?
20
+ REQUIRED_KEYS.each { |key| return false if send(key.to_sym).nil? }
21
+ true
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module MimiMailer
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mimi_mailer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mimi_mailer"
8
+ spec.version = MimiMailer::VERSION
9
+ spec.authors = ["Jeff Browning"]
10
+ spec.email = ["jeff@jkbrowning.com"]
11
+ spec.summary = %q{A stripped-down way to interact with the Mimi mailer API}
12
+ spec.description = %q{This gem is unsupported. Use at your own risk. :)}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.required_ruby_version = '>= 1.9.3'
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "httparty"
23
+
24
+ spec.add_development_dependency "webmock"
25
+ spec.add_development_dependency "rspec", "~> 2.14"
26
+ spec.add_development_dependency "bundler", "~> 1.2"
27
+ spec.add_development_dependency "rake"
28
+ end
@@ -0,0 +1,378 @@
1
+ require 'spec_helper'
2
+
3
+ describe MimiMailer::Base do
4
+ let(:promotion_name) { "kittens" }
5
+ let(:email_subject) { "omg kittens" }
6
+ let(:body) { { cats: "rule", dogs: "drool" } }
7
+ let(:username) { "cats@themansion.org" }
8
+ let(:api_key) { "apikey" }
9
+ let(:default_from) { "catsinthecradle@themansion.com" }
10
+
11
+ subject { MimiMailer::Base }
12
+
13
+ describe ".deliver" do
14
+ class TestMailer < MimiMailer::Base; end
15
+
16
+ subject { TestMailer }
17
+
18
+ it "raies an error if not implemented" do
19
+ expect {
20
+ subject.deliver
21
+ }.to raise_error(NotImplementedError, /overridden/i)
22
+ end
23
+ end
24
+
25
+ describe ".mail" do
26
+ let(:to_address) { "dog@thepound.org" }
27
+ let(:endpoint) { "https://api.madmimi.com/mailer" }
28
+ let(:default_options) {
29
+ {
30
+ promotion_name: promotion_name,
31
+ to: to_address,
32
+ from: default_from,
33
+ subject: email_subject
34
+ }
35
+ }
36
+
37
+ before do
38
+ stub_request(:post, "https://api.madmimi.com/mailer")
39
+ MimiMailer.config.stub(
40
+ username: username, api_key: api_key, default_from_address: default_from)
41
+ MimiMailer.stub(deliveries_enabled?: true)
42
+ subject.stub(from_address: default_from)
43
+ end
44
+
45
+ it "raises an error if the config is not valid" do
46
+ MimiMailer.config.stub(valid?: false)
47
+ expect {
48
+ subject.mail(default_options)
49
+ }.to raise_error(MimiMailer::InvalidConfigurationError)
50
+ end
51
+
52
+ it "raises an error if :to is not specified" do
53
+ default_options.delete(:to)
54
+ expect {
55
+ subject.mail(default_options)
56
+ }.to raise_error(ArgumentError, /to.+specified/i)
57
+ end
58
+
59
+ it "raises an error if :promotion_name is not specified" do
60
+ default_options.delete(:promotion_name)
61
+ expect {
62
+ subject.mail(default_options)
63
+ }.to raise_error(ArgumentError, /promotion_name.+specified/i)
64
+ end
65
+
66
+ it "posts to the correct API endpoint" do
67
+ subject.mail(default_options)
68
+ expect(a_request(:post, endpoint)).to have_been_requested
69
+ end
70
+
71
+ it "passes in the correct the username" do
72
+ request = stub_request(:post, endpoint).with(
73
+ body: hash_including(username: username))
74
+
75
+ subject.mail(default_options)
76
+ expect(request).to have_been_requested
77
+ end
78
+
79
+ it "passes in the correct the api_key" do
80
+ request = stub_request(:post, endpoint).with(
81
+ body: hash_including(api_key: api_key))
82
+
83
+ subject.mail(default_options)
84
+ expect(request).to have_been_requested
85
+ end
86
+
87
+ it "passes in the right subject" do
88
+ request = stub_request(:post, endpoint).with(
89
+ body: hash_including(subject: email_subject))
90
+
91
+ subject.mail(default_options)
92
+ expect(request).to have_been_requested
93
+ end
94
+
95
+ it "passes in the right promotion name" do
96
+ request = stub_request(:post, endpoint).with(
97
+ body: hash_including(promotion_name: promotion_name))
98
+
99
+ subject.mail(default_options)
100
+ expect(request).to have_been_requested
101
+ end
102
+
103
+ it "passes in the right recipient" do
104
+ request = stub_request(:post, endpoint).with(
105
+ body: hash_including(recipient: to_address))
106
+
107
+ subject.mail(default_options)
108
+ expect(request).to have_been_requested
109
+ end
110
+
111
+ context "when it contains a :body parameter" do
112
+ let(:options) { default_options.merge(body: body) }
113
+
114
+ it "passes in the yaml-converted body" do
115
+ expected_body = body.to_yaml
116
+
117
+ request = stub_request(:post, endpoint).with(
118
+ body: hash_including(body: expected_body))
119
+
120
+ subject.mail(options)
121
+ expect(request).to have_been_requested
122
+ end
123
+ end
124
+
125
+ context "when it contains a :raw_plain_text parameter" do
126
+ let(:raw_plain_text) { "Cameron the cat would never miss a trick" }
127
+ let(:options) { default_options.merge(raw_plain_text: raw_plain_text) }
128
+
129
+ it "passes in the unmodified body" do
130
+ request = stub_request(:post, endpoint).with(
131
+ body: hash_including(raw_plain_text: raw_plain_text))
132
+
133
+ subject.mail(options)
134
+ expect(request).to have_been_requested
135
+ end
136
+ end
137
+
138
+ context "when it contains a :raw_html parameter" do
139
+ let(:raw_html) { "<h1>OMG KITTENS</h1>" }
140
+ let(:options) { default_options.merge(raw_html: raw_html) }
141
+
142
+ it "passes in the unmodified body" do
143
+ request = stub_request(:post, endpoint).with(
144
+ body: hash_including(raw_html: raw_html))
145
+
146
+ subject.mail(options)
147
+ expect(request).to have_been_requested
148
+ end
149
+ end
150
+
151
+ it "returns the Mimi transaction ID" do
152
+ transaction_id = rand(1000)
153
+ stub_request(:post, endpoint).to_return(
154
+ body: transaction_id.to_s)
155
+
156
+ result = subject.mail(default_options)
157
+ expect(result).to eql(transaction_id)
158
+ end
159
+
160
+ it "passes in the right from address" do
161
+ request = stub_request(:post, endpoint).with(
162
+ body: hash_including(from: default_from))
163
+
164
+ subject.mail(default_options)
165
+ expect(request).to have_been_requested
166
+ end
167
+
168
+ context "when deliveries are disabled" do
169
+ before { MimiMailer.stub(deliveries_enabled?: false) }
170
+
171
+ it "does not post anything" do
172
+ request = stub_request(:post, endpoint)
173
+ subject.mail(default_options)
174
+ expect(request).to_not have_been_requested
175
+ end
176
+ end
177
+ end
178
+
179
+ describe ".bulk_mail" do
180
+ let(:audience_list) { "kittens lovers" }
181
+ let(:csv_file) { "email,first name,last name\ntomcat@example.com,Tom,Cat\nbigdog@example.com,Big,Dog" }
182
+ let(:endpoint) { "https://api.madmimi.com/mailer/to_imported_list" }
183
+ let(:default_options) {
184
+ {
185
+ audience_list: audience_list,
186
+ promotion_name: promotion_name,
187
+ to: csv_file,
188
+ from: default_from,
189
+ subject: email_subject
190
+ }
191
+ }
192
+
193
+ before do
194
+ stub_request(:post, endpoint)
195
+ MimiMailer.config.stub(
196
+ username: username, api_key: api_key, default_from_address: default_from)
197
+ MimiMailer.stub(deliveries_enabled?: true)
198
+ subject.stub(from_address: default_from)
199
+ end
200
+
201
+ it "raises an error if the config is not valid" do
202
+ MimiMailer.config.stub(valid?: false)
203
+ expect {
204
+ subject.bulk_mail(default_options)
205
+ }.to raise_error(MimiMailer::InvalidConfigurationError)
206
+ end
207
+
208
+ it "raises an error if :to is not specified" do
209
+ default_options.delete(:to)
210
+ expect {
211
+ subject.bulk_mail(default_options)
212
+ }.to raise_error(ArgumentError, /to.+specified/i)
213
+ end
214
+
215
+ it "raises an error if :promotion_name is not specified" do
216
+ default_options.delete(:promotion_name)
217
+ expect {
218
+ subject.bulk_mail(default_options)
219
+ }.to raise_error(ArgumentError, /promotion_name.+specified/i)
220
+ end
221
+
222
+ it "raises an error if :audience_list is not specified" do
223
+ default_options.delete(:audience_list)
224
+ expect {
225
+ subject.bulk_mail(default_options)
226
+ }.to raise_error(ArgumentError, /audience_list.+specified/i)
227
+ end
228
+
229
+ it "posts to the correct API endpoint" do
230
+ subject.bulk_mail(default_options)
231
+ expect(a_request(:post, endpoint)).to have_been_requested
232
+ end
233
+
234
+ it "passes in the correct the username" do
235
+ request = stub_request(:post, endpoint).with(
236
+ body: hash_including(username: username))
237
+
238
+ subject.bulk_mail(default_options)
239
+ expect(request).to have_been_requested
240
+ end
241
+
242
+ it "passes in the correct the api_key" do
243
+ request = stub_request(:post, endpoint).with(
244
+ body: hash_including(api_key: api_key))
245
+
246
+ subject.bulk_mail(default_options)
247
+ expect(request).to have_been_requested
248
+ end
249
+
250
+ it "passes in the right subject" do
251
+ request = stub_request(:post, endpoint).with(
252
+ body: hash_including(subject: email_subject))
253
+
254
+ subject.bulk_mail(default_options)
255
+ expect(request).to have_been_requested
256
+ end
257
+
258
+ it "passes in the right promotion name" do
259
+ request = stub_request(:post, endpoint).with(
260
+ body: hash_including(promotion_name: promotion_name))
261
+
262
+ subject.bulk_mail(default_options)
263
+ expect(request).to have_been_requested
264
+ end
265
+
266
+ it "passes in the right csv file" do
267
+ request = stub_request(:post, endpoint).with(
268
+ body: hash_including(csv_file: csv_file))
269
+
270
+ subject.bulk_mail(default_options)
271
+ expect(request).to have_been_requested
272
+ end
273
+
274
+ context "when it contains a :body parameter" do
275
+ let(:options) { default_options.merge(body: body) }
276
+
277
+ it "passes in the yaml-converted body" do
278
+ expected_body = body.to_yaml
279
+
280
+ request = stub_request(:post, endpoint).with(
281
+ body: hash_including(body: expected_body))
282
+
283
+ subject.bulk_mail(options)
284
+ expect(request).to have_been_requested
285
+ end
286
+ end
287
+
288
+ context "when it contains a :raw_plain_text parameter" do
289
+ let(:raw_plain_text) { "Cameron the cat would never miss a trick" }
290
+ let(:options) { default_options.merge(raw_plain_text: raw_plain_text) }
291
+
292
+ it "passes in the unmodified body" do
293
+ request = stub_request(:post, endpoint).with(
294
+ body: hash_including(raw_plain_text: raw_plain_text))
295
+
296
+ subject.bulk_mail(options)
297
+ expect(request).to have_been_requested
298
+ end
299
+ end
300
+
301
+ context "when it contains a :raw_html parameter" do
302
+ let(:raw_html) { "<h1>OMG KITTENS</h1>" }
303
+ let(:options) { default_options.merge(raw_html: raw_html) }
304
+
305
+ it "passes in the unmodified body" do
306
+ request = stub_request(:post, endpoint).with(
307
+ body: hash_including(raw_html: raw_html))
308
+
309
+ subject.bulk_mail(options)
310
+ expect(request).to have_been_requested
311
+ end
312
+ end
313
+
314
+ it "returns the Mimi transaction ID" do
315
+ transaction_id = rand(1000)
316
+ stub_request(:post, endpoint).to_return(
317
+ body: transaction_id.to_s)
318
+
319
+ result = subject.bulk_mail(default_options)
320
+ expect(result).to eql(transaction_id)
321
+ end
322
+
323
+ it "passes in the right from address" do
324
+ request = stub_request(:post, endpoint).with(
325
+ body: hash_including(from: default_from))
326
+
327
+ subject.bulk_mail(default_options)
328
+ expect(request).to have_been_requested
329
+ end
330
+
331
+ context "when deliveries are disabled" do
332
+ before { MimiMailer.stub(deliveries_enabled?: false) }
333
+
334
+ it "does not post anything" do
335
+ request = stub_request(:post, endpoint)
336
+ subject.bulk_mail(default_options)
337
+ expect(request).to_not have_been_requested
338
+ end
339
+ end
340
+ end
341
+
342
+ describe ".from_address" do
343
+ class MailerWithFromAddress < MimiMailer::Base
344
+ from_address 'tomcat@example.com'
345
+ end
346
+
347
+ class MailerWithOtherFromAddress < MimiMailer::Base
348
+ from_address 'harrycat@example.com'
349
+ end
350
+
351
+ class MailerWithoutFromAddress < MimiMailer::Base
352
+ end
353
+
354
+ let(:default_from) { 'socks@whitehouse.gov' }
355
+
356
+ before { MimiMailer.config.stub(default_from_address: default_from) }
357
+
358
+ it "sets and returns the configured class from address" do
359
+ expect(MailerWithFromAddress.from_address).to eql('tomcat@example.com')
360
+ end
361
+
362
+ it "returns the default from address if the class doesn't have its own" do
363
+ expect(MailerWithoutFromAddress.from_address).to eql(default_from)
364
+ end
365
+
366
+ it "does not return another class' email address" do
367
+ expect(MailerWithFromAddress.from_address).to eql('tomcat@example.com')
368
+ expect(MailerWithOtherFromAddress.from_address).to eql('harrycat@example.com')
369
+ end
370
+
371
+ it "returns the username if default_from_address is not configured" do
372
+ username = "kittycat@example.com"
373
+ MimiMailer.config.unstub(:default_from_address)
374
+ MimiMailer.config.stub(username: username)
375
+ expect(MailerWithoutFromAddress.from_address).to eql(username)
376
+ end
377
+ end
378
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe MimiMailer::Configuration do
4
+ describe "value setting and retrieval" do
5
+ subject { MimiMailer::Configuration.new }
6
+
7
+ it "works with method syntax" do
8
+ username = "user@example.com"
9
+ subject.username = username
10
+ expect(subject.username).to eql(username)
11
+ end
12
+
13
+ it "works when setting initial values on initialization" do
14
+ username = "user@example.com"
15
+ subject = MimiMailer::Configuration.new(username: username)
16
+ expect(subject.username).to eql(username)
17
+ end
18
+ end
19
+
20
+ describe "valid?" do
21
+ context "valid config" do
22
+ subject { MimiMailer::Configuration.new(username: "user@example.com",
23
+ api_key: "key",
24
+ default_from_address: "addy@example.com") }
25
+
26
+ it "returns true if all required config is set" do
27
+ expect(subject.valid?).to be_true
28
+ end
29
+ end
30
+
31
+ context "invalid config" do
32
+ subject { MimiMailer::Configuration.new }
33
+
34
+ it "returns false if a required option is not set" do
35
+ expect(subject.valid?).to be_false
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe MimiMailer do
4
+ context 'configuration' do
5
+ describe '.configure' do
6
+ it "raises an error if a block is not supplied" do
7
+ expect {
8
+ MimiMailer.configure
9
+ }.to raise_error(ArgumentError)
10
+ end
11
+
12
+ it "yeilds a MimiMailer::Configuration object" do
13
+ expect { |b|
14
+ MimiMailer.configure(&b)
15
+ }.to yield_with_args(MimiMailer::Configuration)
16
+ end
17
+ end
18
+
19
+ describe ".config" do
20
+ it "returns a MimiMailer::Configuration object" do
21
+ expect(MimiMailer.config).to be_a(MimiMailer::Configuration)
22
+ end
23
+
24
+ it "returns the same MimiMailer::Configuration object on subsequent calls" do
25
+ config = MimiMailer.config
26
+ expect(MimiMailer.config).to equal(config)
27
+ end
28
+ end
29
+
30
+ describe ".enable_deliveries!" do
31
+ it "sets MimiMailer.config.deliveries_enabled to true" do
32
+ MimiMailer.config.deliveries_enabled = false
33
+ expect {
34
+ MimiMailer.enable_deliveries!
35
+ }.to change { MimiMailer.config.deliveries_enabled }.to(true)
36
+ end
37
+ end
38
+
39
+ describe ".disable_deliveries!" do
40
+ it "sets MimiMailer.config.deliveries_enabled to false" do
41
+ MimiMailer.config.deliveries_enabled = true
42
+ expect {
43
+ MimiMailer.disable_deliveries!
44
+ }.to change { MimiMailer.config.deliveries_enabled }.to(false)
45
+ end
46
+ end
47
+
48
+ describe ".deliveries_enabled?" do
49
+ it "defers to config.deliveries_enabled" do
50
+ MimiMailer.config.should_receive(:deliveries_enabled)
51
+ MimiMailer.deliveries_enabled?
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,20 @@
1
+ require 'webmock/rspec'
2
+ require 'mimi_mailer'
3
+
4
+ # This file was generated by the `rspec --init` command. Conventionally, all
5
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
6
+ # Require this file using `require "spec_helper"` to ensure that it is only
7
+ # loaded once.
8
+ #
9
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
10
+ RSpec.configure do |config|
11
+ config.treat_symbols_as_metadata_keys_with_true_values = true
12
+ config.run_all_when_everything_filtered = true
13
+ config.filter_run :focus
14
+
15
+ # Run specs in random order to surface order dependencies. If you find an
16
+ # order dependency and want to debug it, you can fix the order by providing
17
+ # the seed, which is printed after each run.
18
+ # --seed 1234
19
+ config.order = 'random'
20
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mimi_mailer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeff Browning
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: webmock
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.14'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: This gem is unsupported. Use at your own risk. :)
84
+ email:
85
+ - jeff@jkbrowning.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - .rspec
92
+ - CHANGELOG.md
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - lib/mimi_mailer.rb
98
+ - lib/mimi_mailer/base.rb
99
+ - lib/mimi_mailer/configuration.rb
100
+ - lib/mimi_mailer/version.rb
101
+ - mimi_mailer.gemspec
102
+ - spec/mimi_mailer/base_spec.rb
103
+ - spec/mimi_mailer/configuration_spec.rb
104
+ - spec/mimi_mailer_spec.rb
105
+ - spec/spec_helper.rb
106
+ homepage: ''
107
+ licenses:
108
+ - MIT
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: 1.9.3
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.2.2
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: A stripped-down way to interact with the Mimi mailer API
130
+ test_files:
131
+ - spec/mimi_mailer/base_spec.rb
132
+ - spec/mimi_mailer/configuration_spec.rb
133
+ - spec/mimi_mailer_spec.rb
134
+ - spec/spec_helper.rb