expresspigeon-ruby 0.0.1
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/.gitignore +19 -0
- data/.rvmrc +8 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +24 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/expresspigeon-ruby.gemspec +20 -0
- data/lib/expresspigeon-ruby/version.rb +5 -0
- data/lib/expresspigeon-ruby.rb +306 -0
- data/spec/campaigns_spec.rb +109 -0
- data/spec/contacts_spec.rb +152 -0
- data/spec/lists_spec.rb +149 -0
- data/spec/messages_spec.rb +127 -0
- data/spec/pigeon_helper.rb +16 -0
- metadata +82 -0
data/.gitignore
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
*.rbc
|
2
|
+
*.sassc
|
3
|
+
.sass-cache
|
4
|
+
capybara-*.html
|
5
|
+
.rspec
|
6
|
+
/.bundle
|
7
|
+
/vendor/bundle
|
8
|
+
/log/*
|
9
|
+
/tmp/*
|
10
|
+
/db/*.sqlite3
|
11
|
+
/public/system/*
|
12
|
+
/coverage/
|
13
|
+
/spec/tmp/*
|
14
|
+
**.orig
|
15
|
+
rerun.txt
|
16
|
+
pickle-email-*.html
|
17
|
+
doc/structures.csv
|
18
|
+
*.iml
|
19
|
+
.idea/
|
data/.rvmrc
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
expresspigeon-ruby (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.2.5)
|
10
|
+
rspec (2.14.1)
|
11
|
+
rspec-core (~> 2.14.0)
|
12
|
+
rspec-expectations (~> 2.14.0)
|
13
|
+
rspec-mocks (~> 2.14.0)
|
14
|
+
rspec-core (2.14.5)
|
15
|
+
rspec-expectations (2.14.3)
|
16
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
17
|
+
rspec-mocks (2.14.3)
|
18
|
+
|
19
|
+
PLATFORMS
|
20
|
+
ruby
|
21
|
+
|
22
|
+
DEPENDENCIES
|
23
|
+
expresspigeon-ruby!
|
24
|
+
rspec (~> 2.6)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 ExpressPigeon
|
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,29 @@
|
|
1
|
+
# Expresspigeon::Ruby
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'expresspigeon-ruby'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install expresspigeon-ruby
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'expresspigeon-ruby/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "expresspigeon-ruby"
|
8
|
+
gem.version = Expresspigeon::API::VERSION
|
9
|
+
gem.authors = ["ipolevoy"]
|
10
|
+
gem.email = ["ipolevoy@groupon.com"]
|
11
|
+
gem.description = %q{ExpressPigeon Ruby API for sending transactional messages, manipulating lists, contacts nad more}
|
12
|
+
gem.summary = %q{ExpressPigeon API Ruby Wrapper}
|
13
|
+
gem.homepage = "https://github.com/expresspigeon/expresspigeon-ruby"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
gem.add_development_dependency "rspec", "~> 2.6"
|
20
|
+
end
|
@@ -0,0 +1,306 @@
|
|
1
|
+
require "expresspigeon-ruby/version"
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'json'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
AUTH_KEY = ENV['EXPRESSPIGEON_AUTH_KEY']
|
8
|
+
ROOT = 'https://api.expresspigeon.com/'
|
9
|
+
#ROOT = 'http://localhost:8888/api/'
|
10
|
+
USE_SSL = true
|
11
|
+
|
12
|
+
module ExpressPigeon
|
13
|
+
module API
|
14
|
+
unless AUTH_KEY
|
15
|
+
raise 'Provide EXPRESSPIGEON_AUTH_KEY environment variable'
|
16
|
+
end
|
17
|
+
|
18
|
+
def http(path, method, params = {})
|
19
|
+
uri = URI.parse "#{ROOT}#{path}"
|
20
|
+
req = Net::HTTP.const_get("#{method}").new "#{ROOT}#{path}"
|
21
|
+
req['X-auth-key'] = AUTH_KEY
|
22
|
+
if params
|
23
|
+
req.body = params.to_json
|
24
|
+
req['Content-type'] = 'application/json'
|
25
|
+
end
|
26
|
+
|
27
|
+
if block_given?
|
28
|
+
Net::HTTP.start(uri.host, uri.port, :use_ssl => USE_SSL) do |http|
|
29
|
+
http.request req do |res|
|
30
|
+
res.read_body do |seg|
|
31
|
+
yield seg
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
else
|
36
|
+
resp = Net::HTTP.start(uri.host, uri.port, :use_ssl => USE_SSL) do |http|
|
37
|
+
http.request req
|
38
|
+
end
|
39
|
+
parsed = JSON.parse(resp.body)
|
40
|
+
if parsed.kind_of? Hash
|
41
|
+
MetaHash.new parsed
|
42
|
+
else
|
43
|
+
parsed
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def get(path, &block)
|
49
|
+
http path, 'Get', nil, &block
|
50
|
+
end
|
51
|
+
|
52
|
+
def post(path, params = {})
|
53
|
+
http path, 'Post', params
|
54
|
+
end
|
55
|
+
|
56
|
+
def del(path, params = {})
|
57
|
+
http path, 'Delete', params
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.campaigns
|
61
|
+
Campaigns.new
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.lists
|
65
|
+
Lists.new
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.contacts
|
69
|
+
Contacts.new
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.messages
|
73
|
+
Messages.new
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
class MetaHash < Hash
|
80
|
+
|
81
|
+
def initialize(delegate)
|
82
|
+
super
|
83
|
+
@delegate = delegate
|
84
|
+
@delegate.each_key do |k|
|
85
|
+
v = @delegate[k] # lets go only one level down for now
|
86
|
+
if v.kind_of? Hash
|
87
|
+
@delegate[k] = MetaHash.new(v)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def method_missing(m, *args, &block)
|
93
|
+
@delegate[m.to_s]
|
94
|
+
end
|
95
|
+
|
96
|
+
def to_s
|
97
|
+
@delegate.to_s
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
class Lists
|
103
|
+
|
104
|
+
include ExpressPigeon::API
|
105
|
+
|
106
|
+
def initialize
|
107
|
+
@endpoint = 'lists'
|
108
|
+
end
|
109
|
+
|
110
|
+
def create(list_name, from_name, reply_to)
|
111
|
+
post @endpoint, {:name => list_name, :from_name => from_name, :reply_to => reply_to}
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
# Query all lists.
|
116
|
+
# returns: array of hashes each representing a list for this user
|
117
|
+
def all
|
118
|
+
get @endpoint
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
#Updates existing list
|
123
|
+
#
|
124
|
+
#:param list_id: Id of list to be updated
|
125
|
+
#:type list_id: int
|
126
|
+
#
|
127
|
+
#:param params: JSON object represents a list to be updated
|
128
|
+
|
129
|
+
#
|
130
|
+
#:returns: EpResponse with status, code, message, and updated list
|
131
|
+
#:rtype: EpResponse
|
132
|
+
#TODO: resolve API on Python side, then implement this
|
133
|
+
#def update(list_id, params = {})
|
134
|
+
# params['id'] = list_id
|
135
|
+
# return self.ep.put(self.endpoint, params=params)
|
136
|
+
#end
|
137
|
+
|
138
|
+
|
139
|
+
# Removes a list with a given id. A list must be enabled and has no dependent subscriptions and/or scheduled campaigns.
|
140
|
+
#
|
141
|
+
# param list_id: Id of list to be removed.
|
142
|
+
# returns response hash with status, code, and message
|
143
|
+
def delete(list_id)
|
144
|
+
del "#{@endpoint}/#{list_id}"
|
145
|
+
end
|
146
|
+
|
147
|
+
def csv(list_id, &block)
|
148
|
+
get "#{@endpoint}/#{list_id}/csv", &block
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
class Campaigns
|
155
|
+
include ExpressPigeon::API
|
156
|
+
|
157
|
+
def initialize
|
158
|
+
@endpoint = 'campaigns'
|
159
|
+
end
|
160
|
+
|
161
|
+
def all
|
162
|
+
get @endpoint
|
163
|
+
end
|
164
|
+
|
165
|
+
def report(campaign_id)
|
166
|
+
get "#{@endpoint}/#{campaign_id}"
|
167
|
+
end
|
168
|
+
|
169
|
+
def bounced(campaign_id)
|
170
|
+
get "#{@endpoint}/#{campaign_id}/bounced"
|
171
|
+
end
|
172
|
+
|
173
|
+
def unsubscribed(campaign_id)
|
174
|
+
get "#{@endpoint}/#{campaign_id}/unsubscribed"
|
175
|
+
end
|
176
|
+
|
177
|
+
def spam(campaign_id)
|
178
|
+
get "#{@endpoint}/#{campaign_id}/spam"
|
179
|
+
end
|
180
|
+
|
181
|
+
#
|
182
|
+
# Schedules a new campaign to be sent.
|
183
|
+
# Parameters:
|
184
|
+
# * *list_id* - id of list to send to
|
185
|
+
# * *template_id* - id of template to send
|
186
|
+
# * *name* - name of a newly created campaign
|
187
|
+
# * *from_name* - from name
|
188
|
+
# * *reply_to* - reply to
|
189
|
+
# * *subject* - subject of campaign
|
190
|
+
# * *google_analytics* - true to turn Google Analytics on
|
191
|
+
def send(params = {})
|
192
|
+
post @endpoint, params
|
193
|
+
end
|
194
|
+
|
195
|
+
#
|
196
|
+
# Schedules a new campaign to be sent.
|
197
|
+
# Parameters:
|
198
|
+
# * *list_id* - id of list to send to
|
199
|
+
# * *template_id* - id of template to send
|
200
|
+
# * *name* - name of a newly created campaign
|
201
|
+
# * *from_name* - from name
|
202
|
+
# * *reply_to* - reply to
|
203
|
+
# * *subject* - subject of campaign
|
204
|
+
# * *google_analytics* - true to turn Google Analytics on
|
205
|
+
# * *schedule_for* - Specifies what time a campaign should be sent. If it is provided the campaign will
|
206
|
+
# be scheduled to this time, otherwise campaign is sent immediately. The schedule_for
|
207
|
+
# must be in ISO date format and should be in the future.
|
208
|
+
def schedule(params = {})
|
209
|
+
post @endpoint, params
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
|
214
|
+
class Contacts
|
215
|
+
include ExpressPigeon::API
|
216
|
+
|
217
|
+
def initialize
|
218
|
+
@endpoint = 'contacts'
|
219
|
+
end
|
220
|
+
|
221
|
+
def find_by_email(email)
|
222
|
+
get "#{@endpoint}?email=#{email}"
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
# JSON document represents a contact to be created or updated.
|
227
|
+
# The email field is required.
|
228
|
+
# When updating a contact, list_id is optional,
|
229
|
+
# since the contact is uniquely identified by email across all lists.
|
230
|
+
#
|
231
|
+
# :param list_id: Contact list ID (Fixnum) the contact will be added to
|
232
|
+
#
|
233
|
+
# :param contact: Hash describes new contact. The "email" field is required.
|
234
|
+
#
|
235
|
+
# :returns: representation of a contact
|
236
|
+
#
|
237
|
+
def upsert(list_id, contact)
|
238
|
+
post @endpoint, params = {:list_id => list_id, :contact => contact}
|
239
|
+
end
|
240
|
+
|
241
|
+
# Delete single contact. If list_id is not provided, contact will be deleted from system.
|
242
|
+
# :param email: contact email to be deleted.
|
243
|
+
# :param list_id: list id to remove contact from, if not provided, contact will be deleted from system.
|
244
|
+
def delete(email, list_id = nil)
|
245
|
+
if list_id
|
246
|
+
query = "email=#{email}&list_id=#{list_id}"
|
247
|
+
else
|
248
|
+
query = "email=#{email}"
|
249
|
+
end
|
250
|
+
del "#{@endpoint}?#{query}", nil
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
end
|
255
|
+
class Messages
|
256
|
+
|
257
|
+
include ExpressPigeon::API
|
258
|
+
|
259
|
+
def initialize
|
260
|
+
@endpoint = 'messages'
|
261
|
+
end
|
262
|
+
|
263
|
+
def send_message(template_id, to, reply_to, from_name, subject, merge_fields = nil, view_online = false, click_tracking = true)
|
264
|
+
post @endpoint, params = {template_id: template_id, :to => to, reply_to: reply_to, :from => from_name, :subject => subject,
|
265
|
+
:merge_fields => merge_fields, :view_online => view_online, :click_tracking => click_tracking}
|
266
|
+
end
|
267
|
+
|
268
|
+
def report(message_id)
|
269
|
+
get "#{@endpoint}/#{message_id}"
|
270
|
+
end
|
271
|
+
|
272
|
+
#
|
273
|
+
#
|
274
|
+
# start_date is instance of Time
|
275
|
+
# end_date is instance of Time
|
276
|
+
def reports(from_id, start_date = nil, end_date = nil)
|
277
|
+
params = []
|
278
|
+
|
279
|
+
if from_id
|
280
|
+
params << "from_id=#{from_id}"
|
281
|
+
end
|
282
|
+
|
283
|
+
if start_date and not end_date
|
284
|
+
raise 'must include both start_date and end_date'
|
285
|
+
end
|
286
|
+
if end_date and not start_date
|
287
|
+
raise 'must include both start_date and end_date'
|
288
|
+
end
|
289
|
+
|
290
|
+
if start_date and end_date
|
291
|
+
params << "start_date=#{start_date.strftime('%FT%T.%L%z')}"
|
292
|
+
params << "end_date=#{end_date.strftime('%FT%T.%L%z')}"
|
293
|
+
end
|
294
|
+
|
295
|
+
query = "#{@endpoint}?"
|
296
|
+
|
297
|
+
if params.size > 0
|
298
|
+
query << params.join('&')
|
299
|
+
end
|
300
|
+
|
301
|
+
puts "calling: #{query}"
|
302
|
+
get query
|
303
|
+
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require './lib/expresspigeon-ruby'
|
2
|
+
require 'pigeon_helper'
|
3
|
+
|
4
|
+
describe 'campaigns integration test' do
|
5
|
+
|
6
|
+
include PigeonSpecHelper
|
7
|
+
it 'should return more than 0 campaign ids' do
|
8
|
+
res = PIGEON.campaigns.all
|
9
|
+
res.class.should == Array
|
10
|
+
res.size.should > 0
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'cannot send with missing parameters' do
|
14
|
+
res = PIGEON.campaigns.send(:template_id => 15233, :name => 'API Test campaign',
|
15
|
+
:from_name => 'Igor Polevoy', :reply_to => 'igor@polevoy.org',
|
16
|
+
:subject => 'API test', :google_analytics => true)
|
17
|
+
validate_response res, 400, 'error', /required parameters: list_id, template_id, name, from_name, reply_to, subject, google_analytics/
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'cannot send with bad reply_to' do
|
21
|
+
res = PIGEON.campaigns.send(:list_id => -1, :template_id => -1, :name => 'My Campaign', :from_name => 'John', :reply_to => 'j',
|
22
|
+
:subject => 'Hi', :google_analytics => false)
|
23
|
+
validate_response res, 400, 'error', /reply_to should be valid email address/
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'cannot send with non-existing template' do
|
27
|
+
res = PIGEON.campaigns.send(:list_id => -1, :template_id => -1, :name => 'My Campaign', :from_name => 'John',
|
28
|
+
:reply_to => 'j@j.j',
|
29
|
+
:subject => 'Hi', :google_analytics => false)
|
30
|
+
validate_response res, 400, 'error', /template=-1 is not found/
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'cannot send to non-existing list' do
|
34
|
+
|
35
|
+
res = PIGEON.campaigns.send(:list_id => -1, :template_id => TEMPLATE_ID, :name => 'My Campaign', :from_name => 'John',
|
36
|
+
:reply_to => 'j@j.j',
|
37
|
+
:subject => 'Hi', :google_analytics => false)
|
38
|
+
validate_response res, 400, 'error', /list=-1 is not found/
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'cannot send to disabled list' do
|
42
|
+
res = PIGEON.campaigns.send(:list_id => LIST_ID, :template_id => TEMPLATE_ID, :name => 'My Campaign', :from_name => 'John',
|
43
|
+
:reply_to => 'j@j.j',
|
44
|
+
:subject => 'Hi', :google_analytics => false)
|
45
|
+
validate_response res, 400, 'error', /list=#{DISABLED_LIST} is disabled/
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should create new list, add contact and send successful campaign' do
|
49
|
+
|
50
|
+
list_resp = PIGEON.lists.create('My list', 'John', API_USER)
|
51
|
+
list_id = list_resp.list.id
|
52
|
+
PIGEON.contacts.upsert(list_id, {:email => API_USER})
|
53
|
+
resp = PIGEON.campaigns.send(:list_id => list_id, :template_id => TEMPLATE_ID, :name => 'My Campaign', :from_name => 'John',
|
54
|
+
:reply_to => API_USER,
|
55
|
+
:subject => 'Hi', :google_analytics => false)
|
56
|
+
validate_response resp, 200, 'success', /new campaign created successfully/
|
57
|
+
report = PIGEON.campaigns.report(resp.campaign_id)
|
58
|
+
(report.delivered == 0 or report.delivered == 1).should be_true
|
59
|
+
report.clicked.should eq 0
|
60
|
+
report.opened.should eq 0
|
61
|
+
report.spam.should eq 0
|
62
|
+
(report.in_transit == 0 or report.in_transit == 1).should be_true
|
63
|
+
report.unsubscribed.should eq 0
|
64
|
+
report.bounced.should eq 0
|
65
|
+
bounced = PIGEON.campaigns.bounced(resp.campaign_id)
|
66
|
+
unsubscribed = PIGEON.campaigns.unsubscribed(resp.campaign_id)
|
67
|
+
spam = PIGEON.campaigns.spam(resp.campaign_id)
|
68
|
+
|
69
|
+
bounced.size.should eq 0
|
70
|
+
unsubscribed.size.should eq 0
|
71
|
+
spam.size.should eq 0
|
72
|
+
|
73
|
+
resp = PIGEON.contacts.delete(API_USER)
|
74
|
+
validate_response resp, 200, 'success', /contact=non@non.non deleted successfully/
|
75
|
+
|
76
|
+
resp = PIGEON.contacts.find_by_email(API_USER)
|
77
|
+
validate_response resp, 404, 'error', /contact=non@non.non not found/
|
78
|
+
|
79
|
+
resp = PIGEON.lists.delete(list_id)
|
80
|
+
validate_response resp, 200, 'success', /deleted successfully/
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
it 'cannot send campaign if scheduling with bad date' do
|
85
|
+
|
86
|
+
list_resp = PIGEON.lists.create "My list", "John", API_USER
|
87
|
+
resp = PIGEON.campaigns.schedule :list_id => list_resp.list.id, :template_id => TEMPLATE_ID, :name => 'My Campaign',
|
88
|
+
|
89
|
+
:from_name => 'John',
|
90
|
+
:reply_to => API_USER, :subject => 'Hi',
|
91
|
+
:google_analytics => false, :schedule_for => "2013-05-28"
|
92
|
+
|
93
|
+
validate_response resp, 400, 'error', /schedule_for is not in ISO date format, example: 2013-05-28T17:19:50.779/
|
94
|
+
resp = PIGEON.lists.delete(list_resp.list.id)
|
95
|
+
validate_response resp, 200, 'success', /deleted successfully/
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should not schedule campaign with date in the past' do
|
99
|
+
list_resp = PIGEON.lists.create('My list', 'John', API_USER)
|
100
|
+
resp = PIGEON.campaigns.schedule :list_id => list_resp.list.id, :template_id => TEMPLATE_ID, :name => 'My Campaign',
|
101
|
+
:from_name => 'John',
|
102
|
+
:reply_to => API_USER, :subject => 'Hi',
|
103
|
+
:google_analytics => false, :schedule_for => '2010-05-28T17:19:50.779+0300'
|
104
|
+
|
105
|
+
validate_response resp, 400, 'error', /schedule_for should be in the future/
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require './lib/expresspigeon-ruby'
|
2
|
+
require 'pigeon_helper'
|
3
|
+
|
4
|
+
describe 'contacts integration test' do
|
5
|
+
|
6
|
+
include PigeonSpecHelper
|
7
|
+
|
8
|
+
it 'should not create contact without contact data' do
|
9
|
+
resp = PIGEON.contacts.upsert(-1, {})
|
10
|
+
validate_response resp, 400, 'error', /contact and contact.email are required/
|
11
|
+
end
|
12
|
+
it 'should not create contact without email' do
|
13
|
+
resp = PIGEON.contacts.upsert -1, :email => '', :first_name => 'Marylin', :last_name => 'Monroe'
|
14
|
+
validate_response resp, 400, 'error', /contact and contact.email are required/
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should not add contact with too many custom fields' do
|
18
|
+
custom_fields = {}
|
19
|
+
(1..25).each { |n| custom_fields["custom_field_#{n}"] = n }
|
20
|
+
resp = PIGEON.contacts.upsert -1, :email => "mary@e.e", :custom_fields => custom_fields
|
21
|
+
validate_response resp, 400, 'error', /You cannot create more than 20 custom fields. Use one of the 'custom_fields'./
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should not create new contact without list_id' do
|
25
|
+
resp = PIGEON.contacts.upsert '', :email => 'ee@e.e', :first_name => 'Marylin', :last_name => 'Monroe'
|
26
|
+
validate_response resp, 404, 'error', /contact=ee@e.e not found/
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'test_create_with_suppressed_contact' do
|
30
|
+
resp = PIGEON.contacts.upsert -1, :email => 'suppressed@e.e'
|
31
|
+
validate_response resp, 400, 'error', /contact=suppressed@e.e is in suppress list/
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'cannot create with non-existent_list' do
|
35
|
+
resp = PIGEON.contacts.upsert -1, :email => "e@e.e"
|
36
|
+
validate_response resp, 404, 'error', /list=-1 not found/
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'creates list with contacts' do
|
40
|
+
list_response = PIGEON.lists.create 'My List', 'John Doe', 'john@doe.com'
|
41
|
+
list_id = list_response.list.id
|
42
|
+
resp = PIGEON.contacts.upsert list_id, email: "mary@e.e",
|
43
|
+
:custom_fields => {:custom_field_1 => "custom_value_1", }
|
44
|
+
validate_response resp, 200, 'success', /contact=mary@e.e created\/updated successfully/
|
45
|
+
resp.contact.custom_fields.custom_field_1.should eq 'custom_value_1'
|
46
|
+
resp.contact.email.should eq 'mary@e.e'
|
47
|
+
resp.contact.email_format.should eq 'html'
|
48
|
+
resp.contact.status.should eq 'ACTIVE'
|
49
|
+
PIGEON.lists.delete(list_id)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'creates list non-existent custom field' do
|
53
|
+
list_response = PIGEON.lists.create 'My List', 'John Doe', 'a@a.a'
|
54
|
+
list_id = list_response.list.id
|
55
|
+
resp = PIGEON.contacts.upsert(list_id, {:email => "mary@e.e", :custom_fields => {:c => "c", }})
|
56
|
+
validate_response resp, 200, 'success', nil
|
57
|
+
PIGEON.lists.delete(list_id)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'cannot export contacts from list without list_id' do
|
61
|
+
content = ''
|
62
|
+
PIGEON.lists.csv "-1" do |c|
|
63
|
+
content << c
|
64
|
+
end
|
65
|
+
resp = JSON.parse(content)
|
66
|
+
validate_response MetaHash.new(resp), 404, 'error', /list=-1 not found/
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should get contacts from suppressed list' do
|
70
|
+
content =''
|
71
|
+
PIGEON.lists.csv "suppress_list" do |c|
|
72
|
+
content += c
|
73
|
+
end
|
74
|
+
resp = content.split /\n/
|
75
|
+
resp.size.should eq 2
|
76
|
+
resp[1].should =~ /"suppressed@e.e","Suppressed","Doe"/
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should get single contact' do
|
80
|
+
resp = PIGEON.contacts.find_by_email 'suppressed@e.e'
|
81
|
+
resp.email.should eq 'suppressed@e.e'
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should not find non existent contact' do
|
85
|
+
resp = PIGEON.contacts.find_by_email 'a@a.a'
|
86
|
+
validate_response resp, 404, 'error', /contact=a@a.a not found/
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should update contact' do
|
90
|
+
|
91
|
+
list_response = PIGEON.lists.create('My List', 'John Doe', "a@a.a")
|
92
|
+
resp = PIGEON.contacts.upsert list_response.list.id,
|
93
|
+
:email => "mary@e.e", :first_name => "Mary", :last_name => "Doe"
|
94
|
+
validate_response resp, 200, 'success', /contact=mary@e.e created\/updated successfully/
|
95
|
+
PIGEON.contacts.find_by_email("mary@e.e").last_name.should eq 'Doe'
|
96
|
+
|
97
|
+
resp = PIGEON.contacts.upsert list_response.list.id,
|
98
|
+
:email => 'mary@e.e', :first_name => 'Mary', :last_name => 'Johns'
|
99
|
+
validate_response resp, 200, 'success', /contact=mary@e.e created\/updated successfully/
|
100
|
+
PIGEON.contacts.find_by_email("mary@e.e").last_name.should eq 'Johns'
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'cannot delete contact with non-existent email' do
|
104
|
+
res = PIGEON.contacts.delete("g@g.g")
|
105
|
+
validate_response res, 404, 'error', /contact=g@g.g not found/
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should not delete suppressed contact' do
|
109
|
+
res = PIGEON.contacts.delete("suppressed@e.e")
|
110
|
+
validate_response res, 400, 'error', /contact=suppressed@e.e is in suppress list/
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should delete single contact from all lists' do
|
114
|
+
list_response = PIGEON.lists.create 'My List', 'Jane Doe', 'a@a.a'
|
115
|
+
PIGEON.contacts.upsert list_response.list.id, :email => 'mary@e.e'
|
116
|
+
res = PIGEON.contacts.delete 'mary@e.e'
|
117
|
+
validate_response res, 200, 'success', /contact=mary@e.e deleted successfully/
|
118
|
+
PIGEON.lists.delete list_response.list.id
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'deletes single contact from single list' do
|
122
|
+
list_response = PIGEON.lists.create 'My List', 'John D.', 'a@a.a'
|
123
|
+
list_response_2 = PIGEON.lists.create('My List2', "Jane D.", 'a@a.a')
|
124
|
+
PIGEON.contacts.upsert(list_response.list.id, {:email => 'mary@e.e'})
|
125
|
+
PIGEON.contacts.upsert(list_response_2.list.id, {:email => 'mary@e.e'})
|
126
|
+
|
127
|
+
res = PIGEON.contacts.delete 'mary@e.e', list_response.list.id
|
128
|
+
|
129
|
+
validate_response res, 200, 'success', /contact=mary@e.e deleted successfully/
|
130
|
+
|
131
|
+
contacts_exported = ''
|
132
|
+
PIGEON.lists.csv list_response.list.id do |c|
|
133
|
+
contacts_exported << c
|
134
|
+
end
|
135
|
+
contacts_exported = contacts_exported.split /\n/
|
136
|
+
contacts_exported.size.should eq 1
|
137
|
+
|
138
|
+
contacts_exported_2 = ''
|
139
|
+
PIGEON.lists.csv list_response_2.list.id do |c|
|
140
|
+
contacts_exported_2 << c
|
141
|
+
end
|
142
|
+
|
143
|
+
contacts_exported_2 = contacts_exported_2.split /\n/
|
144
|
+
contacts_exported_2.size.should eq 2
|
145
|
+
contacts_exported_2[1].should =~ /"mary@e.e"/
|
146
|
+
|
147
|
+
PIGEON.lists.delete(list_response.list.id)
|
148
|
+
PIGEON.lists.delete(list_response_2.list.id)
|
149
|
+
PIGEON.contacts.delete('mary@e.e')
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
data/spec/lists_spec.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
require './lib/expresspigeon-ruby'
|
2
|
+
require 'pigeon_helper'
|
3
|
+
|
4
|
+
describe 'contacts integration test' do
|
5
|
+
|
6
|
+
include PigeonSpecHelper
|
7
|
+
|
8
|
+
it 'test_create_and_delete_new_list(self):' do
|
9
|
+
contact_list = PIGEON.lists.create 'Active customers', 'Bob', 'bob@acmetools.com'
|
10
|
+
|
11
|
+
puts "*****************************"
|
12
|
+
puts contact_list
|
13
|
+
|
14
|
+
validate_response contact_list, 200, 'success', /list=#{contact_list.list.id} created\/updated successfully/
|
15
|
+
contact_list.list.name.should eq "Active customers"
|
16
|
+
contact_list.list.from_name.should eq "Bob"
|
17
|
+
contact_list.list.reply_to.should eq "bob@acmetools.com"
|
18
|
+
contact_list.list.contact_count.should eq 0
|
19
|
+
|
20
|
+
#TODO: uncomment when running against real test env
|
21
|
+
#contact_list.list.zip.should eq '220000'
|
22
|
+
#contact_list.list.state.should eq "AL"
|
23
|
+
#contact_list.list.address1.should eq "Coolman 11"
|
24
|
+
#contact_list.list.city.should eq "Minsk"
|
25
|
+
#contact_list.list.country.should eq "Belarus"
|
26
|
+
#contact_list.list.organization.should eq "ExpressPigeon"
|
27
|
+
|
28
|
+
res = PIGEON.lists.delete(contact_list.list.id)
|
29
|
+
validate_response res, 200, 'success', /list=#{contact_list.list.id} deleted successfully/
|
30
|
+
end
|
31
|
+
|
32
|
+
#TODO: implement Lists.update method
|
33
|
+
it 'should update existing list' do
|
34
|
+
|
35
|
+
existing_list = PIGEON.lists.create("Update", "Bob", "bob@acmetools.com")
|
36
|
+
#res = PIGEON.lists.update existing_list.list.id, :name => 'Updated Name', :from_name => 'Bill'
|
37
|
+
#
|
38
|
+
#validate_response res, 200, 'success', /list=#{res.list.id} created\/updated successfully/
|
39
|
+
#res.list.name.should eq "Updated Name"
|
40
|
+
#res.list.from_name.should eq 'Bill'
|
41
|
+
#PIGEON.lists.delete res.list.id
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
it 'should upload contacts'
|
46
|
+
|
47
|
+
list_name = "Upload_#{Kernel.rand(9999).to_s}"
|
48
|
+
existing_list = PIGEON.lists.create(list_name, 'Bob', 'bob@acmetools.com')
|
49
|
+
|
50
|
+
#res = PIGEON.lists.upload(existing_list.list.id, self.file_to_upload)
|
51
|
+
|
52
|
+
|
53
|
+
#self.assertEqual(res.status, "success")
|
54
|
+
#self.assertEqual(res.code, 200)
|
55
|
+
#self.assertEquals(res.message, "file uploaded successfully")
|
56
|
+
#self.assertTrue(res.upload_id is not None)
|
57
|
+
#
|
58
|
+
#sleep(5)
|
59
|
+
#
|
60
|
+
#res = self.api.lists.upload_status(res.upload_id)
|
61
|
+
#self.assertEqual(res.message, "file upload completed")
|
62
|
+
#self.assertEqual(res.status, "success")
|
63
|
+
#self.assertEqual(res.code, 200)
|
64
|
+
#report = res.report
|
65
|
+
#self.assertTrue(report.completed)
|
66
|
+
#self.assertFalse(report.failed)
|
67
|
+
#self.assertEqual(report.suppressed, 0)
|
68
|
+
#self.assertEqual(report.skipped, 0)
|
69
|
+
#self.assertEqual(report.list_name, list_name)
|
70
|
+
#self.assertEqual(report.imported, 2)
|
71
|
+
|
72
|
+
# def test_upsert_list_with_non_existent_id(self):
|
73
|
+
# res = self.api.lists.update(-1, {"name": "Updated Name", "from_name": "Bill"})
|
74
|
+
# self.assertEqual(res.status, "error")
|
75
|
+
# self.assertEqual(res.code, 404)
|
76
|
+
# self.assertEqual(res.message, "list=-1 not found")
|
77
|
+
#
|
78
|
+
# def test_delete_list_with_non_existent_id(self):
|
79
|
+
# res = self.api.lists.delete(-1)
|
80
|
+
# self.assertEqual(res.status, "error")
|
81
|
+
# self.assertEqual(res.code, 404)
|
82
|
+
# self.assertEqual(res.message, "list=-1 not found")
|
83
|
+
#
|
84
|
+
# def test_remove_disabled_list(self):
|
85
|
+
# res = self.api.lists.delete(130)
|
86
|
+
# self.assertEqual(res.code, 400)
|
87
|
+
# self.assertEqual(res.status, "error")
|
88
|
+
# self.assertEqual(res.message, "could not delete disabled list=130")
|
89
|
+
#
|
90
|
+
# def test_upload_without_id(self):
|
91
|
+
# res = self.api.lists.upload("", self.file_to_upload)
|
92
|
+
# self.assertEqual(res.code, 400)
|
93
|
+
# self.assertEqual(res.status, "error")
|
94
|
+
# self.assertEqual(res.message, "you must provide list_id in URL")
|
95
|
+
#
|
96
|
+
# def test_upload_with_non_existent_id(self):
|
97
|
+
# res = self.api.lists.upload(-1, self.file_to_upload)
|
98
|
+
# self.assertEqual(res.code, 404)
|
99
|
+
# self.assertEqual(res.message, "list=-1 not found")
|
100
|
+
#
|
101
|
+
# def test_upload_status_without_upload_id(self):
|
102
|
+
# res = self.api.lists.upload_status("")
|
103
|
+
# self.assertEqual(res.code, 400)
|
104
|
+
# self.assertEqual(res.status, "error")
|
105
|
+
# self.assertEqual(res.message, "you must provide upload id")
|
106
|
+
#
|
107
|
+
# def test_enabled_list_removal(self):
|
108
|
+
# list_resp = self.api.lists.create("My list", "John", os.environ['EXPRESSPIGEON_API_USER'])
|
109
|
+
# self.api.contacts.upsert(list_resp.list.id, {"email": os.environ['EXPRESSPIGEON_API_USER']})
|
110
|
+
#
|
111
|
+
# now = datetime.datetime.now(pytz.UTC)
|
112
|
+
# schedule = self.format_date(now + datetime.timedelta(hours=1))
|
113
|
+
#
|
114
|
+
# res = self.api.campaigns.schedule(list_id=list_resp.list.id, template_id=self.template_id, name="My Campaign",
|
115
|
+
# from_name="John",
|
116
|
+
# reply_to=os.environ['EXPRESSPIGEON_API_USER'], subject="Hi",
|
117
|
+
# google_analytics=False,
|
118
|
+
# schedule_for=schedule)
|
119
|
+
# self.assertEqual(res.code, 200)
|
120
|
+
# self.assertEqual(res.status, "success")
|
121
|
+
# self.assertEqual(res.message, "new campaign created successfully")
|
122
|
+
# self.assertTrue(res.campaign_id is not None)
|
123
|
+
#
|
124
|
+
# res = self.api.lists.delete(list_resp.list.id)
|
125
|
+
# self.assertEqual(res.code, 400)
|
126
|
+
# self.assertEqual(res.status, "error")
|
127
|
+
# self.assertEqual(res.message,
|
128
|
+
# "could not delete list={0}, it has dependent subscriptions and/or scheduled campaigns".format(
|
129
|
+
# list_resp.list.id))
|
130
|
+
#
|
131
|
+
# def test_export_csv(self):
|
132
|
+
# list_response = self.api.lists.create("My List", "a@a.a", "a@a.a")
|
133
|
+
# self.api.contacts.upsert(list_response.list.id, {"email": "mary@a.a"})
|
134
|
+
#
|
135
|
+
# res = self.api.lists.csv(list_response.list.id).split("\n")
|
136
|
+
# self.assertEquals(len(res), 2)
|
137
|
+
# headers = '"Email", "First name", "Last name", "City", "Phone", "Company", "Title", "Address 1", "Address 2", ' \
|
138
|
+
# '"State", "Zip", "Country", "Date of birth", "custom_field_1", "custom_field_10", "custom_field_11", ' \
|
139
|
+
# '"custom_field_12", "custom_field_13", "custom_field_18", "custom_field_19", "custom_field_2", ' \
|
140
|
+
# '"custom_field_20", "custom_field_21", "custom_field_22", "custom_field_23", "custom_field_24", ' \
|
141
|
+
# '"custom_field_3", "custom_field_4", "custom_field_5", "custom_field_6", "custom_field_7", ' \
|
142
|
+
# '"custom_field_8", "custom_field_9"'
|
143
|
+
# self.assertEquals(res[0], headers)
|
144
|
+
# self.assertEquals(res[1], '"mary@a.a",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,')
|
145
|
+
#
|
146
|
+
# self.api.lists.delete(list_response.list.id)
|
147
|
+
# self.api.contacts.delete("mary@a.a")
|
148
|
+
|
149
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require './lib/expresspigeon-ruby'
|
2
|
+
require 'pigeon_helper'
|
3
|
+
|
4
|
+
describe 'transactional messages integration test' do
|
5
|
+
|
6
|
+
include PigeonSpecHelper
|
7
|
+
|
8
|
+
#def test_sending_message_and_report_without_params(self):
|
9
|
+
# res = self.api.messages.send_message(template_id=-1, to="", reply_to="", from_name="", subject="")
|
10
|
+
# self.assertEqual(res.code, 400)
|
11
|
+
# self.assertEqual(res.status, "error")
|
12
|
+
# self.assertEqual(res.message, "Required fields: template_id, reply_to, from, to, and subject")
|
13
|
+
#
|
14
|
+
#def test_sending_message_and_report_with_wrong_email_in_to(self):
|
15
|
+
# res = self.api.messages.send_message(template_id=-1, to="e", reply_to="a@a.a", from_name="me", subject="Hi")
|
16
|
+
# self.assertEqual(res.code, 400)
|
17
|
+
# self.assertEqual(res.status, "error")
|
18
|
+
# self.assertEqual(res.message, "Email in the 'to' field is not valid")
|
19
|
+
#
|
20
|
+
#def test_sending_message_and_report_with_wrong_email_in_reply_to(self):
|
21
|
+
# res = self.api.messages.send_message(template_id=-1, to="e@e.e", reply_to="a", from_name="me", subject="Hi")
|
22
|
+
# self.assertEqual(res.code, 400)
|
23
|
+
# self.assertEqual(res.status, "error")
|
24
|
+
# self.assertEqual(res.message, "Email in the 'reply_to' field is not valid")
|
25
|
+
#
|
26
|
+
#def test_sending_message_and_report_with_wrong_template_id(self):
|
27
|
+
# res = self.api.messages.send_message(template_id=-1, to="e@e.e", reply_to="a@a.a", from_name="me", subject="Hi")
|
28
|
+
# self.assertEqual(res.code, 400)
|
29
|
+
# self.assertEqual(res.status, "error")
|
30
|
+
# self.assertEqual(res.message, "template=-1 not found")
|
31
|
+
|
32
|
+
|
33
|
+
#TODO: complete the spec
|
34
|
+
it 'sends a single transactional message' do
|
35
|
+
message_response = PIGEON.messages.send_message 4905, ENV['TARGET_EMAIL'], ENV['TARGET_EMAIL'], "Team ExpressPigeon", "Hi there!",
|
36
|
+
:first_name => "Igor"
|
37
|
+
validate_response message_response, 200, 'success', /email queued/
|
38
|
+
report = PIGEON.messages.report(message_response.id)
|
39
|
+
report.id.should eq message_response.id
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
#
|
44
|
+
#def test_reports_with_bad_dates(self):
|
45
|
+
# res = self.api.messages.reports("abc", "")
|
46
|
+
# self.assertEquals(res.code, 400)
|
47
|
+
# self.assertEquals(res.status, "error")
|
48
|
+
# self.assertEquals(res.message, "invalid 'start_date' or 'end_date'")
|
49
|
+
#
|
50
|
+
#def test_reports_with_start_date_only(self):
|
51
|
+
# res = self.api.messages.reports("2013-03-16T11:22:23.210+0000", "")
|
52
|
+
# self.assertEquals(res.code, 400)
|
53
|
+
# self.assertEquals(res.status, "error")
|
54
|
+
# self.assertEquals(res.message, "'start_date' and 'end_date' should be provided together")
|
55
|
+
#
|
56
|
+
#def test_reports_with_end_date_only(self):
|
57
|
+
# res = self.api.messages.reports("", "2013-03-16T11:22:23.210+0000")
|
58
|
+
# self.assertEquals(res.code, 400)
|
59
|
+
# self.assertEquals(res.status, "error")
|
60
|
+
# self.assertEquals(res.message, "'start_date' and 'end_date' should be provided together")
|
61
|
+
#
|
62
|
+
#def test_sending_multiple_messages_and_get_reports(self):
|
63
|
+
# message_response = self.api.messages.send_message(template_id=self.template_id,
|
64
|
+
# to=os.environ['EXPRESSPIGEON_API_USER'],
|
65
|
+
# reply_to="a@a.a", from_name="me", subject="Hi",
|
66
|
+
# merge_fields={"first_name": "Gleb"})
|
67
|
+
# self.assertEqual(message_response.code, 200)
|
68
|
+
# self.assertEqual(message_response.status, "success")
|
69
|
+
# self.assertEqual(message_response.message, "email queued")
|
70
|
+
# self.assertTrue(message_response.id is not None and message_response.id != "")
|
71
|
+
#
|
72
|
+
# message_response_2 = self.api.messages.send_message(template_id=self.template_id,
|
73
|
+
# to=os.environ['EXPRESSPIGEON_API_USER'],
|
74
|
+
# reply_to="a@a.a", from_name="me", subject="Hi 2",
|
75
|
+
# merge_fields={"first_name": "Gleb"})
|
76
|
+
# self.assertEqual(message_response_2.code, 200)
|
77
|
+
# self.assertEqual(message_response_2.status, "success")
|
78
|
+
# self.assertEqual(message_response_2.message, "email queued")
|
79
|
+
# self.assertTrue(message_response_2.id is not None and message_response.id != "")
|
80
|
+
#
|
81
|
+
# report = self.__get_report_by_id__(message_response.id)
|
82
|
+
#
|
83
|
+
# self.assertEquals(report.id, message_response.id)
|
84
|
+
# self.assertEquals(report.email, os.environ['EXPRESSPIGEON_API_USER'])
|
85
|
+
# self.assertTrue(report.in_transit is not None)
|
86
|
+
#
|
87
|
+
# report2 = self.__get_report_by_id__(message_response_2.id)
|
88
|
+
#
|
89
|
+
# self.assertEquals(report2.id, message_response_2.id)
|
90
|
+
# self.assertEquals(report2.email, os.environ['EXPRESSPIGEON_API_USER'])
|
91
|
+
# self.assertTrue(report2.in_transit is not None)
|
92
|
+
#
|
93
|
+
it 'test_sending_multiple_messages_and_get_reports_for_today(self):' do
|
94
|
+
|
95
|
+
start = Time.now.utc - 60 # one minute ago
|
96
|
+
|
97
|
+
message_response = PIGEON.messages.send_message 4905, ENV['TARGET_EMAIL'], ENV['TARGET_EMAIL'],
|
98
|
+
'Team EP', "Hi, there!", :first_name => "Bob"
|
99
|
+
|
100
|
+
validate_response message_response, 200, 'success', /email queued/
|
101
|
+
message_response.id should_not be_nil
|
102
|
+
|
103
|
+
message_response2 = PIGEON.messages.send_message 4905, ENV['TARGET_EMAIL'], ENV['TARGET_EMAIL'],
|
104
|
+
'Team EP', "Hi, there!", :first_name => "Bob"
|
105
|
+
validate_response message_response2, 200, 'success', /email queued/
|
106
|
+
message_response2.id should_not be_nil
|
107
|
+
|
108
|
+
finish = start + 120 # two minutes after start
|
109
|
+
reports = PIGEON.messages.reports (message_response.id - 1), start, finish
|
110
|
+
|
111
|
+
reports.size.should eq 2
|
112
|
+
reports[0]['id'].should eq message_response.id
|
113
|
+
reports[1]['id'].should eq message_response2.id
|
114
|
+
|
115
|
+
reports[0]['email'].should eq ENV['TARGET_EMAIL']
|
116
|
+
reports[1]['email'].should eq ENV['TARGET_EMAIL']
|
117
|
+
end
|
118
|
+
#
|
119
|
+
#def __get_report_by_id__(self, message_id, start_date=None, end_date=None):
|
120
|
+
# reports = self.api.messages.reports() if start_date is None and end_date is None else \
|
121
|
+
# self.api.messages.reports(start_date, end_date)
|
122
|
+
# report = [r for r in reports if r.id == message_id]
|
123
|
+
# self.assertEquals(len(report), 1)
|
124
|
+
# return report[0]
|
125
|
+
|
126
|
+
|
127
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
PIGEON ||= ExpressPigeon::API
|
2
|
+
TEMPLATE_ID ||= 1
|
3
|
+
LIST_ID ||= 12
|
4
|
+
API_USER ||= "non@non.non"
|
5
|
+
DISABLED_LIST ||= 12
|
6
|
+
|
7
|
+
module PigeonSpecHelper
|
8
|
+
def validate_response res, code, status, message
|
9
|
+
res.code.should eq code
|
10
|
+
res.status.should eq status
|
11
|
+
if message
|
12
|
+
(res.message =~ message).should_not be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: expresspigeon-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- ipolevoy
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-01-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.6'
|
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: '2.6'
|
30
|
+
description: ExpressPigeon Ruby API for sending transactional messages, manipulating
|
31
|
+
lists, contacts nad more
|
32
|
+
email:
|
33
|
+
- ipolevoy@groupon.com
|
34
|
+
executables: []
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- .gitignore
|
39
|
+
- .rvmrc
|
40
|
+
- Gemfile
|
41
|
+
- Gemfile.lock
|
42
|
+
- LICENSE.txt
|
43
|
+
- README.md
|
44
|
+
- Rakefile
|
45
|
+
- expresspigeon-ruby.gemspec
|
46
|
+
- lib/expresspigeon-ruby.rb
|
47
|
+
- lib/expresspigeon-ruby/version.rb
|
48
|
+
- spec/campaigns_spec.rb
|
49
|
+
- spec/contacts_spec.rb
|
50
|
+
- spec/lists_spec.rb
|
51
|
+
- spec/messages_spec.rb
|
52
|
+
- spec/pigeon_helper.rb
|
53
|
+
homepage: https://github.com/expresspigeon/expresspigeon-ruby
|
54
|
+
licenses: []
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.8.25
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: ExpressPigeon API Ruby Wrapper
|
77
|
+
test_files:
|
78
|
+
- spec/campaigns_spec.rb
|
79
|
+
- spec/contacts_spec.rb
|
80
|
+
- spec/lists_spec.rb
|
81
|
+
- spec/messages_spec.rb
|
82
|
+
- spec/pigeon_helper.rb
|