nationbuilder-rb 1.1.0 → 1.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile +5 -5
- data/Gemfile.lock +41 -36
- data/README.md +6 -2
- data/VERSION +1 -1
- data/lib/nationbuilder.rb +1 -0
- data/lib/nationbuilder/client.rb +45 -8
- data/lib/nationbuilder/errors.rb +6 -0
- data/nationbuilder-rb.gemspec +19 -18
- data/spec/fixtures/parametered_post.yml +2 -2
- data/spec/nationbuilder_client_spec.rb +51 -6
- data/spec/nationbuilder_paginator_spec.rb +6 -6
- metadata +13 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f736fe98de0df24dd6a2e38b3d7013ec6d49245
|
4
|
+
data.tar.gz: fca4e68a8753f003ba0f6815abcf74e9d16c8e7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25aec085a33bab04ce580aa96d6f650893a5d603f87caa46f4b910401559b3d66bc161d71bb56370b9bada6a20be5d11b0f4759a587b9edcc3d6c252eb6f2d8f
|
7
|
+
data.tar.gz: a958baba40eaefda72a00248ef5d3ada11d9b751763de3a97ad17ef068fe6a21220f7eafdf74007ffca41c105f9bad5fa4a463f15ca1a708fa1a67921708e080
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -3,9 +3,9 @@ source 'http://rubygems.org'
|
|
3
3
|
gem 'httpclient', '~> 2.4.0'
|
4
4
|
|
5
5
|
group :development do
|
6
|
-
gem 'jeweler', '~> 2.0
|
7
|
-
gem 'rspec', '~> 2
|
8
|
-
gem 'simplecov', '~> 0.8
|
9
|
-
gem 'vcr', '~> 2.9
|
10
|
-
gem 'webmock', '~> 1.18
|
6
|
+
gem 'jeweler', '~> 2.0'
|
7
|
+
gem 'rspec', '~> 3.2'
|
8
|
+
gem 'simplecov', '~> 0.8'
|
9
|
+
gem 'vcr', '~> 2.9'
|
10
|
+
gem 'webmock', '~> 1.18'
|
11
11
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
addressable (2.3.
|
4
|
+
addressable (2.3.7)
|
5
5
|
builder (3.2.2)
|
6
6
|
crack (0.4.2)
|
7
7
|
safe_yaml (~> 1.0.0)
|
8
8
|
descendants_tracker (0.0.4)
|
9
9
|
thread_safe (~> 0.3, >= 0.3.1)
|
10
|
-
diff-lcs (1.
|
10
|
+
diff-lcs (1.2.5)
|
11
11
|
docile (1.1.5)
|
12
|
-
faraday (0.9.
|
12
|
+
faraday (0.9.1)
|
13
13
|
multipart-post (>= 1.2, < 3)
|
14
|
-
git (1.2.
|
15
|
-
github_api (0.
|
14
|
+
git (1.2.9.1)
|
15
|
+
github_api (0.12.3)
|
16
16
|
addressable (~> 2.3)
|
17
|
-
descendants_tracker (~> 0.0.
|
17
|
+
descendants_tracker (~> 0.0.4)
|
18
18
|
faraday (~> 0.8, < 0.10)
|
19
|
-
hashie (>=
|
19
|
+
hashie (>= 3.3)
|
20
20
|
multi_json (>= 1.7.5, < 2.0)
|
21
|
-
nokogiri (~> 1.6.
|
21
|
+
nokogiri (~> 1.6.3)
|
22
22
|
oauth2
|
23
|
-
hashie (3.
|
23
|
+
hashie (3.4.0)
|
24
24
|
highline (1.6.21)
|
25
25
|
httpclient (2.4.0)
|
26
26
|
jeweler (2.0.1)
|
@@ -32,41 +32,46 @@ GEM
|
|
32
32
|
nokogiri (>= 1.5.10)
|
33
33
|
rake
|
34
34
|
rdoc
|
35
|
-
json (1.8.
|
36
|
-
jwt (1.
|
37
|
-
mini_portile (0.6.
|
35
|
+
json (1.8.2)
|
36
|
+
jwt (1.2.1)
|
37
|
+
mini_portile (0.6.2)
|
38
38
|
multi_json (1.10.1)
|
39
39
|
multi_xml (0.5.5)
|
40
40
|
multipart-post (2.0.0)
|
41
|
-
nokogiri (1.6.2
|
42
|
-
mini_portile (
|
43
|
-
oauth2 (0.
|
41
|
+
nokogiri (1.6.6.2)
|
42
|
+
mini_portile (~> 0.6.0)
|
43
|
+
oauth2 (1.0.0)
|
44
44
|
faraday (>= 0.8, < 0.10)
|
45
45
|
jwt (~> 1.0)
|
46
46
|
multi_json (~> 1.3)
|
47
47
|
multi_xml (~> 0.5)
|
48
48
|
rack (~> 1.2)
|
49
|
-
rack (1.
|
50
|
-
rake (10.
|
51
|
-
rdoc (4.
|
49
|
+
rack (1.6.0)
|
50
|
+
rake (10.4.2)
|
51
|
+
rdoc (4.2.0)
|
52
52
|
json (~> 1.4)
|
53
|
-
rspec (2.
|
54
|
-
rspec-core (~> 2.
|
55
|
-
rspec-expectations (~> 2.
|
56
|
-
rspec-mocks (~> 2.
|
57
|
-
rspec-core (2.
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
53
|
+
rspec (3.2.0)
|
54
|
+
rspec-core (~> 3.2.0)
|
55
|
+
rspec-expectations (~> 3.2.0)
|
56
|
+
rspec-mocks (~> 3.2.0)
|
57
|
+
rspec-core (3.2.0)
|
58
|
+
rspec-support (~> 3.2.0)
|
59
|
+
rspec-expectations (3.2.0)
|
60
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
61
|
+
rspec-support (~> 3.2.0)
|
62
|
+
rspec-mocks (3.2.0)
|
63
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
64
|
+
rspec-support (~> 3.2.0)
|
65
|
+
rspec-support (3.2.1)
|
66
|
+
safe_yaml (1.0.4)
|
67
|
+
simplecov (0.9.1)
|
63
68
|
docile (~> 1.1.0)
|
64
|
-
multi_json
|
69
|
+
multi_json (~> 1.0)
|
65
70
|
simplecov-html (~> 0.8.0)
|
66
71
|
simplecov-html (0.8.0)
|
67
72
|
thread_safe (0.3.4)
|
68
|
-
vcr (2.9.
|
69
|
-
webmock (1.
|
73
|
+
vcr (2.9.3)
|
74
|
+
webmock (1.20.4)
|
70
75
|
addressable (>= 2.3.6)
|
71
76
|
crack (>= 0.3.2)
|
72
77
|
|
@@ -75,8 +80,8 @@ PLATFORMS
|
|
75
80
|
|
76
81
|
DEPENDENCIES
|
77
82
|
httpclient (~> 2.4.0)
|
78
|
-
jeweler (~> 2.0
|
79
|
-
rspec (~> 2
|
80
|
-
simplecov (~> 0.8
|
81
|
-
vcr (~> 2.9
|
82
|
-
webmock (~> 1.18
|
83
|
+
jeweler (~> 2.0)
|
84
|
+
rspec (~> 3.2)
|
85
|
+
simplecov (~> 0.8)
|
86
|
+
vcr (~> 2.9)
|
87
|
+
webmock (~> 1.18)
|
data/README.md
CHANGED
@@ -30,9 +30,13 @@ Then, create a client by specifying the name of your nation and
|
|
30
30
|
your API token:
|
31
31
|
|
32
32
|
```ruby
|
33
|
-
client = NationBuilder::Client.new('my_nation_name', 'my_api_token')
|
33
|
+
client = NationBuilder::Client.new('my_nation_name', 'my_api_token', retries: 8)
|
34
34
|
```
|
35
35
|
|
36
|
+
The `retries` parameter specifies the maximum number of retries to attempt
|
37
|
+
when the client is rate limited. This uses an exponential backoff strategy.
|
38
|
+
The default is `8`.
|
39
|
+
|
36
40
|
## Calling the API
|
37
41
|
|
38
42
|
The primary method for calling the NationBuilder API in
|
@@ -81,7 +85,7 @@ page1 = paginated
|
|
81
85
|
page2 = page1.next
|
82
86
|
page3 = page2.next
|
83
87
|
```
|
84
|
-
Methods `#next` and `#prev` return the results of the next or previous page of results, nil if none. `#next?` and `#prev?` return the path to the next or prev page, or nil if none. The results of a page can be accessed through `.body` - in the above example, `page1.body` returns the same hash as `response`.
|
88
|
+
Methods `#next` and `#prev` return the results of the next or previous page of results, nil if none. `#next?` and `#prev?` return the path to the next or prev page, or nil if none. The results of a page can be accessed through `.body` - in the above example, `page1.body` returns the same hash as `response`.
|
85
89
|
|
86
90
|
## Documentation
|
87
91
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
data/lib/nationbuilder.rb
CHANGED
data/lib/nationbuilder/client.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
class NationBuilder::Client
|
2
2
|
|
3
|
-
def initialize(nation_name, api_key,
|
3
|
+
def initialize(nation_name, api_key, opts = {})
|
4
4
|
@nation_name = nation_name
|
5
5
|
@api_key = api_key
|
6
|
-
@base_url = base_url
|
7
6
|
@name_to_endpoint = {}
|
7
|
+
@base_url = opts[:base_url] || 'https://:nation_name.nationbuilder.com'
|
8
|
+
@retries = opts[:retries] || 8
|
9
|
+
|
10
|
+
if @retries < 1
|
11
|
+
raise 'A positive number of retries must be specified'
|
12
|
+
end
|
13
|
+
|
8
14
|
parsed_endpoints.each do |endpoint|
|
9
15
|
@name_to_endpoint[endpoint.name] = endpoint
|
10
16
|
end
|
@@ -31,6 +37,8 @@ class NationBuilder::Client
|
|
31
37
|
@base_url.gsub(':nation_name', @nation_name)
|
32
38
|
end
|
33
39
|
|
40
|
+
RETRY_DELAY = 0.1 # seconds
|
41
|
+
|
34
42
|
def raw_call(path, method, body = {}, args = {})
|
35
43
|
url = NationBuilder::URL.new(base_url).generate_url(path, args)
|
36
44
|
|
@@ -51,8 +59,7 @@ class NationBuilder::Client
|
|
51
59
|
request_args[:body] = JSON(body)
|
52
60
|
end
|
53
61
|
|
54
|
-
|
55
|
-
return parse_response_body(response)
|
62
|
+
perform_request_with_retries(method, url, request_args)
|
56
63
|
end
|
57
64
|
|
58
65
|
def call(endpoint_name, method_name, args={})
|
@@ -64,22 +71,52 @@ class NationBuilder::Client
|
|
64
71
|
return raw_call(method.uri, method.http_method, nonmethod_args, args)
|
65
72
|
end
|
66
73
|
|
74
|
+
def perform_request_with_retries(method, url, request_args)
|
75
|
+
raw_response = HTTPClient.send(method, url, request_args)
|
76
|
+
parsed_response = nil
|
77
|
+
|
78
|
+
@retries.times do |i|
|
79
|
+
begin
|
80
|
+
parsed_response = parse_response_body(raw_response)
|
81
|
+
rescue NationBuilder::RateLimitedError
|
82
|
+
Kernel.sleep(RETRY_DELAY * 2**i)
|
83
|
+
rescue => e
|
84
|
+
raise e
|
85
|
+
else
|
86
|
+
break
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
set_response(raw_response)
|
91
|
+
parsed_response
|
92
|
+
end
|
93
|
+
|
67
94
|
def set_response(value)
|
68
95
|
Thread.current[:nationbuilder_rb_response] = value
|
69
96
|
end
|
70
97
|
|
98
|
+
# This getter is used for fetching the raw response
|
71
99
|
def response
|
72
100
|
Thread.current[:nationbuilder_rb_response]
|
73
101
|
end
|
74
102
|
|
75
|
-
|
103
|
+
def classify_response_error(response)
|
104
|
+
case
|
105
|
+
when response.code == 429
|
106
|
+
return NationBuilder::RateLimitedError.new(response.body)
|
107
|
+
when response.code.to_s.start_with?('4')
|
108
|
+
return NationBuilder::ClientError.new(response.body)
|
109
|
+
when response.code.to_s.start_with?('5')
|
110
|
+
return NationBuilder::ServerError.new(response.body)
|
111
|
+
end
|
112
|
+
end
|
76
113
|
|
77
114
|
def parse_response_body(response)
|
78
|
-
|
115
|
+
error = classify_response_error(response)
|
116
|
+
raise error if error
|
79
117
|
|
80
118
|
if response.header['Content-Type'].first != 'application/json'
|
81
|
-
return
|
82
|
-
raise ServerResponseError.new("Non-JSON content-type for server response: #{response.body}")
|
119
|
+
return nil
|
83
120
|
end
|
84
121
|
|
85
122
|
body = response.body.strip
|
data/nationbuilder-rb.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: nationbuilder-rb 1.
|
5
|
+
# stub: nationbuilder-rb 1.2.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "nationbuilder-rb"
|
9
|
-
s.version = "1.
|
9
|
+
s.version = "1.2.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["David Huie"]
|
14
|
-
s.date = "2015-02-
|
14
|
+
s.date = "2015-02-17"
|
15
15
|
s.description = "A Ruby client to the NationBuilder API"
|
16
16
|
s.email = "david@nationbuilder.com"
|
17
17
|
s.executables = ["nbdoc"]
|
@@ -37,6 +37,7 @@ Gem::Specification.new do |s|
|
|
37
37
|
"lib/nationbuilder/api_spec.json",
|
38
38
|
"lib/nationbuilder/client.rb",
|
39
39
|
"lib/nationbuilder/endpoint.rb",
|
40
|
+
"lib/nationbuilder/errors.rb",
|
40
41
|
"lib/nationbuilder/method.rb",
|
41
42
|
"lib/nationbuilder/paginator.rb",
|
42
43
|
"lib/nationbuilder/parameter.rb",
|
@@ -62,26 +63,26 @@ Gem::Specification.new do |s|
|
|
62
63
|
|
63
64
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
64
65
|
s.add_runtime_dependency(%q<httpclient>, ["~> 2.4.0"])
|
65
|
-
s.add_development_dependency(%q<jeweler>, ["~> 2.0
|
66
|
-
s.add_development_dependency(%q<rspec>, ["~> 2
|
67
|
-
s.add_development_dependency(%q<simplecov>, ["~> 0.8
|
68
|
-
s.add_development_dependency(%q<vcr>, ["~> 2.9
|
69
|
-
s.add_development_dependency(%q<webmock>, ["~> 1.18
|
66
|
+
s.add_development_dependency(%q<jeweler>, ["~> 2.0"])
|
67
|
+
s.add_development_dependency(%q<rspec>, ["~> 3.2"])
|
68
|
+
s.add_development_dependency(%q<simplecov>, ["~> 0.8"])
|
69
|
+
s.add_development_dependency(%q<vcr>, ["~> 2.9"])
|
70
|
+
s.add_development_dependency(%q<webmock>, ["~> 1.18"])
|
70
71
|
else
|
71
72
|
s.add_dependency(%q<httpclient>, ["~> 2.4.0"])
|
72
|
-
s.add_dependency(%q<jeweler>, ["~> 2.0
|
73
|
-
s.add_dependency(%q<rspec>, ["~> 2
|
74
|
-
s.add_dependency(%q<simplecov>, ["~> 0.8
|
75
|
-
s.add_dependency(%q<vcr>, ["~> 2.9
|
76
|
-
s.add_dependency(%q<webmock>, ["~> 1.18
|
73
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0"])
|
74
|
+
s.add_dependency(%q<rspec>, ["~> 3.2"])
|
75
|
+
s.add_dependency(%q<simplecov>, ["~> 0.8"])
|
76
|
+
s.add_dependency(%q<vcr>, ["~> 2.9"])
|
77
|
+
s.add_dependency(%q<webmock>, ["~> 1.18"])
|
77
78
|
end
|
78
79
|
else
|
79
80
|
s.add_dependency(%q<httpclient>, ["~> 2.4.0"])
|
80
|
-
s.add_dependency(%q<jeweler>, ["~> 2.0
|
81
|
-
s.add_dependency(%q<rspec>, ["~> 2
|
82
|
-
s.add_dependency(%q<simplecov>, ["~> 0.8
|
83
|
-
s.add_dependency(%q<vcr>, ["~> 2.9
|
84
|
-
s.add_dependency(%q<webmock>, ["~> 1.18
|
81
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0"])
|
82
|
+
s.add_dependency(%q<rspec>, ["~> 3.2"])
|
83
|
+
s.add_dependency(%q<simplecov>, ["~> 0.8"])
|
84
|
+
s.add_dependency(%q<vcr>, ["~> 2.9"])
|
85
|
+
s.add_dependency(%q<webmock>, ["~> 1.18"])
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
@@ -17,7 +17,7 @@ http_interactions:
|
|
17
17
|
- application/json
|
18
18
|
response:
|
19
19
|
status:
|
20
|
-
code:
|
20
|
+
code: 200
|
21
21
|
message: Conflict
|
22
22
|
headers:
|
23
23
|
Server:
|
@@ -76,6 +76,6 @@ http_interactions:
|
|
76
76
|
LOS ANGELES\",\"closed_invoices_amount_in_cents\":null,\"closed_invoices_count\":null,\"contact_status_id\":null,\"contact_status_name\":null,\"could_vote_status\":null,\"demo\":\"\",\"donations_amount_in_cents\":0,\"donations_amount_this_cycle_in_cents\":0,\"donations_count\":0,\"donations_count_this_cycle\":0,\"donations_pledged_amount_in_cents\":0,\"donations_raised_amount_in_cents\":0,\"donations_raised_amount_this_cycle_in_cents\":0,\"donations_raised_count\":0,\"donations_raised_count_this_cycle\":0,\"donations_to_raise_amount_in_cents\":0,\"email1\":\"bob@example.com\",\"email1_is_bad\":false,\"email2\":null,\"email2_is_bad\":false,\"email3\":null,\"email3_is_bad\":false,\"email4\":null,\"email4_is_bad\":false,\"ethnicity\":\"\",\"facebook_address\":null,\"facebook_profile_url\":null,\"facebook_updated_at\":null,\"facebook_username\":null,\"fax_number\":\"\",\"federal_donotcall\":false,\"first_donated_at\":null,\"first_fundraised_at\":null,\"first_invoice_at\":null,\"first_prospect_at\":null,\"first_recruited_at\":null,\"first_supporter_at\":\"2014-04-24T10:27:34-07:00\",\"first_volunteer_at\":\"2014-09-02T13:10:28-07:00\",\"full_name\":\"Bob
|
77
77
|
Smith\",\"home_address\":null,\"import_id\":null,\"inferred_party\":\"\",\"inferred_support_level\":null,\"invoice_payments_amount_in_cents\":null,\"invoice_payments_referred_amount_in_cents\":null,\"invoices_amount_in_cents\":null,\"invoices_count\":null,\"is_deceased\":false,\"is_donor\":false,\"is_fundraiser\":false,\"is_ignore_donation_limits\":false,\"is_leaderboardable\":true,\"is_mobile_bad\":false,\"is_possible_duplicate\":false,\"is_profile_private\":false,\"is_profile_searchable\":true,\"is_prospect\":false,\"is_supporter\":true,\"is_survey_question_private\":false,\"language\":\"\",\"last_call_id\":null,\"last_contacted_at\":null,\"last_contacted_by\":null,\"last_donated_at\":null,\"last_fundraised_at\":null,\"last_invoice_at\":null,\"last_rule_violation_at\":null,\"legal_name\":null,\"locale\":\"\",\"mailing_address\":null,\"marital_status\":\"\",\"media_market_name\":null,\"meetup_address\":null,\"membership_expires_at\":null,\"membership_level_name\":null,\"membership_started_at\":null,\"middle_name\":null,\"mobile_normalized\":null,\"nbec_precinct_code\":null,\"note_updated_at\":null,\"outstanding_invoices_amount_in_cents\":null,\"outstanding_invoices_count\":null,\"overdue_invoices_count\":null,\"page_slug\":\"ticket_page\",\"parent\":null,\"parent_id\":null,\"party_member\":false,\"phone_normalized\":\"2135551234\",\"phone_time\":\"\",\"precinct_code\":null,\"precinct_name\":null,\"prefix\":null,\"previous_party\":\"\",\"primary_email_id\":1,\"priority_level\":null,\"priority_level_changed_at\":null,\"profile_content\":null,\"profile_content_html\":null,\"profile_headline\":null,\"received_capital_amount_in_cents\":17700,\"recruiter\":null,\"recruits_count\":0,\"registered_address\":null,\"registered_at\":null,\"religion\":\"\",\"rule_violations_count\":0,\"spent_capital_amount_in_cents\":1000,\"submitted_address\":\"\",\"subnations\":[],\"suffix\":null,\"support_level_changed_at\":null,\"support_probability_score\":null,\"turnout_probability_score\":null,\"twitter_address\":null,\"twitter_description\":null,\"twitter_followers_count\":null,\"twitter_friends_count\":null,\"twitter_location\":null,\"twitter_login\":null,\"twitter_updated_at\":null,\"twitter_website\":null,\"unsubscribed_at\":null,\"user_submitted_address\":{\"address1\":\"488
|
78
78
|
S Hill St\",\"address2\":null,\"address3\":null,\"city\":\"Los Angeles\",\"state\":\"CA\",\"country_code\":\"US\",\"zip\":\"90013\",\"lat\":\"34.0490467\",\"lng\":\"-118.2515224\"},\"username\":\"randomeveguy\",\"warnings_count\":0,\"website\":null,\"work_address\":null,\"bag_preference\":null,\"do_you_drive_a_fork_lift\":null,\"have_you_ever_been_contacted_by_a_union_representative_before_\":null,\"have_you_been_involved_in_an_election_campaign_before_\":null,\"sub_branch\":null,\"sams_custom_field\":null,\"mrow\":null,\"received_an_email\":null,\"brett_petition_mc\":null,\"headshot_url\":null,\"university\":null,\"membership_number\":null},\"precinct\":null}"
|
79
|
-
http_version:
|
79
|
+
http_version:
|
80
80
|
recorded_at: Thu, 05 Feb 2015 05:54:33 GMT
|
81
81
|
recorded_with: VCR 2.9.2
|
@@ -4,13 +4,14 @@ describe NationBuilder::Client do
|
|
4
4
|
|
5
5
|
let(:client) do
|
6
6
|
NationBuilder::Client.new('organizeralexandreschmitt',
|
7
|
-
'53920a524356034a065515a37650df2bd295971975d5742b9daa50eb8c7404d5'
|
7
|
+
'53920a524356034a065515a37650df2bd295971975d5742b9daa50eb8c7404d5',
|
8
|
+
retries: 2)
|
8
9
|
end
|
9
10
|
|
10
11
|
describe '#endpoints' do
|
11
12
|
|
12
13
|
it 'should contain all defined endpoints' do
|
13
|
-
client.endpoints.sort.
|
14
|
+
expect(client.endpoints.sort).to eq([
|
14
15
|
:basic_pages,
|
15
16
|
:blog_posts,
|
16
17
|
:blogs,
|
@@ -38,7 +39,7 @@ describe NationBuilder::Client do
|
|
38
39
|
describe '#base_url' do
|
39
40
|
|
40
41
|
it 'should contain the nation slug' do
|
41
|
-
client.base_url.
|
42
|
+
expect(client.base_url).to eq('https://organizeralexandreschmitt.nationbuilder.com')
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
@@ -48,7 +49,7 @@ describe NationBuilder::Client do
|
|
48
49
|
VCR.use_cassette('parametered_get') do
|
49
50
|
response = client.call(:basic_pages, :index, site_slug: 'organizeralexandreschmitt')
|
50
51
|
response['results'].each do |result|
|
51
|
-
result['site_slug'].
|
52
|
+
expect(result['site_slug']).to eq('organizeralexandreschmitt')
|
52
53
|
end
|
53
54
|
end
|
54
55
|
end
|
@@ -66,7 +67,7 @@ describe NationBuilder::Client do
|
|
66
67
|
client.call(:people, :create, params)
|
67
68
|
end
|
68
69
|
|
69
|
-
response['person']['first_name'].
|
70
|
+
expect(response['person']['first_name']).to eq('Bob')
|
70
71
|
end
|
71
72
|
|
72
73
|
it 'should handle a DELETE' do
|
@@ -78,7 +79,51 @@ describe NationBuilder::Client do
|
|
78
79
|
client.call(:people, :destroy, params)
|
79
80
|
end
|
80
81
|
|
81
|
-
response.
|
82
|
+
expect(response).to eq(nil)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#classify_response_error' do
|
87
|
+
it 'should account for rate limits' do
|
88
|
+
response = double(code: 429, body: 'rate limiting')
|
89
|
+
expect(client.classify_response_error(response).class).
|
90
|
+
to eq(NationBuilder::RateLimitedError)
|
91
|
+
end
|
92
|
+
it 'should account for client errors' do
|
93
|
+
response = double(code: 404, body: '404ing')
|
94
|
+
expect(client.classify_response_error(response).class).
|
95
|
+
to eq(NationBuilder::ClientError)
|
96
|
+
end
|
97
|
+
it 'should account for client errors' do
|
98
|
+
response = double(code: 500, body: '500ing')
|
99
|
+
expect(client.classify_response_error(response).class).
|
100
|
+
to eq(NationBuilder::ServerError)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe '#perform_request_with_retries' do
|
105
|
+
before do
|
106
|
+
expect(HTTPClient).to receive(:send)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should raise non-rate limiting execeptions' do
|
110
|
+
expect(client).to receive(:parse_response_body) { raise StandardError.new('boom') }
|
111
|
+
expect do
|
112
|
+
client.perform_request_with_retries(nil, nil, nil)
|
113
|
+
end.to raise_error
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should return a response if the rate limit is eventually dropped' do
|
117
|
+
expect(Kernel).to receive(:sleep).twice
|
118
|
+
allow(client).to receive(:parse_response_body) do
|
119
|
+
@count ||= 0
|
120
|
+
if @count != 2
|
121
|
+
raise NationBuilder::RateLimitedError.new
|
122
|
+
end
|
123
|
+
end
|
124
|
+
expect do
|
125
|
+
client.perform_request_with_retries(nil, nil, nil)
|
126
|
+
end.to_not raise_error
|
82
127
|
end
|
83
128
|
end
|
84
129
|
end
|
@@ -19,26 +19,26 @@ describe Paginator do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'should check for next and prev page link' do
|
22
|
-
@page1.next
|
23
|
-
@page1.prev
|
22
|
+
expect(@page1.next?).to_not be_nil
|
23
|
+
expect(@page1.prev?).to be_nil
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'should return next page' do
|
27
27
|
VCR.use_cassette('paginated_get_page2') do
|
28
28
|
page2 = @page1.next
|
29
|
-
page2.body.
|
29
|
+
expect(page2.body).to_not eq(@page1.body)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'should return additional pages' do
|
34
34
|
VCR.use_cassette('paginated_get_page3') do
|
35
35
|
page3 = @page2.next
|
36
|
-
page3.body.
|
36
|
+
expect(page3.body).to_not eq(@page2.body)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'should return nil if no prev page' do
|
41
|
-
@page1.prev.
|
41
|
+
expect(@page1.prev).to be_nil
|
42
42
|
end
|
43
43
|
end
|
44
|
-
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nationbuilder-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Huie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httpclient
|
@@ -30,70 +30,70 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.0
|
33
|
+
version: '2.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.0
|
40
|
+
version: '2.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2
|
47
|
+
version: '3.2'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 2
|
54
|
+
version: '3.2'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: simplecov
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.8
|
61
|
+
version: '0.8'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.8
|
68
|
+
version: '0.8'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: vcr
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 2.9
|
75
|
+
version: '2.9'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 2.9
|
82
|
+
version: '2.9'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: webmock
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 1.18
|
89
|
+
version: '1.18'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 1.18
|
96
|
+
version: '1.18'
|
97
97
|
description: A Ruby client to the NationBuilder API
|
98
98
|
email: david@nationbuilder.com
|
99
99
|
executables:
|
@@ -120,6 +120,7 @@ files:
|
|
120
120
|
- lib/nationbuilder/api_spec.json
|
121
121
|
- lib/nationbuilder/client.rb
|
122
122
|
- lib/nationbuilder/endpoint.rb
|
123
|
+
- lib/nationbuilder/errors.rb
|
123
124
|
- lib/nationbuilder/method.rb
|
124
125
|
- lib/nationbuilder/paginator.rb
|
125
126
|
- lib/nationbuilder/parameter.rb
|