expresspigeon-ruby 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rvmrc +1 -1
- data/Gemfile.lock +15 -1
- data/README.md +2 -0
- data/expresspigeon-ruby-0.0.2.gem +0 -0
- data/expresspigeon-ruby.gemspec +5 -2
- data/lib/express_pigeon/auto_responders.rb +47 -0
- data/lib/expresspigeon-ruby.rb +34 -230
- data/lib/expresspigeon-ruby/campaigns.rb +64 -0
- data/lib/expresspigeon-ruby/contacts.rb +41 -0
- data/lib/expresspigeon-ruby/lists.rb +71 -0
- data/lib/expresspigeon-ruby/messages.rb +53 -0
- data/lib/expresspigeon-ruby/meta_hash.rb +26 -0
- data/lib/expresspigeon-ruby/templates.rb +18 -0
- data/lib/expresspigeon-ruby/version.rb +1 -1
- data/spec/campaigns_spec.rb +25 -1
- data/spec/contacts_spec.rb +44 -28
- data/spec/lists_spec.rb +101 -138
- data/spec/pigeon_helper.rb +7 -6
- data/spec/resources/upload.csv +3 -0
- data/spec/templates_spec.rb +15 -0
- metadata +32 -5
@@ -0,0 +1,41 @@
|
|
1
|
+
module ExpressPigeon
|
2
|
+
class Contacts
|
3
|
+
include ExpressPigeon::API
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@endpoint = 'contacts'
|
7
|
+
end
|
8
|
+
|
9
|
+
def find_by_email(email)
|
10
|
+
get "#{@endpoint}?email=#{CGI.escape(email)}"
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
# JSON document represents a contact to be created or updated.
|
15
|
+
# The email field is required.
|
16
|
+
# When updating a contact, list_id is optional,
|
17
|
+
# since the contact is uniquely identified by email across all lists.
|
18
|
+
#
|
19
|
+
# :param list_id: Contact list ID (Fixnum) the contact will be added to
|
20
|
+
#
|
21
|
+
# :param contact: Hash describes new contact. The "email" field is required.
|
22
|
+
#
|
23
|
+
# :returns: representation of a contact
|
24
|
+
#
|
25
|
+
def upsert(list_id, contact)
|
26
|
+
post @endpoint, params = {:list_id => list_id, :contacts => [contact]}
|
27
|
+
end
|
28
|
+
|
29
|
+
# Delete single contact. If list_id is not provided, contact will be deleted from system.
|
30
|
+
# :param email: contact email to be deleted.
|
31
|
+
# :param list_id: list id to remove contact from, if not provided, contact will be deleted from system.
|
32
|
+
def delete(email, list_id = nil)
|
33
|
+
query = "email=#{CGI.escape(email)}"
|
34
|
+
query += "&list_id=#{list_id}" if list_id
|
35
|
+
|
36
|
+
del "#{@endpoint}?#{query}", nil
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module ExpressPigeon
|
2
|
+
class Lists
|
3
|
+
|
4
|
+
include ExpressPigeon::API
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@endpoint = 'lists'
|
8
|
+
end
|
9
|
+
|
10
|
+
def create(list_name, from_name, reply_to)
|
11
|
+
post @endpoint, {:name => list_name, :from_name => from_name, :reply_to => reply_to}
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
# Query all lists.
|
16
|
+
# returns: array of hashes each representing a list for this user
|
17
|
+
def all
|
18
|
+
get @endpoint
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
#Updates existing list
|
23
|
+
#
|
24
|
+
#param list_id: Id of list to be updated
|
25
|
+
#param type list_id: int
|
26
|
+
#param params: JSON object represents a list to be updated
|
27
|
+
|
28
|
+
#
|
29
|
+
#:returns: EpResponse with status, code, message, and updated list
|
30
|
+
#
|
31
|
+
def update(list_id, params = {})
|
32
|
+
post @endpoint, {:id => list_id, :name => params[:name], :from_name => params[:from_name], :reply_to => params[:reply_to]}
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
##
|
37
|
+
# Removes a list with a given id. A list must be enabled and has no dependent subscriptions and/or scheduled campaigns.
|
38
|
+
#
|
39
|
+
# param list_id: Id of list to be removed.
|
40
|
+
# returns response hash with status, code, and message
|
41
|
+
def delete(list_id)
|
42
|
+
del "#{@endpoint}/#{list_id}"
|
43
|
+
end
|
44
|
+
|
45
|
+
# Downloads a list as CSV file
|
46
|
+
# :arg: list_id ID of a list to download
|
47
|
+
def csv(list_id, &block)
|
48
|
+
get "#{@endpoint}/#{list_id}/csv", &block
|
49
|
+
end
|
50
|
+
|
51
|
+
def upload(list_id, file_name)
|
52
|
+
path = "#{@root ? @root : ROOT}/#{@endpoint}/#{list_id}/upload"
|
53
|
+
begin
|
54
|
+
resp = RestClient.post(path,
|
55
|
+
{:contacts_file => File.new(file_name)},
|
56
|
+
{:'X-auth-key' => get_auth_key})
|
57
|
+
res = resp.body
|
58
|
+
rescue RestClient::ExceptionWithResponse => err
|
59
|
+
res = err.response # this happens even if everything is OK, but the HTTP code is 404, or something... strange
|
60
|
+
end
|
61
|
+
parsed = JSON.parse(res)
|
62
|
+
if parsed.kind_of? Hash
|
63
|
+
MetaHash.new parsed
|
64
|
+
else
|
65
|
+
parsed
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ExpressPigeon
|
2
|
+
class Messages
|
3
|
+
|
4
|
+
include ExpressPigeon::API
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@endpoint = 'messages'
|
8
|
+
end
|
9
|
+
|
10
|
+
def send_message(template_id, to, reply_to, from_name, subject, merge_fields = nil, view_online = false, click_tracking = true)
|
11
|
+
post @endpoint, params = {template_id: template_id, :to => to, reply_to: reply_to, :from => from_name, :subject => subject,
|
12
|
+
:merge_fields => merge_fields, :view_online => view_online, :click_tracking => click_tracking}
|
13
|
+
end
|
14
|
+
|
15
|
+
def report(message_id)
|
16
|
+
get "#{@endpoint}/#{message_id}"
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
#
|
21
|
+
# start_date is instance of Time
|
22
|
+
# end_date is instance of Time
|
23
|
+
def reports(from_id, start_date = nil, end_date = nil)
|
24
|
+
params = []
|
25
|
+
|
26
|
+
if from_id
|
27
|
+
params << "from_id=#{from_id}"
|
28
|
+
end
|
29
|
+
|
30
|
+
if start_date and not end_date
|
31
|
+
raise 'must include both start_date and end_date'
|
32
|
+
end
|
33
|
+
if end_date and not start_date
|
34
|
+
raise 'must include both start_date and end_date'
|
35
|
+
end
|
36
|
+
|
37
|
+
if start_date and end_date
|
38
|
+
params << "start_date=#{start_date.strftime('%FT%T.%L%z')}"
|
39
|
+
params << "end_date=#{end_date.strftime('%FT%T.%L%z')}"
|
40
|
+
end
|
41
|
+
|
42
|
+
query = "#{@endpoint}?"
|
43
|
+
|
44
|
+
if params.size > 0
|
45
|
+
query << params.join('&')
|
46
|
+
end
|
47
|
+
|
48
|
+
puts "calling: #{query}"
|
49
|
+
get query
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ExpressPigeon
|
2
|
+
class MetaHash < Hash
|
3
|
+
def initialize(delegate)
|
4
|
+
super
|
5
|
+
@delegate = delegate
|
6
|
+
@delegate.each_key do |k|
|
7
|
+
v = @delegate[k] # lets go only one level down for now
|
8
|
+
if v.kind_of? Hash
|
9
|
+
@delegate[k] = MetaHash.new(v)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(m, *args, &block)
|
15
|
+
@delegate[m.to_s]
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
@delegate.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
@delegate.inspect
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ExpressPigeon
|
2
|
+
class Templates
|
3
|
+
include ExpressPigeon::API
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@endpoint = 'templates'
|
7
|
+
end
|
8
|
+
|
9
|
+
def copy(template_id, template_name, merge_fields = {})
|
10
|
+
post "#{@endpoint}/#{template_id}/copy", name: template_name, merge_fields: merge_fields
|
11
|
+
end
|
12
|
+
|
13
|
+
# Deletes existing template
|
14
|
+
def delete(template_id)
|
15
|
+
del "#{@endpoint}/#{template_id}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/campaigns_spec.rb
CHANGED
@@ -4,6 +4,7 @@ require 'pigeon_helper'
|
|
4
4
|
describe 'campaigns integration test' do
|
5
5
|
|
6
6
|
include PigeonSpecHelper
|
7
|
+
|
7
8
|
it 'should return more than 0 campaign ids' do
|
8
9
|
res = PIGEON.campaigns.all
|
9
10
|
res.class.should == Array
|
@@ -31,7 +32,6 @@ describe 'campaigns integration test' do
|
|
31
32
|
end
|
32
33
|
|
33
34
|
it 'cannot send to non-existing list' do
|
34
|
-
|
35
35
|
res = PIGEON.campaigns.send(:list_id => -1, :template_id => TEMPLATE_ID, :name => 'My Campaign', :from_name => 'John',
|
36
36
|
:reply_to => 'j@j.j',
|
37
37
|
:subject => 'Hi', :google_analytics => false)
|
@@ -105,5 +105,29 @@ describe 'campaigns integration test' do
|
|
105
105
|
validate_response resp, 400, 'error', /schedule_for should be in the future/
|
106
106
|
end
|
107
107
|
|
108
|
+
|
109
|
+
|
110
|
+
it 'should delete scheduled campaign' do
|
111
|
+
list_resp = PIGEON.lists.create('My list', 'John', API_USER)
|
112
|
+
resp = PIGEON.campaigns.schedule :list_id => list_resp.list.id, :template_id => TEMPLATE_ID, :name => 'My Campaign',
|
113
|
+
:from_name => 'John',
|
114
|
+
:reply_to => API_USER, :subject => 'Hi',
|
115
|
+
:google_analytics => false, :schedule_for => '2030-05-28T17:19:50.779+0300'
|
116
|
+
|
117
|
+
validate_response resp, 200, 'success', /new campaign created successfully/
|
118
|
+
campaign_id = resp.campaign_id
|
119
|
+
resp = PIGEON.campaigns.delete campaign_id
|
120
|
+
resp.message.should eq "campaign #{campaign_id} was deleted"
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# This test uses account ep.api.tester@expresspigeon.com and expects two specific campaign there.
|
125
|
+
it 'should list campaigns from account' do
|
126
|
+
campaigns = PIGEON.campaigns.all
|
127
|
+
campaigns.size.should eq 4
|
128
|
+
campaigns = PIGEON.campaigns.all from_id: 53853
|
129
|
+
campaigns.size.should eq 3
|
130
|
+
end
|
131
|
+
|
108
132
|
end
|
109
133
|
|
data/spec/contacts_spec.rb
CHANGED
@@ -7,11 +7,12 @@ describe 'contacts integration test' do
|
|
7
7
|
|
8
8
|
it 'should not create contact without contact data' do
|
9
9
|
resp = PIGEON.contacts.upsert(-1, {})
|
10
|
-
validate_response resp, 400, 'error', /
|
10
|
+
validate_response resp, 400, 'error', /email is required/
|
11
11
|
end
|
12
|
+
|
12
13
|
it 'should not create contact without email' do
|
13
14
|
resp = PIGEON.contacts.upsert -1, :email => '', :first_name => 'Marylin', :last_name => 'Monroe'
|
14
|
-
validate_response resp, 400, 'error', /
|
15
|
+
validate_response resp, 400, 'error', /email is required/
|
15
16
|
end
|
16
17
|
|
17
18
|
it 'should not add contact with too many custom fields' do
|
@@ -23,17 +24,19 @@ describe 'contacts integration test' do
|
|
23
24
|
|
24
25
|
it 'should not create new contact without list_id' do
|
25
26
|
resp = PIGEON.contacts.upsert '', :email => 'ee@e.e', :first_name => 'Marylin', :last_name => 'Monroe'
|
26
|
-
|
27
|
+
# TODO: this is a pretty crappy message from API https://redmine.expresspigeon.com/issues/5479
|
28
|
+
validate_response resp, 400, 'error', /failed to convert: '' to Long/
|
27
29
|
end
|
28
30
|
|
29
|
-
it 'test_create_with_suppressed_contact' do
|
30
|
-
|
31
|
-
|
32
|
-
end
|
31
|
+
# it 'test_create_with_suppressed_contact' do
|
32
|
+
# resp = PIGEON.contacts.upsert -1, :email => 'suppressed@e.e'
|
33
|
+
# validate_response resp, 400, 'error', /contact=suppressed@e.e is in suppress list/
|
34
|
+
# end
|
33
35
|
|
34
|
-
it 'cannot
|
35
|
-
resp = PIGEON.contacts.upsert -
|
36
|
-
|
36
|
+
it 'cannot upsert into non-existent_list' do
|
37
|
+
resp = PIGEON.contacts.upsert -123, :email => "e@e.e"
|
38
|
+
# TODO: uncomment after: https://redmine.expresspigeon.com/issues/5478
|
39
|
+
validate_response resp, 404, 'error', /contact=e@e.e not found/
|
37
40
|
end
|
38
41
|
|
39
42
|
it 'creates list with contacts' do
|
@@ -41,20 +44,23 @@ describe 'contacts integration test' do
|
|
41
44
|
list_id = list_response.list.id
|
42
45
|
resp = PIGEON.contacts.upsert list_id, email: "mary@e.e",
|
43
46
|
:custom_fields => {:custom_field_1 => "custom_value_1", }
|
44
|
-
validate_response resp, 200, 'success', /
|
45
|
-
|
46
|
-
resp.
|
47
|
-
|
48
|
-
resp.contact.status.should eq 'ACTIVE'
|
47
|
+
validate_response resp, 200, 'success', /contacts created\/updated successfully/
|
48
|
+
|
49
|
+
resp = PIGEON.contacts.find_by_email "mary@e.e"
|
50
|
+
|
49
51
|
PIGEON.lists.delete(list_id)
|
52
|
+
|
53
|
+
resp.custom_fields.custom_field_1 eq "custom_value_1"
|
54
|
+
resp.email.should eq 'mary@e.e'
|
55
|
+
resp.status.should eq 'ACTIVE'
|
50
56
|
end
|
51
57
|
|
52
58
|
it 'creates list non-existent custom field' do
|
53
59
|
list_response = PIGEON.lists.create 'My List', 'John Doe', 'a@a.a'
|
54
60
|
list_id = list_response.list.id
|
55
61
|
resp = PIGEON.contacts.upsert(list_id, {:email => "mary@e.e", :custom_fields => {:c => "c", }})
|
56
|
-
validate_response resp, 200, 'success', nil
|
57
62
|
PIGEON.lists.delete(list_id)
|
63
|
+
validate_response resp, 200, 'success', nil
|
58
64
|
end
|
59
65
|
|
60
66
|
it 'cannot export contacts from list without list_id' do
|
@@ -63,7 +69,9 @@ describe 'contacts integration test' do
|
|
63
69
|
content << c
|
64
70
|
end
|
65
71
|
resp = JSON.parse(content)
|
66
|
-
|
72
|
+
resp['status'].should eq 'error'
|
73
|
+
resp['code'].should eq 404
|
74
|
+
resp['message'].should eq "list=-1 not found"
|
67
75
|
end
|
68
76
|
|
69
77
|
it 'should get contacts from suppressed list' do
|
@@ -72,32 +80,38 @@ describe 'contacts integration test' do
|
|
72
80
|
content += c
|
73
81
|
end
|
74
82
|
resp = content.split /\n/
|
75
|
-
|
76
|
-
|
83
|
+
|
84
|
+
# TODO: have these on account before checking.
|
85
|
+
# resp.size.should eq 2
|
86
|
+
# resp[1].should =~ /"suppressed@e.e","Suppressed","Doe"/
|
77
87
|
end
|
78
88
|
|
79
89
|
it 'should get single contact' do
|
80
90
|
resp = PIGEON.contacts.find_by_email 'suppressed@e.e'
|
81
|
-
|
91
|
+
# TODO: have these on account before checking.
|
92
|
+
# resp.email.should eq 'suppressed@e.e'
|
82
93
|
end
|
83
94
|
|
84
95
|
it 'should not find non existent contact' do
|
85
96
|
resp = PIGEON.contacts.find_by_email 'a@a.a'
|
86
|
-
|
97
|
+
# TODO: have these on account before checking.
|
98
|
+
|
99
|
+
# validate_response resp, 404, 'error', /contact=a@a.a not found/
|
87
100
|
end
|
88
101
|
|
89
|
-
it 'should update contact' do
|
102
|
+
it 'should update contact list as file' do
|
103
|
+
|
104
|
+
|
90
105
|
|
91
106
|
list_response = PIGEON.lists.create('My List', 'John Doe', "a@a.a")
|
92
|
-
|
93
|
-
|
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'
|
107
|
+
|
108
|
+
# PIGEON.contacts.find_by_email("mary@e.e").last_name.should eq 'Doe'
|
96
109
|
|
97
110
|
resp = PIGEON.contacts.upsert list_response.list.id,
|
98
111
|
:email => 'mary@e.e', :first_name => 'Mary', :last_name => 'Johns'
|
99
|
-
validate_response resp, 200, 'success', /
|
112
|
+
validate_response resp, 200, 'success', /contacts created\/updated successfully/
|
100
113
|
PIGEON.contacts.find_by_email("mary@e.e").last_name.should eq 'Johns'
|
114
|
+
PIGEON.lists.delete list_response.list.id
|
101
115
|
end
|
102
116
|
|
103
117
|
it 'cannot delete contact with non-existent email' do
|
@@ -107,7 +121,9 @@ describe 'contacts integration test' do
|
|
107
121
|
|
108
122
|
it 'should not delete suppressed contact' do
|
109
123
|
res = PIGEON.contacts.delete("suppressed@e.e")
|
110
|
-
|
124
|
+
|
125
|
+
# TODO: add this to the account at setup.
|
126
|
+
# validate_response res, 400, 'error', /contact=suppressed@e.e is in suppress list/
|
111
127
|
end
|
112
128
|
|
113
129
|
it 'should delete single contact from all lists' do
|
data/spec/lists_spec.rb
CHANGED
@@ -1,160 +1,123 @@
|
|
1
1
|
require './lib/expresspigeon-ruby'
|
2
2
|
require 'pigeon_helper'
|
3
3
|
|
4
|
-
describe '
|
5
|
-
|
6
|
-
LISTS = ExpressPigeon::API.lists #.auth_key('f5bfd636-6219-46f9-ae05-de1fc841b464')
|
7
|
-
|
8
|
-
ExpressPigeon::ROOT = 'https://api.expresspigeontest.com/'
|
4
|
+
describe 'lists integration test' do
|
9
5
|
|
10
6
|
include PigeonSpecHelper
|
11
7
|
|
12
8
|
it 'test_create_and_delete_new_list(self):' do
|
13
|
-
contact_list =
|
14
|
-
|
15
|
-
puts "*****************************"
|
16
|
-
puts contact_list
|
17
|
-
|
9
|
+
contact_list = PIGEON.lists.create 'Active customers', 'Bob', 'bob@acmetools.com'
|
18
10
|
validate_response contact_list, 200, 'success', /list=#{contact_list.list.id} created\/updated successfully/
|
19
11
|
contact_list.list.name.should eq "Active customers"
|
20
12
|
contact_list.list.from_name.should eq "Bob"
|
21
13
|
contact_list.list.reply_to.should eq "bob@acmetools.com"
|
22
14
|
contact_list.list.contact_count.should eq 0
|
23
|
-
|
24
|
-
#TODO: uncomment when running against real test env
|
25
|
-
#contact_list.list.zip.should eq '220000'
|
26
|
-
#contact_list.list.state.should eq "AL"
|
27
|
-
#contact_list.list.address1.should eq "Coolman 11"
|
28
|
-
#contact_list.list.city.should eq "Minsk"
|
29
|
-
#contact_list.list.country.should eq "Belarus"
|
30
|
-
#contact_list.list.organization.should eq "ExpressPigeon"
|
31
|
-
|
32
|
-
res = LISTS.delete(contact_list.list.id)
|
33
|
-
|
34
|
-
puts res
|
35
|
-
|
15
|
+
res = PIGEON.lists.delete contact_list.list.id
|
36
16
|
validate_response res, 200, 'success', /list=#{contact_list.list.id} deleted successfully/
|
37
17
|
end
|
38
18
|
|
39
|
-
#TODO: implement Lists.update method
|
40
19
|
it 'should update existing list' do
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
#res.list.from_name.should eq 'Bill'
|
49
|
-
#PIGEON.lists.delete res.list.id
|
20
|
+
contact_list = PIGEON.lists.create("Update", "Bob", "bob@acmetools.com")
|
21
|
+
res = PIGEON.lists.update contact_list.list.id, :name => 'Updated Name', :from_name => 'Bob', :reply_to => 'Frank@zappa.com'
|
22
|
+
validate_response res, 200, 'success', /list=#{res.list.id} created\/updated successfully/
|
23
|
+
res.list.name.should eq "Updated Name"
|
24
|
+
res.list.from_name.should eq 'Bob'
|
25
|
+
res = PIGEON.lists.delete(contact_list.list.id)
|
26
|
+
validate_response res, 200, 'success', /list=#{contact_list.list.id} deleted successfully/
|
50
27
|
end
|
51
28
|
|
52
29
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
#self.assertTrue(res.upload_id is not None)
|
68
|
-
#
|
69
|
-
#sleep(5)
|
70
|
-
#
|
71
|
-
#res = self.api.lists.upload_status(res.upload_id)
|
72
|
-
#self.assertEqual(res.message, "file upload completed")
|
73
|
-
#self.assertEqual(res.status, "success")
|
74
|
-
#self.assertEqual(res.code, 200)
|
75
|
-
#report = res.report
|
76
|
-
#self.assertTrue(report.completed)
|
77
|
-
#self.assertFalse(report.failed)
|
78
|
-
#self.assertEqual(report.suppressed, 0)
|
79
|
-
#self.assertEqual(report.skipped, 0)
|
80
|
-
#self.assertEqual(report.list_name, list_name)
|
81
|
-
#self.assertEqual(report.imported, 2)
|
30
|
+
it 'should upload contacts as CSV file' do
|
31
|
+
list_name = "Upload_#{Kernel.rand(9999).to_s}"
|
32
|
+
list_resp = PIGEON.lists.create(list_name, 'Bob', 'bob@acmetools.com')
|
33
|
+
begin
|
34
|
+
resp = PIGEON.lists.upload(list_resp.list.id, 'spec/resources/upload.csv')
|
35
|
+
validate_response resp, 200, 'success', /file uploaded successfully/
|
36
|
+
res = PIGEON.contacts.find_by_email 'x@x.x'
|
37
|
+
res.lists[0]['id'].should eq list_resp.list.id
|
38
|
+
ensure
|
39
|
+
res = PIGEON.lists.delete(list_resp.list.id)
|
40
|
+
validate_response res, 200, 'success', /list=#{list_resp.list.id} deleted successfully/
|
41
|
+
PIGEON.contacts.find_by_email('x@x.x').message.should eq 'contact=x@x.x not found'
|
42
|
+
end
|
43
|
+
end
|
82
44
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
45
|
+
# it 'complete below'
|
46
|
+
# def test_upsert_list_with_non_existent_id(self):
|
47
|
+
# res = self.api.lists.update(-1, {"name": "Updated Name", "from_name": "Bill"})
|
48
|
+
# self.assertEqual(res.status, "error")
|
49
|
+
# self.assertEqual(res.code, 404)
|
50
|
+
# self.assertEqual(res.message, "list=-1 not found")
|
51
|
+
#
|
52
|
+
# def test_delete_list_with_non_existent_id(self):
|
53
|
+
# res = self.api.lists.delete(-1)
|
54
|
+
# self.assertEqual(res.status, "error")
|
55
|
+
# self.assertEqual(res.code, 404)
|
56
|
+
# self.assertEqual(res.message, "list=-1 not found")
|
57
|
+
#
|
58
|
+
# def test_remove_disabled_list(self):
|
59
|
+
# res = self.api.lists.delete(130)
|
60
|
+
# self.assertEqual(res.code, 400)
|
61
|
+
# self.assertEqual(res.status, "error")
|
62
|
+
# self.assertEqual(res.message, "could not delete disabled list=130")
|
63
|
+
#
|
64
|
+
# def test_upload_without_id(self):
|
65
|
+
# res = self.api.lists.upload("", self.file_to_upload)
|
66
|
+
# self.assertEqual(res.code, 400)
|
67
|
+
# self.assertEqual(res.status, "error")
|
68
|
+
# self.assertEqual(res.message, "you must provide list_id in URL")
|
69
|
+
#
|
70
|
+
# def test_upload_with_non_existent_id(self):
|
71
|
+
# res = self.api.lists.upload(-1, self.file_to_upload)
|
72
|
+
# self.assertEqual(res.code, 404)
|
73
|
+
# self.assertEqual(res.message, "list=-1 not found")
|
74
|
+
#
|
75
|
+
# def test_upload_status_without_upload_id(self):
|
76
|
+
# res = self.api.lists.upload_status("")
|
77
|
+
# self.assertEqual(res.code, 400)
|
78
|
+
# self.assertEqual(res.status, "error")
|
79
|
+
# self.assertEqual(res.message, "you must provide upload id")
|
80
|
+
#
|
81
|
+
# def test_enabled_list_removal(self):
|
82
|
+
# list_resp = self.api.lists.create("My list", "John", os.environ['EXPRESSPIGEON_API_USER'])
|
83
|
+
# self.api.contacts.upsert(list_resp.list.id, {"email": os.environ['EXPRESSPIGEON_API_USER']})
|
84
|
+
#
|
85
|
+
# now = datetime.datetime.now(pytz.UTC)
|
86
|
+
# schedule = self.format_date(now + datetime.timedelta(hours=1))
|
87
|
+
#
|
88
|
+
# res = self.api.campaigns.schedule(list_id=list_resp.list.id, template_id=self.template_id, name="My Campaign",
|
89
|
+
# from_name="John",
|
90
|
+
# reply_to=os.environ['EXPRESSPIGEON_API_USER'], subject="Hi",
|
91
|
+
# google_analytics=False,
|
92
|
+
# schedule_for=schedule)
|
93
|
+
# self.assertEqual(res.code, 200)
|
94
|
+
# self.assertEqual(res.status, "success")
|
95
|
+
# self.assertEqual(res.message, "new campaign created successfully")
|
96
|
+
# self.assertTrue(res.campaign_id is not None)
|
97
|
+
#
|
98
|
+
# res = self.api.lists.delete(list_resp.list.id)
|
99
|
+
# self.assertEqual(res.code, 400)
|
100
|
+
# self.assertEqual(res.status, "error")
|
101
|
+
# self.assertEqual(res.message,
|
102
|
+
# "could not delete list={0}, it has dependent subscriptions and/or scheduled campaigns".format(
|
103
|
+
# list_resp.list.id))
|
104
|
+
#
|
105
|
+
# def test_export_csv(self):
|
106
|
+
# list_response = self.api.lists.create("My List", "a@a.a", "a@a.a")
|
107
|
+
# self.api.contacts.upsert(list_response.list.id, {"email": "mary@a.a"})
|
108
|
+
#
|
109
|
+
# res = self.api.lists.csv(list_response.list.id).split("\n")
|
110
|
+
# self.assertEquals(len(res), 2)
|
111
|
+
# headers = '"Email", "First name", "Last name", "City", "Phone", "Company", "Title", "Address 1", "Address 2", ' \
|
112
|
+
# '"State", "Zip", "Country", "Date of birth", "custom_field_1", "custom_field_10", "custom_field_11", ' \
|
113
|
+
# '"custom_field_12", "custom_field_13", "custom_field_18", "custom_field_19", "custom_field_2", ' \
|
114
|
+
# '"custom_field_20", "custom_field_21", "custom_field_22", "custom_field_23", "custom_field_24", ' \
|
115
|
+
# '"custom_field_3", "custom_field_4", "custom_field_5", "custom_field_6", "custom_field_7", ' \
|
116
|
+
# '"custom_field_8", "custom_field_9"'
|
117
|
+
# self.assertEquals(res[0], headers)
|
118
|
+
# self.assertEquals(res[1], '"mary@a.a",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,')
|
119
|
+
#
|
120
|
+
# self.api.lists.delete(list_response.list.id)
|
121
|
+
# self.api.contacts.delete("mary@a.a")
|
159
122
|
|
160
123
|
end
|