mailgunner 1.0.0
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.
- data/README.md +45 -0
- data/lib/mailgunner.rb +300 -0
- data/mailgunner.gemspec +14 -0
- data/spec/mailgunner_spec.rb +763 -0
- metadata +82 -0
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
A Ruby wrapper for the [Mailgun API](http://documentation.mailgun.net/api_reference.html)
|
2
|
+
=========================================================================================
|
3
|
+
|
4
|
+
|
5
|
+
Quick Start
|
6
|
+
-----------
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
require 'mailgunner'
|
10
|
+
|
11
|
+
mailgun = Mailgunner::Client.new(domain: 'samples.mailgun.org', api_key: 'key-3ax6xnjp29jd6fds4gc373sgvjxteol0')
|
12
|
+
|
13
|
+
response = mailgun.get_stats(limit: 5)
|
14
|
+
|
15
|
+
if response.ok?
|
16
|
+
# do something with response.object
|
17
|
+
else
|
18
|
+
# handle client/server error
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
|
23
|
+
Alternative JSON Implementations
|
24
|
+
--------------------------------
|
25
|
+
|
26
|
+
Mailgunner::Client defaults to using the "json" library which is available
|
27
|
+
in the Ruby 1.9 standard library, and as a gem for Ruby 1.8. You can specify
|
28
|
+
an alternative implementation using the json option when constructing a client
|
29
|
+
object. For example, to use [multi_json](https://rubygems.org/gems/multi_json):
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
mailgun = Mailgunner::Client.new(:json => MultiJson)
|
33
|
+
```
|
34
|
+
|
35
|
+
|
36
|
+
Environment Variables
|
37
|
+
---------------------
|
38
|
+
|
39
|
+
Best practice for storing credentials for external services is to use environment
|
40
|
+
variables, as described by [12factor.net/config](http://www.12factor.net/config).
|
41
|
+
|
42
|
+
Mailgunner::Client defaults to extracting the domain and api_key values it needs
|
43
|
+
from the MAILGUN_API_KEY and MAILGUN_SMTP_LOGIN environment variables. These will
|
44
|
+
exist if you are using Mailgun on Heroku, or you can set them manually.
|
45
|
+
|
data/lib/mailgunner.rb
ADDED
@@ -0,0 +1,300 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
require 'cgi'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
module Mailgunner
|
7
|
+
class Client
|
8
|
+
attr_accessor :domain, :api_key, :json, :http
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@domain = options.fetch(:domain) { ENV.fetch('MAILGUN_SMTP_LOGIN').split('@').last }
|
12
|
+
|
13
|
+
@api_key = options.fetch(:api_key) { ENV.fetch('MAILGUN_API_KEY') }
|
14
|
+
|
15
|
+
@json = options.fetch(:json) { JSON }
|
16
|
+
|
17
|
+
@http = Net::HTTP.new('api.mailgun.net', Net::HTTP.https_default_port)
|
18
|
+
|
19
|
+
@http.use_ssl = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def send_message(attributes = {})
|
23
|
+
post("/v2/#{escape @domain}/messages", attributes)
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_domains(params = {})
|
27
|
+
get('/v2/domains', params)
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_domain(name)
|
31
|
+
get("/v2/domains/#{escape name}")
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_domain(attributes = {})
|
35
|
+
post('/v2/domains', attributes)
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_unsubscribes(params = {})
|
39
|
+
get("/v2/#{escape @domain}/unsubscribes", params)
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_unsubscribe(address)
|
43
|
+
get("/v2/#{escape @domain}/unsubscribes/#{escape address}")
|
44
|
+
end
|
45
|
+
|
46
|
+
def delete_unsubscribe(address_or_id)
|
47
|
+
delete("/v2/#{escape @domain}/unsubscribes/#{escape address_or_id}")
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_unsubscribe(attributes = {})
|
51
|
+
post("/v2/#{escape @domain}/unsubscribes", attributes)
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_complaints(params = {})
|
55
|
+
get("/v2/#{escape @domain}/complaints", params)
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_complaint(address)
|
59
|
+
get("/v2/#{escape @domain}/complaints/#{escape address}")
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_complaint(attributes = {})
|
63
|
+
post("/v2/#{escape @domain}/complaints", attributes)
|
64
|
+
end
|
65
|
+
|
66
|
+
def delete_complaint(address)
|
67
|
+
delete("/v2/#{escape @domain}/complaints/#{escape address}")
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_bounces(params = {})
|
71
|
+
get("/v2/#{escape @domain}/bounces", params)
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_bounce(address)
|
75
|
+
get("/v2/#{escape @domain}/bounces/#{escape address}")
|
76
|
+
end
|
77
|
+
|
78
|
+
def add_bounce(attributes = {})
|
79
|
+
post("/v2/#{escape @domain}/bounces", attributes)
|
80
|
+
end
|
81
|
+
|
82
|
+
def delete_bounce(address)
|
83
|
+
delete("/v2/#{escape @domain}/bounces/#{escape address}")
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_stats(params = {})
|
87
|
+
get("/v2/#{escape @domain}/stats", params)
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_log(params = {})
|
91
|
+
get("/v2/#{escape @domain}/log", params)
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_routes(params = {})
|
95
|
+
get('/v2/routes', params)
|
96
|
+
end
|
97
|
+
|
98
|
+
def get_route(id)
|
99
|
+
get("/v2/routes/#{escape id}")
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_route(attributes = {})
|
103
|
+
post('/v2/routes', attributes)
|
104
|
+
end
|
105
|
+
|
106
|
+
def update_route(id, attributes = {})
|
107
|
+
put("/v2/routes/#{escape id}", attributes)
|
108
|
+
end
|
109
|
+
|
110
|
+
def delete_route(id)
|
111
|
+
delete("/v2/routes/#{escape id}")
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_mailboxes(params = {})
|
115
|
+
get("/v2/#{escape @domain}/mailboxes", params)
|
116
|
+
end
|
117
|
+
|
118
|
+
def add_mailbox(attributes = {})
|
119
|
+
post("/v2/#{escape @domain}/mailboxes", attributes)
|
120
|
+
end
|
121
|
+
|
122
|
+
def update_mailbox(name, attributes = {})
|
123
|
+
put("/v2/#{escape @domain}/mailboxes/#{escape name}", attributes)
|
124
|
+
end
|
125
|
+
|
126
|
+
def delete_mailbox(name)
|
127
|
+
delete("/v2/#{escape @domain}/mailboxes/#{escape name}")
|
128
|
+
end
|
129
|
+
|
130
|
+
def get_campaigns(params = {})
|
131
|
+
get("/v2/#{escape @domain}/campaigns", params)
|
132
|
+
end
|
133
|
+
|
134
|
+
def get_campaign(id)
|
135
|
+
get("/v2/#{escape @domain}/campaigns/#{escape id}")
|
136
|
+
end
|
137
|
+
|
138
|
+
def add_campaign(attributes = {})
|
139
|
+
post("/v2/#{escape @domain}/campaigns", attributes)
|
140
|
+
end
|
141
|
+
|
142
|
+
def update_campaign(id, attributes = {})
|
143
|
+
put("/v2/#{escape @domain}/campaigns/#{escape id}", attributes)
|
144
|
+
end
|
145
|
+
|
146
|
+
def delete_campaign(id)
|
147
|
+
delete("/v2/#{escape @domain}/campaigns/#{escape id}")
|
148
|
+
end
|
149
|
+
|
150
|
+
def get_campaign_events(campaign_id, params = {})
|
151
|
+
get("/v2/#{escape @domain}/campaigns/#{escape campaign_id}/events", params)
|
152
|
+
end
|
153
|
+
|
154
|
+
def get_campaign_stats(campaign_id, params = {})
|
155
|
+
get("/v2/#{escape @domain}/campaigns/#{escape campaign_id}/stats", params)
|
156
|
+
end
|
157
|
+
|
158
|
+
def get_campaign_clicks(campaign_id, params = {})
|
159
|
+
get("/v2/#{escape @domain}/campaigns/#{escape campaign_id}/clicks", params)
|
160
|
+
end
|
161
|
+
|
162
|
+
def get_campaign_opens(campaign_id, params = {})
|
163
|
+
get("/v2/#{escape @domain}/campaigns/#{escape campaign_id}/opens", params)
|
164
|
+
end
|
165
|
+
|
166
|
+
def get_campaign_unsubscribes(campaign_id, params = {})
|
167
|
+
get("/v2/#{escape @domain}/campaigns/#{escape campaign_id}/unsubscribes", params)
|
168
|
+
end
|
169
|
+
|
170
|
+
def get_campaign_complaints(campaign_id, params = {})
|
171
|
+
get("/v2/#{escape @domain}/campaigns/#{escape campaign_id}/complaints", params)
|
172
|
+
end
|
173
|
+
|
174
|
+
def get_lists(params = {})
|
175
|
+
get('/v2/lists', params)
|
176
|
+
end
|
177
|
+
|
178
|
+
def get_list(address)
|
179
|
+
get("/v2/lists/#{escape address}")
|
180
|
+
end
|
181
|
+
|
182
|
+
def add_list(attributes = {})
|
183
|
+
post('/v2/lists', attributes)
|
184
|
+
end
|
185
|
+
|
186
|
+
def update_list(address, attributes = {})
|
187
|
+
put("/v2/lists/#{escape address}", attributes)
|
188
|
+
end
|
189
|
+
|
190
|
+
def delete_list(address)
|
191
|
+
delete("/v2/lists/#{escape address}")
|
192
|
+
end
|
193
|
+
|
194
|
+
def get_list_members(list_address, params = {})
|
195
|
+
get("/v2/lists/#{escape list_address}/members", params)
|
196
|
+
end
|
197
|
+
|
198
|
+
def get_list_member(list_address, member_address)
|
199
|
+
get("/v2/lists/#{escape list_address}/members/#{escape member_address}")
|
200
|
+
end
|
201
|
+
|
202
|
+
def add_list_member(list_address, member_attributes)
|
203
|
+
post("/v2/lists/#{escape list_address}/members", member_attributes)
|
204
|
+
end
|
205
|
+
|
206
|
+
def update_list_member(list_address, member_address, member_attributes)
|
207
|
+
put("/v2/lists/#{escape list_address}/members/#{escape member_address}", member_attributes)
|
208
|
+
end
|
209
|
+
|
210
|
+
def delete_list_member(list_address, member_address)
|
211
|
+
delete("/v2/lists/#{escape list_address}/members/#{escape member_address}")
|
212
|
+
end
|
213
|
+
|
214
|
+
def get_list_stats(list_address)
|
215
|
+
get("/v2/lists/#{escape list_address}/stats")
|
216
|
+
end
|
217
|
+
|
218
|
+
private
|
219
|
+
|
220
|
+
def get(path, params = {})
|
221
|
+
transmit(Net::HTTP::Get, request_uri(path, params))
|
222
|
+
end
|
223
|
+
|
224
|
+
def post(path, attributes = {})
|
225
|
+
transmit(Net::HTTP::Post, path, attributes)
|
226
|
+
end
|
227
|
+
|
228
|
+
def put(path, attributes = {})
|
229
|
+
transmit(Net::HTTP::Put, path, attributes)
|
230
|
+
end
|
231
|
+
|
232
|
+
def delete(path)
|
233
|
+
transmit(Net::HTTP::Delete, path)
|
234
|
+
end
|
235
|
+
|
236
|
+
def transmit(subclass, path, attributes = nil)
|
237
|
+
message = subclass.new(path)
|
238
|
+
message.basic_auth('api', @api_key)
|
239
|
+
message.body = URI.encode_www_form(attributes) if attributes
|
240
|
+
|
241
|
+
Response.new(@http.request(message), :json => @json)
|
242
|
+
end
|
243
|
+
|
244
|
+
def request_uri(path, params_hash)
|
245
|
+
if params_hash.empty?
|
246
|
+
path
|
247
|
+
else
|
248
|
+
tmp = []
|
249
|
+
|
250
|
+
params_hash.each do |key, values|
|
251
|
+
Array(values).each do |value|
|
252
|
+
tmp << "#{escape(key)}=#{escape(value)}"
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
path + '?' + tmp.join('&')
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def escape(component)
|
261
|
+
CGI.escape(component.to_s)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
class Response
|
266
|
+
def initialize(http_response, options = {})
|
267
|
+
@http_response = http_response
|
268
|
+
|
269
|
+
@json = options.fetch(:json) { JSON }
|
270
|
+
end
|
271
|
+
|
272
|
+
def method_missing(name, *args, &block)
|
273
|
+
@http_response.send(name, *args, &block)
|
274
|
+
end
|
275
|
+
|
276
|
+
def respond_to_missing?(name, include_private = false)
|
277
|
+
@http_response.respond_to?(name)
|
278
|
+
end
|
279
|
+
|
280
|
+
def ok?
|
281
|
+
code.to_i == 200
|
282
|
+
end
|
283
|
+
|
284
|
+
def client_error?
|
285
|
+
(400 .. 499).include?(code.to_i)
|
286
|
+
end
|
287
|
+
|
288
|
+
def server_error?
|
289
|
+
(500 .. 599).include?(code.to_i)
|
290
|
+
end
|
291
|
+
|
292
|
+
def json?
|
293
|
+
self['Content-Type'].split(';').first == 'application/json'
|
294
|
+
end
|
295
|
+
|
296
|
+
def object
|
297
|
+
@object ||= @json.load(body)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
data/mailgunner.gemspec
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'mailgunner'
|
3
|
+
s.version = '1.0.0'
|
4
|
+
s.platform = Gem::Platform::RUBY
|
5
|
+
s.authors = ['Tim Craft']
|
6
|
+
s.email = ['mail@timcraft.com']
|
7
|
+
s.homepage = 'http://github.com/timcraft/mailgunner'
|
8
|
+
s.description = 'A Ruby wrapper for the Mailgun API'
|
9
|
+
s.summary = 'See description'
|
10
|
+
s.files = Dir.glob('{lib,spec}/**/*') + %w(README.md mailgunner.gemspec)
|
11
|
+
s.add_development_dependency('rake', '>= 0.9.3')
|
12
|
+
s.add_development_dependency('mocha', '~> 0.10.3')
|
13
|
+
s.require_path = 'lib'
|
14
|
+
end
|
@@ -0,0 +1,763 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'mailgunner'
|
3
|
+
require 'mocha'
|
4
|
+
|
5
|
+
class Net::HTTPGenericRequest
|
6
|
+
def inspect
|
7
|
+
if request_body_permitted?
|
8
|
+
"<#{self.class.name} #{path} #{body}>"
|
9
|
+
else
|
10
|
+
"<#{self.class.name} #{path}>"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'Mailgunner::Client' do
|
16
|
+
before do
|
17
|
+
@domain = 'samples.mailgun.org'
|
18
|
+
|
19
|
+
@api_key = 'xxx'
|
20
|
+
|
21
|
+
@client = Mailgunner::Client.new(domain: @domain, api_key: @api_key)
|
22
|
+
|
23
|
+
@address = 'user@example.com'
|
24
|
+
|
25
|
+
@encoded_address = 'user%40example.com'
|
26
|
+
end
|
27
|
+
|
28
|
+
def expect(request_class, arg)
|
29
|
+
matcher = String === arg ? responds_with(:path, arg) : arg
|
30
|
+
|
31
|
+
@client.http.expects(:request).with(all_of(instance_of(request_class), matcher)).returns(stub)
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'http method' do
|
35
|
+
it 'returns a net http object that uses ssl' do
|
36
|
+
@client.http.must_be_instance_of(Net::HTTP)
|
37
|
+
|
38
|
+
@client.http.use_ssl?.must_equal(true)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'domain method' do
|
43
|
+
it 'returns the value passed to the constructor' do
|
44
|
+
@client.domain.must_equal(@domain)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'defaults to the domain in the MAILGUN_SMTP_LOGIN environment variable' do
|
48
|
+
ENV['MAILGUN_SMTP_LOGIN'] = 'postmaster@samples.mailgun.org'
|
49
|
+
|
50
|
+
Mailgunner::Client.new(api_key: @api_key).domain.must_equal(@domain)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'api_key method' do
|
55
|
+
it 'returns the value passed to the constructor' do
|
56
|
+
@client.api_key.must_equal(@api_key)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'defaults to the value of MAILGUN_API_KEY environment variable' do
|
60
|
+
ENV['MAILGUN_API_KEY'] = @api_key
|
61
|
+
|
62
|
+
Mailgunner::Client.new(domain: @domain).api_key.must_equal(@api_key)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'json method' do
|
67
|
+
it 'returns the value passed to the constructor' do
|
68
|
+
json = stub
|
69
|
+
|
70
|
+
Mailgunner::Client.new(json: json).json.must_equal(json)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'defaults to the standard library json implementation' do
|
74
|
+
@client.json.must_equal(JSON)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe 'send_message method' do
|
79
|
+
it 'posts to the domain messages resource and returns a response object' do
|
80
|
+
expect(Net::HTTP::Post, "/v2/#@domain/messages")
|
81
|
+
|
82
|
+
@client.send_message({}).must_be_instance_of(Mailgunner::Response)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'encodes the message attributes' do
|
86
|
+
expect(Net::HTTP::Post, responds_with(:body, "to=#@encoded_address"))
|
87
|
+
|
88
|
+
@client.add_domain({to: @address})
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'encodes the message attributes as multipart form data when sending attachments' do
|
92
|
+
# TODO
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe 'get_domains method' do
|
97
|
+
it 'fetches the domains resource and returns a response object' do
|
98
|
+
expect(Net::HTTP::Get, '/v2/domains')
|
99
|
+
|
100
|
+
@client.get_domains.must_be_instance_of(Mailgunner::Response)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe 'get_domain method' do
|
105
|
+
it 'fetches the domain resource and returns a response object' do
|
106
|
+
expect(Net::HTTP::Get, "/v2/domains/#@domain")
|
107
|
+
|
108
|
+
@client.get_domain(@domain).must_be_instance_of(Mailgunner::Response)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe 'add_domain method' do
|
113
|
+
it 'posts to the domains resource and returns a response object' do
|
114
|
+
expect(Net::HTTP::Post, '/v2/domains')
|
115
|
+
|
116
|
+
@client.add_domain({}).must_be_instance_of(Mailgunner::Response)
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'encodes the domain attributes' do
|
120
|
+
expect(Net::HTTP::Post, responds_with(:body, "name=#@domain"))
|
121
|
+
|
122
|
+
@client.add_domain({name: @domain})
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe 'get_unsubscribes method' do
|
127
|
+
it 'fetches the domain unsubscribes resource and returns a response object' do
|
128
|
+
expect(Net::HTTP::Get, "/v2/#@domain/unsubscribes")
|
129
|
+
|
130
|
+
@client.get_unsubscribes.must_be_instance_of(Mailgunner::Response)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'encodes skip and limit parameters' do
|
134
|
+
expect(Net::HTTP::Get, "/v2/#@domain/unsubscribes?skip=1&limit=2")
|
135
|
+
|
136
|
+
@client.get_unsubscribes(skip: 1, limit: 2)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe 'get_unsubscribe method' do
|
141
|
+
it 'fetches the unsubscribe resource with the given address and returns a response object' do
|
142
|
+
expect(Net::HTTP::Get, "/v2/#@domain/unsubscribes/#@encoded_address")
|
143
|
+
|
144
|
+
@client.get_unsubscribe(@address).must_be_instance_of(Mailgunner::Response)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe 'delete_unsubscribe method' do
|
149
|
+
it 'deletes the domain unsubscribe resource with the given address and returns a response object' do
|
150
|
+
expect(Net::HTTP::Delete, "/v2/#@domain/unsubscribes/#@encoded_address")
|
151
|
+
|
152
|
+
@client.delete_unsubscribe(@address).must_be_instance_of(Mailgunner::Response)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe 'add_unsubscribe method' do
|
157
|
+
it 'posts to the domain unsubscribes resource and returns a response object' do
|
158
|
+
expect(Net::HTTP::Post, "/v2/#@domain/unsubscribes")
|
159
|
+
|
160
|
+
@client.add_unsubscribe({}).must_be_instance_of(Mailgunner::Response)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'encodes the unsubscribe attributes' do
|
164
|
+
expect(Net::HTTP::Post, responds_with(:body, "address=#@encoded_address"))
|
165
|
+
|
166
|
+
@client.add_unsubscribe({address: @address})
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe 'get_complaints method' do
|
171
|
+
it 'fetches the domain complaints resource and returns a response object' do
|
172
|
+
expect(Net::HTTP::Get, "/v2/#@domain/complaints")
|
173
|
+
|
174
|
+
@client.get_complaints.must_be_instance_of(Mailgunner::Response)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'encodes skip and limit parameters' do
|
178
|
+
expect(Net::HTTP::Get, "/v2/#@domain/complaints?skip=1&limit=2")
|
179
|
+
|
180
|
+
@client.get_complaints(skip: 1, limit: 2)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe 'get_complaint method' do
|
185
|
+
it 'fetches the complaint resource with the given address and returns a response object' do
|
186
|
+
expect(Net::HTTP::Get, "/v2/#@domain/complaints/#@encoded_address")
|
187
|
+
|
188
|
+
@client.get_complaint(@address).must_be_instance_of(Mailgunner::Response)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe 'add_complaint method' do
|
193
|
+
it 'posts to the domain complaints resource and returns a response object' do
|
194
|
+
expect(Net::HTTP::Post, "/v2/#@domain/complaints")
|
195
|
+
|
196
|
+
@client.add_complaint({}).must_be_instance_of(Mailgunner::Response)
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'encodes the complaint attributes' do
|
200
|
+
expect(Net::HTTP::Post, responds_with(:body, "address=#@encoded_address"))
|
201
|
+
|
202
|
+
@client.add_complaint({address: @address})
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe 'delete_complaint method' do
|
207
|
+
it 'deletes the domain complaint resource with the given address and returns a response object' do
|
208
|
+
expect(Net::HTTP::Delete, "/v2/#@domain/complaints/#@encoded_address")
|
209
|
+
|
210
|
+
@client.delete_complaint(@address).must_be_instance_of(Mailgunner::Response)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe 'get_bounces method' do
|
215
|
+
it 'fetches the domain bounces resource and returns a response object' do
|
216
|
+
expect(Net::HTTP::Get, "/v2/#@domain/bounces")
|
217
|
+
|
218
|
+
@client.get_bounces.must_be_instance_of(Mailgunner::Response)
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'encodes skip and limit parameters' do
|
222
|
+
expect(Net::HTTP::Get, "/v2/#@domain/bounces?skip=1&limit=2")
|
223
|
+
|
224
|
+
@client.get_bounces(skip: 1, limit: 2)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe 'get_bounce method' do
|
229
|
+
it 'fetches the bounce resource with the given address and returns a response object' do
|
230
|
+
expect(Net::HTTP::Get, "/v2/#@domain/bounces/#@encoded_address")
|
231
|
+
|
232
|
+
@client.get_bounce(@address).must_be_instance_of(Mailgunner::Response)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe 'add_bounce method' do
|
237
|
+
it 'posts to the domain bounces resource and returns a response object' do
|
238
|
+
expect(Net::HTTP::Post, "/v2/#@domain/bounces")
|
239
|
+
|
240
|
+
@client.add_bounce({}).must_be_instance_of(Mailgunner::Response)
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'encodes the bounce attributes' do
|
244
|
+
expect(Net::HTTP::Post, responds_with(:body, "address=#@encoded_address"))
|
245
|
+
|
246
|
+
@client.add_bounce({address: @address})
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
describe 'delete_bounce method' do
|
251
|
+
it 'deletes the domain bounce resource with the given address and returns a response object' do
|
252
|
+
expect(Net::HTTP::Delete, "/v2/#@domain/bounces/#@encoded_address")
|
253
|
+
|
254
|
+
@client.delete_bounce(@address).must_be_instance_of(Mailgunner::Response)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
describe 'get_stats method' do
|
259
|
+
it 'fetches the domain stats resource and returns a response object' do
|
260
|
+
expect(Net::HTTP::Get, "/v2/#@domain/stats")
|
261
|
+
|
262
|
+
@client.get_stats.must_be_instance_of(Mailgunner::Response)
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'encodes skip and limit parameters' do
|
266
|
+
expect(Net::HTTP::Get, "/v2/#@domain/stats?skip=1&limit=2")
|
267
|
+
|
268
|
+
@client.get_stats(skip: 1, limit: 2)
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'encodes an event parameter with multiple values' do
|
272
|
+
expect(Net::HTTP::Get, "/v2/#@domain/stats?event=sent&event=opened")
|
273
|
+
|
274
|
+
@client.get_stats(event: %w(sent opened))
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe 'get_log method' do
|
279
|
+
it 'fetches the domain stats resource and returns a response object' do
|
280
|
+
expect(Net::HTTP::Get, "/v2/#@domain/log")
|
281
|
+
|
282
|
+
@client.get_log.must_be_instance_of(Mailgunner::Response)
|
283
|
+
end
|
284
|
+
|
285
|
+
it 'encodes skip and limit parameters' do
|
286
|
+
expect(Net::HTTP::Get, "/v2/#@domain/log?skip=1&limit=2")
|
287
|
+
|
288
|
+
@client.get_log(skip: 1, limit: 2)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
describe 'get_routes method' do
|
293
|
+
it 'fetches the global routes resource and returns a response object' do
|
294
|
+
expect(Net::HTTP::Get, '/v2/routes')
|
295
|
+
|
296
|
+
@client.get_routes.must_be_instance_of(Mailgunner::Response)
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'encodes skip and limit parameters' do
|
300
|
+
expect(Net::HTTP::Get, '/v2/routes?skip=1&limit=2')
|
301
|
+
|
302
|
+
@client.get_routes(skip: 1, limit: 2)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
describe 'get_route method' do
|
307
|
+
it 'fetches the route resource with the given id and returns a response object' do
|
308
|
+
expect(Net::HTTP::Get, '/v2/routes/4f3bad2335335426750048c6')
|
309
|
+
|
310
|
+
@client.get_route('4f3bad2335335426750048c6').must_be_instance_of(Mailgunner::Response)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
describe 'add_route method' do
|
315
|
+
it 'posts to the routes resource and returns a response object' do
|
316
|
+
expect(Net::HTTP::Post, '/v2/routes')
|
317
|
+
|
318
|
+
@client.add_route({}).must_be_instance_of(Mailgunner::Response)
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'encodes the route attributes' do
|
322
|
+
expect(Net::HTTP::Post, responds_with(:body, 'description=Example+route&priority=1'))
|
323
|
+
|
324
|
+
@client.add_route({description: 'Example route', priority: 1})
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
describe 'update_route method' do
|
329
|
+
it 'updates the route resource with the given id and returns a response object' do
|
330
|
+
expect(Net::HTTP::Put, '/v2/routes/4f3bad2335335426750048c6')
|
331
|
+
|
332
|
+
@client.update_route('4f3bad2335335426750048c6', {}).must_be_instance_of(Mailgunner::Response)
|
333
|
+
end
|
334
|
+
|
335
|
+
it 'encodes the route attributes' do
|
336
|
+
expect(Net::HTTP::Put, responds_with(:body, 'priority=10'))
|
337
|
+
|
338
|
+
@client.update_route('4f3bad2335335426750048c6', {priority: 10})
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe 'delete_route method' do
|
343
|
+
it 'deletes the route resource with the given id and returns a response object' do
|
344
|
+
expect(Net::HTTP::Delete, '/v2/routes/4f3bad2335335426750048c6')
|
345
|
+
|
346
|
+
@client.delete_route('4f3bad2335335426750048c6').must_be_instance_of(Mailgunner::Response)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
describe 'get_mailboxes method' do
|
351
|
+
it 'fetches the domain mailboxes resource and returns a response object' do
|
352
|
+
expect(Net::HTTP::Get, "/v2/#@domain/mailboxes")
|
353
|
+
|
354
|
+
@client.get_mailboxes.must_be_instance_of(Mailgunner::Response)
|
355
|
+
end
|
356
|
+
|
357
|
+
it 'encodes skip and limit parameters' do
|
358
|
+
expect(Net::HTTP::Get, "/v2/#@domain/mailboxes?skip=1&limit=2")
|
359
|
+
|
360
|
+
@client.get_mailboxes(skip: 1, limit: 2)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
describe 'add_mailbox method' do
|
365
|
+
it 'posts to the domain mailboxes resource and returns a response object' do
|
366
|
+
expect(Net::HTTP::Post, "/v2/#@domain/mailboxes")
|
367
|
+
|
368
|
+
@client.add_mailbox({}).must_be_instance_of(Mailgunner::Response)
|
369
|
+
end
|
370
|
+
|
371
|
+
it 'encodes the mailbox attributes' do
|
372
|
+
expect(Net::HTTP::Post, responds_with(:body, 'mailbox=user'))
|
373
|
+
|
374
|
+
@client.add_mailbox({mailbox: 'user'})
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
describe 'update_mailbox method' do
|
379
|
+
it 'updates the mailbox resource and returns a response object' do
|
380
|
+
expect(Net::HTTP::Put, "/v2/#@domain/mailboxes/user")
|
381
|
+
|
382
|
+
@client.update_mailbox('user', {}).must_be_instance_of(Mailgunner::Response)
|
383
|
+
end
|
384
|
+
|
385
|
+
it 'encodes the mailbox attributes' do
|
386
|
+
expect(Net::HTTP::Put, responds_with(:body, 'password=secret'))
|
387
|
+
|
388
|
+
@client.update_mailbox('user', {password: 'secret'})
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
describe 'delete_mailbox method' do
|
393
|
+
it 'deletes the domain mailbox resource with the given address and returns a response object' do
|
394
|
+
expect(Net::HTTP::Delete, "/v2/#@domain/mailboxes/user")
|
395
|
+
|
396
|
+
@client.delete_mailbox('user').must_be_instance_of(Mailgunner::Response)
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
describe 'get_campaigns method' do
|
401
|
+
it 'fetches the domain campaigns resource and returns a response object' do
|
402
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns")
|
403
|
+
|
404
|
+
@client.get_campaigns.must_be_instance_of(Mailgunner::Response)
|
405
|
+
end
|
406
|
+
|
407
|
+
it 'encodes skip and limit parameters' do
|
408
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns?skip=1&limit=2")
|
409
|
+
|
410
|
+
@client.get_campaigns(skip: 1, limit: 2)
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
describe 'get_campaign method' do
|
415
|
+
it 'fetches the campaign resource with the given id and returns a response object' do
|
416
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id")
|
417
|
+
|
418
|
+
@client.get_campaign('id').must_be_instance_of(Mailgunner::Response)
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
describe 'add_campaign method' do
|
423
|
+
it 'posts to the domain campaigns resource and returns a response object' do
|
424
|
+
expect(Net::HTTP::Post, "/v2/#@domain/campaigns")
|
425
|
+
|
426
|
+
@client.add_campaign({}).must_be_instance_of(Mailgunner::Response)
|
427
|
+
end
|
428
|
+
|
429
|
+
it 'encodes the campaign attributes' do
|
430
|
+
expect(Net::HTTP::Post, responds_with(:body, 'id=id'))
|
431
|
+
|
432
|
+
@client.add_campaign({id: 'id'})
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
describe 'update_campaign method' do
|
437
|
+
it 'updates the campaign resource and returns a response object' do
|
438
|
+
expect(Net::HTTP::Put, "/v2/#@domain/campaigns/id")
|
439
|
+
|
440
|
+
@client.update_campaign('id', {}).must_be_instance_of(Mailgunner::Response)
|
441
|
+
end
|
442
|
+
|
443
|
+
it 'encodes the campaign attributes' do
|
444
|
+
expect(Net::HTTP::Put, responds_with(:body, 'name=Example+Campaign'))
|
445
|
+
|
446
|
+
@client.update_campaign('id', {name: 'Example Campaign'})
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
describe 'delete_campaign method' do
|
451
|
+
it 'deletes the domain campaign resource with the given id and returns a response object' do
|
452
|
+
expect(Net::HTTP::Delete, "/v2/#@domain/campaigns/id")
|
453
|
+
|
454
|
+
@client.delete_campaign('id').must_be_instance_of(Mailgunner::Response)
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
describe 'get_campaign_events method' do
|
459
|
+
it 'fetches the domain campaign events resource and returns a response object' do
|
460
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/events")
|
461
|
+
|
462
|
+
@client.get_campaign_events('id').must_be_instance_of(Mailgunner::Response)
|
463
|
+
end
|
464
|
+
|
465
|
+
it 'encodes the optional parameters' do
|
466
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/events?country=US&limit=100")
|
467
|
+
|
468
|
+
@client.get_campaign_events('id', country: 'US', limit: 100)
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
describe 'get_campaign_stats method' do
|
473
|
+
it 'fetches the domain campaign stats resource and returns a response object' do
|
474
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/stats")
|
475
|
+
|
476
|
+
@client.get_campaign_stats('id').must_be_instance_of(Mailgunner::Response)
|
477
|
+
end
|
478
|
+
|
479
|
+
it 'encodes the optional parameters' do
|
480
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/stats?groupby=dailyhour")
|
481
|
+
|
482
|
+
@client.get_campaign_stats('id', groupby: 'dailyhour')
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
describe 'get_campaign_clicks method' do
|
487
|
+
it 'fetches the domain campaign clicks resource and returns a response object' do
|
488
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/clicks")
|
489
|
+
|
490
|
+
@client.get_campaign_clicks('id').must_be_instance_of(Mailgunner::Response)
|
491
|
+
end
|
492
|
+
|
493
|
+
it 'encodes the optional parameters' do
|
494
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/clicks?groupby=month&limit=100")
|
495
|
+
|
496
|
+
@client.get_campaign_clicks('id', groupby: 'month', limit: 100)
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
describe 'get_campaign_opens method' do
|
501
|
+
it 'fetches the domain campaign opens resource and returns a response object' do
|
502
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/opens")
|
503
|
+
|
504
|
+
@client.get_campaign_opens('id').must_be_instance_of(Mailgunner::Response)
|
505
|
+
end
|
506
|
+
|
507
|
+
it 'encodes the optional parameters' do
|
508
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/opens?groupby=month&limit=100")
|
509
|
+
|
510
|
+
@client.get_campaign_opens('id', groupby: 'month', limit: 100)
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
describe 'get_campaign_unsubscribes method' do
|
515
|
+
it 'fetches the domain campaign unsubscribes resource and returns a response object' do
|
516
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/unsubscribes")
|
517
|
+
|
518
|
+
@client.get_campaign_unsubscribes('id').must_be_instance_of(Mailgunner::Response)
|
519
|
+
end
|
520
|
+
|
521
|
+
it 'encodes the optional parameters' do
|
522
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/unsubscribes?groupby=month&limit=100")
|
523
|
+
|
524
|
+
@client.get_campaign_unsubscribes('id', groupby: 'month', limit: 100)
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
describe 'get_campaign_complaints method' do
|
529
|
+
it 'fetches the domain campaign complaints resource and returns a response object' do
|
530
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/complaints")
|
531
|
+
|
532
|
+
@client.get_campaign_complaints('id').must_be_instance_of(Mailgunner::Response)
|
533
|
+
end
|
534
|
+
|
535
|
+
it 'encodes the optional parameters' do
|
536
|
+
expect(Net::HTTP::Get, "/v2/#@domain/campaigns/id/complaints?groupby=month&limit=100")
|
537
|
+
|
538
|
+
@client.get_campaign_complaints('id', groupby: 'month', limit: 100)
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
describe 'get_lists method' do
|
543
|
+
it 'fetches the domain lists resource and returns a response object' do
|
544
|
+
expect(Net::HTTP::Get, '/v2/lists')
|
545
|
+
|
546
|
+
@client.get_lists.must_be_instance_of(Mailgunner::Response)
|
547
|
+
end
|
548
|
+
|
549
|
+
it 'encodes skip and limit parameters' do
|
550
|
+
expect(Net::HTTP::Get, '/v2/lists?skip=1&limit=2')
|
551
|
+
|
552
|
+
@client.get_lists(skip: 1, limit: 2)
|
553
|
+
end
|
554
|
+
end
|
555
|
+
|
556
|
+
describe 'get_list method' do
|
557
|
+
it 'fetches the list resource with the given address and returns a response object' do
|
558
|
+
expect(Net::HTTP::Get, '/v2/lists/developers%40mailgun.net')
|
559
|
+
|
560
|
+
@client.get_list('developers@mailgun.net').must_be_instance_of(Mailgunner::Response)
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
describe 'add_list method' do
|
565
|
+
it 'posts to the domain lists resource and returns a response object' do
|
566
|
+
expect(Net::HTTP::Post, '/v2/lists')
|
567
|
+
|
568
|
+
@client.add_list({}).must_be_instance_of(Mailgunner::Response)
|
569
|
+
end
|
570
|
+
|
571
|
+
it 'encodes the list attributes' do
|
572
|
+
expect(Net::HTTP::Post, responds_with(:body, 'address=developers%40mailgun.net'))
|
573
|
+
|
574
|
+
@client.add_list({address: 'developers@mailgun.net'})
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
describe 'update_list method' do
|
579
|
+
it 'updates the list resource and returns a response object' do
|
580
|
+
expect(Net::HTTP::Put, '/v2/lists/developers%40mailgun.net')
|
581
|
+
|
582
|
+
@client.update_list('developers@mailgun.net', {}).must_be_instance_of(Mailgunner::Response)
|
583
|
+
end
|
584
|
+
|
585
|
+
it 'encodes the list attributes' do
|
586
|
+
expect(Net::HTTP::Put, responds_with(:body, 'name=Example+list'))
|
587
|
+
|
588
|
+
@client.update_list('developers@mailgun.net', {name: 'Example list'})
|
589
|
+
end
|
590
|
+
end
|
591
|
+
|
592
|
+
describe 'delete_list method' do
|
593
|
+
it 'deletes the domain list resource with the given address and returns a response object' do
|
594
|
+
expect(Net::HTTP::Delete, '/v2/lists/developers%40mailgun.net')
|
595
|
+
|
596
|
+
@client.delete_list('developers@mailgun.net').must_be_instance_of(Mailgunner::Response)
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
describe 'get_list_members method' do
|
601
|
+
it 'fetches the list members resource and returns a response object' do
|
602
|
+
expect(Net::HTTP::Get, '/v2/lists/developers%40mailgun.net/members')
|
603
|
+
|
604
|
+
@client.get_list_members('developers@mailgun.net').must_be_instance_of(Mailgunner::Response)
|
605
|
+
end
|
606
|
+
|
607
|
+
it 'encodes skip and limit parameters' do
|
608
|
+
expect(Net::HTTP::Get, '/v2/lists/developers%40mailgun.net/members?skip=1&limit=2')
|
609
|
+
|
610
|
+
@client.get_list_members('developers@mailgun.net', skip: 1, limit: 2)
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
describe 'get_list_member method' do
|
615
|
+
it 'fetches the list member resource with the given address and returns a response object' do
|
616
|
+
expect(Net::HTTP::Get, "/v2/lists/developers%40mailgun.net/members/#@encoded_address")
|
617
|
+
|
618
|
+
@client.get_list_member('developers@mailgun.net', @address).must_be_instance_of(Mailgunner::Response)
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
describe 'add_list_member method' do
|
623
|
+
it 'posts to the list members resource and returns a response object' do
|
624
|
+
expect(Net::HTTP::Post, '/v2/lists/developers%40mailgun.net/members')
|
625
|
+
|
626
|
+
@client.add_list_member('developers@mailgun.net', {}).must_be_instance_of(Mailgunner::Response)
|
627
|
+
end
|
628
|
+
|
629
|
+
it 'encodes the list attributes' do
|
630
|
+
expect(Net::HTTP::Post, responds_with(:body, "address=#@encoded_address"))
|
631
|
+
|
632
|
+
@client.add_list_member('developers@mailgun.net', {address: @address})
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
describe 'update_list_member method' do
|
637
|
+
it 'updates the list member resource with the given address and returns a response object' do
|
638
|
+
expect(Net::HTTP::Put, "/v2/lists/developers%40mailgun.net/members/#@encoded_address")
|
639
|
+
|
640
|
+
@client.update_list_member('developers@mailgun.net', @address, {}).must_be_instance_of(Mailgunner::Response)
|
641
|
+
end
|
642
|
+
|
643
|
+
it 'encodes the list member attributes' do
|
644
|
+
expect(Net::HTTP::Put, responds_with(:body, 'subscribed=no'))
|
645
|
+
|
646
|
+
@client.update_list_member('developers@mailgun.net', @address, {subscribed: 'no'})
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
650
|
+
describe 'delete_list_member method' do
|
651
|
+
it 'deletes the list member resource with the given address and returns a response object' do
|
652
|
+
expect(Net::HTTP::Delete, "/v2/lists/developers%40mailgun.net/members/#@encoded_address")
|
653
|
+
|
654
|
+
@client.delete_list_member('developers@mailgun.net', @address).must_be_instance_of(Mailgunner::Response)
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
describe 'get_list_stats method' do
|
659
|
+
it 'fetches the list stats resource and returns a response object' do
|
660
|
+
expect(Net::HTTP::Get, '/v2/lists/developers%40mailgun.net/stats')
|
661
|
+
|
662
|
+
@client.get_list_stats('developers@mailgun.net').must_be_instance_of(Mailgunner::Response)
|
663
|
+
end
|
664
|
+
end
|
665
|
+
end
|
666
|
+
|
667
|
+
describe 'Mailgunner::Response' do
|
668
|
+
before do
|
669
|
+
@http_response = mock()
|
670
|
+
|
671
|
+
@response = Mailgunner::Response.new(@http_response)
|
672
|
+
end
|
673
|
+
|
674
|
+
it 'delegates missing methods to the http response object' do
|
675
|
+
@http_response.stubs(:code).returns('200')
|
676
|
+
|
677
|
+
@response.code.must_equal('200')
|
678
|
+
end
|
679
|
+
|
680
|
+
describe 'ok query method' do
|
681
|
+
it 'returns true if the status code is 200' do
|
682
|
+
@http_response.expects(:code).returns('200')
|
683
|
+
|
684
|
+
@response.ok?.must_equal(true)
|
685
|
+
end
|
686
|
+
|
687
|
+
it 'returns false otherwise' do
|
688
|
+
@http_response.expects(:code).returns('400')
|
689
|
+
|
690
|
+
@response.ok?.must_equal(false)
|
691
|
+
end
|
692
|
+
end
|
693
|
+
|
694
|
+
describe 'client_error query method' do
|
695
|
+
it 'returns true if the status code is 4xx' do
|
696
|
+
@http_response.stubs(:code).returns(%w(400 401 402 404).sample)
|
697
|
+
|
698
|
+
@response.client_error?.must_equal(true)
|
699
|
+
end
|
700
|
+
|
701
|
+
it 'returns false otherwise' do
|
702
|
+
@http_response.stubs(:code).returns('200')
|
703
|
+
|
704
|
+
@response.client_error?.must_equal(false)
|
705
|
+
end
|
706
|
+
end
|
707
|
+
|
708
|
+
describe 'server_error query method' do
|
709
|
+
it 'returns true if the status code is 5xx' do
|
710
|
+
@http_response.stubs(:code).returns(%w(500 502 503 504).sample)
|
711
|
+
|
712
|
+
@response.server_error?.must_equal(true)
|
713
|
+
end
|
714
|
+
|
715
|
+
it 'returns false otherwise' do
|
716
|
+
@http_response.stubs(:code).returns('200')
|
717
|
+
|
718
|
+
@response.server_error?.must_equal(false)
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|
722
|
+
describe 'json query method' do
|
723
|
+
it 'returns true if the response has a json content type' do
|
724
|
+
@http_response.expects(:[]).with('Content-Type').returns('application/json;charset=utf-8')
|
725
|
+
|
726
|
+
@response.json?.must_equal(true)
|
727
|
+
end
|
728
|
+
|
729
|
+
it 'returns false otherwise' do
|
730
|
+
@http_response.expects(:[]).with('Content-Type').returns('text/html')
|
731
|
+
|
732
|
+
@response.json?.must_equal(false)
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
describe 'object method' do
|
737
|
+
it 'decodes the response body as json and returns a hash' do
|
738
|
+
@http_response.expects(:body).returns('{"foo":"bar"}')
|
739
|
+
|
740
|
+
@response.object.must_equal({'foo' => 'bar'})
|
741
|
+
end
|
742
|
+
end
|
743
|
+
end
|
744
|
+
|
745
|
+
describe 'Mailgunner::Response initialized with an alternative json implementation' do
|
746
|
+
before do
|
747
|
+
@json = mock()
|
748
|
+
|
749
|
+
@http_response = mock()
|
750
|
+
|
751
|
+
@response = Mailgunner::Response.new(@http_response, :json => @json)
|
752
|
+
end
|
753
|
+
|
754
|
+
describe 'object method' do
|
755
|
+
it 'uses the alternative json implementation to parse the response body' do
|
756
|
+
@http_response.stubs(:body).returns(response_body = '{"foo":"bar"}')
|
757
|
+
|
758
|
+
@json.expects(:load).with(response_body)
|
759
|
+
|
760
|
+
@response.object
|
761
|
+
end
|
762
|
+
end
|
763
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mailgunner
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tim Craft
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.3
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.3
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: mocha
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.10.3
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.10.3
|
46
|
+
description: A Ruby wrapper for the Mailgun API
|
47
|
+
email:
|
48
|
+
- mail@timcraft.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- lib/mailgunner.rb
|
54
|
+
- spec/mailgunner_spec.rb
|
55
|
+
- README.md
|
56
|
+
- mailgunner.gemspec
|
57
|
+
homepage: http://github.com/timcraft/mailgunner
|
58
|
+
licenses: []
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
requirements: []
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.8.24
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: See description
|
81
|
+
test_files: []
|
82
|
+
has_rdoc:
|