gibbon 3.0.2 → 3.3.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of gibbon might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.travis.yml +6 -4
- data/CHANGELOG.md +23 -1
- data/CODE_OF_CONDUCT.md +76 -0
- data/LICENSE.txt +1 -1
- data/README.markdown +48 -7
- data/gibbon.gemspec +3 -3
- data/lib/gibbon.rb +1 -0
- data/lib/gibbon/api_request.rb +9 -7
- data/lib/gibbon/export.rb +93 -0
- data/lib/gibbon/request.rb +9 -1
- data/lib/gibbon/version.rb +2 -2
- data/spec/gibbon/api_request_spec.rb +50 -36
- data/spec/gibbon/export_spec.rb +32 -0
- data/spec/gibbon/gibbon_spec.rb +10 -1
- data/spec/gibbon/mailchimp_error_spec.rb +49 -0
- metadata +12 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d116d72d4ffa666a00c6f1a9829f98e916036193564370d545872d7902d2a562
|
4
|
+
data.tar.gz: 51889994e6f00e418846932611c5b901678ff1610c7ff4d0b26d0ed367512af5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbb61ecde87bce694487e2cc3d640c6c028a263daa63b5a7b37cfce662fbbcaeb338da84b089584dc994074201e3518627b60ccc206989b3290822565a294fbf
|
7
|
+
data.tar.gz: 404210a9577aaf10984ed9da977606928a2a95b244aa7c55224d3630b6a03dcda1cee7e943325b845142f395d30cc5cf02b4fb9d9f12f200b03e7233ae4fbec3
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
## [Unreleased][unreleased]
|
2
2
|
|
3
|
+
## [3.3.1] - 2019-11-08
|
4
|
+
- Fix statically setting `faraday_adapter` did not set adapter on new requests
|
5
|
+
|
6
|
+
## [3.3.0] - 2019-10-02
|
7
|
+
- Fixed compatibility with Faraday 0.16.2+
|
8
|
+
- Set minimum Ruby to 2.3.8
|
9
|
+
|
10
|
+
## [3.2.1] - 2017-11-08
|
11
|
+
- Set minimum Ruby to 2.1
|
12
|
+
|
13
|
+
## [3.2.0] - 2017-11-08
|
14
|
+
- Force TLS version 1.2
|
15
|
+
|
16
|
+
## [3.1.1] - 2017-09-25
|
17
|
+
- Fix MailChimpError initialization
|
18
|
+
|
19
|
+
## [3.1.0] - 2017-07-27
|
20
|
+
- Add back support for Export API until MailChimp stops supporting it
|
21
|
+
- Implement `responds_to_missing`
|
22
|
+
|
3
23
|
## [3.0.2] - 2017-05-08
|
4
24
|
- Fix subtle bug in `symbolize_keys` when parsing error
|
5
25
|
|
@@ -69,7 +89,9 @@
|
|
69
89
|
## [1.1.4] - 2012-11-04
|
70
90
|
- Fix JSON::ParserError on export calls that return blank results
|
71
91
|
|
72
|
-
[unreleased]: https://github.com/amro/gibbon/compare/v3.0
|
92
|
+
[unreleased]: https://github.com/amro/gibbon/compare/v3.1.0...HEAD
|
93
|
+
[3.1.0]: https://github.com/amro/gibbon/compare/v3.0.2...v3.1.0
|
94
|
+
[3.0.2]: https://github.com/amro/gibbon/compare/v3.0.1...v3.0.2
|
73
95
|
[3.0.1]: https://github.com/amro/gibbon/compare/v3.0.0...v3.0.1
|
74
96
|
[3.0.0]: https://github.com/amro/gibbon/compare/v2.2.5...v3.0.0
|
75
97
|
[2.2.5]: https://github.com/amro/gibbon/compare/v2.2.4...v2.2.5
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
9
|
+
level of experience, education, socio-economic status, nationality, personal
|
10
|
+
appearance, race, religion, or sexual identity and orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at amromousa@gmail.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
72
|
+
|
73
|
+
[homepage]: https://www.contributor-covenant.org
|
74
|
+
|
75
|
+
For answers to common questions about this code of conduct, see
|
76
|
+
https://www.contributor-covenant.org/faq
|
data/LICENSE.txt
CHANGED
data/README.markdown
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
Gibbon is an API wrapper for MailChimp's [API](http://kb.mailchimp.com/api/).
|
4
4
|
|
5
5
|
[![Build Status](https://secure.travis-ci.org/amro/gibbon.svg)](http://travis-ci.org/amro/gibbon)
|
6
|
-
[![Dependency Status](https://gemnasium.com/amro/gibbon.svg)](https://gemnasium.com/amro/gibbon)
|
7
6
|
|
8
7
|
## Important Notes
|
9
8
|
|
@@ -27,7 +26,7 @@ First, create a *one-time use instance* of `Gibbon::Request`:
|
|
27
26
|
gibbon = Gibbon::Request.new(api_key: "your_api_key")
|
28
27
|
```
|
29
28
|
|
30
|
-
***Note*** Only reuse instances of Gibbon after terminating a call with a verb, which makes a request. Requests are light weight objects that update an internal path based on your call chain. When you terminate a call chain with a verb, a request instance makes a request
|
29
|
+
***Note*** Only reuse instances of Gibbon after terminating a call with a verb, which makes a request. Requests are light weight objects that update an internal path based on your call chain. When you terminate a call chain with a verb, a request instance makes a request and resets the path.
|
31
30
|
|
32
31
|
You can set an individual request's `timeout` and `open_timeout` like this:
|
33
32
|
|
@@ -111,7 +110,7 @@ Gibbon::Request.logger = MyLogger.new
|
|
111
110
|
|
112
111
|
### Lists
|
113
112
|
|
114
|
-
Fetch
|
113
|
+
Fetch first page of lists:
|
115
114
|
|
116
115
|
```ruby
|
117
116
|
gibbon.lists.retrieve
|
@@ -131,7 +130,7 @@ gibbon.lists(list_id).members.retrieve
|
|
131
130
|
|
132
131
|
### Subscribers
|
133
132
|
|
134
|
-
Get
|
133
|
+
Get first page of subscribers for a list:
|
135
134
|
|
136
135
|
```ruby
|
137
136
|
gibbon.lists(list_id).members.retrieve
|
@@ -179,6 +178,21 @@ Get a specific member's information (open/click rates etc.) from MailChimp:
|
|
179
178
|
gibbon.lists(list_id).members(lower_case_md5_hashed_email_address).retrieve
|
180
179
|
```
|
181
180
|
|
181
|
+
### Tags
|
182
|
+
|
183
|
+
[Tags](https://mailchimp.com/help/getting-started-tags/) are a flexible way to organize (slice and dice) your list: for example, you can send a campaign directly to one or more tags.
|
184
|
+
|
185
|
+
Add tags to a subscriber:
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
gibbon.lists(list_id).members(Digest::MD5.hexdigest(email)).tags.create(
|
189
|
+
body: {
|
190
|
+
tags: [{name:"referred-from-xyz", status:"active"},{name:"pro-plan",status:"active"}]
|
191
|
+
}
|
192
|
+
)
|
193
|
+
```
|
194
|
+
|
195
|
+
|
182
196
|
### Batch Operations
|
183
197
|
|
184
198
|
Any API call that can be made directly can also be organized into batch operations. Performing batch operations requires you to generate a hash for each individual API call and pass them as an `Array` to the Batch endpoint.
|
@@ -237,7 +251,7 @@ gibbon.lists(list_id).members.retrieve(params: {"fields": "members.email_address
|
|
237
251
|
|
238
252
|
### Campaigns
|
239
253
|
|
240
|
-
Get
|
254
|
+
Get first page of campaigns:
|
241
255
|
|
242
256
|
```ruby
|
243
257
|
campaigns = gibbon.campaigns.retrieve
|
@@ -458,6 +472,33 @@ Gibbon 2.x+:
|
|
458
472
|
```ruby
|
459
473
|
gibbon.lists(list_id).members.create(body: {email_address: "foo@bar.com", status: "subscribed", merge_fields: {FNAME: "Bob", LNAME: "Smith"}})
|
460
474
|
```
|
475
|
+
## Export API 1.0
|
476
|
+
|
477
|
+
Gibbon 3.0.0+ supports MailChimp's [Export API 1.0](https://apidocs.mailchimp.com/export/1.0/). You can choose to handle the API response all at
|
478
|
+
once or line by line by passing a block. To access the Export API with Gibbon, you must first create an instance of `Gibbon::Export`:
|
479
|
+
|
480
|
+
```ruby
|
481
|
+
export = Gibbon::Export.new(api_key: "your_api_key")
|
482
|
+
```
|
483
|
+
|
484
|
+
Next, call the method corresponding to the API endpoint you'd like to query:
|
485
|
+
|
486
|
+
```ruby
|
487
|
+
export.list(id: list_id)
|
488
|
+
```
|
489
|
+
|
490
|
+
This fetches and returns all of the results at once. Pass a block if you'd like to handle the response as individual lines:
|
491
|
+
|
492
|
+
```ruby
|
493
|
+
export = Gibbon::Export.new(api_key: "your_api_key", timeout: 1200)
|
494
|
+
export.list(id: list_id) do |row|
|
495
|
+
puts row
|
496
|
+
end
|
497
|
+
```
|
498
|
+
|
499
|
+
This is useful when handling large sets of data. Setting the `timeout` here is optional, but a high value is recommended given the nature of the Export API. The default timeout is 600 seconds.
|
500
|
+
|
501
|
+
Gibbon supports all current Export API endpoints: `/list`, `/ecommOrders`, and `/campaignSubscriberActivity`. They're mapped onto Ruby methods with similar names: `list()`, `ecomm_orders()`, and `campaign_subscriber_activity()` respectively. Please see [MailChimp's API documentation](https://developer.mailchimp.com/documentation/mailchimp/guides/how-to-use-the-export-api/) for supported parameters.
|
461
502
|
|
462
503
|
## Thanks
|
463
504
|
|
@@ -465,5 +506,5 @@ Thanks to everyone who has [contributed](https://github.com/amro/gibbon/contribu
|
|
465
506
|
|
466
507
|
## Copyright
|
467
508
|
|
468
|
-
* Copyright (c) 2010-
|
469
|
-
* MailChimp (c) 2001-
|
509
|
+
* Copyright (c) 2010-2020 Amro Mousa. See LICENSE.txt for details.
|
510
|
+
* MailChimp (c) 2001-2020 The Rocket Science Group.
|
data/gibbon.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.email = ["amromousa@gmail.com"]
|
10
10
|
s.homepage = "http://github.com/amro/gibbon"
|
11
11
|
|
12
|
-
s.summary = %q{A wrapper for MailChimp API 3.0}
|
13
|
-
s.description = %q{A wrapper for MailChimp API 3.0}
|
12
|
+
s.summary = %q{A wrapper for MailChimp API 3.0 and Export API}
|
13
|
+
s.description = %q{A wrapper for MailChimp API 3.0 and Export API}
|
14
14
|
s.license = "MIT"
|
15
15
|
|
16
16
|
s.rubyforge_project = "gibbon"
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
20
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
21
|
s.require_paths = ["lib"]
|
22
|
-
s.required_ruby_version = '>= 2.
|
22
|
+
s.required_ruby_version = '>= 2.3.8'
|
23
23
|
|
24
24
|
s.add_dependency('faraday', '>= 0.9.1')
|
25
25
|
s.add_dependency('multi_json', '>= 1.11.0')
|
data/lib/gibbon.rb
CHANGED
data/lib/gibbon/api_request.rb
CHANGED
@@ -102,14 +102,17 @@ module Gibbon
|
|
102
102
|
def symbolize_keys
|
103
103
|
@request_builder.symbolize_keys
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
# Helpers
|
107
107
|
|
108
108
|
def handle_error(error)
|
109
109
|
error_params = {}
|
110
110
|
|
111
111
|
begin
|
112
|
-
|
112
|
+
# Faraday::ClientError is used in Faraday 0.16.0+
|
113
|
+
# Faraday::Error::ClientError was used before 0.16.0
|
114
|
+
client_error = error.is_a?(Faraday::ClientError) || error.is_a?(Faraday::Error::ClientError)
|
115
|
+
if client_error && error.response
|
113
116
|
error_params[:status_code] = error.response[:status]
|
114
117
|
error_params[:raw_body] = error.response[:body]
|
115
118
|
|
@@ -146,7 +149,7 @@ module Gibbon
|
|
146
149
|
end
|
147
150
|
|
148
151
|
def rest_client
|
149
|
-
client = Faraday.new(self.api_url, proxy: self.proxy) do |faraday|
|
152
|
+
client = Faraday.new(self.api_url, proxy: self.proxy, ssl: { version: "TLSv1_2" }) do |faraday|
|
150
153
|
faraday.response :raise_error
|
151
154
|
faraday.adapter adapter
|
152
155
|
if @request_builder.debug
|
@@ -157,7 +160,7 @@ module Gibbon
|
|
157
160
|
client
|
158
161
|
end
|
159
162
|
|
160
|
-
def parse_response(response)
|
163
|
+
def parse_response(response)
|
161
164
|
parsed_response = nil
|
162
165
|
|
163
166
|
if response.body && !response.body.empty?
|
@@ -166,9 +169,8 @@ module Gibbon
|
|
166
169
|
body = MultiJson.load(response.body, symbolize_keys: symbolize_keys)
|
167
170
|
parsed_response = Response.new(headers: headers, body: body)
|
168
171
|
rescue MultiJson::ParseError
|
169
|
-
|
170
|
-
error
|
171
|
-
error.status_code = 500
|
172
|
+
error_params = { title: "UNPARSEABLE_RESPONSE", status_code: 500 }
|
173
|
+
error = MailChimpError.new("Unparseable response: #{response.body}", error_params)
|
172
174
|
raise error
|
173
175
|
end
|
174
176
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
|
3
|
+
module Gibbon
|
4
|
+
class Export
|
5
|
+
include Helpers
|
6
|
+
|
7
|
+
attr_accessor :api_key, :timeout
|
8
|
+
|
9
|
+
def initialize(api_key: nil, timeout: nil)
|
10
|
+
@api_key = api_key || self.class.api_key
|
11
|
+
@timeout = timeout || self.class.timeout || 600
|
12
|
+
end
|
13
|
+
|
14
|
+
def list(params = {}, &block)
|
15
|
+
call("list", params, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def ecomm_orders(params = {}, &block)
|
19
|
+
call("ecommOrders", params, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def campaign_subscriber_activity(params = {}, &block)
|
23
|
+
call("campaignSubscriberActivity", params, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def export_api_url
|
29
|
+
"https://#{get_data_center_from_api_key(@api_key)}api.mailchimp.com/export/1.0/"
|
30
|
+
end
|
31
|
+
|
32
|
+
def call(method, params = {}, &block)
|
33
|
+
rows = []
|
34
|
+
|
35
|
+
api_url = export_api_url + method + "/"
|
36
|
+
params = params.merge({ apikey: @api_key })
|
37
|
+
block = Proc.new { |row| rows << row } unless block_given?
|
38
|
+
|
39
|
+
ensure_api_key(params)
|
40
|
+
|
41
|
+
url = URI.parse(api_url)
|
42
|
+
req = Net::HTTP::Post.new(url.path, initheader = {'Content-Type' => 'application/json'})
|
43
|
+
req.body = MultiJson.dump(params)
|
44
|
+
Net::HTTP.start(url.host, url.port, read_timeout: @timeout, use_ssl: true, ssl_version: :TLSv1_2) do |http|
|
45
|
+
# http://stackoverflow.com/questions/29598196/ruby-net-http-read-body-nethttpokread-body-called-twice-ioerror
|
46
|
+
http.request req do |response|
|
47
|
+
i = -1
|
48
|
+
last = ''
|
49
|
+
response.read_body do |chunk|
|
50
|
+
next if chunk.nil? or chunk.strip.empty?
|
51
|
+
infix = "\n" if last[-1, 1]==']'
|
52
|
+
lines, last = try_parse_line("#{last}#{infix}#{chunk}")
|
53
|
+
lines.each { |line| block.call(line, i += 1) }
|
54
|
+
end
|
55
|
+
block.call(parse_line(last), i += 1) unless last.nil? or last.empty?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
rows unless block_given?
|
59
|
+
end
|
60
|
+
|
61
|
+
def try_parse_line(res)
|
62
|
+
lines = res.split("\n")
|
63
|
+
last = lines.pop || ''
|
64
|
+
lines.map! { |line| parse_line(line) }
|
65
|
+
[lines.compact, last]
|
66
|
+
rescue MultiJson::ParseError
|
67
|
+
[[], last]
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def parse_line(line)
|
72
|
+
parsed_response = MultiJson.load(line)
|
73
|
+
rescue MultiJson::ParseError
|
74
|
+
return []
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def ensure_api_key(params)
|
80
|
+
unless params[:apikey] && (get_data_center_from_api_key(params[:apikey]) != "")
|
81
|
+
raise Gibbon::GibbonError, "You must set an api_key prior to making a call"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class << self
|
86
|
+
attr_accessor :api_key, :timeout
|
87
|
+
|
88
|
+
def method_missing(sym, *args, &block)
|
89
|
+
new(api_key: self.api_key, timeout: self.timeout).send(sym, *args, &block)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/gibbon/request.rb
CHANGED
@@ -13,7 +13,7 @@ module Gibbon
|
|
13
13
|
@timeout = timeout || self.class.timeout || DEFAULT_TIMEOUT
|
14
14
|
@open_timeout = open_timeout || self.class.open_timeout || DEFAULT_OPEN_TIMEOUT
|
15
15
|
@proxy = proxy || self.class.proxy || ENV['MAILCHIMP_PROXY']
|
16
|
-
@faraday_adapter = faraday_adapter || Faraday.default_adapter
|
16
|
+
@faraday_adapter = faraday_adapter || self.class.faraday_adapter || Faraday.default_adapter
|
17
17
|
@symbolize_keys = symbolize_keys || self.class.symbolize_keys || false
|
18
18
|
@debug = debug || self.class.debug || false
|
19
19
|
@logger = logger || self.class.logger || ::Logger.new(STDOUT)
|
@@ -27,6 +27,10 @@ module Gibbon
|
|
27
27
|
self
|
28
28
|
end
|
29
29
|
|
30
|
+
def respond_to_missing?(method_name, include_private = false)
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
30
34
|
def send(*args)
|
31
35
|
if args.length == 0
|
32
36
|
method_missing(:send, args)
|
@@ -81,6 +85,10 @@ module Gibbon
|
|
81
85
|
def method_missing(sym, *args, &block)
|
82
86
|
new(api_key: self.api_key, api_endpoint: self.api_endpoint, timeout: self.timeout, open_timeout: self.open_timeout, faraday_adapter: self.faraday_adapter, symbolize_keys: self.symbolize_keys, debug: self.debug, proxy: self.proxy, logger: self.logger).send(sym, *args, &block)
|
83
87
|
end
|
88
|
+
|
89
|
+
def respond_to_missing?(method_name, include_private = false)
|
90
|
+
true
|
91
|
+
end
|
84
92
|
end
|
85
93
|
end
|
86
94
|
end
|
data/lib/gibbon/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Gibbon
|
2
|
-
VERSION = "3.
|
3
|
-
end
|
2
|
+
VERSION = "3.3.1"
|
3
|
+
end
|
@@ -9,52 +9,66 @@ describe Gibbon::APIRequest do
|
|
9
9
|
@api_root = "https://apikey:#{api_key}@us1.api.mailchimp.com/3.0"
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
it "surfaces an unparseable client request exception as a Gibbon::MailChimpError" do
|
19
|
-
exception = Faraday::Error::ClientError.new(
|
20
|
-
"the server responded with status 503")
|
21
|
-
stub_request(:get, "#{@api_root}/lists").to_raise(exception)
|
22
|
-
expect { @gibbon.lists.retrieve }.to raise_error(Gibbon::MailChimpError)
|
23
|
-
end
|
12
|
+
shared_examples_for 'client error handling' do
|
13
|
+
it "surfaces client request exceptions as a Gibbon::MailChimpError" do
|
14
|
+
exception = error_class.new("the server responded with status 503")
|
15
|
+
stub_request(:get, "#{@api_root}/lists").to_raise(exception)
|
16
|
+
expect { @gibbon.lists.retrieve }.to raise_error(Gibbon::MailChimpError)
|
17
|
+
end
|
24
18
|
|
25
|
-
|
26
|
-
|
27
|
-
|
19
|
+
it "surfaces an unparseable client request exception as a Gibbon::MailChimpError" do
|
20
|
+
exception = error_class.new(
|
21
|
+
"the server responded with status 503")
|
22
|
+
stub_request(:get, "#{@api_root}/lists").to_raise(exception)
|
23
|
+
expect { @gibbon.lists.retrieve }.to raise_error(Gibbon::MailChimpError)
|
24
|
+
end
|
28
25
|
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
it "surfaces an unparseable response body as a Gibbon::MailChimpError" do
|
27
|
+
response_values = {:status => 503, :headers => {}, :body => '[foo]'}
|
28
|
+
exception = error_class.new("the server responded with status 503", response_values)
|
32
29
|
|
33
|
-
|
34
|
-
|
35
|
-
response_values = {:status => 503, :headers => {}, :body => 'A non JSON response'}
|
36
|
-
exception = Faraday::Error::ClientError.new("the server responded with status 503", response_values)
|
37
|
-
api_request = Gibbon::APIRequest.new(builder: Gibbon::Request)
|
38
|
-
begin
|
39
|
-
api_request.send :handle_error, exception
|
40
|
-
rescue => boom
|
41
|
-
expect(boom.status_code).to eq 503
|
42
|
-
expect(boom.raw_body).to eq "A non JSON response"
|
43
|
-
end
|
30
|
+
stub_request(:get, "#{@api_root}/lists").to_raise(exception)
|
31
|
+
expect { @gibbon.lists.retrieve }.to raise_error(Gibbon::MailChimpError)
|
44
32
|
end
|
45
33
|
|
46
|
-
context "
|
47
|
-
it "
|
48
|
-
response_values = {:status =>
|
49
|
-
exception =
|
50
|
-
api_request = Gibbon::APIRequest.new(builder: Gibbon::Request
|
34
|
+
context "handle_error" do
|
35
|
+
it "includes status and raw body even when json can't be parsed" do
|
36
|
+
response_values = {:status => 503, :headers => {}, :body => 'A non JSON response'}
|
37
|
+
exception = error_class.new("the server responded with status 503", response_values)
|
38
|
+
api_request = Gibbon::APIRequest.new(builder: Gibbon::Request)
|
51
39
|
begin
|
52
40
|
api_request.send :handle_error, exception
|
53
41
|
rescue => boom
|
54
|
-
expect(boom.
|
55
|
-
expect(boom.
|
42
|
+
expect(boom.status_code).to eq 503
|
43
|
+
expect(boom.raw_body).to eq "A non JSON response"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when symbolize_keys is true" do
|
48
|
+
it "sets title and detail on the error params" do
|
49
|
+
response_values = {:status => 422, :headers => {}, :body => '{"title": "foo", "detail": "bar"}'}
|
50
|
+
exception = error_class.new("the server responded with status 422", response_values)
|
51
|
+
api_request = Gibbon::APIRequest.new(builder: Gibbon::Request.new(symbolize_keys: true))
|
52
|
+
begin
|
53
|
+
api_request.send :handle_error, exception
|
54
|
+
rescue => boom
|
55
|
+
expect(boom.title).to eq "foo"
|
56
|
+
expect(boom.detail).to eq "bar"
|
57
|
+
end
|
56
58
|
end
|
57
59
|
end
|
58
60
|
end
|
59
61
|
end
|
62
|
+
|
63
|
+
context 'Faraday::Error::ClientError' do
|
64
|
+
let(:error_class) { Faraday::Error::ClientError }
|
65
|
+
|
66
|
+
include_examples 'client error handling'
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'Faraday::ClientError' do
|
70
|
+
let(:error_class) { Faraday::ClientError }
|
71
|
+
|
72
|
+
include_examples 'client error handling'
|
73
|
+
end
|
60
74
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'webmock/rspec'
|
3
|
+
|
4
|
+
describe Gibbon::Export do
|
5
|
+
before do
|
6
|
+
Gibbon::Export.send(:public, *Gibbon::Export.protected_instance_methods)
|
7
|
+
@export = Gibbon::Export.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "doesn't allow empty api key" do
|
11
|
+
expect {@export.list(id: "123456")}.to raise_error(Gibbon::GibbonError)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "doesn't allow api key without data center" do
|
15
|
+
@api_key = "123"
|
16
|
+
@export.api_key = @api_key
|
17
|
+
expect {@export.list(id: "123456")}.to raise_error(Gibbon::GibbonError)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "sets correct endpoint from api key" do
|
21
|
+
@api_key = "TESTKEY-us1"
|
22
|
+
@export.api_key = @api_key
|
23
|
+
expect(@export.export_api_url).to eq("https://us1.api.mailchimp.com/export/1.0/")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "sets correct timeout" do
|
27
|
+
@api_key = "TESTKEY-us1"
|
28
|
+
@export.api_key = @api_key
|
29
|
+
@export.timeout = 9
|
30
|
+
expect(@export.timeout).to eq(9)
|
31
|
+
end
|
32
|
+
end
|
data/spec/gibbon/gibbon_spec.rb
CHANGED
@@ -73,7 +73,7 @@ describe Gibbon do
|
|
73
73
|
expect(@gibbon.proxy).to be_nil
|
74
74
|
end
|
75
75
|
|
76
|
-
it "sets
|
76
|
+
it "sets a proxy url key from the 'MAILCHIMP_PROXY' ENV variable" do
|
77
77
|
ENV['MAILCHIMP_PROXY'] = @proxy
|
78
78
|
@gibbon = Gibbon::Request.new
|
79
79
|
expect(@gibbon.proxy).to eq(@proxy)
|
@@ -222,4 +222,13 @@ describe Gibbon do
|
|
222
222
|
expect(Gibbon::Request.new.logger).to eq(logger)
|
223
223
|
end
|
224
224
|
end
|
225
|
+
|
226
|
+
describe "missing methods" do
|
227
|
+
it "respond to .method call on class" do
|
228
|
+
expect(Gibbon::Request.method(:lists)).to be_a(Method)
|
229
|
+
end
|
230
|
+
it "respond to .method call on instance" do
|
231
|
+
expect(Gibbon::Request.new.method(:lists)).to be_a(Method)
|
232
|
+
end
|
233
|
+
end
|
225
234
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gibbon::MailChimpError do
|
4
|
+
let(:message) { 'Foo' }
|
5
|
+
let(:params) do
|
6
|
+
{
|
7
|
+
title: 'error_title',
|
8
|
+
detail: 'error_detail',
|
9
|
+
body: 'error_body',
|
10
|
+
raw_body: 'error_raw_body',
|
11
|
+
status_code: 'error_status_code'
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
@gibbon = Gibbon::MailChimpError.new(message, params)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "adds the error params to the error message" do
|
20
|
+
expected_message = "Foo " \
|
21
|
+
"@title=\"error_title\", " \
|
22
|
+
"@detail=\"error_detail\", " \
|
23
|
+
"@body=\"error_body\", " \
|
24
|
+
"@raw_body=\"error_raw_body\", " \
|
25
|
+
"@status_code=\"error_status_code\""
|
26
|
+
|
27
|
+
expect(@gibbon.message).to eq(expected_message)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'sets the title attribute' do
|
31
|
+
expect(@gibbon.title).to eq(params[:title])
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'sets the detail attribute' do
|
35
|
+
expect(@gibbon.detail).to eq(params[:detail])
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'sets the body attribute' do
|
39
|
+
expect(@gibbon.body).to eq(params[:body])
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'sets the raw_body attribute' do
|
43
|
+
expect(@gibbon.raw_body).to eq(params[:raw_body])
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'sets the status_code attribute' do
|
47
|
+
expect(@gibbon.status_code).to eq(params[:status_code])
|
48
|
+
end
|
49
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gibbon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Amro Mousa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -80,7 +80,7 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 1.21.0
|
83
|
-
description: A wrapper for MailChimp API 3.0
|
83
|
+
description: A wrapper for MailChimp API 3.0 and Export API
|
84
84
|
email:
|
85
85
|
- amromousa@gmail.com
|
86
86
|
executables: []
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- ".gitignore"
|
92
92
|
- ".travis.yml"
|
93
93
|
- CHANGELOG.md
|
94
|
+
- CODE_OF_CONDUCT.md
|
94
95
|
- Gemfile
|
95
96
|
- LICENSE.txt
|
96
97
|
- README.markdown
|
@@ -98,6 +99,7 @@ files:
|
|
98
99
|
- gibbon.gemspec
|
99
100
|
- lib/gibbon.rb
|
100
101
|
- lib/gibbon/api_request.rb
|
102
|
+
- lib/gibbon/export.rb
|
101
103
|
- lib/gibbon/gibbon_error.rb
|
102
104
|
- lib/gibbon/gibbon_helpers.rb
|
103
105
|
- lib/gibbon/mailchimp_error.rb
|
@@ -105,7 +107,9 @@ files:
|
|
105
107
|
- lib/gibbon/response.rb
|
106
108
|
- lib/gibbon/version.rb
|
107
109
|
- spec/gibbon/api_request_spec.rb
|
110
|
+
- spec/gibbon/export_spec.rb
|
108
111
|
- spec/gibbon/gibbon_spec.rb
|
112
|
+
- spec/gibbon/mailchimp_error_spec.rb
|
109
113
|
- spec/gibbon/upsert_spec.rb
|
110
114
|
- spec/spec_helper.rb
|
111
115
|
homepage: http://github.com/amro/gibbon
|
@@ -120,20 +124,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
120
124
|
requirements:
|
121
125
|
- - ">="
|
122
126
|
- !ruby/object:Gem::Version
|
123
|
-
version: 2.
|
127
|
+
version: 2.3.8
|
124
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
129
|
requirements:
|
126
130
|
- - ">="
|
127
131
|
- !ruby/object:Gem::Version
|
128
132
|
version: '0'
|
129
133
|
requirements: []
|
130
|
-
|
131
|
-
rubygems_version: 2.4.6
|
134
|
+
rubygems_version: 3.0.6
|
132
135
|
signing_key:
|
133
136
|
specification_version: 4
|
134
|
-
summary: A wrapper for MailChimp API 3.0
|
137
|
+
summary: A wrapper for MailChimp API 3.0 and Export API
|
135
138
|
test_files:
|
136
139
|
- spec/gibbon/api_request_spec.rb
|
140
|
+
- spec/gibbon/export_spec.rb
|
137
141
|
- spec/gibbon/gibbon_spec.rb
|
142
|
+
- spec/gibbon/mailchimp_error_spec.rb
|
138
143
|
- spec/gibbon/upsert_spec.rb
|
139
144
|
- spec/spec_helper.rb
|