createsend 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.coveralls.yml +1 -0
- data/.gitignore +1 -2
- data/Gemfile +1 -1
- data/Gemfile.lock +19 -2
- data/HISTORY.md +21 -0
- data/README.md +22 -6
- data/createsend.gemspec +2 -0
- data/lib/createsend/createsend.rb +36 -24
- data/lib/createsend/segment.rb +0 -4
- data/lib/createsend/subscriber.rb +1 -1
- data/lib/createsend/version.rb +1 -1
- data/test/createsend_test.rb +58 -18
- data/test/fixtures/invalid_oauth_token_api_error.json +4 -0
- data/test/fixtures/oauth_refresh_token_error.json +4 -0
- data/test/fixtures/revoked_oauth_token_api_error.json +4 -0
- data/test/helper.rb +10 -1
- data/test/subscriber_test.rb +12 -0
- metadata +43 -4
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,19 +1,26 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
createsend (3.
|
4
|
+
createsend (3.1.0)
|
5
5
|
hashie (>= 1.2, < 3)
|
6
6
|
httparty (~> 0.10)
|
7
7
|
json
|
8
8
|
|
9
9
|
GEM
|
10
|
-
remote:
|
10
|
+
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
12
|
activesupport (3.2.11)
|
13
13
|
i18n (~> 0.6)
|
14
14
|
multi_json (~> 1.0)
|
15
15
|
bourne (1.1.2)
|
16
16
|
mocha (= 0.10.5)
|
17
|
+
colorize (0.5.8)
|
18
|
+
coveralls (0.6.3)
|
19
|
+
colorize
|
20
|
+
multi_json (~> 1.3)
|
21
|
+
rest-client
|
22
|
+
simplecov (>= 0.7)
|
23
|
+
thor
|
17
24
|
fakeweb (1.3.0)
|
18
25
|
hashie (2.0.3)
|
19
26
|
httparty (0.10.2)
|
@@ -23,11 +30,14 @@ GEM
|
|
23
30
|
jnunemaker-matchy (0.4.0)
|
24
31
|
json (1.7.7)
|
25
32
|
metaclass (0.0.1)
|
33
|
+
mime-types (1.21)
|
26
34
|
mocha (0.10.5)
|
27
35
|
metaclass (~> 0.0.1)
|
28
36
|
multi_json (1.5.0)
|
29
37
|
multi_xml (0.5.3)
|
30
38
|
rake (10.0.3)
|
39
|
+
rest-client (1.6.7)
|
40
|
+
mime-types (>= 1.16)
|
31
41
|
shoulda (3.3.2)
|
32
42
|
shoulda-context (~> 1.0.1)
|
33
43
|
shoulda-matchers (~> 1.4.1)
|
@@ -35,13 +45,20 @@ GEM
|
|
35
45
|
shoulda-matchers (1.4.2)
|
36
46
|
activesupport (>= 3.0.0)
|
37
47
|
bourne (~> 1.1.2)
|
48
|
+
simplecov (0.7.1)
|
49
|
+
multi_json (~> 1.0)
|
50
|
+
simplecov-html (~> 0.7.1)
|
51
|
+
simplecov-html (0.7.1)
|
52
|
+
thor (0.18.0)
|
38
53
|
|
39
54
|
PLATFORMS
|
40
55
|
ruby
|
41
56
|
|
42
57
|
DEPENDENCIES
|
58
|
+
coveralls
|
43
59
|
createsend!
|
44
60
|
fakeweb (~> 1.3)
|
45
61
|
jnunemaker-matchy (~> 0.4)
|
46
62
|
rake (~> 10.0)
|
47
63
|
shoulda (~> 3.3)
|
64
|
+
simplecov
|
data/HISTORY.md
CHANGED
@@ -1,5 +1,26 @@
|
|
1
1
|
# createsend-ruby history
|
2
2
|
|
3
|
+
## v3.1.0 - 28 Mar, 2013 (8a91dda)
|
4
|
+
|
5
|
+
* Added `CreateSend::CreateSend.refresh_access_token` to allow easier refreshing of access tokens when using class methods.
|
6
|
+
|
7
|
+
So you can now refresh an access token using _any_ refresh token like so:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
access_token, expires_in, refresh_token =
|
11
|
+
CreateSend::CreateSend.refresh_access_token 'refresh token'
|
12
|
+
```
|
13
|
+
|
14
|
+
Or, you can refresh the _current_ access token (with your current refresh token) like so:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
cs = CreateSend::CreateSend.new :access_token => 'access token',
|
18
|
+
:refresh_token => 'refresh token'
|
19
|
+
access_token, expires_in, refresh_token = cs.refresh_token
|
20
|
+
```
|
21
|
+
|
22
|
+
* Added `CreateSend::InvalidOAuthToken` and `CreateSend::RevokedOAuthToken` exceptions to make handling of OAuth exceptions in user code easier.
|
23
|
+
|
3
24
|
## v3.0.0 - 25 Mar, 2013 (129ad0e)
|
4
25
|
|
5
26
|
* Added support for authenticating using OAuth. See the [README](README.md#authenticating) for full usage instructions.
|
data/README.md
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# createsend
|
2
|
-
[![Build Status](https://secure.travis-ci.org/campaignmonitor/createsend-ruby.png)][travis] [![Dependency Status](https://gemnasium.com/campaignmonitor/createsend-ruby.png)][gemnasium] [![Gem Version](https://badge.fury.io/rb/createsend.png)][gembadge]
|
2
|
+
[![Build Status](https://secure.travis-ci.org/campaignmonitor/createsend-ruby.png)][travis] [![Coverage Status](https://coveralls.io/repos/campaignmonitor/createsend-ruby/badge.png?branch=master)][coveralls] [![Dependency Status](https://gemnasium.com/campaignmonitor/createsend-ruby.png)][gemnasium] [![Gem Version](https://badge.fury.io/rb/createsend.png)][gembadge]
|
3
3
|
|
4
4
|
A ruby library which implements the complete functionality of the [Campaign Monitor API](http://www.campaignmonitor.com/api/).
|
5
5
|
|
6
6
|
[travis]: http://travis-ci.org/campaignmonitor/createsend-ruby
|
7
|
+
[coveralls]: https://coveralls.io/r/campaignmonitor/createsend-ruby
|
7
8
|
[gemnasium]: https://gemnasium.com/campaignmonitor/createsend-ruby
|
8
9
|
[gembadge]: http://badge.fury.io/rb/createsend
|
9
10
|
|
@@ -31,6 +32,8 @@ If you're developing a Rails or Rack based application, we recommend using [omni
|
|
31
32
|
|
32
33
|
If you don't use [omniauth-createsend](https://github.com/jdennes/omniauth-createsend), you'll need to get access tokens for your users by following the instructions included in the Campaign Monitor API [documentation](http://www.campaignmonitor.com/api/getting-started/#authenticating_with_oauth). This gem provides functionality to help you do this, as described below. There's also another [example application](https://gist.github.com/jdennes/4945412) you may wish to reference, which doesn't depend on any OAuth libraries.
|
33
34
|
|
35
|
+
#### Redirecting to the authorization URL
|
36
|
+
|
34
37
|
The first thing your application should do is redirect your user to the Campaign Monitor authorization URL where they will have the opportunity to approve your application to access their Campaign Monitor account. You can get this authorization URL by using `CreateSend::CreateSend.authorize_url`, like so:
|
35
38
|
|
36
39
|
```ruby
|
@@ -45,6 +48,8 @@ authorize_url = CreateSend::CreateSend.authorize_url(
|
|
45
48
|
# Redirect your users to authorize_url.
|
46
49
|
```
|
47
50
|
|
51
|
+
#### Exchanging an OAuth code for an access token
|
52
|
+
|
48
53
|
If your user approves your application, they will then be redirected to the `redirect_uri` you specified, which will include a `code` parameter, and optionally a `state` parameter in the query string. Your application should implement a handler which can exchange the code passed to it for an access token, using `CreateSend::CreateSend.exchange_token` like so:
|
49
54
|
|
50
55
|
```ruby
|
@@ -61,6 +66,8 @@ access_token, expires_in, refresh_token = CreateSend::CreateSend.exchange_token(
|
|
61
66
|
|
62
67
|
At this point you have an access token and refresh token for your user which you should store somewhere convenient so that your application can look up these values when your user wants to make future Campaign Monitor API calls.
|
63
68
|
|
69
|
+
#### Making API calls using an access token
|
70
|
+
|
64
71
|
Once you have an access token and refresh token for your user, you can use the `createsend` gem to authenticate and make further API calls like so:
|
65
72
|
|
66
73
|
```ruby
|
@@ -74,7 +81,11 @@ cs = CreateSend::CreateSend.new auth
|
|
74
81
|
clients = cs.clients
|
75
82
|
```
|
76
83
|
|
77
|
-
|
84
|
+
#### Refreshing access tokens
|
85
|
+
|
86
|
+
All OAuth access tokens have an expiry time, and can be renewed with a refresh token. If your access token expires when attempting to make an API call, the `CreateSend::ExpiredOAuthToken` exception will be raised, so your code should handle this. You can handle this using either `CreateSend::CreateSend.refresh_access_token` (when calling class methods) or `CreateSend::CreateSend#refresh_token` (when calling instance methods).
|
87
|
+
|
88
|
+
Here's an example of using `CreateSend::CreateSend#refresh_token` to refresh your current access token when calling `CreateSend::CreateSend#clients`:
|
78
89
|
|
79
90
|
```ruby
|
80
91
|
require 'createsend'
|
@@ -90,7 +101,9 @@ begin
|
|
90
101
|
clients = cs.clients
|
91
102
|
rescue CreateSend::ExpiredOAuthToken => eot
|
92
103
|
access_token, expires_in, refresh_token = cs.refresh_token
|
93
|
-
#
|
104
|
+
# Here you should save your updated access token, 'expire in' value,
|
105
|
+
# and refresh token. `cs` will automatically have the new access token
|
106
|
+
# set, so there is no need to set it again.
|
94
107
|
retry unless (tries -= 1).zero?
|
95
108
|
p "Error: #{eot}"
|
96
109
|
rescue Exception => e
|
@@ -98,6 +111,8 @@ begin
|
|
98
111
|
end
|
99
112
|
```
|
100
113
|
|
114
|
+
In addition to raising `CreateSend::ExpiredOAuthToken` when an access token has expired, this library also raises `CreateSend::InvalidOAuthToken` if an invalid access token is used, and raises `CreateSend::RevokedOAuthToken` if a user has revoked the access token being used. This makes it easier for you to handle these cases in your code.
|
115
|
+
|
101
116
|
### Using an API key
|
102
117
|
|
103
118
|
```ruby
|
@@ -154,7 +169,8 @@ auth = {
|
|
154
169
|
}
|
155
170
|
|
156
171
|
begin
|
157
|
-
id = CreateSend::Campaign.create auth, "4a397ccaaa55eb4e6aa1221e1e2d7122",
|
172
|
+
id = CreateSend::Campaign.create auth, "4a397ccaaa55eb4e6aa1221e1e2d7122",
|
173
|
+
"", "", "", "", "", "", "", [], []
|
158
174
|
p "New campaign ID: #{id}"
|
159
175
|
rescue CreateSend::BadRequest => br
|
160
176
|
p "Bad request error: #{br}"
|
@@ -182,7 +198,7 @@ For example, if you wanted to find out how to call the CreateSend::Subscriber.ad
|
|
182
198
|
should "add a subscriber with custom fields" do
|
183
199
|
stub_post(@auth, "subscribers/#{@list_id}.json", "add_subscriber.json")
|
184
200
|
custom_fields = [ { :Key => 'website', :Value => 'http://example.com/' } ]
|
185
|
-
email_address = CreateSend::Subscriber.add @list_id, "subscriber@example.com", "Subscriber", custom_fields, true
|
201
|
+
email_address = CreateSend::Subscriber.add @auth, @list_id, "subscriber@example.com", "Subscriber", custom_fields, true
|
186
202
|
email_address.should == "subscriber@example.com"
|
187
203
|
end
|
188
204
|
```
|
@@ -193,7 +209,7 @@ Full documentation is hosted by [RubyDoc.info](http://rubydoc.info/gems/createse
|
|
193
209
|
|
194
210
|
## Contributing
|
195
211
|
1. Fork the repository
|
196
|
-
2. Make your changes, including tests for your changes.
|
212
|
+
2. Make your changes, including tests for your changes which maintain [coverage][coveralls].
|
197
213
|
3. Ensure that the build passes, by running `bundle exec rake` (CI runs on: `2.0.0`, `1.9.3`, `1.9.2`, `1.8.7`, and `ree`)
|
198
214
|
4. It should go without saying, but do not increment the version number in your commits.
|
199
215
|
5. Submit a pull request.
|
data/createsend.gemspec
CHANGED
@@ -8,6 +8,8 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.add_development_dependency 'fakeweb', '~> 1.3'
|
9
9
|
s.add_development_dependency 'jnunemaker-matchy', '~> 0.4'
|
10
10
|
s.add_development_dependency 'shoulda', '~> 3.3'
|
11
|
+
s.add_development_dependency 'simplecov'
|
12
|
+
s.add_development_dependency 'coveralls'
|
11
13
|
s.add_runtime_dependency 'json', '>= 0'
|
12
14
|
s.add_runtime_dependency 'hashie', ['>= 1.2', '< 3']
|
13
15
|
s.add_runtime_dependency 'httparty', '~> 0.10'
|
@@ -29,9 +29,15 @@ module CreateSend
|
|
29
29
|
# Raised for HTTP response code of 404
|
30
30
|
class NotFound < ClientError; end
|
31
31
|
|
32
|
+
# Raised for HTTP response code of 401, specifically when an OAuth token
|
33
|
+
# in invalid (Code: 120, Message: 'Invalid OAuth Token')
|
34
|
+
class InvalidOAuthToken < Unauthorized; end
|
32
35
|
# Raised for HTTP response code of 401, specifically when an OAuth token
|
33
36
|
# has expired (Code: 121, Message: 'Expired OAuth Token')
|
34
37
|
class ExpiredOAuthToken < Unauthorized; end
|
38
|
+
# Raised for HTTP response code of 401, specifically when an OAuth token
|
39
|
+
# has been revoked (Code: 122, Message: 'Revoked OAuth Token')
|
40
|
+
class RevokedOAuthToken < Unauthorized; end
|
35
41
|
|
36
42
|
# Provides high level CreateSend functionality/data you'll probably need.
|
37
43
|
class CreateSend
|
@@ -49,7 +55,7 @@ module CreateSend
|
|
49
55
|
end
|
50
56
|
|
51
57
|
# Exchange a provided OAuth code for an OAuth access token, 'expires in'
|
52
|
-
# value and refresh token.
|
58
|
+
# value, and refresh token.
|
53
59
|
def self.exchange_token(client_id, client_secret, redirect_uri, code)
|
54
60
|
body = "grant_type=authorization_code"
|
55
61
|
body << "&client_id=#{CGI.escape(client_id.to_s)}"
|
@@ -67,25 +73,27 @@ module CreateSend
|
|
67
73
|
[r.access_token, r.expires_in, r.refresh_token]
|
68
74
|
end
|
69
75
|
|
76
|
+
# Refresh an OAuth access token, given an OAuth refresh token.
|
77
|
+
# Returns a new access token, 'expires in' value, and refresh token.
|
78
|
+
def self.refresh_access_token(refresh_token)
|
79
|
+
options = {
|
80
|
+
:body => "grant_type=refresh_token&refresh_token=#{refresh_token}" }
|
81
|
+
response = HTTParty.post(@@oauth_token_uri, options)
|
82
|
+
if response.has_key? 'error' and response.has_key? 'error_description'
|
83
|
+
err = "Error refreshing access token: "
|
84
|
+
err << "#{response['error']} - #{response['error_description']}"
|
85
|
+
raise err
|
86
|
+
end
|
87
|
+
r = Hashie::Mash.new(response)
|
88
|
+
[r.access_token, r.expires_in, r.refresh_token]
|
89
|
+
end
|
90
|
+
|
70
91
|
def initialize(*args)
|
71
92
|
if args.size > 0
|
72
93
|
auth args.first # Expect auth details as first argument
|
73
94
|
end
|
74
95
|
end
|
75
96
|
|
76
|
-
# Deals with an unfortunate situation where responses aren't valid json.
|
77
|
-
class Parser::DealWithCreateSendInvalidJson < HTTParty::Parser
|
78
|
-
# The createsend API returns an ID as a string when a 201 Created
|
79
|
-
# response is returned. Unfortunately this is invalid json.
|
80
|
-
def parse
|
81
|
-
begin
|
82
|
-
super
|
83
|
-
rescue MultiJson::DecodeError => e
|
84
|
-
body[1..-2] # Strip surrounding quotes and return as is.
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
parser Parser::DealWithCreateSendInvalidJson
|
89
97
|
@@base_uri = "https://api.createsend.com/api/v3"
|
90
98
|
@@oauth_base_uri = "https://api.createsend.com/oauth"
|
91
99
|
@@oauth_token_uri = "#{@@oauth_base_uri}/token"
|
@@ -108,14 +116,12 @@ module CreateSend
|
|
108
116
|
raise '@auth_details[:refresh_token] does not contain a refresh token.'
|
109
117
|
end
|
110
118
|
|
111
|
-
|
112
|
-
|
113
|
-
response = HTTParty.post(@@oauth_token_uri, options)
|
114
|
-
r = Hashie::Mash.new(response)
|
119
|
+
access_token, expires_in, refresh_token =
|
120
|
+
self.class.refresh_access_token @auth_details[:refresh_token]
|
115
121
|
auth({
|
116
|
-
:access_token =>
|
117
|
-
:refresh_token =>
|
118
|
-
[
|
122
|
+
:access_token => access_token,
|
123
|
+
:refresh_token => refresh_token})
|
124
|
+
[access_token, expires_in, refresh_token]
|
119
125
|
end
|
120
126
|
|
121
127
|
# Gets your CreateSend API key, given your site url, username and password.
|
@@ -227,10 +233,16 @@ module CreateSend
|
|
227
233
|
raise BadRequest.new(Hashie::Mash.new response)
|
228
234
|
when 401
|
229
235
|
data = Hashie::Mash.new(response)
|
230
|
-
|
231
|
-
|
236
|
+
case data.Code
|
237
|
+
when 120
|
238
|
+
raise InvalidOAuthToken.new data
|
239
|
+
when 121
|
240
|
+
raise ExpiredOAuthToken.new data
|
241
|
+
when 122
|
242
|
+
raise RevokedOAuthToken.new data
|
243
|
+
else
|
244
|
+
raise Unauthorized.new data
|
232
245
|
end
|
233
|
-
raise Unauthorized.new(data)
|
234
246
|
when 404
|
235
247
|
raise NotFound.new
|
236
248
|
when 400...500
|
data/lib/createsend/segment.rb
CHANGED
data/lib/createsend/version.rb
CHANGED
data/test/createsend_test.rb
CHANGED
@@ -73,6 +73,32 @@ class CreateSendTest < Test::Unit::TestCase
|
|
73
73
|
Exception, 'Error exchanging code for access token: invalid_grant - Specified code was invalid or expired')
|
74
74
|
FakeWeb.last_request.body.should == "grant_type=authorization_code&client_id=8998879&client_secret=iou0q9wud0q9wd0q9wid0q9iwd0q9wid0q9wdqwd&redirect_uri=http%3A%2F%2Fexample.com%2Fauth&code=invalidcode"
|
75
75
|
end
|
76
|
+
|
77
|
+
should "refresh an access token given a refresh token" do
|
78
|
+
refresh_token = 'tGzv3JOkF0XG5Qx2TlKWIA'
|
79
|
+
options = {
|
80
|
+
:body => fixture_file("refresh_oauth_token.json"),
|
81
|
+
:content_type => "application/json; charset=utf-8" }
|
82
|
+
FakeWeb.register_uri(:post, "https://api.createsend.com/oauth/token", options)
|
83
|
+
new_access_token, new_expires_in, new_refresh_token = CreateSend::CreateSend.refresh_access_token refresh_token
|
84
|
+
|
85
|
+
FakeWeb.last_request.body.should == "grant_type=refresh_token&refresh_token=#{refresh_token}"
|
86
|
+
new_access_token.should == "SlAV32hkKG2e12e"
|
87
|
+
new_expires_in.should == 1209600
|
88
|
+
new_refresh_token.should == "tGzv3JOkF0XG5Qx2TlKWIA"
|
89
|
+
end
|
90
|
+
|
91
|
+
should "raise an error when an attempt to refresh an access token fails" do
|
92
|
+
refresh_token = 'invalidrefreshtoken'
|
93
|
+
options = {
|
94
|
+
:body => fixture_file("oauth_refresh_token_error.json"),
|
95
|
+
:content_type => "application/json; charset=utf-8" }
|
96
|
+
FakeWeb.register_uri(:post, "https://api.createsend.com/oauth/token", options)
|
97
|
+
lambda { access_token, expires_in, refresh_token = CreateSend::CreateSend.refresh_access_token(
|
98
|
+
refresh_token) }.should raise_error(
|
99
|
+
Exception, 'Error refreshing access token: invalid_grant - Specified refresh_token was invalid or expired')
|
100
|
+
FakeWeb.last_request.body.should == "grant_type=refresh_token&refresh_token=#{refresh_token}"
|
101
|
+
end
|
76
102
|
|
77
103
|
should "get a person's api key" do
|
78
104
|
base_uri = "https://api.createsend.com/api/v3"
|
@@ -134,6 +160,36 @@ class CreateSendTest < Test::Unit::TestCase
|
|
134
160
|
lambda { new_access_token, new_refresh_token = cs.refresh_token }.should raise_error(
|
135
161
|
Exception, '@auth_details[:refresh_token] does not contain a refresh token.')
|
136
162
|
end
|
163
|
+
|
164
|
+
should "raise an error when an attempt to refresh the access token is made but the refresh token is invalid" do
|
165
|
+
refresh_token = 'invalidrefreshtoken'
|
166
|
+
cs = CreateSend::CreateSend.new :access_token => 'any token', :refresh_token => refresh_token
|
167
|
+
options = {
|
168
|
+
:body => fixture_file("oauth_refresh_token_error.json"),
|
169
|
+
:content_type => "application/json; charset=utf-8" }
|
170
|
+
FakeWeb.register_uri(:post, "https://api.createsend.com/oauth/token", options)
|
171
|
+
lambda { access_token, expires_in, refresh_token = cs.refresh_token }.should raise_error(
|
172
|
+
Exception, 'Error refreshing access token: invalid_grant - Specified refresh_token was invalid or expired')
|
173
|
+
end
|
174
|
+
|
175
|
+
should "raise a CreateSend::InvalidOAuthToken error when an access token is invalid" do
|
176
|
+
cs = CreateSend::CreateSend.new @auth
|
177
|
+
stub_get(@auth, "countries.json", "invalid_oauth_token_api_error.json", ["401", "Unauthorized"])
|
178
|
+
lambda { c = cs.countries }.should raise_error(CreateSend::InvalidOAuthToken)
|
179
|
+
end
|
180
|
+
|
181
|
+
should "raise a CreateSend::ExpiredOAuthToken error when an access token is expired" do
|
182
|
+
cs = CreateSend::CreateSend.new @auth
|
183
|
+
stub_get(@auth, "countries.json", "expired_oauth_token_api_error.json", ["401", "Unauthorized"])
|
184
|
+
lambda { c = cs.countries }.should raise_error(CreateSend::ExpiredOAuthToken)
|
185
|
+
end
|
186
|
+
|
187
|
+
should "raise a CreateSend::RevokedOAuthToken error when an access token is revoked" do
|
188
|
+
cs = CreateSend::CreateSend.new @auth
|
189
|
+
stub_get(@auth, "countries.json", "revoked_oauth_token_api_error.json", ["401", "Unauthorized"])
|
190
|
+
lambda { c = cs.countries }.should raise_error(CreateSend::RevokedOAuthToken)
|
191
|
+
end
|
192
|
+
|
137
193
|
end
|
138
194
|
|
139
195
|
multiple_contexts "authenticated_using_oauth_context", "authenticated_using_api_key_context" do
|
@@ -218,6 +274,7 @@ class CreateSendTest < Test::Unit::TestCase
|
|
218
274
|
{ ["400", "Bad Request"] => CreateSend::BadRequest,
|
219
275
|
["401", "Unauthorized"] => CreateSend::Unauthorized,
|
220
276
|
["404", "Not Found"] => CreateSend::NotFound,
|
277
|
+
["418", "I'm a teapot"] => CreateSend::ClientError,
|
221
278
|
["500", "Server Error"] => CreateSend::ServerError
|
222
279
|
}.each do |status, exception|
|
223
280
|
context "#{status.first}, a get" do
|
@@ -229,7 +286,7 @@ class CreateSendTest < Test::Unit::TestCase
|
|
229
286
|
|
230
287
|
context "#{status.first}, a post" do
|
231
288
|
should "raise a #{exception.name} error" do
|
232
|
-
stub_post(@auth, "clients.json", (status.first == '400' or status.first == '401') ? 'custom_api_error.json' : nil, status)
|
289
|
+
stub_post(@auth, "clients.json", (status.first == '400' or status.first == '401') ? 'custom_api_error.json' : nil, status)
|
233
290
|
lambda { CreateSend::Client.create @auth, "Client Company Name",
|
234
291
|
"(GMT+10:00) Canberra, Melbourne, Sydney", "Australia" }.should raise_error(exception)
|
235
292
|
end
|
@@ -252,23 +309,6 @@ class CreateSendTest < Test::Unit::TestCase
|
|
252
309
|
end
|
253
310
|
end
|
254
311
|
|
255
|
-
context "when authenticated using oauth and the access token has expired" do
|
256
|
-
setup do
|
257
|
-
@access_token = '98y98u98u98ue212'
|
258
|
-
@refresh_token = 'kj9wud09wi0qi0w'
|
259
|
-
@auth = {
|
260
|
-
:access_token => @access_token,
|
261
|
-
:refresh_token => @refresh_token
|
262
|
-
}
|
263
|
-
@cs = CreateSend::CreateSend.new @auth
|
264
|
-
end
|
265
|
-
|
266
|
-
should "raise a CreateSend::ExpiredOAuthToken error" do
|
267
|
-
stub_get(@auth, "countries.json", "expired_oauth_token_api_error.json", ["401", "Unauthorized"])
|
268
|
-
lambda { c = @cs.countries }.should raise_error(CreateSend::ExpiredOAuthToken)
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
312
|
end
|
273
313
|
|
274
314
|
end
|
data/test/helper.rb
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
require 'coveralls'
|
3
|
+
|
4
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
5
|
+
SimpleCov::Formatter::HTMLFormatter,
|
6
|
+
Coveralls::SimpleCov::Formatter
|
7
|
+
]
|
8
|
+
SimpleCov.start
|
9
|
+
|
1
10
|
require 'test/unit'
|
2
11
|
require 'pathname'
|
3
12
|
|
@@ -9,7 +18,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
9
18
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
10
19
|
require 'createsend'
|
11
20
|
|
12
|
-
FakeWeb.allow_net_connect =
|
21
|
+
FakeWeb.allow_net_connect = %r[^https?://coveralls.io]
|
13
22
|
|
14
23
|
def fixture_file(filename)
|
15
24
|
return '' if filename == ''
|
data/test/subscriber_test.rb
CHANGED
@@ -125,6 +125,18 @@ class SubscriberTest < Test::Unit::TestCase
|
|
125
125
|
import_result.DuplicateEmailsInSubmission.size.should == 0
|
126
126
|
end
|
127
127
|
|
128
|
+
should "raise a BadRequest error if the import _completely_ fails because of a bad request" do
|
129
|
+
# Stub request with 400 Bad Request as the expected response status
|
130
|
+
stub_post(@auth, "subscribers/#{@list_id}/import.json", "custom_api_error.json", 400)
|
131
|
+
subscribers = [
|
132
|
+
{ :EmailAddress => "example+1@example", :Name => "Example One" },
|
133
|
+
{ :EmailAddress => "example+2@example.com", :Name => "Example Two" },
|
134
|
+
{ :EmailAddress => "example+3@example.com", :Name => "Example Three" },
|
135
|
+
]
|
136
|
+
lambda { import_result = CreateSend::Subscriber.import @auth, @list_id, subscribers, true
|
137
|
+
}.should raise_error(CreateSend::BadRequest)
|
138
|
+
end
|
139
|
+
|
128
140
|
should "unsubscribe a subscriber" do
|
129
141
|
stub_post(@auth, "subscribers/#{@subscriber.list_id}/unsubscribe.json", nil)
|
130
142
|
@subscriber.unsubscribe
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: createsend
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -75,6 +75,38 @@ dependencies:
|
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '3.3'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: simplecov
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: coveralls
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
78
110
|
- !ruby/object:Gem::Dependency
|
79
111
|
name: json
|
80
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,6 +168,7 @@ executables: []
|
|
136
168
|
extensions: []
|
137
169
|
extra_rdoc_files: []
|
138
170
|
files:
|
171
|
+
- .coveralls.yml
|
139
172
|
- .gitignore
|
140
173
|
- .travis.yml
|
141
174
|
- Gemfile
|
@@ -200,6 +233,7 @@ files:
|
|
200
233
|
- test/fixtures/expired_oauth_token_api_error.json
|
201
234
|
- test/fixtures/import_subscribers.json
|
202
235
|
- test/fixtures/import_subscribers_partial_success.json
|
236
|
+
- test/fixtures/invalid_oauth_token_api_error.json
|
203
237
|
- test/fixtures/list_details.json
|
204
238
|
- test/fixtures/list_stats.json
|
205
239
|
- test/fixtures/list_webhooks.json
|
@@ -207,9 +241,11 @@ files:
|
|
207
241
|
- test/fixtures/listsforemail.json
|
208
242
|
- test/fixtures/oauth_exchange_token.json
|
209
243
|
- test/fixtures/oauth_exchange_token_error.json
|
244
|
+
- test/fixtures/oauth_refresh_token_error.json
|
210
245
|
- test/fixtures/people.json
|
211
246
|
- test/fixtures/person_details.json
|
212
247
|
- test/fixtures/refresh_oauth_token.json
|
248
|
+
- test/fixtures/revoked_oauth_token_api_error.json
|
213
249
|
- test/fixtures/scheduled_campaigns.json
|
214
250
|
- test/fixtures/segment_details.json
|
215
251
|
- test/fixtures/segment_subscribers.json
|
@@ -245,7 +281,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
245
281
|
version: '0'
|
246
282
|
segments:
|
247
283
|
- 0
|
248
|
-
hash:
|
284
|
+
hash: -935543352703407509
|
249
285
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
250
286
|
none: false
|
251
287
|
requirements:
|
@@ -254,7 +290,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
254
290
|
version: 1.3.6
|
255
291
|
requirements: []
|
256
292
|
rubyforge_project:
|
257
|
-
rubygems_version: 1.8.
|
293
|
+
rubygems_version: 1.8.23
|
258
294
|
signing_key:
|
259
295
|
specification_version: 3
|
260
296
|
summary: A library which implements the complete functionality of the Campaign Monitor
|
@@ -304,6 +340,7 @@ test_files:
|
|
304
340
|
- test/fixtures/expired_oauth_token_api_error.json
|
305
341
|
- test/fixtures/import_subscribers.json
|
306
342
|
- test/fixtures/import_subscribers_partial_success.json
|
343
|
+
- test/fixtures/invalid_oauth_token_api_error.json
|
307
344
|
- test/fixtures/list_details.json
|
308
345
|
- test/fixtures/list_stats.json
|
309
346
|
- test/fixtures/list_webhooks.json
|
@@ -311,9 +348,11 @@ test_files:
|
|
311
348
|
- test/fixtures/listsforemail.json
|
312
349
|
- test/fixtures/oauth_exchange_token.json
|
313
350
|
- test/fixtures/oauth_exchange_token_error.json
|
351
|
+
- test/fixtures/oauth_refresh_token_error.json
|
314
352
|
- test/fixtures/people.json
|
315
353
|
- test/fixtures/person_details.json
|
316
354
|
- test/fixtures/refresh_oauth_token.json
|
355
|
+
- test/fixtures/revoked_oauth_token_api_error.json
|
317
356
|
- test/fixtures/scheduled_campaigns.json
|
318
357
|
- test/fixtures/segment_details.json
|
319
358
|
- test/fixtures/segment_subscribers.json
|