interspire 0.1.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/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +13 -0
- data/README.md +31 -0
- data/Rakefile +6 -0
- data/bin/interspire +6 -0
- data/interspire.gemspec +25 -0
- data/lib/interspire.rb +8 -0
- data/lib/interspire/api.rb +222 -0
- data/lib/interspire/contact_list.rb +24 -0
- data/lib/interspire/interspire_exception.rb +4 -0
- data/lib/interspire/subscriber.rb +12 -0
- data/spec/fixtures/add_subscriber.xml +5 -0
- data/spec/fixtures/authenticated.xml +8 -0
- data/spec/fixtures/delete_subscriber.xml +5 -0
- data/spec/fixtures/in_contact_list.xml +5 -0
- data/spec/fixtures/lists.xml +63 -0
- data/spec/fixtures/not_authenticated.xml +5 -0
- data/spec/fixtures/not_in_contact_list.xml +5 -0
- data/spec/fixtures/subscribers.xml +29 -0
- data/spec/interspire/api_spec.rb +84 -0
- data/spec/interspire/contact_list_spec.rb +25 -0
- data/spec/spec_helper.rb +10 -0
- metadata +131 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
2
|
+
Version 2, December 2004
|
3
|
+
|
4
|
+
Copyright (C) 2013 Dale Campbell <oshuma@gmail.com>
|
5
|
+
|
6
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
7
|
+
copies of this license document, and changing it is allowed as long
|
8
|
+
as the name is changed.
|
9
|
+
|
10
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
11
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
12
|
+
|
13
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Interspire
|
2
|
+
|
3
|
+
Ruby library for the {http://www.interspire.com/ Interspire} API ({https://www.interspire.com/support/kb/questions/1224/Email+Marketer+XML+API+Documentation pdf}).
|
4
|
+
|
5
|
+
See the {Interspire::API} class for detailed documentation.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'interspire'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install interspire
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/interspire
ADDED
data/interspire.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'interspire'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "interspire"
|
8
|
+
gem.version = Interspire::VERSION
|
9
|
+
gem.authors = ["Dale Campbell"]
|
10
|
+
gem.email = ["oshuma@gmail.com"]
|
11
|
+
gem.description = %q{Ruby library for the Interspire API.}
|
12
|
+
gem.summary = %q{Ruby library for the Interspire API.}
|
13
|
+
gem.homepage = "https://github.com/Oshuma/interspire"
|
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
|
+
|
20
|
+
gem.add_runtime_dependency 'nokogiri'
|
21
|
+
|
22
|
+
gem.add_development_dependency 'rspec'
|
23
|
+
gem.add_development_dependency 'webmock'
|
24
|
+
gem.add_development_dependency 'yard'
|
25
|
+
end
|
data/lib/interspire.rb
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
module Interspire
|
5
|
+
class API
|
6
|
+
|
7
|
+
# @param api_url [String] The XML API of your Interspire installation; ex. http://example.com/xml.php
|
8
|
+
# @param user [String] The Interspire user's login name.
|
9
|
+
# @param token [String] The Interspire user's API token.
|
10
|
+
#
|
11
|
+
# @return [Inter::API] An instance of the Interspire API for the given parameters.
|
12
|
+
def initialize(api_url, user, token)
|
13
|
+
@api_url = api_url
|
14
|
+
@user = user
|
15
|
+
@token = token
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param list_id [Integer] The id of the contact list.
|
19
|
+
# @param email [String] The subscriber's email address.
|
20
|
+
# @param confirmed [boolean] (optional) +true+ if the subscriber should be set as confirmed; defaults to +false+.
|
21
|
+
# @param format [String] (optional) The email format; either +html+ or +text+; defaults to +html+.
|
22
|
+
#
|
23
|
+
# @return [Integer] Returns the subscriber's ID upon success.
|
24
|
+
def add_subscriber(list_id, email, confirmed = false, format = 'html')
|
25
|
+
xml = %Q[
|
26
|
+
<xmlrequest>
|
27
|
+
<username>#{@user}</username>
|
28
|
+
<usertoken>#{@token}</usertoken>
|
29
|
+
<requesttype>subscribers</requesttype>
|
30
|
+
<requestmethod>AddSubscriberToList</requestmethod>
|
31
|
+
<details>
|
32
|
+
<emailaddress>#{email}</emailaddress>
|
33
|
+
<mailinglist>#{list_id}</mailinglist>
|
34
|
+
<format>#{format}</format>
|
35
|
+
<confirmed>#{confirmed}</confirmed>
|
36
|
+
</details>
|
37
|
+
</xmlrequest>
|
38
|
+
]
|
39
|
+
|
40
|
+
response = get_response(xml)
|
41
|
+
|
42
|
+
if success?(response)
|
43
|
+
response.xpath('response/data').first.content.to_i
|
44
|
+
else
|
45
|
+
error!(response)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [boolean] Returns +true+ if the user is authenticated.
|
50
|
+
def authenticated?
|
51
|
+
xml = %Q[
|
52
|
+
<xmlrequest>
|
53
|
+
<username>#{@user}</username>
|
54
|
+
<usertoken>#{@token}</usertoken>
|
55
|
+
<requesttype>authentication</requesttype>
|
56
|
+
<requestmethod>xmlapitest</requestmethod>
|
57
|
+
<details>
|
58
|
+
</details>
|
59
|
+
</xmlrequest>
|
60
|
+
]
|
61
|
+
|
62
|
+
response = get_response(xml)
|
63
|
+
success?(response)
|
64
|
+
end
|
65
|
+
|
66
|
+
# @param list_id [Integer] The id of the contact list.
|
67
|
+
# @param email [String] The subscriber's email address.
|
68
|
+
#
|
69
|
+
# @return [boolean] Returns +true+ upon success or raises an {Interspire::InterspireException} on failure.
|
70
|
+
def delete_subscriber(list_id, email)
|
71
|
+
xml = %Q[
|
72
|
+
<xmlrequest>
|
73
|
+
<username>#{@user}</username>
|
74
|
+
<usertoken>#{@token}</usertoken>
|
75
|
+
<requesttype>subscribers</requesttype>
|
76
|
+
<requestmethod>DeleteSubscriber</requestmethod>
|
77
|
+
<details>
|
78
|
+
<list>#{list_id}</list>
|
79
|
+
<emailaddress>#{email}</emailaddress>
|
80
|
+
</details>
|
81
|
+
</xmlrequest>
|
82
|
+
]
|
83
|
+
|
84
|
+
response = get_response(xml)
|
85
|
+
success?(response) ? true : error!(response)
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [Array] An Array of {Interspire::ContactList} objects.
|
89
|
+
def get_lists
|
90
|
+
xml = %Q[
|
91
|
+
<xmlrequest>
|
92
|
+
<username>#{@user}</username>
|
93
|
+
<usertoken>#{@token}</usertoken>
|
94
|
+
<requesttype>user</requesttype>
|
95
|
+
<requestmethod>GetLists</requestmethod>
|
96
|
+
<details>
|
97
|
+
</details>
|
98
|
+
</xmlrequest>
|
99
|
+
]
|
100
|
+
|
101
|
+
response = get_response(xml)
|
102
|
+
|
103
|
+
if success?(response)
|
104
|
+
lists = []
|
105
|
+
response.xpath('response/data/item').each do |list|
|
106
|
+
lists << Interspire::ContactList.new({
|
107
|
+
id: list.xpath('listid').first.content,
|
108
|
+
name: list.xpath('name').first.content,
|
109
|
+
subscribe_count: list.xpath('subscribecount').first.content,
|
110
|
+
unsubscribe_count: list.xpath('unsubscribecount').first.content,
|
111
|
+
auto_responder_count: list.xpath('autorespondercount').first.content,
|
112
|
+
})
|
113
|
+
end
|
114
|
+
|
115
|
+
lists
|
116
|
+
else
|
117
|
+
error!(response)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# @param list_id [Integer] The ID of the contact list.
|
122
|
+
# @param email [String] The domain (including '@') of subscribers to filter by; ex. '@example.com' would only return subscribers like 'foo@example.com'; defaults to an empty String (returns all subscribers).
|
123
|
+
#
|
124
|
+
# @return [Hash] A Hash containing a +:count+ key and a +:subscribers+ Array with {Interspire::Subscriber} objects.
|
125
|
+
def get_subscribers(list_id, email = '')
|
126
|
+
xml = %Q[
|
127
|
+
<xmlrequest>
|
128
|
+
<username>#{@user}</username>
|
129
|
+
<usertoken>#{@token}</usertoken>
|
130
|
+
<requesttype>subscribers</requesttype>
|
131
|
+
<requestmethod>GetSubscribers</requestmethod>
|
132
|
+
<details>
|
133
|
+
<searchinfo>
|
134
|
+
<List>#{list_id}</List>
|
135
|
+
<Email>#{email}</Email>
|
136
|
+
</searchinfo>
|
137
|
+
</details>
|
138
|
+
</xmlrequest>
|
139
|
+
]
|
140
|
+
|
141
|
+
response = get_response(xml)
|
142
|
+
|
143
|
+
if success?(response)
|
144
|
+
subscribers = {}
|
145
|
+
subscribers[:count] = response.xpath('response/data/count').first.content
|
146
|
+
subscribers[:subscribers] = []
|
147
|
+
|
148
|
+
response.xpath('response/data').each do |data|
|
149
|
+
data.xpath('subscriberlist/item').each do |item|
|
150
|
+
id = item.xpath('subscriberid').first.content.to_i
|
151
|
+
email = item.xpath('emailaddress').first.content
|
152
|
+
subscribers[:subscribers] << Interspire::Subscriber.new(id, email)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
subscribers
|
157
|
+
else
|
158
|
+
error!(response)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# @param list_id [Integer] The ID of the contact list.
|
163
|
+
# @param email [String] The subscriber's email address.
|
164
|
+
#
|
165
|
+
# @return [boolean] +true+ or +false+ if the +email+ is on the given contact list.
|
166
|
+
def in_contact_list?(list_id, email)
|
167
|
+
xml = %Q[
|
168
|
+
<xmlrequest>
|
169
|
+
<username>#{@user}</username>
|
170
|
+
<usertoken>#{@token}</usertoken>
|
171
|
+
<requesttype>subscribers</requesttype>
|
172
|
+
<requestmethod>IsSubscriberOnList</requestmethod>
|
173
|
+
<details>
|
174
|
+
<emailaddress>#{email}</emailaddress>
|
175
|
+
<listids>#{list_id}</listids>
|
176
|
+
</details>
|
177
|
+
</xmlrequest>
|
178
|
+
]
|
179
|
+
|
180
|
+
response = get_response(xml)
|
181
|
+
|
182
|
+
if success?(response)
|
183
|
+
# The 'data' element will contain the subscriber ID.
|
184
|
+
! response.xpath('response/data').first.content.empty?
|
185
|
+
else
|
186
|
+
false
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
# @param xml [String] A String containing the XML request.
|
193
|
+
#
|
194
|
+
# @return [Nokogiri::Document] A +Nokogiri::Document+ build from the API response.
|
195
|
+
def get_response(xml)
|
196
|
+
url = URI.parse(@api_url)
|
197
|
+
request = Net::HTTP::Post.new(url.path)
|
198
|
+
request.body = xml
|
199
|
+
|
200
|
+
response = Net::HTTP.new(url.host, url.port).start { |http| http.request(request) }
|
201
|
+
|
202
|
+
Nokogiri::XML.parse(response.body)
|
203
|
+
end
|
204
|
+
|
205
|
+
# @param response [Nokogiri::Document] A +Nokogiri::Document+ parsed from the API response.
|
206
|
+
#
|
207
|
+
# @return [boolean] +true+ or +false+ if the +response+ was a success.
|
208
|
+
def success?(response)
|
209
|
+
response.xpath('response/status').first.content == 'SUCCESS'
|
210
|
+
end
|
211
|
+
|
212
|
+
# Raises an {Interspire::InterspireException} with details from the API +response+.
|
213
|
+
#
|
214
|
+
# @param response [Nokogiri::Document] A +Nokogiri::Document+ parsed from the API response.
|
215
|
+
def error!(response)
|
216
|
+
type = response.xpath('response/status').first.content
|
217
|
+
error = response.xpath('response/errormessage').first.content
|
218
|
+
raise InterspireException, "#{type}: #{error.empty? ? 'No error message given.' : error}"
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Interspire
|
2
|
+
class ContactList
|
3
|
+
attr_reader :id, :name, :subscribe_count, :unsubscribe_count, :auto_responder_count
|
4
|
+
|
5
|
+
# Instantiate with hash of contact list details that should look like this:
|
6
|
+
#
|
7
|
+
# {
|
8
|
+
# :id => '42', # Contact list ID.
|
9
|
+
# :name => 'Serious Contacts',
|
10
|
+
# :subscribe_count => '6420',
|
11
|
+
# :unsubscribe_count => '421',
|
12
|
+
# :auto_responder_count => '124'
|
13
|
+
# }
|
14
|
+
#
|
15
|
+
# @param details [Hash] A hash of contact list info.
|
16
|
+
def initialize(details)
|
17
|
+
@id = details[:id]
|
18
|
+
@name = details[:name]
|
19
|
+
@subscribe_count = details[:subscribe_count]
|
20
|
+
@unsubscribe_count = details[:unsubscribe_count]
|
21
|
+
@auto_responder_count = details[:auto_responder_count]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
2
|
+
<response>
|
3
|
+
<status>SUCCESS</status>
|
4
|
+
<data>
|
5
|
+
<item>
|
6
|
+
<listid>7</listid>
|
7
|
+
<name>Neighborhood Newsletter</name>
|
8
|
+
<ownername>Jane Doe</ownername>
|
9
|
+
<owneremail>jane.doe@example.com</owneremail>
|
10
|
+
<bounceemail>jane.doe@example.com</bounceemail>
|
11
|
+
<replytoemail>jane.doe@example.com</replytoemail>
|
12
|
+
<bounceserver></bounceserver>
|
13
|
+
<bounceusername></bounceusername>
|
14
|
+
<bouncepassword></bouncepassword>
|
15
|
+
<extramailsettings></extramailsettings>
|
16
|
+
<companyname>ExampleCorp</companyname>
|
17
|
+
<companyaddress>123 Main St, Anytown, FL 30635</companyaddress>
|
18
|
+
<companyphone></companyphone>
|
19
|
+
<format>b</format>
|
20
|
+
<notifyowner>1</notifyowner>
|
21
|
+
<imapaccount>0</imapaccount>
|
22
|
+
<createdate>1348502776</createdate>
|
23
|
+
<subscribecount>666</subscribecount>
|
24
|
+
<unsubscribecount>4</unsubscribecount>
|
25
|
+
<bouncecount>0</bouncecount>
|
26
|
+
<processbounce>0</processbounce>
|
27
|
+
<agreedelete>1</agreedelete>
|
28
|
+
<agreedeleteall>0</agreedeleteall>
|
29
|
+
<visiblefields>emailaddress,subscribedate,status,confirmed</visiblefields>
|
30
|
+
<ownerid>3</ownerid>
|
31
|
+
<autorespondercount></autorespondercount>
|
32
|
+
</item>
|
33
|
+
|
34
|
+
<item>
|
35
|
+
<listid>84</listid>
|
36
|
+
<name>Totes Bitchin Email List</name>
|
37
|
+
<ownername>John Doe</ownername>
|
38
|
+
<owneremail>john.doe@example.com</owneremail>
|
39
|
+
<bounceemail>john.doe@example.com</bounceemail>
|
40
|
+
<replytoemail>john.doe@example.com</replytoemail>
|
41
|
+
<bounceserver></bounceserver>
|
42
|
+
<bounceusername></bounceusername>
|
43
|
+
<bouncepassword></bouncepassword>
|
44
|
+
<extramailsettings></extramailsettings>
|
45
|
+
<companyname>ExampleCorp</companyname>
|
46
|
+
<companyaddress>123 Main St, Anytown, FL 30635</companyaddress>
|
47
|
+
<companyphone></companyphone>
|
48
|
+
<format>b</format>
|
49
|
+
<notifyowner>1</notifyowner>
|
50
|
+
<imapaccount>0</imapaccount>
|
51
|
+
<createdate>1348552776</createdate>
|
52
|
+
<subscribecount>12345</subscribecount>
|
53
|
+
<unsubscribecount>20</unsubscribecount>
|
54
|
+
<bouncecount>0</bouncecount>
|
55
|
+
<processbounce>0</processbounce>
|
56
|
+
<agreedelete>1</agreedelete>
|
57
|
+
<agreedeleteall>0</agreedeleteall>
|
58
|
+
<visiblefields>emailaddress,subscribedate,status,confirmed</visiblefields>
|
59
|
+
<ownerid>12</ownerid>
|
60
|
+
<autorespondercount></autorespondercount>
|
61
|
+
</item>
|
62
|
+
</data>
|
63
|
+
</response>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
2
|
+
<response>
|
3
|
+
<status>SUCCESS</status>
|
4
|
+
<data>
|
5
|
+
<count>2</count>
|
6
|
+
<subscriberlist>
|
7
|
+
<item>
|
8
|
+
<subscriberid>283206</subscriberid>
|
9
|
+
<emailaddress>jane.doe@example.com</emailaddress>
|
10
|
+
<format>h</format>
|
11
|
+
<subscribedate>1348602753</subscribedate>
|
12
|
+
<confirmed>1</confirmed>
|
13
|
+
<unsubscribed>0</unsubscribed>
|
14
|
+
<bounced>0</bounced>
|
15
|
+
<listid>8</listid>
|
16
|
+
</item>
|
17
|
+
<item>
|
18
|
+
<subscriberid>283207</subscriberid>
|
19
|
+
<emailaddress>john.doe@example.com</emailaddress>
|
20
|
+
<format>h</format>
|
21
|
+
<subscribedate>1348602763</subscribedate>
|
22
|
+
<confirmed>1</confirmed>
|
23
|
+
<unsubscribed>0</unsubscribed>
|
24
|
+
<bounced>0</bounced>
|
25
|
+
<listid>8</listid>
|
26
|
+
</item>
|
27
|
+
</subscriberlist>
|
28
|
+
</data>
|
29
|
+
</response>
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Interspire::API do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@api_url = 'http://example.com/xml.php'
|
7
|
+
@user = 'luser'
|
8
|
+
@token = 'some_totally_valid_token'
|
9
|
+
|
10
|
+
@api = Interspire::API.new(@api_url, @user, @token)
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'authentication' do
|
14
|
+
it 'should be authenticated' do
|
15
|
+
stub_request(:post, @api_url).to_return(:body => fixture("authenticated.xml"))
|
16
|
+
|
17
|
+
@api.should be_authenticated # @api.authenticated? should return true
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should not be authenticated' do
|
21
|
+
stub_request(:post, @api_url).to_return(:body => fixture("not_authenticated.xml"))
|
22
|
+
|
23
|
+
@api.should_not be_authenticated # @api.authenticated? should return false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'lists' do
|
28
|
+
it 'should get all lists' do
|
29
|
+
stub_request(:post, @api_url).to_return(:body => fixture("lists.xml"))
|
30
|
+
|
31
|
+
lists = @api.get_lists
|
32
|
+
|
33
|
+
# Make sure each list has expected values:
|
34
|
+
lists.each do |list|
|
35
|
+
list.id.should_not be_nil
|
36
|
+
list.name.should_not be_nil
|
37
|
+
list.subscribe_count.should_not be_nil
|
38
|
+
list.unsubscribe_count.should_not be_nil
|
39
|
+
list.auto_responder_count.should_not be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should get all subscribers on a list' do
|
44
|
+
stub_request(:post, @api_url).to_return(:body => fixture("subscribers.xml"))
|
45
|
+
|
46
|
+
subscribers = @api.get_subscribers(1) # Contact list ID is arbitrary for this test.
|
47
|
+
|
48
|
+
# Make sure there's a count.
|
49
|
+
subscribers[:count].should_not be_nil
|
50
|
+
|
51
|
+
# Make sure the required values are there:
|
52
|
+
subscribers[:subscribers].each do |subscriber|
|
53
|
+
subscriber.id.should_not be_nil
|
54
|
+
subscriber.id.should be_a(Integer)
|
55
|
+
|
56
|
+
subscriber.email.should_not be_nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'subscribers' do
|
62
|
+
it 'should add the subscriber' do
|
63
|
+
stub_request(:post, @api_url).to_return(:body => fixture("add_subscriber.xml"))
|
64
|
+
subscriber_id = @api.add_subscriber(1, 'foo@example.com') # '1' is the (fake) contact list ID.
|
65
|
+
subscriber_id.should be_a(Integer)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should delete the subscriber' do
|
69
|
+
stub_request(:post, @api_url).to_return(:body => fixture("delete_subscriber.xml"))
|
70
|
+
@api.delete_subscriber(1, 'foo@example.com').should be_true
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should be in contact list' do
|
74
|
+
stub_request(:post, @api_url).to_return(:body => fixture("in_contact_list.xml"))
|
75
|
+
@api.in_contact_list?(1, 'foo@example.com').should be_true
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should not be in contact list' do
|
79
|
+
stub_request(:post, @api_url).to_return(:body => fixture("not_in_contact_list.xml"))
|
80
|
+
@api.in_contact_list?(1, 'foo@example.com').should_not be_true
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Interspire::ContactList do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@details = {
|
7
|
+
:id => 4,
|
8
|
+
:name => 'List Foo',
|
9
|
+
:subscribe_count => 321,
|
10
|
+
:unsubscribe_count => 123,
|
11
|
+
:auto_responder_count => 4,
|
12
|
+
}
|
13
|
+
|
14
|
+
@list = Interspire::ContactList.new(@details)
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'accessors' do
|
18
|
+
it 'id' do; @list.id.should == @details[:id]; end
|
19
|
+
it 'name' do; @list.name.should == @details[:name]; end
|
20
|
+
it 'subscribe_count' do; @list.subscribe_count.should == @details[:subscribe_count]; end
|
21
|
+
it 'unsubscribe_count' do; @list.unsubscribe_count.should == @details[:unsubscribe_count]; end
|
22
|
+
it 'auto_responder_count' do; @list.auto_responder_count.should == @details[:auto_responder_count]; end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: interspire
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dale Campbell
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: nokogiri
|
16
|
+
requirement: &82085980 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *82085980
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &82085610 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *82085610
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: webmock
|
38
|
+
requirement: &82085360 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *82085360
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: yard
|
49
|
+
requirement: &82085080 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *82085080
|
58
|
+
description: Ruby library for the Interspire API.
|
59
|
+
email:
|
60
|
+
- oshuma@gmail.com
|
61
|
+
executables:
|
62
|
+
- interspire
|
63
|
+
extensions: []
|
64
|
+
extra_rdoc_files: []
|
65
|
+
files:
|
66
|
+
- .gitignore
|
67
|
+
- Gemfile
|
68
|
+
- LICENSE.txt
|
69
|
+
- README.md
|
70
|
+
- Rakefile
|
71
|
+
- bin/interspire
|
72
|
+
- interspire.gemspec
|
73
|
+
- lib/interspire.rb
|
74
|
+
- lib/interspire/api.rb
|
75
|
+
- lib/interspire/contact_list.rb
|
76
|
+
- lib/interspire/interspire_exception.rb
|
77
|
+
- lib/interspire/subscriber.rb
|
78
|
+
- spec/fixtures/add_subscriber.xml
|
79
|
+
- spec/fixtures/authenticated.xml
|
80
|
+
- spec/fixtures/delete_subscriber.xml
|
81
|
+
- spec/fixtures/in_contact_list.xml
|
82
|
+
- spec/fixtures/lists.xml
|
83
|
+
- spec/fixtures/not_authenticated.xml
|
84
|
+
- spec/fixtures/not_in_contact_list.xml
|
85
|
+
- spec/fixtures/subscribers.xml
|
86
|
+
- spec/interspire/api_spec.rb
|
87
|
+
- spec/interspire/contact_list_spec.rb
|
88
|
+
- spec/spec_helper.rb
|
89
|
+
homepage: https://github.com/Oshuma/interspire
|
90
|
+
licenses: []
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ! '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
hash: 942893455
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
hash: 942893455
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 1.8.10
|
116
|
+
signing_key:
|
117
|
+
specification_version: 3
|
118
|
+
summary: Ruby library for the Interspire API.
|
119
|
+
test_files:
|
120
|
+
- spec/fixtures/add_subscriber.xml
|
121
|
+
- spec/fixtures/authenticated.xml
|
122
|
+
- spec/fixtures/delete_subscriber.xml
|
123
|
+
- spec/fixtures/in_contact_list.xml
|
124
|
+
- spec/fixtures/lists.xml
|
125
|
+
- spec/fixtures/not_authenticated.xml
|
126
|
+
- spec/fixtures/not_in_contact_list.xml
|
127
|
+
- spec/fixtures/subscribers.xml
|
128
|
+
- spec/interspire/api_spec.rb
|
129
|
+
- spec/interspire/contact_list_spec.rb
|
130
|
+
- spec/spec_helper.rb
|
131
|
+
has_rdoc:
|